This source file includes following definitions.
- edit_load_status_update_cb
- edit_load_file_fast
- edit_find_filter
- edit_get_filter
- edit_insert_stream
- check_file_access
- edit_load_file
- edit_load_position
- edit_save_position
- edit_purge_widget
- edit_pop_undo_action
- edit_pop_redo_action
- get_prev_undo_action
- edit_modification
- is_in_indent
- is_blank
- edit_find_line
- edit_move_up_paragraph
- edit_move_down_paragraph
- edit_begin_page
- edit_end_page
- edit_move_to_top
- edit_move_to_bottom
- edit_cursor_to_bol
- edit_cursor_to_eol
- my_type_of
- edit_left_word_move
- edit_left_word_move_cmd
- edit_right_word_move
- edit_right_word_move_cmd
- edit_right_char_move_cmd
- edit_left_char_move_cmd
- edit_move_updown
- edit_right_delete_word
- edit_left_delete_word
- edit_do_undo
- edit_do_redo
- edit_group_undo
- edit_delete_to_line_end
- edit_delete_to_line_begin
- is_aligned_on_a_tab
- right_of_four_spaces
- left_of_four_spaces
- edit_auto_indent
- edit_double_newline
- insert_spaces_tab
- edit_tab_cmd
- check_and_wrap_line
- edit_get_bracket
- edit_goto_matching_bracket
- edit_move_block_to_right
- edit_move_block_to_left
- edit_print_string
- edit_insert_column_from_file
- edit_user_menu
- edit_get_write_filter
- edit_write_stream
- is_break_char
- edit_insert_file
- edit_init
- edit_clean
- edit_reload_line
- edit_set_codeset
- edit_push_undo_action
- edit_push_redo_action
- edit_insert
- edit_insert_ahead
- edit_insert_over
- edit_delete
- edit_backspace
- edit_cursor_move
- edit_move_forward3
- edit_get_cursor_offset
- edit_get_col
- edit_update_curs_row
- edit_update_curs_col
- edit_get_curs_col
- edit_scroll_upward
- edit_scroll_downward
- edit_scroll_right
- edit_scroll_left
- edit_move_to_prev_col
- edit_line_is_blank
- edit_move_to_line
- edit_move_display
- edit_push_markers
- edit_set_markers
- eval_marks
- edit_mark_cmd
- edit_mark_current_word_cmd
- edit_mark_current_line_cmd
- edit_delete_line
- edit_push_key_press
- edit_find_bracket
- edit_execute_key_command
- edit_execute_cmd
- edit_stack_init
- edit_stack_free
- edit_move_up
- edit_move_down
- edit_arg_vpath_new
- edit_arg_new
- edit_arg_init
- edit_arg_assign
- edit_arg_free
- edit_get_file_name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <config.h>
35 #include <stdio.h>
36 #include <stdarg.h>
37 #include <sys/types.h>
38 #include <unistd.h>
39 #include <string.h>
40 #include <ctype.h>
41 #include <sys/stat.h>
42 #include <stdint.h>
43 #include <stdlib.h>
44
45 #include "lib/global.h"
46
47 #include "lib/tty/color.h"
48 #include "lib/tty/tty.h"
49 #include "lib/tty/key.h"
50 #include "lib/skin.h"
51 #include "lib/fileloc.h"
52 #include "lib/vfs/vfs.h"
53 #include "lib/strutil.h"
54 #include "lib/util.h"
55 #include "lib/timefmt.h"
56 #include "lib/lock.h"
57 #include "lib/widget.h"
58 #include "lib/charsets.h"
59
60 #include "src/usermenu.h"
61
62 #include "src/keymap.h"
63 #include "src/util.h"
64
65 #include "edit-impl.h"
66 #include "editwidget.h"
67 #include "editsearch.h"
68 #include "editcomplete.h"
69 #include "editmacros.h"
70 #include "etags.h"
71 #ifdef HAVE_ASPELL
72 #include "spell.h"
73 #endif
74
75
76
77 edit_options_t edit_options = {
78 .word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH,
79 .typewriter_wrap = FALSE,
80 .auto_para_formatting = FALSE,
81 .fill_tabs_with_spaces = FALSE,
82 .return_does_auto_indent = TRUE,
83 .backspace_through_tabs = FALSE,
84 .fake_half_tabs = TRUE,
85 .persistent_selections = TRUE,
86 .drop_selection_on_copy = TRUE,
87 .cursor_beyond_eol = FALSE,
88 .cursor_after_inserted_block = FALSE,
89 .state_full_filename = FALSE,
90 .line_state = FALSE,
91 .line_state_width = 0,
92 .save_mode = EDIT_QUICK_SAVE,
93 .confirm_save = TRUE,
94 .save_position = TRUE,
95 .syntax_highlighting = TRUE,
96 .group_undo = FALSE,
97 .backup_ext = NULL,
98 .filesize_threshold = NULL,
99 .stop_format_chars = NULL,
100 .visible_tabs = TRUE,
101 .visible_tws = TRUE,
102 .show_right_margin = FALSE,
103 .simple_statusbar = FALSE,
104 .check_nl_at_eof = FALSE,
105 };
106
107 int max_undo = 32768;
108
109 gboolean enable_show_tabs_tws = TRUE;
110
111 unsigned int edit_stack_iterator = 0;
112 edit_arg_t edit_history_moveto[MAX_HISTORY_MOVETO];
113
114 const char VERTICAL_MAGIC[] = { '\1', '\1', '\1', '\1', '\n' };
115
116
117
118 #define TEMP_BUF_LEN 1024
119
120 #define space_width 1
121
122
123
124
125
126
127
128
129
130
131
132 static const struct edit_filters
133 {
134 const char *read, *write, *extension;
135 } all_filters[] = {
136 { "xz -cd %s 2>&1", "xz > %s", ".xz" },
137 { "zstd -cd %s 2>&1", "zstd > %s", ".zst" },
138 { "lz4 -cd %s 2>&1", "lz4 > %s", ".lz4" },
139 { "lzip -cd %s 2>&1", "lzip > %s", ".lz" },
140 { "lzma -cd %s 2>&1", "lzma > %s", ".lzma" },
141 { "lzop -cd %s 2>&1", "lzop > %s", ".lzo" },
142 { "bzip2 -cd %s 2>&1", "bzip2 > %s", ".bz2" },
143 { "gzip -cd %s 2>&1", "gzip > %s", ".gz" },
144 { "gzip -cd %s 2>&1", "gzip > %s", ".Z" },
145 };
146
147 static const off_t filesize_default_threshold = 64 * 1024 * 1024;
148
149
150
151
152
153 static int
154 edit_load_status_update_cb (status_msg_t *sm)
155 {
156 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
157 edit_buffer_read_file_status_msg_t *rsm = (edit_buffer_read_file_status_msg_t *) sm;
158 Widget *wd = WIDGET (sm->dlg);
159
160 if (verbose)
161 label_set_textv (ssm->label, _ ("Loading: %3d%%"),
162 edit_buffer_calc_percent (rsm->buf, rsm->loaded));
163 else
164 label_set_text (ssm->label, _ ("Loading..."));
165
166 if (rsm->first)
167 {
168 Widget *lw = WIDGET (ssm->label);
169 WRect r;
170
171 r = wd->rect;
172 r.cols = MAX (r.cols, lw->rect.cols + 6);
173 widget_set_size_rect (wd, &r);
174 r = lw->rect;
175 r.x = wd->rect.x + (wd->rect.cols - r.cols) / 2;
176 widget_set_size_rect (lw, &r);
177 rsm->first = FALSE;
178 }
179
180 return status_msg_common_update (sm);
181 }
182
183
184
185
186
187
188
189
190 static gboolean
191 edit_load_file_fast (edit_buffer_t *buf, const vfs_path_t *filename_vpath)
192 {
193 int file;
194 gboolean ret;
195 edit_buffer_read_file_status_msg_t rsm;
196 gboolean aborted;
197
198 file = mc_open (filename_vpath, O_RDONLY | O_BINARY);
199 if (file < 0)
200 {
201 file_error_message (_ ("Cannot open\n%s"), vfs_path_as_str (filename_vpath));
202 return FALSE;
203 }
204
205 rsm.first = TRUE;
206 rsm.buf = buf;
207 rsm.loaded = 0;
208
209 status_msg_init (STATUS_MSG (&rsm), _ ("Load file"), 1.0, simple_status_msg_init_cb,
210 edit_load_status_update_cb, NULL);
211
212 ret = (edit_buffer_read_file (buf, file, buf->size, &rsm, &aborted) == buf->size);
213
214 status_msg_deinit (STATUS_MSG (&rsm));
215
216 if (!ret && !aborted)
217 message (D_ERROR, MSG_ERROR, _ ("Error reading %s"), vfs_path_as_str (filename_vpath));
218
219 mc_close (file);
220 return ret;
221 }
222
223
224
225
226 static int
227 edit_find_filter (const vfs_path_t *filename_vpath)
228 {
229 if (filename_vpath != NULL)
230 {
231 const char *s;
232 size_t i;
233
234 s = vfs_path_as_str (filename_vpath);
235
236 for (i = 0; i < G_N_ELEMENTS (all_filters); i++)
237 if (g_str_has_suffix (s, all_filters[i].extension))
238 return i;
239 }
240
241 return -1;
242 }
243
244
245
246 static char *
247 edit_get_filter (const vfs_path_t *filename_vpath)
248 {
249 int i;
250 char *quoted_name;
251 char *p = NULL;
252
253 i = edit_find_filter (filename_vpath);
254 if (i < 0)
255 return NULL;
256
257 quoted_name = name_quote (vfs_path_as_str (filename_vpath), FALSE);
258 if (quoted_name != NULL)
259 {
260 p = g_strdup_printf (all_filters[i].read, quoted_name);
261 g_free (quoted_name);
262 }
263
264 return p;
265 }
266
267
268
269 static off_t
270 edit_insert_stream (WEdit *edit, FILE *f)
271 {
272 int c;
273 off_t i;
274
275 for (i = 0; (c = fgetc (f)) >= 0; i++)
276 edit_insert (edit, c);
277
278 return i;
279 }
280
281
282
283
284
285
286
287
288
289
290
291 static gboolean
292 check_file_access (WEdit *edit, const vfs_path_t *filename_vpath, struct stat *st)
293 {
294 static uintmax_t threshold = UINTMAX_MAX;
295 int file;
296 gchar *errmsg = NULL;
297 gboolean ret = TRUE;
298
299
300 file = mc_open (filename_vpath, O_NONBLOCK | O_RDONLY | O_BINARY, 0666);
301 if (file < 0)
302 {
303
304
305
306
307 file = mc_open (filename_vpath, O_NONBLOCK | O_RDONLY | O_BINARY | O_CREAT | O_EXCL, 0666);
308 if (file < 0)
309 {
310 file_error_message (_ ("Cannot open\n%s"), vfs_path_as_str (filename_vpath));
311 return FALSE;
312 }
313
314
315 edit->delete_file = 1;
316 }
317
318
319 if (mc_fstat (file, st) < 0)
320 {
321 file_error_message (_ ("Cannot stat\n%s"), vfs_path_as_str (filename_vpath));
322 return FALSE;
323 }
324
325
326 if (!S_ISREG (st->st_mode))
327 {
328 errmsg =
329 g_strdup_printf (_ ("%s\nis not a regular file"), vfs_path_as_str (filename_vpath));
330 goto cleanup;
331 }
332
333
334 if (threshold == UINTMAX_MAX)
335 {
336 gboolean err = FALSE;
337
338 threshold = parse_integer (edit_options.filesize_threshold, &err);
339 if (err)
340 threshold = filesize_default_threshold;
341 }
342
343
344
345
346
347 if (st->st_size > 0)
348 edit->delete_file = 0;
349
350 if ((uintmax_t) st->st_size > threshold)
351 {
352 int act;
353
354 errmsg = g_strdup_printf (_ ("File \"%s\" is too large.\nOpen it anyway?"),
355 vfs_path_as_str (filename_vpath));
356 act = edit_query_dialog2 (_ ("Warning"), errmsg, _ ("&Yes"), _ ("&No"));
357 MC_PTR_FREE (errmsg);
358
359 if (act != 0)
360 ret = FALSE;
361 }
362
363 cleanup:
364 (void) mc_close (file);
365
366 if (errmsg != NULL)
367 {
368 message (D_ERROR, MSG_ERROR, "%s", errmsg);
369 g_free (errmsg);
370 ret = FALSE;
371 }
372
373 return ret;
374 }
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390 static gboolean
391 edit_load_file (WEdit *edit)
392 {
393 gboolean fast_load = TRUE;
394
395
396 if (edit_find_filter (edit->filename_vpath) >= 0)
397 fast_load = FALSE;
398
399
400
401
402
403 if (edit->filename_vpath != NULL)
404 {
405
406
407
408
409 if (!vfs_file_is_local (edit->filename_vpath))
410 fast_load = FALSE;
411
412
413 if (!check_file_access (edit, edit->filename_vpath, &edit->stat1))
414 {
415 edit_clean (edit);
416 return FALSE;
417 }
418 }
419 else
420 {
421
422 fast_load = FALSE;
423 }
424
425 if (fast_load)
426 {
427 edit_buffer_init (&edit->buffer, edit->stat1.st_size);
428
429 if (!edit_load_file_fast (&edit->buffer, edit->filename_vpath))
430 {
431 edit_clean (edit);
432 return FALSE;
433 }
434 }
435 else
436 {
437 edit_buffer_init (&edit->buffer, 0);
438
439 if (edit->filename_vpath != NULL
440 && *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) != '\0')
441 {
442 edit->undo_stack_disable = 1;
443 if (edit_insert_file (edit, edit->filename_vpath) < 0)
444 {
445 edit_clean (edit);
446 return FALSE;
447 }
448 edit->undo_stack_disable = 0;
449 }
450 }
451 edit->lb = LB_ASIS;
452 return TRUE;
453 }
454
455
456
457
458
459
460
461
462
463
464 static void
465 edit_load_position (WEdit *edit, gboolean load_position)
466 {
467 long line, column;
468 off_t offset;
469 off_t b;
470
471 if (edit->filename_vpath == NULL
472 || *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) == '\0')
473 return;
474
475 load_file_position (edit->filename_vpath, &line, &column, &offset, &edit->serialized_bookmarks);
476
477 book_mark_restore (edit, BOOK_MARK_COLOR);
478
479 if (!load_position)
480 return;
481
482 if (line > 0)
483 {
484 edit_move_to_line (edit, line - 1);
485 edit->prev_col = column;
486 }
487 else if (offset > 0)
488 {
489 edit_cursor_move (edit, offset);
490 line = edit->buffer.curs_line;
491 edit->search_start = edit->buffer.curs1;
492 }
493
494 b = edit_buffer_get_current_bol (&edit->buffer);
495 edit_move_to_prev_col (edit, b);
496 edit_move_display (edit, line - (WIDGET (edit)->rect.lines / 2));
497 }
498
499
500
501
502 static void
503 edit_save_position (WEdit *edit)
504 {
505 if (edit->filename_vpath == NULL
506 || *(vfs_path_get_by_index (edit->filename_vpath, 0)->path) == '\0')
507 return;
508
509 book_mark_serialize (edit, BOOK_MARK_COLOR);
510 save_file_position (edit->filename_vpath, edit->buffer.curs_line + 1, edit->curs_col,
511 edit->buffer.curs1, edit->serialized_bookmarks);
512 edit->serialized_bookmarks = NULL;
513 }
514
515
516
517
518 static void
519 edit_purge_widget (WEdit *edit)
520 {
521 size_t len = sizeof (WEdit) - sizeof (Widget);
522 char *start = (char *) edit + sizeof (Widget);
523 memset (start, 0, len);
524 }
525
526
527
528
529
530
531
532
533 static long
534 edit_pop_undo_action (WEdit *edit)
535 {
536 long c;
537 unsigned long sp = edit->undo_stack_pointer;
538
539 if (sp == edit->undo_stack_bottom)
540 return STACK_BOTTOM;
541
542 sp = (sp - 1) & edit->undo_stack_size_mask;
543 c = edit->undo_stack[sp];
544 if (c >= 0)
545 {
546
547 edit->undo_stack_pointer = (edit->undo_stack_pointer - 1) & edit->undo_stack_size_mask;
548 return c;
549 }
550
551 if (sp == edit->undo_stack_bottom)
552 return STACK_BOTTOM;
553
554 c = edit->undo_stack[(sp - 1) & edit->undo_stack_size_mask];
555 if (edit->undo_stack[sp] == -2)
556 {
557
558 edit->undo_stack_pointer = sp;
559 }
560 else
561 edit->undo_stack[sp]++;
562
563 return c;
564 }
565
566
567
568 static long
569 edit_pop_redo_action (WEdit *edit)
570 {
571 long c;
572 unsigned long sp = edit->redo_stack_pointer;
573
574 if (sp == edit->redo_stack_bottom)
575 return STACK_BOTTOM;
576
577 sp = (sp - 1) & edit->redo_stack_size_mask;
578 c = edit->redo_stack[sp];
579 if (c >= 0)
580 {
581 edit->redo_stack_pointer = (edit->redo_stack_pointer - 1) & edit->redo_stack_size_mask;
582 return c;
583 }
584
585 if (sp == edit->redo_stack_bottom)
586 return STACK_BOTTOM;
587
588 c = edit->redo_stack[(sp - 1) & edit->redo_stack_size_mask];
589 if (edit->redo_stack[sp] == -2)
590 edit->redo_stack_pointer = sp;
591 else
592 edit->redo_stack[sp]++;
593
594 return c;
595 }
596
597
598
599 static long
600 get_prev_undo_action (WEdit *edit)
601 {
602 long c;
603 unsigned long sp = edit->undo_stack_pointer;
604
605 if (sp == edit->undo_stack_bottom)
606 return STACK_BOTTOM;
607
608 sp = (sp - 1) & edit->undo_stack_size_mask;
609 c = edit->undo_stack[sp];
610 if (c >= 0)
611 return c;
612
613 if (sp == edit->undo_stack_bottom)
614 return STACK_BOTTOM;
615
616 c = edit->undo_stack[(sp - 1) & edit->undo_stack_size_mask];
617 return c;
618 }
619
620
621
622
623 static void
624 edit_modification (WEdit *edit)
625 {
626 edit->caches_valid = FALSE;
627
628
629 if (edit->modified == 0 && edit->delete_file == 0)
630 edit->locked = lock_file (edit->filename_vpath);
631 edit->modified = 1;
632 }
633
634
635
636
637
638
639
640
641
642
643
644 static gboolean
645 is_in_indent (const edit_buffer_t *buf)
646 {
647 off_t p;
648
649 for (p = edit_buffer_get_current_bol (buf); p < buf->curs1; p++)
650 if (strchr (" \t", edit_buffer_get_byte (buf, p)) == NULL)
651 return FALSE;
652
653 return TRUE;
654 }
655
656
657
658
659
660
661
662
663
664
665 static gboolean
666 is_blank (const edit_buffer_t *buf, off_t offset)
667 {
668 off_t s, f;
669
670 s = edit_buffer_get_bol (buf, offset);
671 f = edit_buffer_get_eol (buf, offset);
672 for (; s < f; s++)
673 {
674 int c;
675
676 c = edit_buffer_get_byte (buf, s);
677 if (!isspace (c))
678 return FALSE;
679 }
680 return TRUE;
681 }
682
683
684
685
686 static off_t
687 edit_find_line (WEdit *edit, long line)
688 {
689 long i;
690 long j = 0;
691 long m = 2000000000;
692
693 if (!edit->caches_valid)
694 {
695 memset (edit->line_numbers, 0, sizeof (edit->line_numbers));
696 memset (edit->line_offsets, 0, sizeof (edit->line_offsets));
697
698 edit->line_numbers[1] = edit->buffer.curs_line;
699 edit->line_offsets[1] = edit_buffer_get_current_bol (&edit->buffer);
700 edit->line_numbers[2] = edit->buffer.lines;
701 edit->line_offsets[2] = edit_buffer_get_bol (&edit->buffer, edit->buffer.size);
702 edit->caches_valid = TRUE;
703 }
704 if (line >= edit->buffer.lines)
705 return edit->line_offsets[2];
706 if (line <= 0)
707 return 0;
708
709 for (i = 0; i < N_LINE_CACHES; i++)
710 {
711 long n;
712
713 n = labs (edit->line_numbers[i] - line);
714 if (n < m)
715 {
716 m = n;
717 j = i;
718 }
719 }
720 if (m == 0)
721 return edit->line_offsets[j];
722 if (m == 1 && j >= 3)
723 i = j;
724 else
725 i = 3 + (rand () % (N_LINE_CACHES - 3));
726 if (line > edit->line_numbers[j])
727 edit->line_offsets[i] = edit_buffer_get_forward_offset (
728 &edit->buffer, edit->line_offsets[j], line - edit->line_numbers[j], 0);
729 else
730 edit->line_offsets[i] = edit_buffer_get_backward_offset (
731 &edit->buffer, edit->line_offsets[j], edit->line_numbers[j] - line);
732 edit->line_numbers[i] = line;
733 return edit->line_offsets[i];
734 }
735
736
737
738
739
740 static void
741 edit_move_up_paragraph (WEdit *edit, gboolean do_scroll)
742 {
743 long i = 0;
744
745 if (edit->buffer.curs_line > 1)
746 {
747 if (!edit_line_is_blank (edit, edit->buffer.curs_line))
748 {
749 for (i = edit->buffer.curs_line - 1; i != 0; i--)
750 if (edit_line_is_blank (edit, i))
751 break;
752 }
753 else if (edit_line_is_blank (edit, edit->buffer.curs_line - 1))
754 {
755 for (i = edit->buffer.curs_line - 1; i != 0; i--)
756 if (!edit_line_is_blank (edit, i))
757 {
758 i++;
759 break;
760 }
761 }
762 else
763 {
764 for (i = edit->buffer.curs_line - 1; i != 0; i--)
765 if (edit_line_is_blank (edit, i))
766 break;
767 }
768 }
769
770 edit_move_up (edit, edit->buffer.curs_line - i, do_scroll);
771 }
772
773
774
775
776
777 static void
778 edit_move_down_paragraph (WEdit *edit, gboolean do_scroll)
779 {
780 long i;
781
782 if (edit->buffer.curs_line >= edit->buffer.lines - 1)
783 i = edit->buffer.lines;
784 else if (!edit_line_is_blank (edit, edit->buffer.curs_line))
785 {
786 for (i = edit->buffer.curs_line + 1; i != 0; i++)
787 if (edit_line_is_blank (edit, i) || i >= edit->buffer.lines)
788 break;
789 }
790 else if (edit_line_is_blank (edit, edit->buffer.curs_line + 1))
791 {
792 for (i = edit->buffer.curs_line + 1; i != 0; i++)
793 if (!edit_line_is_blank (edit, i) || i > edit->buffer.lines)
794 {
795 i--;
796 break;
797 }
798 }
799 else
800 {
801 for (i = edit->buffer.curs_line + 1; i != 0; i++)
802 if (edit_line_is_blank (edit, i) || i >= edit->buffer.lines)
803 break;
804 }
805 edit_move_down (edit, i - edit->buffer.curs_line, do_scroll);
806 }
807
808
809
810 static void
811 edit_begin_page (WEdit *edit)
812 {
813 edit_update_curs_row (edit);
814 edit_move_up (edit, edit->curs_row, FALSE);
815 }
816
817
818
819 static void
820 edit_end_page (WEdit *edit)
821 {
822 edit_update_curs_row (edit);
823 edit_move_down (edit, WIDGET (edit)->rect.lines - edit->curs_row - (edit->fullscreen ? 1 : 3),
824 FALSE);
825 }
826
827
828
829
830 static void
831 edit_move_to_top (WEdit *edit)
832 {
833 if (edit->buffer.curs_line != 0)
834 {
835 edit_cursor_move (edit, -edit->buffer.curs1);
836 edit_move_to_prev_col (edit, 0);
837 edit->force |= REDRAW_PAGE;
838 edit->search_start = 0;
839 edit_update_curs_row (edit);
840 }
841 }
842
843
844
845
846 static void
847 edit_move_to_bottom (WEdit *edit)
848 {
849 if (edit->buffer.curs_line < edit->buffer.lines)
850 {
851 edit_move_down (edit, edit->buffer.lines - edit->curs_row, FALSE);
852 edit->start_display = edit->buffer.size;
853 edit->start_line = edit->buffer.lines;
854 edit_scroll_upward (edit, WIDGET (edit)->rect.lines - 1);
855 edit->force |= REDRAW_PAGE;
856 }
857 }
858
859
860
861
862 static void
863 edit_cursor_to_bol (WEdit *edit)
864 {
865 off_t b;
866
867 b = edit_buffer_get_current_bol (&edit->buffer);
868 edit_cursor_move (edit, b - edit->buffer.curs1);
869 edit->search_start = edit->buffer.curs1;
870 edit->prev_col = edit_get_col (edit);
871 edit->over_col = 0;
872 }
873
874
875
876
877 static void
878 edit_cursor_to_eol (WEdit *edit)
879 {
880 off_t b;
881
882 b = edit_buffer_get_current_eol (&edit->buffer);
883 edit_cursor_move (edit, b - edit->buffer.curs1);
884 edit->search_start = edit->buffer.curs1;
885 edit->prev_col = edit_get_col (edit);
886 edit->over_col = 0;
887 }
888
889
890
891 static unsigned long
892 my_type_of (int c)
893 {
894 unsigned long r = 0;
895 const char *q;
896 const char chars_move_whole_word[] =
897 "!=&|<>^~ !:;, !'!`!.?!\"!( !) !{ !} !Aa0 !+-*/= |<> ![ !] !\\#! ";
898
899 if (c == 0)
900 return 0;
901 if (c == '!')
902 return 2;
903
904 if (g_ascii_isupper ((gchar) c))
905 c = 'A';
906 else if (g_ascii_islower ((gchar) c))
907 c = 'a';
908 else if (g_ascii_isalpha (c))
909 c = 'a';
910 else if (isdigit (c))
911 c = '0';
912 else if (isspace (c))
913 c = ' ';
914 q = strchr (chars_move_whole_word, c);
915 if (q == NULL)
916 return 0xFFFFFFFFUL;
917
918 do
919 {
920 unsigned long x;
921 const char *p;
922
923 for (x = 1, p = chars_move_whole_word; p < q; p++)
924 if (*p == '!')
925 x <<= 1;
926 r |= x;
927 }
928 while ((q = strchr (q + 1, c)) != NULL);
929
930 return r;
931 }
932
933
934
935 static void
936 edit_left_word_move (WEdit *edit, int s)
937 {
938 while (TRUE)
939 {
940 int c1, c2;
941
942 if (edit->column_highlight && edit->mark1 != edit->mark2 && edit->over_col == 0
943 && edit->buffer.curs1 == edit_buffer_get_current_bol (&edit->buffer))
944 break;
945 edit_cursor_move (edit, -1);
946 if (edit->buffer.curs1 == 0)
947 break;
948 c1 = edit_buffer_get_previous_byte (&edit->buffer);
949 if (c1 == '\n')
950 break;
951 c2 = edit_buffer_get_current_byte (&edit->buffer);
952 if (c2 == '\n')
953 break;
954 if ((my_type_of (c1) & my_type_of (c2)) == 0)
955 break;
956 if (isspace (c1) && !isspace (c2))
957 break;
958 if (s != 0 && !isspace (c1) && isspace (c2))
959 break;
960 }
961 }
962
963
964
965 static void
966 edit_left_word_move_cmd (WEdit *edit)
967 {
968 edit_left_word_move (edit, 0);
969 edit->force |= REDRAW_PAGE;
970 }
971
972
973
974 static void
975 edit_right_word_move (WEdit *edit, int s)
976 {
977 while (TRUE)
978 {
979 int c1, c2;
980
981 if (edit->column_highlight && edit->mark1 != edit->mark2 && edit->over_col == 0
982 && edit->buffer.curs1 == edit_buffer_get_current_eol (&edit->buffer))
983 break;
984 edit_cursor_move (edit, 1);
985 if (edit->buffer.curs1 >= edit->buffer.size)
986 break;
987 c1 = edit_buffer_get_previous_byte (&edit->buffer);
988 if (c1 == '\n')
989 break;
990 c2 = edit_buffer_get_current_byte (&edit->buffer);
991 if (c2 == '\n')
992 break;
993 if ((my_type_of (c1) & my_type_of (c2)) == 0)
994 break;
995 if (isspace (c1) && !isspace (c2))
996 break;
997 if (s != 0 && !isspace (c1) && isspace (c2))
998 break;
999 }
1000 }
1001
1002
1003
1004 static void
1005 edit_right_word_move_cmd (WEdit *edit)
1006 {
1007 edit_right_word_move (edit, 0);
1008 edit->force |= REDRAW_PAGE;
1009 }
1010
1011
1012
1013 static void
1014 edit_right_char_move_cmd (WEdit *edit)
1015 {
1016 int char_length = 1;
1017 int c;
1018
1019 if (edit->utf8)
1020 {
1021 c = edit_buffer_get_utf (&edit->buffer, edit->buffer.curs1, &char_length);
1022 if (char_length < 1)
1023 char_length = 1;
1024 }
1025 else
1026 c = edit_buffer_get_current_byte (&edit->buffer);
1027
1028 if (edit_options.cursor_beyond_eol && c == '\n')
1029 edit->over_col++;
1030 else
1031 edit_cursor_move (edit, char_length);
1032 }
1033
1034
1035
1036 static void
1037 edit_left_char_move_cmd (WEdit *edit)
1038 {
1039 int char_length = 1;
1040
1041 if (edit->column_highlight && edit_options.cursor_beyond_eol && edit->mark1 != edit->mark2
1042 && edit->over_col == 0 && edit->buffer.curs1 == edit_buffer_get_current_bol (&edit->buffer))
1043 return;
1044
1045 if (edit->utf8)
1046 {
1047 edit_buffer_get_prev_utf (&edit->buffer, edit->buffer.curs1, &char_length);
1048 if (char_length < 1)
1049 char_length = 1;
1050 }
1051
1052 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
1053 edit->over_col--;
1054 else
1055 edit_cursor_move (edit, -char_length);
1056 }
1057
1058
1059
1060
1061
1062
1063
1064 static void
1065 edit_move_updown (WEdit *edit, long lines, gboolean do_scroll, gboolean direction)
1066 {
1067 long p;
1068 long l = direction ? edit->buffer.curs_line : edit->buffer.lines - edit->buffer.curs_line;
1069
1070 if (lines > l)
1071 lines = l;
1072
1073 if (lines == 0)
1074 return;
1075
1076 if (lines > 1)
1077 edit->force |= REDRAW_PAGE;
1078 if (do_scroll)
1079 {
1080 if (direction)
1081 edit_scroll_upward (edit, lines);
1082 else
1083 edit_scroll_downward (edit, lines);
1084 }
1085 p = edit_buffer_get_current_bol (&edit->buffer);
1086 p = direction ? edit_buffer_get_backward_offset (&edit->buffer, p, lines)
1087 : edit_buffer_get_forward_offset (&edit->buffer, p, lines, 0);
1088 edit_cursor_move (edit, p - edit->buffer.curs1);
1089 edit_move_to_prev_col (edit, p);
1090
1091
1092 if (edit->buffer.curs1 > 0 && edit->buffer.curs1 + 1 < edit->buffer.size
1093 && edit_buffer_get_current_byte (&edit->buffer) >= 256)
1094 {
1095 edit_right_char_move_cmd (edit);
1096 edit_left_char_move_cmd (edit);
1097 }
1098
1099 edit->search_start = edit->buffer.curs1;
1100 edit->found_len = 0;
1101 }
1102
1103
1104
1105 static void
1106 edit_right_delete_word (WEdit *edit)
1107 {
1108 while (edit->buffer.curs1 < edit->buffer.size)
1109 {
1110 int c1, c2;
1111
1112 c1 = edit_delete (edit, TRUE);
1113 if (c1 == '\n')
1114 break;
1115 c2 = edit_buffer_get_current_byte (&edit->buffer);
1116 if (c2 == '\n')
1117 break;
1118 if ((isspace (c1) == 0) != (isspace (c2) == 0))
1119 break;
1120 if ((my_type_of (c1) & my_type_of (c2)) == 0)
1121 break;
1122 }
1123 }
1124
1125
1126
1127 static void
1128 edit_left_delete_word (WEdit *edit)
1129 {
1130 while (edit->buffer.curs1 > 0)
1131 {
1132 int c1, c2;
1133
1134 c1 = edit_backspace (edit, TRUE);
1135 if (c1 == '\n')
1136 break;
1137 c2 = edit_buffer_get_previous_byte (&edit->buffer);
1138 if (c2 == '\n')
1139 break;
1140 if ((isspace (c1) == 0) != (isspace (c2) == 0))
1141 break;
1142 if ((my_type_of (c1) & my_type_of (c2)) == 0)
1143 break;
1144 }
1145 }
1146
1147
1148
1149
1150
1151
1152
1153 static void
1154 edit_do_undo (WEdit *edit)
1155 {
1156 long ac;
1157 long count = 0;
1158
1159 edit->undo_stack_disable = 1;
1160 edit->over_col = 0;
1161
1162 while ((ac = edit_pop_undo_action (edit)) < KEY_PRESS)
1163 {
1164 off_t b;
1165
1166 switch ((int) ac)
1167 {
1168 case STACK_BOTTOM:
1169 goto done_undo;
1170 case CURS_RIGHT:
1171 edit_cursor_move (edit, 1);
1172 break;
1173 case CURS_LEFT:
1174 edit_cursor_move (edit, -1);
1175 break;
1176 case BACKSPACE:
1177 case BACKSPACE_BR:
1178 edit_backspace (edit, TRUE);
1179 break;
1180 case DELCHAR:
1181 case DELCHAR_BR:
1182 edit_delete (edit, TRUE);
1183 break;
1184 case COLUMN_ON:
1185 edit->column_highlight = 1;
1186 break;
1187 case COLUMN_OFF:
1188 edit->column_highlight = 0;
1189 break;
1190 default:
1191 break;
1192 }
1193 if (ac >= 256 && ac < 512)
1194 edit_insert_ahead (edit, ac - 256);
1195 if (ac >= 0 && ac < 256)
1196 edit_insert (edit, ac);
1197
1198 if (ac >= MARK_1 - 2 && ac < MARK_2 - 2)
1199 {
1200 edit->mark1 = ac - MARK_1;
1201 b = edit_buffer_get_bol (&edit->buffer, edit->mark1);
1202 edit->column1 = (long) edit_move_forward3 (edit, b, 0, edit->mark1);
1203 }
1204 if (ac >= MARK_2 - 2 && ac < MARK_CURS - 2)
1205 {
1206 edit->mark2 = ac - MARK_2;
1207 b = edit_buffer_get_bol (&edit->buffer, edit->mark2);
1208 edit->column2 = (long) edit_move_forward3 (edit, b, 0, edit->mark2);
1209 }
1210 else if (ac >= MARK_CURS - 2 && ac < KEY_PRESS)
1211 {
1212 edit->end_mark_curs = ac - MARK_CURS;
1213 }
1214 if (count++)
1215 edit->force |= REDRAW_PAGE;
1216 }
1217
1218 if (edit->start_display > ac - KEY_PRESS)
1219 {
1220 edit->start_line -=
1221 edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display);
1222 edit->force |= REDRAW_PAGE;
1223 }
1224 else if (edit->start_display < ac - KEY_PRESS)
1225 {
1226 edit->start_line +=
1227 edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS);
1228 edit->force |= REDRAW_PAGE;
1229 }
1230 edit->start_display = ac - KEY_PRESS;
1231 edit_update_curs_row (edit);
1232
1233 done_undo:
1234 edit->undo_stack_disable = 0;
1235 }
1236
1237
1238
1239 static void
1240 edit_do_redo (WEdit *edit)
1241 {
1242 long ac;
1243 long count = 0;
1244
1245 if (edit->redo_stack_reset)
1246 return;
1247
1248 edit->over_col = 0;
1249
1250 while ((ac = edit_pop_redo_action (edit)) < KEY_PRESS)
1251 {
1252 off_t b;
1253
1254 switch ((int) ac)
1255 {
1256 case STACK_BOTTOM:
1257 goto done_redo;
1258 case CURS_RIGHT:
1259 edit_cursor_move (edit, 1);
1260 break;
1261 case CURS_LEFT:
1262 edit_cursor_move (edit, -1);
1263 break;
1264 case BACKSPACE:
1265 edit_backspace (edit, TRUE);
1266 break;
1267 case DELCHAR:
1268 edit_delete (edit, TRUE);
1269 break;
1270 case COLUMN_ON:
1271 edit->column_highlight = 1;
1272 break;
1273 case COLUMN_OFF:
1274 edit->column_highlight = 0;
1275 break;
1276 default:
1277 break;
1278 }
1279 if (ac >= 256 && ac < 512)
1280 edit_insert_ahead (edit, ac - 256);
1281 if (ac >= 0 && ac < 256)
1282 edit_insert (edit, ac);
1283
1284 if (ac >= MARK_1 - 2 && ac < MARK_2 - 2)
1285 {
1286 edit->mark1 = ac - MARK_1;
1287 b = edit_buffer_get_bol (&edit->buffer, edit->mark1);
1288 edit->column1 = (long) edit_move_forward3 (edit, b, 0, edit->mark1);
1289 }
1290 else if (ac >= MARK_2 - 2 && ac < KEY_PRESS)
1291 {
1292 edit->mark2 = ac - MARK_2;
1293 b = edit_buffer_get_bol (&edit->buffer, edit->mark2);
1294 edit->column2 = (long) edit_move_forward3 (edit, b, 0, edit->mark2);
1295 }
1296
1297 if (count++ != 0)
1298 edit->force |= REDRAW_PAGE;
1299 }
1300
1301 if (edit->start_display > ac - KEY_PRESS)
1302 {
1303 edit->start_line -=
1304 edit_buffer_count_lines (&edit->buffer, ac - KEY_PRESS, edit->start_display);
1305 edit->force |= REDRAW_PAGE;
1306 }
1307 else if (edit->start_display < ac - KEY_PRESS)
1308 {
1309 edit->start_line +=
1310 edit_buffer_count_lines (&edit->buffer, edit->start_display, ac - KEY_PRESS);
1311 edit->force |= REDRAW_PAGE;
1312 }
1313 edit->start_display = ac - KEY_PRESS;
1314 edit_update_curs_row (edit);
1315
1316 done_redo:;
1317 }
1318
1319
1320
1321 static void
1322 edit_group_undo (WEdit *edit)
1323 {
1324 long ac = KEY_PRESS;
1325 long cur_ac = KEY_PRESS;
1326
1327 while (ac != STACK_BOTTOM && ac == cur_ac)
1328 {
1329 cur_ac = get_prev_undo_action (edit);
1330 edit_do_undo (edit);
1331 ac = get_prev_undo_action (edit);
1332
1333
1334
1335 if (!edit_options.group_undo)
1336 ac = STACK_BOTTOM;
1337 }
1338 }
1339
1340
1341
1342 static void
1343 edit_delete_to_line_end (WEdit *edit)
1344 {
1345 while (edit_buffer_get_current_byte (&edit->buffer) != '\n' && edit->buffer.curs2 != 0)
1346 edit_delete (edit, TRUE);
1347 }
1348
1349
1350
1351 static void
1352 edit_delete_to_line_begin (WEdit *edit)
1353 {
1354 while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 != 0)
1355 edit_backspace (edit, TRUE);
1356 }
1357
1358
1359
1360 static gboolean
1361 is_aligned_on_a_tab (WEdit *edit)
1362 {
1363 long curs_col;
1364
1365 edit_update_curs_col (edit);
1366 curs_col = edit->curs_col % (TAB_SIZE * space_width);
1367 return (curs_col == 0 || curs_col == (HALF_TAB_SIZE * space_width));
1368 }
1369
1370
1371
1372 static gboolean
1373 right_of_four_spaces (WEdit *edit)
1374 {
1375 int i;
1376 int ch = 0;
1377
1378 for (i = 1; i <= HALF_TAB_SIZE; i++)
1379 ch |= edit_buffer_get_byte (&edit->buffer, edit->buffer.curs1 - i);
1380
1381 return (ch == ' ' && is_aligned_on_a_tab (edit));
1382 }
1383
1384
1385
1386 static gboolean
1387 left_of_four_spaces (WEdit *edit)
1388 {
1389 int i, ch = 0;
1390
1391 for (i = 0; i < HALF_TAB_SIZE; i++)
1392 ch |= edit_buffer_get_byte (&edit->buffer, edit->buffer.curs1 + i);
1393
1394 return (ch == ' ' && is_aligned_on_a_tab (edit));
1395 }
1396
1397
1398
1399 static void
1400 edit_auto_indent (WEdit *edit)
1401 {
1402 off_t p;
1403
1404 p = edit->buffer.curs1;
1405
1406 p = edit_buffer_get_backward_offset (&edit->buffer, p, 1);
1407
1408 while (TRUE)
1409 {
1410 char c;
1411
1412 c = edit_buffer_get_byte (&edit->buffer, p++);
1413 if (!whitespace (c))
1414 break;
1415 edit_insert (edit, c);
1416 }
1417 }
1418
1419
1420
1421 static inline void
1422 edit_double_newline (WEdit *edit)
1423 {
1424 edit_insert (edit, '\n');
1425 if (edit_buffer_get_current_byte (&edit->buffer) == '\n'
1426 || edit_buffer_get_byte (&edit->buffer, edit->buffer.curs1 - 2) == '\n')
1427 return;
1428 edit->force |= REDRAW_PAGE;
1429 edit_insert (edit, '\n');
1430 }
1431
1432
1433
1434 static void
1435 insert_spaces_tab (WEdit *edit, gboolean half)
1436 {
1437 long i;
1438
1439 edit_update_curs_col (edit);
1440 i = TAB_SIZE * space_width;
1441 if (half)
1442 i /= 2;
1443 if (i != 0)
1444 for (i = ((edit->curs_col / i) + 1) * i - edit->curs_col; i > 0; i -= space_width)
1445 edit_insert (edit, ' ');
1446 }
1447
1448
1449
1450 static inline void
1451 edit_tab_cmd (WEdit *edit)
1452 {
1453 if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer))
1454 {
1455
1456
1457
1458 if (edit_options.fill_tabs_with_spaces || !right_of_four_spaces (edit))
1459 insert_spaces_tab (edit, TRUE);
1460 else
1461 {
1462 int i;
1463
1464 for (i = 1; i <= HALF_TAB_SIZE; i++)
1465 edit_backspace (edit, TRUE);
1466 edit_insert (edit, '\t');
1467 }
1468 }
1469 else if (edit_options.fill_tabs_with_spaces)
1470 insert_spaces_tab (edit, FALSE);
1471 else
1472 edit_insert (edit, '\t');
1473 }
1474
1475
1476
1477 static void
1478 check_and_wrap_line (WEdit *edit)
1479 {
1480 off_t curs;
1481
1482 if (!edit_options.typewriter_wrap)
1483 return;
1484 edit_update_curs_col (edit);
1485 if (edit->curs_col < edit_options.word_wrap_line_length)
1486 return;
1487 curs = edit->buffer.curs1;
1488 while (TRUE)
1489 {
1490 int c;
1491
1492 curs--;
1493 c = edit_buffer_get_byte (&edit->buffer, curs);
1494 if (c == '\n' || curs <= 0)
1495 {
1496 edit_insert (edit, '\n');
1497 return;
1498 }
1499 if (whitespace (c))
1500 {
1501 off_t current = edit->buffer.curs1;
1502 edit_cursor_move (edit, curs - edit->buffer.curs1 + 1);
1503 edit_insert (edit, '\n');
1504 edit_cursor_move (edit, current - edit->buffer.curs1 + 1);
1505 return;
1506 }
1507 }
1508 }
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520 static off_t
1521 edit_get_bracket (WEdit *edit, gboolean in_screen, unsigned long furthest_bracket_search)
1522 {
1523 const char *const b = "{}{[][()(", *p;
1524 int i = 1, inc = -1, c, d, n = 0;
1525 unsigned long j = 0;
1526 off_t q;
1527
1528 edit_update_curs_row (edit);
1529 c = edit_buffer_get_current_byte (&edit->buffer);
1530 p = strchr (b, c);
1531
1532 if (p == NULL || *p == '\0')
1533 return -1;
1534
1535 d = p[1];
1536
1537 if (strchr ("{[(", c) != NULL)
1538 inc = 1;
1539
1540 if (furthest_bracket_search == 0)
1541 furthest_bracket_search--;
1542 for (q = edit->buffer.curs1 + inc;; q += inc)
1543 {
1544 int a;
1545
1546
1547 if (q >= edit->buffer.size || q < 0)
1548 break;
1549 a = edit_buffer_get_byte (&edit->buffer, q);
1550
1551 if (j++ > furthest_bracket_search)
1552 break;
1553
1554 if (in_screen)
1555 {
1556 if (q < edit->start_display)
1557 break;
1558
1559 if (inc > 0 && a == '\n')
1560 if (n++ >= WIDGET (edit)->rect.lines - edit->curs_row)
1561 break;
1562 }
1563
1564 i += (a == c) - (a == d);
1565
1566 if (i == 0)
1567 return q;
1568 }
1569
1570 return -1;
1571 }
1572
1573
1574
1575 static inline void
1576 edit_goto_matching_bracket (WEdit *edit)
1577 {
1578 off_t q;
1579
1580 q = edit_get_bracket (edit, 0, 0);
1581 if (q >= 0)
1582 {
1583 edit->bracket = edit->buffer.curs1;
1584 edit->force |= REDRAW_PAGE;
1585 edit_cursor_move (edit, q - edit->buffer.curs1);
1586 }
1587 }
1588
1589
1590
1591 static void
1592 edit_move_block_to_right (WEdit *edit)
1593 {
1594 off_t start_mark, end_mark;
1595 long cur_bol, start_bol;
1596
1597 if (!eval_marks (edit, &start_mark, &end_mark))
1598 return;
1599
1600 start_bol = edit_buffer_get_bol (&edit->buffer, start_mark);
1601 cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1);
1602
1603 do
1604 {
1605 off_t b;
1606
1607 edit_cursor_move (edit, cur_bol - edit->buffer.curs1);
1608 if (!edit_line_is_blank (edit, edit->buffer.curs_line))
1609 {
1610 if (edit_options.fill_tabs_with_spaces)
1611 insert_spaces_tab (edit, edit_options.fake_half_tabs);
1612 else
1613 edit_insert (edit, '\t');
1614
1615 b = edit_buffer_get_bol (&edit->buffer, cur_bol);
1616 edit_cursor_move (edit, b - edit->buffer.curs1);
1617 }
1618
1619 if (cur_bol == 0)
1620 break;
1621
1622 cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1);
1623 }
1624 while (cur_bol >= start_bol);
1625
1626 edit->force |= REDRAW_PAGE;
1627 }
1628
1629
1630
1631 static void
1632 edit_move_block_to_left (WEdit *edit)
1633 {
1634 off_t start_mark, end_mark;
1635 off_t cur_bol, start_bol;
1636
1637 if (!eval_marks (edit, &start_mark, &end_mark))
1638 return;
1639
1640 start_bol = edit_buffer_get_bol (&edit->buffer, start_mark);
1641 cur_bol = edit_buffer_get_bol (&edit->buffer, end_mark - 1);
1642
1643 do
1644 {
1645 int del_tab_width;
1646 int next_char;
1647
1648 edit_cursor_move (edit, cur_bol - edit->buffer.curs1);
1649
1650 del_tab_width = edit_options.fake_half_tabs ? HALF_TAB_SIZE : TAB_SIZE;
1651
1652 next_char = edit_buffer_get_current_byte (&edit->buffer);
1653 if (next_char == '\t')
1654 edit_delete (edit, TRUE);
1655 else if (next_char == ' ')
1656 {
1657 int i;
1658
1659 for (i = 0; i < del_tab_width; i++)
1660 {
1661 if (next_char == ' ')
1662 edit_delete (edit, TRUE);
1663 next_char = edit_buffer_get_current_byte (&edit->buffer);
1664 }
1665 }
1666
1667 if (cur_bol == 0)
1668 break;
1669
1670 cur_bol = edit_buffer_get_bol (&edit->buffer, cur_bol - 1);
1671 }
1672 while (cur_bol >= start_bol);
1673
1674 edit->force |= REDRAW_PAGE;
1675 }
1676
1677
1678
1679
1680
1681
1682
1683 static size_t
1684 edit_print_string (WEdit *e, const char *s)
1685 {
1686 size_t i;
1687
1688 for (i = 0; s[i] != '\0'; i++)
1689 edit_execute_cmd (e, CK_InsertChar, (unsigned char) s[i]);
1690 e->force |= REDRAW_COMPLETELY;
1691 edit_update_screen (e);
1692 return i;
1693 }
1694
1695
1696
1697 static off_t
1698 edit_insert_column_from_file (WEdit *edit, int file, off_t *start_pos, off_t *end_pos, long *col1,
1699 long *col2)
1700 {
1701 off_t cursor;
1702 long col;
1703 off_t blocklen = -1, width = 0;
1704 unsigned char *data;
1705
1706 cursor = edit->buffer.curs1;
1707 col = edit_get_col (edit);
1708 data = g_malloc0 (TEMP_BUF_LEN);
1709
1710 while ((blocklen = mc_read (file, (char *) data, TEMP_BUF_LEN)) > 0)
1711 {
1712 off_t i;
1713 char *pn;
1714
1715 pn = strchr ((char *) data, '\n');
1716 width = pn == NULL ? blocklen : pn - (char *) data;
1717
1718 for (i = 0; i < blocklen; i++)
1719 {
1720 if (data[i] != '\n')
1721 edit_insert (edit, data[i]);
1722 else
1723 {
1724 long l;
1725 off_t p;
1726
1727 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
1728 for (l = width - (edit_get_col (edit) - col); l > 0; l -= space_width)
1729 edit_insert (edit, ' ');
1730
1731 for (p = edit->buffer.curs1;; p++)
1732 {
1733 if (p == edit->buffer.size)
1734 {
1735 edit_cursor_move (edit, edit->buffer.size - edit->buffer.curs1);
1736 edit_insert_ahead (edit, '\n');
1737 p++;
1738 break;
1739 }
1740 if (edit_buffer_get_byte (&edit->buffer, p) == '\n')
1741 {
1742 p++;
1743 break;
1744 }
1745 }
1746
1747 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1);
1748
1749 for (l = col - edit_get_col (edit); l >= space_width; l -= space_width)
1750 edit_insert (edit, ' ');
1751 }
1752 }
1753 }
1754 *col1 = col;
1755 *col2 = col + width;
1756 *start_pos = cursor;
1757 *end_pos = edit->buffer.curs1;
1758 edit_cursor_move (edit, cursor - edit->buffer.curs1);
1759 g_free (data);
1760
1761 return blocklen;
1762 }
1763
1764
1765
1766
1767
1768
1769
1770 void
1771 edit_user_menu (WEdit *edit, const char *menu_file, int selected_entry)
1772 {
1773 char *block_file;
1774 struct stat status_before;
1775 vfs_path_t *block_file_vpath;
1776 gboolean modified = FALSE;
1777
1778 block_file = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1779 block_file_vpath = vfs_path_from_str (block_file);
1780
1781 const gboolean status_before_ok = mc_stat (block_file_vpath, &status_before) == 0;
1782
1783
1784 if (user_menu_cmd (CONST_WIDGET (edit), menu_file, selected_entry))
1785 {
1786 struct stat status_after;
1787 const gboolean status_after_ok = mc_stat (block_file_vpath, &status_after) == 0;
1788
1789
1790 modified = (!status_before_ok && status_after_ok)
1791 || (status_before_ok && status_after_ok && status_after.st_size != 0
1792 && (status_after.st_size != status_before.st_size
1793 || status_after.st_mtime != status_before.st_mtime));
1794 }
1795
1796 if (modified)
1797 {
1798 gboolean rc = TRUE;
1799 off_t start_mark, end_mark;
1800
1801 const off_t curs = edit->buffer.curs1;
1802 const gboolean mark = eval_marks (edit, &start_mark, &end_mark);
1803
1804
1805 if (mark)
1806 rc = edit_block_delete_cmd (edit);
1807
1808 if (rc)
1809 {
1810 off_t ins_len;
1811
1812 ins_len = edit_insert_file (edit, block_file_vpath);
1813 if (mark && ins_len > 0)
1814 edit_set_markers (edit, start_mark, start_mark + ins_len, 0, 0);
1815 }
1816
1817
1818 mc_unlink (block_file_vpath);
1819
1820 edit_cursor_move (edit, curs - edit->buffer.curs1);
1821 }
1822
1823 g_free (block_file);
1824 vfs_path_free (block_file_vpath, TRUE);
1825
1826 edit->force |= REDRAW_PAGE;
1827 widget_draw (WIDGET (edit));
1828 }
1829
1830
1831
1832 char *
1833 edit_get_write_filter (const vfs_path_t *write_name_vpath, const vfs_path_t *filename_vpath)
1834 {
1835 int i;
1836 const char *write_name;
1837 char *write_name_quoted;
1838 char *p = NULL;
1839
1840 i = edit_find_filter (filename_vpath);
1841 if (i < 0)
1842 return NULL;
1843
1844 write_name = vfs_path_get_last_path_str (write_name_vpath);
1845 write_name_quoted = name_quote (write_name, FALSE);
1846 if (write_name_quoted != NULL)
1847 {
1848 p = g_strdup_printf (all_filters[i].write, write_name_quoted);
1849 g_free (write_name_quoted);
1850 }
1851 return p;
1852 }
1853
1854
1855
1856
1857
1858
1859
1860
1861 off_t
1862 edit_write_stream (WEdit *edit, FILE *f)
1863 {
1864 long i;
1865
1866 if (edit->lb == LB_ASIS)
1867 {
1868 for (i = 0; i < edit->buffer.size; i++)
1869 if (fputc (edit_buffer_get_byte (&edit->buffer, i), f) < 0)
1870 break;
1871 return i;
1872 }
1873
1874
1875 for (i = 0; i < edit->buffer.size; i++)
1876 {
1877 unsigned char c;
1878
1879 c = edit_buffer_get_byte (&edit->buffer, i);
1880 if (!(c == '\n' || c == '\r'))
1881 {
1882
1883 if (fputc (c, f) < 0)
1884 return i;
1885 }
1886 else
1887 {
1888 unsigned char c1;
1889
1890 c1 = edit_buffer_get_byte (&edit->buffer, i + 1);
1891
1892 switch (edit->lb)
1893 {
1894 case LB_UNIX:
1895
1896 if (fputc ('\n', f) < 0)
1897 return i;
1898
1899 i++;
1900
1901 if (c == '\r' && c1 == '\n')
1902
1903 break;
1904
1905 if (c == '\r' && c1 == '\r')
1906 {
1907
1908 if (fputc ('\n', f) < 0)
1909 return i;
1910 break;
1911 }
1912
1913 if (fputc (c1, f) < 0)
1914 return i;
1915 break;
1916
1917 case LB_WIN:
1918
1919 if (fputc ('\r', f) < 0 || fputc ('\n', f) < 0)
1920 return i;
1921
1922 if (c == '\r' && c1 == '\n')
1923
1924 i++;
1925 break;
1926
1927 case LB_MAC:
1928
1929 if (fputc ('\r', f) < 0)
1930 return i;
1931
1932 i++;
1933
1934 if (c == '\r' && c1 == '\n')
1935
1936 break;
1937
1938 if (c == '\n' && c1 == '\n')
1939 {
1940
1941 if (fputc ('\r', f) < 0)
1942 return i;
1943 break;
1944 }
1945
1946 if (fputc (c1, f) < 0)
1947 return i;
1948 break;
1949 case LB_ASIS:
1950 default:
1951 break;
1952 }
1953 }
1954 }
1955
1956 return edit->buffer.size;
1957 }
1958
1959
1960
1961 gboolean
1962 is_break_char (char c)
1963 {
1964 return (isspace (c) || strchr ("{}[]()<>=|/\\!?~-+`'\",.;:#$%^&*", c) != NULL);
1965 }
1966
1967
1968
1969
1970 off_t
1971 edit_insert_file (WEdit *edit, const vfs_path_t *filename_vpath)
1972 {
1973 char *p;
1974 off_t current;
1975 off_t ins_len = 0;
1976
1977 p = edit_get_filter (filename_vpath);
1978 current = edit->buffer.curs1;
1979
1980 if (p != NULL)
1981 {
1982 FILE *f;
1983
1984 f = (FILE *) popen (p, "r");
1985 if (f != NULL)
1986 {
1987 edit_insert_stream (edit, f);
1988
1989
1990 if (!edit_options.cursor_after_inserted_block)
1991 {
1992 ins_len = edit->buffer.curs1 - current;
1993 edit_cursor_move (edit, -ins_len);
1994 }
1995 if (pclose (f) > 0)
1996 {
1997 message (D_ERROR, MSG_ERROR, _ ("Error reading from pipe: %s"), p);
1998 ins_len = -1;
1999 }
2000 }
2001 else
2002 {
2003 file_error_message (_ ("Cannot open pipe for reading\n%s"), p);
2004 ins_len = -1;
2005 }
2006 g_free (p);
2007 }
2008 else
2009 {
2010 int file;
2011 off_t blocklen;
2012 gboolean vertical_insertion = FALSE;
2013 char *buf;
2014
2015 file = mc_open (filename_vpath, O_RDONLY | O_BINARY);
2016 if (file == -1)
2017 return -1;
2018
2019 buf = g_malloc0 (TEMP_BUF_LEN);
2020 blocklen = mc_read (file, buf, sizeof (VERTICAL_MAGIC));
2021 if (blocklen > 0)
2022 {
2023
2024 if (memcmp (buf, VERTICAL_MAGIC, sizeof (VERTICAL_MAGIC)) == 0)
2025 vertical_insertion = TRUE;
2026 else
2027 mc_lseek (file, 0, SEEK_SET);
2028 }
2029
2030 if (vertical_insertion)
2031 {
2032 off_t mark1, mark2;
2033 long c1, c2;
2034
2035 blocklen = edit_insert_column_from_file (edit, file, &mark1, &mark2, &c1, &c2);
2036 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
2037
2038
2039 if (!edit_options.persistent_selections && edit->modified != 0)
2040 {
2041 if (edit->column_highlight == 0)
2042 edit_push_undo_action (edit, COLUMN_OFF);
2043 edit->column_highlight = 1;
2044 }
2045 }
2046 else
2047 {
2048 off_t i;
2049
2050 while ((blocklen = mc_read (file, (char *) buf, TEMP_BUF_LEN)) > 0)
2051 {
2052 for (i = 0; i < blocklen; i++)
2053 edit_insert (edit, buf[i]);
2054 }
2055
2056 if (!edit_options.persistent_selections && edit->modified != 0)
2057 {
2058 edit_set_markers (edit, edit->buffer.curs1, current, 0, 0);
2059 if (edit->column_highlight != 0)
2060 edit_push_undo_action (edit, COLUMN_ON);
2061 edit->column_highlight = 0;
2062 }
2063
2064
2065 if (!edit_options.cursor_after_inserted_block)
2066 {
2067 ins_len = edit->buffer.curs1 - current;
2068 edit_cursor_move (edit, -ins_len);
2069 }
2070 }
2071
2072 edit->force |= REDRAW_PAGE;
2073 g_free (buf);
2074 mc_close (file);
2075 if (blocklen != 0)
2076 ins_len = 0;
2077 }
2078
2079 return ins_len;
2080 }
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091 WEdit *
2092 edit_init (WEdit *edit, const WRect *r, const edit_arg_t *arg)
2093 {
2094 gboolean to_free = FALSE;
2095 long line;
2096
2097 auto_syntax = TRUE;
2098 edit_options.line_state_width = edit_options.line_state ? LINE_STATE_WIDTH : 0;
2099
2100 if (edit != NULL)
2101 {
2102 int fullscreen;
2103 WRect loc_prev;
2104
2105
2106 fullscreen = edit->fullscreen;
2107 loc_prev = edit->loc_prev;
2108
2109 edit_purge_widget (edit);
2110
2111
2112 edit->fullscreen = fullscreen;
2113 edit->loc_prev = loc_prev;
2114 }
2115 else
2116 {
2117 Widget *w;
2118
2119 edit = g_malloc0 (sizeof (WEdit));
2120 to_free = TRUE;
2121
2122 w = WIDGET (edit);
2123 widget_init (w, r, NULL, NULL);
2124 w->options |= WOP_SELECTABLE | WOP_TOP_SELECT | WOP_WANT_CURSOR;
2125 w->keymap = editor_map;
2126 w->ext_keymap = editor_x_map;
2127 edit->fullscreen = 1;
2128 edit_save_size (edit);
2129 }
2130
2131 edit->drag_state = MCEDIT_DRAG_NONE;
2132
2133 edit->stat1.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2134 edit->stat1.st_uid = getuid ();
2135 edit->stat1.st_gid = getgid ();
2136 edit->stat1.st_mtime = 0;
2137
2138 if (arg != NULL)
2139 edit->attrs_ok = (mc_fgetflags (arg->file_vpath, &edit->attrs) == 0);
2140 else
2141 edit->attrs_ok = FALSE;
2142
2143 edit->over_col = 0;
2144 edit->bracket = -1;
2145 edit->last_bracket = -1;
2146 edit->force |= REDRAW_PAGE;
2147
2148
2149 if (arg != NULL)
2150 {
2151 edit_set_filename (edit, arg->file_vpath);
2152 line = arg->line_number;
2153 }
2154 else
2155 {
2156 edit_set_filename (edit, NULL);
2157 line = 0;
2158 }
2159
2160 edit->undo_stack_size = START_STACK_SIZE;
2161 edit->undo_stack_size_mask = START_STACK_SIZE - 1;
2162 edit->undo_stack = g_malloc0 ((edit->undo_stack_size + 10) * sizeof (long));
2163
2164 edit->redo_stack_size = START_STACK_SIZE;
2165 edit->redo_stack_size_mask = START_STACK_SIZE - 1;
2166 edit->redo_stack = g_malloc0 ((edit->redo_stack_size + 10) * sizeof (long));
2167
2168 edit->utf8 = FALSE;
2169 edit->converter = str_cnv_from_term;
2170 edit_set_codeset (edit);
2171
2172 if (!edit_load_file (edit))
2173 {
2174
2175 if (to_free)
2176 g_free (edit);
2177 return NULL;
2178 }
2179
2180 edit->loading_done = 1;
2181 edit->modified = 0;
2182 edit->locked = 0;
2183 edit_load_syntax (edit, NULL, NULL);
2184 edit_get_syntax_color (edit, -1);
2185
2186
2187 if ((line == 0) && edit_options.save_position)
2188 edit_load_position (edit, TRUE);
2189 else
2190 {
2191 edit_load_position (edit, FALSE);
2192 if (line <= 0)
2193 line = 1;
2194 edit_move_display (edit, line - 1);
2195 edit_move_to_line (edit, line - 1);
2196 }
2197
2198 edit_load_macro_cmd (edit);
2199
2200 return edit;
2201 }
2202
2203
2204
2205
2206 gboolean
2207 edit_clean (WEdit *edit)
2208 {
2209 if (edit == NULL)
2210 return FALSE;
2211
2212
2213 if (edit->locked)
2214 edit->locked = unlock_file (edit->filename_vpath);
2215
2216
2217 if (edit_options.save_position)
2218 edit_save_position (edit);
2219 else if (edit->serialized_bookmarks != NULL)
2220 g_array_free (edit->serialized_bookmarks, TRUE);
2221
2222
2223 if (edit->delete_file != 0)
2224 unlink (vfs_path_get_last_path_str (edit->filename_vpath));
2225
2226 edit_free_syntax_rules (edit);
2227 book_mark_flush (edit, -1);
2228
2229 edit_buffer_clean (&edit->buffer);
2230
2231 g_free (edit->undo_stack);
2232 g_free (edit->redo_stack);
2233 vfs_path_free (edit->filename_vpath, TRUE);
2234 vfs_path_free (edit->dir_vpath, TRUE);
2235 edit_search_deinit (edit);
2236
2237 if (edit->converter != str_cnv_from_term)
2238 str_close_conv (edit->converter);
2239
2240 edit_purge_widget (edit);
2241
2242 return TRUE;
2243 }
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254 gboolean
2255 edit_reload_line (WEdit *edit, const edit_arg_t *arg)
2256 {
2257 Widget *w = WIDGET (edit);
2258 WEdit *e;
2259
2260 e = g_malloc0 (sizeof (WEdit));
2261 *WIDGET (e) = *w;
2262
2263 e->fullscreen = edit->fullscreen;
2264 e->loc_prev = edit->loc_prev;
2265
2266 if (edit_init (e, &w->rect, arg) == NULL)
2267 {
2268 g_free (e);
2269 return FALSE;
2270 }
2271
2272 edit_clean (edit);
2273 memcpy (edit, e, sizeof (*edit));
2274 g_free (e);
2275
2276 return TRUE;
2277 }
2278
2279
2280
2281 void
2282 edit_set_codeset (WEdit *edit)
2283 {
2284 const char *cp_id;
2285
2286 cp_id = get_codepage_id (mc_global.source_codepage >= 0 ? mc_global.source_codepage
2287 : mc_global.display_codepage);
2288
2289 if (cp_id != NULL)
2290 {
2291 GIConv conv;
2292 conv = str_crt_conv_from (cp_id);
2293 if (conv != INVALID_CONV)
2294 {
2295 if (edit->converter != str_cnv_from_term)
2296 str_close_conv (edit->converter);
2297 edit->converter = conv;
2298 }
2299 }
2300
2301 if (cp_id != NULL)
2302 edit->utf8 = str_isutf8 (cp_id);
2303 }
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351 void
2352 edit_push_undo_action (WEdit *edit, long c)
2353 {
2354 unsigned long sp = edit->undo_stack_pointer;
2355 unsigned long spm1;
2356
2357
2358 if (sp > edit->undo_stack_size - 10)
2359 {
2360 if (max_undo < 256)
2361 max_undo = 256;
2362 if (edit->undo_stack_size < (unsigned long) max_undo)
2363 {
2364 long *t;
2365
2366 t = g_realloc (edit->undo_stack, (edit->undo_stack_size * 2 + 10) * sizeof (long));
2367 if (t != NULL)
2368 {
2369 edit->undo_stack = t;
2370 edit->undo_stack_size <<= 1;
2371 edit->undo_stack_size_mask = edit->undo_stack_size - 1;
2372 }
2373 }
2374 }
2375 spm1 = (edit->undo_stack_pointer - 1) & edit->undo_stack_size_mask;
2376 if (edit->undo_stack_disable)
2377 {
2378 edit_push_redo_action (edit, KEY_PRESS);
2379 edit_push_redo_action (edit, c);
2380 return;
2381 }
2382
2383 if (edit->redo_stack_reset)
2384 edit->redo_stack_bottom = edit->redo_stack_pointer = 0;
2385
2386 if (edit->undo_stack_bottom != sp && spm1 != edit->undo_stack_bottom
2387 && ((sp - 2) & edit->undo_stack_size_mask) != edit->undo_stack_bottom)
2388 {
2389 long d;
2390
2391 if (edit->undo_stack[spm1] < 0)
2392 {
2393 d = edit->undo_stack[(sp - 2) & edit->undo_stack_size_mask];
2394 if (d == c && edit->undo_stack[spm1] > -1000000000)
2395 {
2396 if (c < KEY_PRESS)
2397 edit->undo_stack[spm1]--;
2398 return;
2399 }
2400 }
2401 else
2402 {
2403 d = edit->undo_stack[spm1];
2404 if (d == c)
2405 {
2406 if (c >= KEY_PRESS)
2407 return;
2408 edit->undo_stack[sp] = -2;
2409 goto check_bottom;
2410 }
2411 }
2412 }
2413 edit->undo_stack[sp] = c;
2414
2415 check_bottom:
2416 edit->undo_stack_pointer = (edit->undo_stack_pointer + 1) & edit->undo_stack_size_mask;
2417
2418
2419
2420
2421 c = (edit->undo_stack_pointer + 2) & edit->undo_stack_size_mask;
2422 if ((unsigned long) c == edit->undo_stack_bottom
2423 || (((unsigned long) c + 1) & edit->undo_stack_size_mask) == edit->undo_stack_bottom)
2424 do
2425 {
2426 edit->undo_stack_bottom = (edit->undo_stack_bottom + 1) & edit->undo_stack_size_mask;
2427 }
2428 while (edit->undo_stack[edit->undo_stack_bottom] < KEY_PRESS
2429 && edit->undo_stack_bottom != edit->undo_stack_pointer);
2430
2431
2432
2433 if (edit->undo_stack_pointer != edit->undo_stack_bottom
2434 && edit->undo_stack[edit->undo_stack_bottom] < KEY_PRESS)
2435 {
2436 edit->undo_stack_bottom = edit->undo_stack_pointer = 0;
2437 }
2438 }
2439
2440
2441
2442 void
2443 edit_push_redo_action (WEdit *edit, long c)
2444 {
2445 unsigned long sp = edit->redo_stack_pointer;
2446 unsigned long spm1;
2447
2448 if (sp > edit->redo_stack_size - 10)
2449 {
2450 if (max_undo < 256)
2451 max_undo = 256;
2452 if (edit->redo_stack_size < (unsigned long) max_undo)
2453 {
2454 long *t;
2455
2456 t = g_realloc (edit->redo_stack, (edit->redo_stack_size * 2 + 10) * sizeof (long));
2457 if (t != NULL)
2458 {
2459 edit->redo_stack = t;
2460 edit->redo_stack_size <<= 1;
2461 edit->redo_stack_size_mask = edit->redo_stack_size - 1;
2462 }
2463 }
2464 }
2465 spm1 = (edit->redo_stack_pointer - 1) & edit->redo_stack_size_mask;
2466
2467 if (edit->redo_stack_bottom != sp && spm1 != edit->redo_stack_bottom
2468 && ((sp - 2) & edit->redo_stack_size_mask) != edit->redo_stack_bottom)
2469 {
2470 long d;
2471
2472 if (edit->redo_stack[spm1] < 0)
2473 {
2474 d = edit->redo_stack[(sp - 2) & edit->redo_stack_size_mask];
2475 if (d == c && edit->redo_stack[spm1] > -1000000000)
2476 {
2477 if (c < KEY_PRESS)
2478 edit->redo_stack[spm1]--;
2479 return;
2480 }
2481 }
2482 else
2483 {
2484 d = edit->redo_stack[spm1];
2485 if (d == c)
2486 {
2487 if (c >= KEY_PRESS)
2488 return;
2489 edit->redo_stack[sp] = -2;
2490 goto redo_check_bottom;
2491 }
2492 }
2493 }
2494 edit->redo_stack[sp] = c;
2495
2496 redo_check_bottom:
2497 edit->redo_stack_pointer = (edit->redo_stack_pointer + 1) & edit->redo_stack_size_mask;
2498
2499
2500
2501
2502 c = (edit->redo_stack_pointer + 2) & edit->redo_stack_size_mask;
2503 if ((unsigned long) c == edit->redo_stack_bottom
2504 || (((unsigned long) c + 1) & edit->redo_stack_size_mask) == edit->redo_stack_bottom)
2505 do
2506 {
2507 edit->redo_stack_bottom = (edit->redo_stack_bottom + 1) & edit->redo_stack_size_mask;
2508 }
2509 while (edit->redo_stack[edit->redo_stack_bottom] < KEY_PRESS
2510 && edit->redo_stack_bottom != edit->redo_stack_pointer);
2511
2512
2513
2514
2515
2516
2517
2518 if (edit->redo_stack_pointer != edit->redo_stack_bottom
2519 && edit->redo_stack[edit->redo_stack_bottom] < KEY_PRESS)
2520 edit->redo_stack_bottom = edit->redo_stack_pointer = 0;
2521 }
2522
2523
2524
2525
2526
2527
2528 void
2529 edit_insert (WEdit *edit, int c)
2530 {
2531
2532 if (edit->buffer.curs1 < edit->start_display)
2533 {
2534 edit->start_display++;
2535 if (c == '\n')
2536 edit->start_line++;
2537 }
2538
2539
2540 if (edit->loading_done != 0)
2541 edit_modification (edit);
2542
2543
2544 if (c == '\n')
2545 {
2546 book_mark_inc (edit, edit->buffer.curs_line);
2547 edit->buffer.curs_line++;
2548 edit->buffer.lines++;
2549 edit->force |= REDRAW_LINE_ABOVE | REDRAW_AFTER_CURSOR;
2550 }
2551
2552
2553
2554 if (c > 32)
2555 edit_push_undo_action (edit, BACKSPACE);
2556 else
2557 edit_push_undo_action (edit, BACKSPACE_BR);
2558
2559 edit->mark1 += (edit->mark1 > edit->buffer.curs1) ? 1 : 0;
2560 edit->mark2 += (edit->mark2 > edit->buffer.curs1) ? 1 : 0;
2561 edit->last_get_rule += (edit->last_get_rule > edit->buffer.curs1) ? 1 : 0;
2562
2563 edit_buffer_insert (&edit->buffer, c);
2564 }
2565
2566
2567
2568
2569 void
2570 edit_insert_ahead (WEdit *edit, int c)
2571 {
2572 if (edit->buffer.curs1 < edit->start_display)
2573 {
2574 edit->start_display++;
2575 if (c == '\n')
2576 edit->start_line++;
2577 }
2578 edit_modification (edit);
2579 if (c == '\n')
2580 {
2581 book_mark_inc (edit, edit->buffer.curs_line);
2582 edit->buffer.lines++;
2583 edit->force |= REDRAW_AFTER_CURSOR;
2584 }
2585
2586 if (c > 32)
2587 edit_push_undo_action (edit, DELCHAR);
2588 else
2589 edit_push_undo_action (edit, DELCHAR_BR);
2590
2591 edit->mark1 += (edit->mark1 >= edit->buffer.curs1) ? 1 : 0;
2592 edit->mark2 += (edit->mark2 >= edit->buffer.curs1) ? 1 : 0;
2593 edit->last_get_rule += (edit->last_get_rule >= edit->buffer.curs1) ? 1 : 0;
2594
2595 edit_buffer_insert_ahead (&edit->buffer, c);
2596 }
2597
2598
2599
2600 void
2601 edit_insert_over (WEdit *edit)
2602 {
2603 long i;
2604
2605 for (i = 0; i < edit->over_col; i++)
2606 edit_insert (edit, ' ');
2607
2608 edit->over_col = 0;
2609 }
2610
2611
2612
2613 int
2614 edit_delete (WEdit *edit, gboolean byte_delete)
2615 {
2616 int p = 0;
2617 int char_length = 1;
2618 int i;
2619
2620 if (edit->buffer.curs2 == 0)
2621 return 0;
2622
2623
2624 if (edit->utf8 && !byte_delete)
2625 {
2626 edit_buffer_get_utf (&edit->buffer, edit->buffer.curs1, &char_length);
2627 if (char_length < 1)
2628 char_length = 1;
2629 }
2630
2631 if (edit->mark2 != edit->mark1)
2632 edit_push_markers (edit);
2633
2634 for (i = 1; i <= char_length; i++)
2635 {
2636 if (edit->mark1 > edit->buffer.curs1)
2637 {
2638 edit->mark1--;
2639 edit->end_mark_curs--;
2640 }
2641 if (edit->mark2 > edit->buffer.curs1)
2642 edit->mark2--;
2643 if (edit->last_get_rule > edit->buffer.curs1)
2644 edit->last_get_rule--;
2645
2646 p = edit_buffer_delete (&edit->buffer);
2647
2648 edit_push_undo_action (edit, p + 256);
2649 }
2650
2651 edit_modification (edit);
2652 if (p == '\n')
2653 {
2654 book_mark_dec (edit, edit->buffer.curs_line);
2655 edit->buffer.lines--;
2656 edit->force |= REDRAW_AFTER_CURSOR;
2657 }
2658 if (edit->buffer.curs1 < edit->start_display)
2659 {
2660 edit->start_display--;
2661 if (p == '\n')
2662 edit->start_line--;
2663 }
2664
2665 return p;
2666 }
2667
2668
2669
2670 int
2671 edit_backspace (WEdit *edit, gboolean byte_delete)
2672 {
2673 int p = 0;
2674 int char_length = 1;
2675 int i;
2676
2677 if (edit->buffer.curs1 == 0)
2678 return 0;
2679
2680 if (edit->mark2 != edit->mark1)
2681 edit_push_markers (edit);
2682
2683 if (edit->utf8 && !byte_delete)
2684 {
2685 edit_buffer_get_prev_utf (&edit->buffer, edit->buffer.curs1, &char_length);
2686 if (char_length < 1)
2687 char_length = 1;
2688 }
2689
2690 for (i = 1; i <= char_length; i++)
2691 {
2692 if (edit->mark1 >= edit->buffer.curs1)
2693 {
2694 edit->mark1--;
2695 edit->end_mark_curs--;
2696 }
2697 if (edit->mark2 >= edit->buffer.curs1)
2698 edit->mark2--;
2699 if (edit->last_get_rule >= edit->buffer.curs1)
2700 edit->last_get_rule--;
2701
2702 p = edit_buffer_backspace (&edit->buffer);
2703
2704 edit_push_undo_action (edit, p);
2705 }
2706 edit_modification (edit);
2707 if (p == '\n')
2708 {
2709 book_mark_dec (edit, edit->buffer.curs_line);
2710 edit->buffer.curs_line--;
2711 edit->buffer.lines--;
2712 edit->force |= REDRAW_AFTER_CURSOR;
2713 }
2714
2715 if (edit->buffer.curs1 < edit->start_display)
2716 {
2717 edit->start_display--;
2718 if (p == '\n')
2719 edit->start_line--;
2720 }
2721
2722 return p;
2723 }
2724
2725
2726
2727
2728 void
2729 edit_cursor_move (WEdit *edit, off_t increment)
2730 {
2731 if (increment < 0)
2732 {
2733 for (; increment < 0 && edit->buffer.curs1 != 0; increment++)
2734 {
2735 int c;
2736
2737 edit_push_undo_action (edit, CURS_RIGHT);
2738
2739 c = edit_buffer_get_previous_byte (&edit->buffer);
2740 edit_buffer_insert_ahead (&edit->buffer, c);
2741 c = edit_buffer_backspace (&edit->buffer);
2742 if (c == '\n')
2743 {
2744 edit->buffer.curs_line--;
2745 edit->force |= REDRAW_LINE_BELOW;
2746 }
2747 }
2748 }
2749 else
2750 {
2751 for (; increment > 0 && edit->buffer.curs2 != 0; increment--)
2752 {
2753 int c;
2754
2755 edit_push_undo_action (edit, CURS_LEFT);
2756
2757 c = edit_buffer_get_current_byte (&edit->buffer);
2758 edit_buffer_insert (&edit->buffer, c);
2759 c = edit_buffer_delete (&edit->buffer);
2760 if (c == '\n')
2761 {
2762 edit->buffer.curs_line++;
2763 edit->force |= REDRAW_LINE_ABOVE;
2764 }
2765 }
2766 }
2767 }
2768
2769
2770
2771
2772
2773 off_t
2774 edit_move_forward3 (const WEdit *edit, off_t current, long cols, off_t upto)
2775 {
2776 off_t p, q;
2777 long col;
2778
2779 if (upto != 0)
2780 {
2781 q = upto;
2782 cols = -10;
2783 }
2784 else
2785 q = edit->buffer.size + 2;
2786
2787 for (col = 0, p = current; p < q; p++)
2788 {
2789 int c, orig_c;
2790
2791 if (cols != -10)
2792 {
2793 if (col == cols)
2794 return p;
2795 if (col > cols)
2796 return p - 1;
2797 }
2798
2799 orig_c = c = edit_buffer_get_byte (&edit->buffer, p);
2800
2801 if (edit->utf8)
2802 {
2803 int utf_ch;
2804 int char_length = 1;
2805
2806 utf_ch = edit_buffer_get_utf (&edit->buffer, p, &char_length);
2807 if (mc_global.utf8_display)
2808 {
2809 if (char_length > 1)
2810 col -= char_length - 1;
2811 if (g_unichar_iswide (utf_ch))
2812 col++;
2813 }
2814 else if (char_length > 1 && g_unichar_isprint (utf_ch))
2815 col -= char_length - 1;
2816 }
2817
2818 c = convert_to_display_c (c);
2819
2820 if (c == '\n')
2821 return (upto != 0 ? (off_t) col : p);
2822 if (c == '\t')
2823 col += TAB_SIZE - col % TAB_SIZE;
2824 else if ((c < 32 || c == 127) && (orig_c == c || (!mc_global.utf8_display && !edit->utf8)))
2825
2826
2827 col += 2;
2828 else
2829 col++;
2830 }
2831 return (off_t) col;
2832 }
2833
2834
2835
2836
2837 off_t
2838 edit_get_cursor_offset (const WEdit *edit)
2839 {
2840 return edit->buffer.curs1;
2841 }
2842
2843
2844
2845
2846 long
2847 edit_get_col (const WEdit *edit)
2848 {
2849 off_t b;
2850
2851 b = edit_buffer_get_current_bol (&edit->buffer);
2852 return (long) edit_move_forward3 (edit, b, 0, edit->buffer.curs1);
2853 }
2854
2855
2856
2857
2858
2859 void
2860 edit_update_curs_row (WEdit *edit)
2861 {
2862 edit->curs_row = edit->buffer.curs_line - edit->start_line;
2863 }
2864
2865
2866
2867 void
2868 edit_update_curs_col (WEdit *edit)
2869 {
2870 off_t b;
2871
2872 b = edit_buffer_get_current_bol (&edit->buffer);
2873 edit->curs_col = (long) edit_move_forward3 (edit, b, 0, edit->buffer.curs1);
2874 }
2875
2876
2877
2878 long
2879 edit_get_curs_col (const WEdit *edit)
2880 {
2881 return edit->curs_col;
2882 }
2883
2884
2885
2886
2887 void
2888 edit_scroll_upward (WEdit *edit, long i)
2889 {
2890 long lines_above = edit->start_line;
2891
2892 if (i > lines_above)
2893 i = lines_above;
2894 if (i != 0)
2895 {
2896 edit->start_line -= i;
2897 edit->start_display =
2898 edit_buffer_get_backward_offset (&edit->buffer, edit->start_display, i);
2899 edit->force |= REDRAW_PAGE;
2900 edit->force &= (0xfff - REDRAW_CHAR_ONLY);
2901 }
2902 edit_update_curs_row (edit);
2903 }
2904
2905
2906
2907 void
2908 edit_scroll_downward (WEdit *edit, long i)
2909 {
2910 long lines_below;
2911
2912 lines_below = edit->buffer.lines - edit->start_line - (WIDGET (edit)->rect.lines - 1);
2913 if (lines_below > 0)
2914 {
2915 if (i > lines_below)
2916 i = lines_below;
2917 edit->start_line += i;
2918 edit->start_display =
2919 edit_buffer_get_forward_offset (&edit->buffer, edit->start_display, i, 0);
2920 edit->force |= REDRAW_PAGE;
2921 edit->force &= (0xfff - REDRAW_CHAR_ONLY);
2922 }
2923 edit_update_curs_row (edit);
2924 }
2925
2926
2927
2928 void
2929 edit_scroll_right (WEdit *edit, long i)
2930 {
2931 edit->force |= REDRAW_PAGE;
2932 edit->force &= (0xfff - REDRAW_CHAR_ONLY);
2933 edit->start_col -= i;
2934 }
2935
2936
2937
2938 void
2939 edit_scroll_left (WEdit *edit, long i)
2940 {
2941 if (edit->start_col)
2942 {
2943 edit->start_col += i;
2944 if (edit->start_col > 0)
2945 edit->start_col = 0;
2946 edit->force |= REDRAW_PAGE;
2947 edit->force &= (0xfff - REDRAW_CHAR_ONLY);
2948 }
2949 }
2950
2951
2952
2953
2954
2955 void
2956 edit_move_to_prev_col (WEdit *edit, off_t p)
2957 {
2958 long prev = edit->prev_col;
2959 long over = edit->over_col;
2960 off_t b;
2961
2962 edit_cursor_move (edit,
2963 edit_move_forward3 (edit, p, prev + edit->over_col, 0) - edit->buffer.curs1);
2964
2965 if (edit_options.cursor_beyond_eol)
2966 {
2967 off_t e;
2968 long line_len;
2969
2970 b = edit_buffer_get_current_bol (&edit->buffer);
2971 e = edit_buffer_get_current_eol (&edit->buffer);
2972 line_len = (long) edit_move_forward3 (edit, b, 0, e);
2973 if (line_len < prev + edit->over_col)
2974 {
2975 edit->over_col = prev + over - line_len;
2976 edit->prev_col = line_len;
2977 edit->curs_col = line_len;
2978 }
2979 else
2980 {
2981 edit->curs_col = prev + over;
2982 edit->prev_col = edit->curs_col;
2983 edit->over_col = 0;
2984 }
2985 }
2986 else
2987 {
2988 edit->over_col = 0;
2989 if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer))
2990 {
2991 long fake_half_tabs;
2992
2993 edit_update_curs_col (edit);
2994
2995 fake_half_tabs = HALF_TAB_SIZE * space_width;
2996 if (fake_half_tabs != 0 && edit->curs_col % fake_half_tabs != 0)
2997 {
2998 long q;
2999
3000 q = edit->curs_col;
3001 edit->curs_col -= (edit->curs_col % fake_half_tabs);
3002 p = edit_buffer_get_current_bol (&edit->buffer);
3003 b = edit_move_forward3 (edit, p, edit->curs_col, 0);
3004 edit_cursor_move (edit, b - edit->buffer.curs1);
3005 if (!left_of_four_spaces (edit))
3006 {
3007 b = edit_move_forward3 (edit, p, q, 0);
3008 edit_cursor_move (edit, b - edit->buffer.curs1);
3009 }
3010 }
3011 }
3012 }
3013 }
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024 gboolean
3025 edit_line_is_blank (WEdit *edit, long line)
3026 {
3027 return is_blank (&edit->buffer, edit_find_line (edit, line));
3028 }
3029
3030
3031
3032
3033 void
3034 edit_move_to_line (WEdit *e, long line)
3035 {
3036 if (line < e->buffer.curs_line)
3037 edit_move_up (e, e->buffer.curs_line - line, FALSE);
3038 else
3039 edit_move_down (e, line - e->buffer.curs_line, FALSE);
3040 edit_scroll_screen_over_cursor (e);
3041 }
3042
3043
3044
3045
3046 void
3047 edit_move_display (WEdit *e, long line)
3048 {
3049 if (line < e->start_line)
3050 edit_scroll_upward (e, e->start_line - line);
3051 else
3052 edit_scroll_downward (e, line - e->start_line);
3053 }
3054
3055
3056
3057
3058 void
3059 edit_push_markers (WEdit *edit)
3060 {
3061 edit_push_undo_action (edit, MARK_1 + edit->mark1);
3062 edit_push_undo_action (edit, MARK_2 + edit->mark2);
3063 edit_push_undo_action (edit, MARK_CURS + edit->end_mark_curs);
3064 }
3065
3066
3067
3068 void
3069 edit_set_markers (WEdit *edit, off_t m1, off_t m2, long c1, long c2)
3070 {
3071 edit->mark1 = m1;
3072 edit->mark2 = m2;
3073 edit->column1 = c1;
3074 edit->column2 = c2;
3075 }
3076
3077
3078
3079
3080
3081
3082
3083
3084 gboolean
3085 eval_marks (WEdit *edit, off_t *start_mark, off_t *end_mark)
3086 {
3087 long end_mark_curs;
3088
3089 if (edit->mark1 == edit->mark2)
3090 {
3091 *start_mark = *end_mark = 0;
3092 edit->column2 = edit->column1 = 0;
3093 return FALSE;
3094 }
3095
3096 if (edit->end_mark_curs < 0)
3097 end_mark_curs = edit->buffer.curs1;
3098 else
3099 end_mark_curs = edit->end_mark_curs;
3100
3101 if (edit->mark2 >= 0)
3102 {
3103 *start_mark = MIN (edit->mark1, edit->mark2);
3104 *end_mark = MAX (edit->mark1, edit->mark2);
3105 }
3106 else
3107 {
3108 *start_mark = MIN (edit->mark1, end_mark_curs);
3109 *end_mark = MAX (edit->mark1, end_mark_curs);
3110 edit->column2 = edit->curs_col + edit->over_col;
3111 }
3112
3113 if (edit->column_highlight != 0
3114 && ((edit->mark1 > end_mark_curs && edit->column1 < edit->column2)
3115 || (edit->mark1 < end_mark_curs && edit->column1 > edit->column2)))
3116 {
3117 off_t start_bol, start_eol;
3118 off_t end_bol, end_eol;
3119 long col1, col2;
3120 off_t diff1, diff2;
3121
3122 start_bol = edit_buffer_get_bol (&edit->buffer, *start_mark);
3123 start_eol = edit_buffer_get_eol (&edit->buffer, start_bol - 1) + 1;
3124 end_bol = edit_buffer_get_bol (&edit->buffer, *end_mark);
3125 end_eol = edit_buffer_get_eol (&edit->buffer, *end_mark);
3126 col1 = MIN (edit->column1, edit->column2);
3127 col2 = MAX (edit->column1, edit->column2);
3128
3129 diff1 = edit_move_forward3 (edit, start_bol, col2, 0)
3130 - edit_move_forward3 (edit, start_bol, col1, 0);
3131 diff2 = edit_move_forward3 (edit, end_bol, col2, 0)
3132 - edit_move_forward3 (edit, end_bol, col1, 0);
3133
3134 *start_mark -= diff1;
3135 *end_mark += diff2;
3136 *start_mark = MAX (*start_mark, start_eol);
3137 *end_mark = MIN (*end_mark, end_eol);
3138 }
3139
3140 return TRUE;
3141 }
3142
3143
3144
3145
3146 void
3147 edit_mark_cmd (WEdit *edit, gboolean unmark)
3148 {
3149 edit_push_markers (edit);
3150 if (unmark)
3151 {
3152 edit_set_markers (edit, 0, 0, 0, 0);
3153 edit->force |= REDRAW_PAGE;
3154 }
3155 else if (edit->mark2 >= 0)
3156 {
3157 edit->end_mark_curs = -1;
3158 edit_set_markers (edit, edit->buffer.curs1, -1, edit->curs_col + edit->over_col,
3159 edit->curs_col + edit->over_col);
3160 edit->force |= REDRAW_PAGE;
3161 }
3162 else
3163 {
3164 edit->end_mark_curs = edit->buffer.curs1;
3165 edit_set_markers (edit, edit->mark1, edit->buffer.curs1, edit->column1,
3166 edit->curs_col + edit->over_col);
3167 }
3168 }
3169
3170
3171
3172
3173 void
3174 edit_mark_current_word_cmd (WEdit *edit)
3175 {
3176 long pos;
3177
3178 for (pos = edit->buffer.curs1; pos != 0; pos--)
3179 {
3180 int c1, c2;
3181
3182 c1 = edit_buffer_get_byte (&edit->buffer, pos);
3183 c2 = edit_buffer_get_byte (&edit->buffer, pos - 1);
3184 if (!isspace (c1) && isspace (c2))
3185 break;
3186 if ((my_type_of (c1) & my_type_of (c2)) == 0)
3187 break;
3188 }
3189 edit->mark1 = pos;
3190
3191 for (; pos < edit->buffer.size; pos++)
3192 {
3193 int c1, c2;
3194
3195 c1 = edit_buffer_get_byte (&edit->buffer, pos);
3196 c2 = edit_buffer_get_byte (&edit->buffer, pos + 1);
3197 if (!isspace (c1) && isspace (c2))
3198 break;
3199 if ((my_type_of (c1) & my_type_of (c2)) == 0)
3200 break;
3201 }
3202 edit->mark2 = MIN (pos + 1, edit->buffer.size);
3203
3204 edit->force |= REDRAW_LINE_ABOVE | REDRAW_AFTER_CURSOR;
3205 }
3206
3207
3208
3209 void
3210 edit_mark_current_line_cmd (WEdit *edit)
3211 {
3212 edit->mark1 = edit_buffer_get_current_bol (&edit->buffer);
3213 edit->mark2 = edit_buffer_get_current_eol (&edit->buffer);
3214
3215 edit->force |= REDRAW_LINE_ABOVE | REDRAW_AFTER_CURSOR;
3216 }
3217
3218
3219
3220 void
3221 edit_delete_line (WEdit *edit)
3222 {
3223
3224
3225
3226
3227
3228 while (edit_buffer_get_current_byte (&edit->buffer) != '\n')
3229 (void) edit_delete (edit, TRUE);
3230
3231
3232
3233
3234
3235
3236 (void) edit_delete (edit, TRUE);
3237
3238
3239
3240
3241
3242 while (edit_buffer_get_previous_byte (&edit->buffer) != '\n')
3243 (void) edit_backspace (edit, TRUE);
3244 }
3245
3246
3247
3248 void
3249 edit_push_key_press (WEdit *edit)
3250 {
3251 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
3252 if (edit->mark2 == -1)
3253 {
3254 edit_push_undo_action (edit, MARK_1 + edit->mark1);
3255 edit_push_undo_action (edit, MARK_CURS + edit->end_mark_curs);
3256 }
3257 }
3258
3259
3260
3261 void
3262 edit_find_bracket (WEdit *edit)
3263 {
3264 edit->bracket = edit_get_bracket (edit, 1, 10000);
3265 if (edit->last_bracket != edit->bracket)
3266 edit->force |= REDRAW_PAGE;
3267 edit->last_bracket = edit->bracket;
3268 }
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281 void
3282 edit_execute_key_command (WEdit *edit, long command, int char_for_insertion)
3283 {
3284 if (command == CK_MacroStartRecord || command == CK_RepeatStartRecord
3285 || (macro_index < 0
3286 && (command == CK_MacroStartStopRecord || command == CK_RepeatStartStopRecord)))
3287 {
3288 macro_index = 0;
3289 edit->force |= REDRAW_CHAR_ONLY | REDRAW_LINE;
3290 return;
3291 }
3292 if (macro_index != -1)
3293 {
3294 edit->force |= REDRAW_COMPLETELY;
3295 if (command == CK_MacroStopRecord || command == CK_MacroStartStopRecord)
3296 {
3297 edit_store_macro_cmd (edit);
3298 macro_index = -1;
3299 return;
3300 }
3301 if (command == CK_RepeatStopRecord || command == CK_RepeatStartStopRecord)
3302 {
3303 edit_repeat_macro_cmd (edit);
3304 macro_index = -1;
3305 return;
3306 }
3307 }
3308
3309 if (macro_index >= 0 && macro_index < MAX_MACRO_LENGTH - 1)
3310 {
3311 record_macro_buf[macro_index].action = command;
3312 record_macro_buf[macro_index++].ch = char_for_insertion;
3313 }
3314
3315 if (command != CK_Undo && command != CK_ExtendedKeyMap)
3316 edit_push_key_press (edit);
3317
3318 edit_execute_cmd (edit, command, char_for_insertion);
3319 if (edit->column_highlight != 0)
3320 edit->force |= REDRAW_PAGE;
3321 }
3322
3323
3324
3325
3326
3327
3328
3329
3330 void
3331 edit_execute_cmd (WEdit *edit, long command, int char_for_insertion)
3332 {
3333 WRect *w = &WIDGET (edit)->rect;
3334
3335 if (command == CK_WindowFullscreen)
3336 {
3337 edit_toggle_fullscreen (edit);
3338 return;
3339 }
3340
3341
3342 if (edit_handle_move_resize (edit, command))
3343 return;
3344
3345 edit->force |= REDRAW_LINE;
3346
3347
3348
3349 if (edit->found_len != 0 || edit->column_highlight != 0)
3350 edit->force |= REDRAW_PAGE;
3351
3352 switch (command)
3353 {
3354
3355 case CK_MarkLeft:
3356 case CK_MarkRight:
3357 case CK_MarkToWordBegin:
3358 case CK_MarkToWordEnd:
3359 case CK_MarkToHome:
3360 case CK_MarkToEnd:
3361 case CK_MarkUp:
3362 case CK_MarkDown:
3363 case CK_MarkPageUp:
3364 case CK_MarkPageDown:
3365 case CK_MarkToFileBegin:
3366 case CK_MarkToFileEnd:
3367 case CK_MarkToPageBegin:
3368 case CK_MarkToPageEnd:
3369 case CK_MarkScrollUp:
3370 case CK_MarkScrollDown:
3371 case CK_MarkParagraphUp:
3372 case CK_MarkParagraphDown:
3373
3374 case CK_MarkColumnPageUp:
3375 case CK_MarkColumnPageDown:
3376 case CK_MarkColumnLeft:
3377 case CK_MarkColumnRight:
3378 case CK_MarkColumnUp:
3379 case CK_MarkColumnDown:
3380 case CK_MarkColumnScrollUp:
3381 case CK_MarkColumnScrollDown:
3382 case CK_MarkColumnParagraphUp:
3383 case CK_MarkColumnParagraphDown:
3384 edit->column_highlight = 0;
3385 if (edit->highlight == 0 || (edit->mark2 != -1 && edit->mark1 != edit->mark2))
3386 {
3387 edit_mark_cmd (edit, TRUE);
3388 edit_mark_cmd (edit, FALSE);
3389 }
3390 edit->highlight = 1;
3391 break;
3392
3393
3394 default:
3395 if (edit->highlight != 0)
3396 edit_mark_cmd (edit, FALSE);
3397 edit->highlight = 0;
3398 }
3399
3400
3401 if (command == CK_Undo)
3402 {
3403 edit->redo_stack_reset = 0;
3404 edit_group_undo (edit);
3405 edit->found_len = 0;
3406 edit->prev_col = edit_get_col (edit);
3407 edit->search_start = edit->buffer.curs1;
3408 return;
3409 }
3410
3411 if (command == CK_Redo)
3412 {
3413 edit->redo_stack_reset = 0;
3414 edit_do_redo (edit);
3415 edit->found_len = 0;
3416 edit->prev_col = edit_get_col (edit);
3417 edit->search_start = edit->buffer.curs1;
3418 return;
3419 }
3420
3421 edit->redo_stack_reset = 1;
3422
3423
3424 if (char_for_insertion >= 0)
3425 {
3426
3427 if (!edit_options.persistent_selections && edit->mark1 != edit->mark2)
3428 edit_block_delete_cmd (edit);
3429
3430 if (edit->overwrite != 0)
3431 {
3432
3433 if (!mc_global.utf8_display || edit->charpoint == 0)
3434 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
3435 edit_delete (edit, FALSE);
3436 }
3437 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3438 edit_insert_over (edit);
3439
3440
3441
3442
3443 if (char_for_insertion > 127 && str_isutf8 (get_codepage_id (mc_global.source_codepage))
3444 && !mc_global.utf8_display)
3445 {
3446 unsigned char str[MB_LEN_MAX + 1];
3447 size_t i;
3448 int res;
3449
3450 res = g_unichar_to_utf8 (char_for_insertion, (char *) str);
3451 if (res == 0)
3452 {
3453 str[0] = '.';
3454 str[1] = '\0';
3455 }
3456 else
3457 str[res] = '\0';
3458
3459 for (i = 0; i <= MB_LEN_MAX && str[i] != '\0'; i++)
3460 {
3461 char_for_insertion = str[i];
3462 edit_insert (edit, char_for_insertion);
3463 }
3464 }
3465 else
3466 edit_insert (edit, char_for_insertion);
3467
3468 if (edit_options.auto_para_formatting)
3469 {
3470 format_paragraph (edit, FALSE);
3471 edit->force |= REDRAW_PAGE;
3472 }
3473 else
3474 check_and_wrap_line (edit);
3475 edit->found_len = 0;
3476 edit->prev_col = edit_get_col (edit);
3477 edit->search_start = edit->buffer.curs1;
3478 edit_find_bracket (edit);
3479 return;
3480 }
3481
3482 switch (command)
3483 {
3484 case CK_TopOnScreen:
3485 case CK_BottomOnScreen:
3486 case CK_Top:
3487 case CK_Bottom:
3488 case CK_PageUp:
3489 case CK_PageDown:
3490 case CK_Home:
3491 case CK_End:
3492 case CK_Up:
3493 case CK_Down:
3494 case CK_Left:
3495 case CK_Right:
3496 case CK_WordLeft:
3497 case CK_WordRight:
3498 if (!edit_options.persistent_selections && edit->mark2 >= 0)
3499 {
3500 if (edit->column_highlight != 0)
3501 edit_push_undo_action (edit, COLUMN_ON);
3502 edit->column_highlight = 0;
3503 edit_mark_cmd (edit, TRUE);
3504 }
3505 break;
3506 default:
3507 break;
3508 }
3509
3510 switch (command)
3511 {
3512 case CK_TopOnScreen:
3513 case CK_BottomOnScreen:
3514 case CK_MarkToPageBegin:
3515 case CK_MarkToPageEnd:
3516 case CK_Up:
3517 case CK_Down:
3518 case CK_WordLeft:
3519 case CK_WordRight:
3520 case CK_MarkToWordBegin:
3521 case CK_MarkToWordEnd:
3522 case CK_MarkUp:
3523 case CK_MarkDown:
3524 case CK_MarkColumnUp:
3525 case CK_MarkColumnDown:
3526 if (edit->mark2 == -1)
3527 break;
3528 MC_FALLTHROUGH;
3529 case CK_Left:
3530 case CK_Right:
3531 case CK_MarkLeft:
3532 case CK_MarkRight:
3533 edit->force |= REDRAW_CHAR_ONLY;
3534 break;
3535 default:
3536 break;
3537 }
3538
3539
3540 switch (command)
3541 {
3542 case CK_BackSpace:
3543
3544 if (!edit_options.persistent_selections && edit->mark1 != edit->mark2)
3545 edit_block_delete_cmd (edit);
3546 else if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3547 edit->over_col--;
3548 else if (edit_options.backspace_through_tabs && is_in_indent (&edit->buffer))
3549 {
3550 while (edit_buffer_get_previous_byte (&edit->buffer) != '\n' && edit->buffer.curs1 > 0)
3551 edit_backspace (edit, TRUE);
3552 }
3553 else if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer)
3554 && right_of_four_spaces (edit))
3555 {
3556 int i;
3557
3558 for (i = 0; i < HALF_TAB_SIZE; i++)
3559 edit_backspace (edit, TRUE);
3560 }
3561 else
3562 edit_backspace (edit, FALSE);
3563 break;
3564 case CK_Delete:
3565
3566 if (!edit_options.persistent_selections && edit->mark1 != edit->mark2)
3567 edit_block_delete_cmd (edit);
3568 else
3569 {
3570 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3571 edit_insert_over (edit);
3572
3573 if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer)
3574 && left_of_four_spaces (edit))
3575 {
3576 int i;
3577
3578 for (i = 1; i <= HALF_TAB_SIZE; i++)
3579 edit_delete (edit, TRUE);
3580 }
3581 else
3582 edit_delete (edit, FALSE);
3583 }
3584 break;
3585 case CK_DeleteToWordBegin:
3586 edit->over_col = 0;
3587 edit_left_delete_word (edit);
3588 break;
3589 case CK_DeleteToWordEnd:
3590 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3591 edit_insert_over (edit);
3592
3593 edit_right_delete_word (edit);
3594 break;
3595 case CK_DeleteLine:
3596 edit_delete_line (edit);
3597 break;
3598 case CK_DeleteToHome:
3599 edit_delete_to_line_begin (edit);
3600 break;
3601 case CK_DeleteToEnd:
3602 edit_delete_to_line_end (edit);
3603 break;
3604 case CK_Enter:
3605 edit->over_col = 0;
3606 if (edit_options.auto_para_formatting)
3607 {
3608 edit_double_newline (edit);
3609 if (edit_options.return_does_auto_indent && !bracketed_pasting_in_progress)
3610 edit_auto_indent (edit);
3611 format_paragraph (edit, FALSE);
3612 }
3613 else
3614 {
3615 edit_insert (edit, '\n');
3616 if (edit_options.return_does_auto_indent && !bracketed_pasting_in_progress)
3617 edit_auto_indent (edit);
3618 }
3619 break;
3620 case CK_Return:
3621 edit_insert (edit, '\n');
3622 break;
3623
3624 case CK_MarkColumnPageUp:
3625 edit->column_highlight = 1;
3626 MC_FALLTHROUGH;
3627 case CK_PageUp:
3628 case CK_MarkPageUp:
3629 edit_move_up (edit, w->lines - (edit->fullscreen ? 1 : 2), TRUE);
3630 break;
3631 case CK_MarkColumnPageDown:
3632 edit->column_highlight = 1;
3633 MC_FALLTHROUGH;
3634 case CK_PageDown:
3635 case CK_MarkPageDown:
3636 edit_move_down (edit, w->lines - (edit->fullscreen ? 1 : 2), TRUE);
3637 break;
3638 case CK_MarkColumnLeft:
3639 edit->column_highlight = 1;
3640 MC_FALLTHROUGH;
3641 case CK_Left:
3642 case CK_MarkLeft:
3643 if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer)
3644 && right_of_four_spaces (edit))
3645 {
3646 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3647 edit->over_col--;
3648 else
3649 edit_cursor_move (edit, -HALF_TAB_SIZE);
3650 edit->force &= (0xFFF - REDRAW_CHAR_ONLY);
3651 }
3652 else
3653 edit_left_char_move_cmd (edit);
3654 break;
3655 case CK_MarkColumnRight:
3656 edit->column_highlight = 1;
3657 MC_FALLTHROUGH;
3658 case CK_Right:
3659 case CK_MarkRight:
3660 if (edit_options.fake_half_tabs && is_in_indent (&edit->buffer)
3661 && left_of_four_spaces (edit))
3662 {
3663 edit_cursor_move (edit, HALF_TAB_SIZE);
3664 edit->force &= (0xFFF - REDRAW_CHAR_ONLY);
3665 }
3666 else
3667 edit_right_char_move_cmd (edit);
3668 break;
3669 case CK_TopOnScreen:
3670 case CK_MarkToPageBegin:
3671 edit_begin_page (edit);
3672 break;
3673 case CK_BottomOnScreen:
3674 case CK_MarkToPageEnd:
3675 edit_end_page (edit);
3676 break;
3677 case CK_WordLeft:
3678 case CK_MarkToWordBegin:
3679 edit->over_col = 0;
3680 edit_left_word_move_cmd (edit);
3681 break;
3682 case CK_WordRight:
3683 case CK_MarkToWordEnd:
3684 edit->over_col = 0;
3685 edit_right_word_move_cmd (edit);
3686 break;
3687 case CK_MarkColumnUp:
3688 edit->column_highlight = 1;
3689 MC_FALLTHROUGH;
3690 case CK_Up:
3691 case CK_MarkUp:
3692 edit_move_up (edit, 1, FALSE);
3693 break;
3694 case CK_MarkColumnDown:
3695 edit->column_highlight = 1;
3696 MC_FALLTHROUGH;
3697 case CK_Down:
3698 case CK_MarkDown:
3699 edit_move_down (edit, 1, FALSE);
3700 break;
3701 case CK_MarkColumnParagraphUp:
3702 edit->column_highlight = 1;
3703 MC_FALLTHROUGH;
3704 case CK_ParagraphUp:
3705 case CK_MarkParagraphUp:
3706 edit_move_up_paragraph (edit, FALSE);
3707 break;
3708 case CK_MarkColumnParagraphDown:
3709 edit->column_highlight = 1;
3710 MC_FALLTHROUGH;
3711 case CK_ParagraphDown:
3712 case CK_MarkParagraphDown:
3713 edit_move_down_paragraph (edit, FALSE);
3714 break;
3715 case CK_MarkColumnScrollUp:
3716 edit->column_highlight = 1;
3717 MC_FALLTHROUGH;
3718 case CK_ScrollUp:
3719 case CK_MarkScrollUp:
3720 edit_move_up (edit, 1, TRUE);
3721 break;
3722 case CK_MarkColumnScrollDown:
3723 edit->column_highlight = 1;
3724 MC_FALLTHROUGH;
3725 case CK_ScrollDown:
3726 case CK_MarkScrollDown:
3727 edit_move_down (edit, 1, TRUE);
3728 break;
3729 case CK_Home:
3730 case CK_MarkToHome:
3731 edit_cursor_to_bol (edit);
3732 break;
3733 case CK_End:
3734 case CK_MarkToEnd:
3735 edit_cursor_to_eol (edit);
3736 break;
3737 case CK_Tab:
3738
3739 if (edit->mark1 != edit->mark2 && !edit_options.persistent_selections)
3740 {
3741 if (edit->mark2 < 0)
3742 edit_mark_cmd (edit, FALSE);
3743 edit_move_block_to_right (edit);
3744 }
3745 else
3746 {
3747 if (edit_options.cursor_beyond_eol)
3748 edit_insert_over (edit);
3749 edit_tab_cmd (edit);
3750 if (edit_options.auto_para_formatting)
3751 {
3752 format_paragraph (edit, FALSE);
3753 edit->force |= REDRAW_PAGE;
3754 }
3755 else
3756 check_and_wrap_line (edit);
3757 }
3758 break;
3759
3760 case CK_InsertOverwrite:
3761 edit->overwrite = !edit->overwrite;
3762 break;
3763
3764 case CK_Mark:
3765 if (edit->mark2 >= 0)
3766 {
3767 if (edit->column_highlight != 0)
3768 edit_push_undo_action (edit, COLUMN_ON);
3769 edit->column_highlight = 0;
3770 }
3771 edit_mark_cmd (edit, FALSE);
3772 break;
3773 case CK_MarkColumn:
3774 if (edit->column_highlight == 0)
3775 edit_push_undo_action (edit, COLUMN_OFF);
3776 edit->column_highlight = 1;
3777 edit_mark_cmd (edit, FALSE);
3778 break;
3779 case CK_MarkAll:
3780 edit_set_markers (edit, 0, edit->buffer.size, 0, 0);
3781 edit->force |= REDRAW_PAGE;
3782 break;
3783 case CK_Unmark:
3784 if (edit->column_highlight != 0)
3785 edit_push_undo_action (edit, COLUMN_ON);
3786 edit->column_highlight = 0;
3787 edit_mark_cmd (edit, TRUE);
3788 break;
3789 case CK_MarkWord:
3790 if (edit->column_highlight != 0)
3791 edit_push_undo_action (edit, COLUMN_ON);
3792 edit->column_highlight = 0;
3793 edit_mark_current_word_cmd (edit);
3794 break;
3795 case CK_MarkLine:
3796 if (edit->column_highlight != 0)
3797 edit_push_undo_action (edit, COLUMN_ON);
3798 edit->column_highlight = 0;
3799 edit_mark_current_line_cmd (edit);
3800 break;
3801
3802 case CK_Bookmark:
3803 book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_FOUND_COLOR);
3804 if (book_mark_query_color (edit, edit->buffer.curs_line, BOOK_MARK_COLOR))
3805 book_mark_clear (edit, edit->buffer.curs_line, BOOK_MARK_COLOR);
3806 else
3807 book_mark_insert (edit, edit->buffer.curs_line, BOOK_MARK_COLOR);
3808 break;
3809 case CK_BookmarkFlush:
3810 book_mark_flush (edit, BOOK_MARK_COLOR);
3811 book_mark_flush (edit, BOOK_MARK_FOUND_COLOR);
3812 edit->force |= REDRAW_PAGE;
3813 break;
3814 case CK_BookmarkNext:
3815 if (edit->book_mark != NULL)
3816 {
3817 edit_book_mark_t *p;
3818
3819 p = book_mark_find (edit, edit->buffer.curs_line);
3820 if (p->next != NULL)
3821 {
3822 p = p->next;
3823 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line)
3824 edit_move_display (edit, p->line - w->lines / 2);
3825 edit_move_to_line (edit, p->line);
3826 }
3827 }
3828 break;
3829 case CK_BookmarkPrev:
3830 if (edit->book_mark != NULL)
3831 {
3832 edit_book_mark_t *p;
3833
3834 p = book_mark_find (edit, edit->buffer.curs_line);
3835 while (p->line == edit->buffer.curs_line)
3836 if (p->prev != NULL)
3837 p = p->prev;
3838 if (p->line >= 0)
3839 {
3840 if (p->line >= edit->start_line + w->lines || p->line < edit->start_line)
3841 edit_move_display (edit, p->line - w->lines / 2);
3842 edit_move_to_line (edit, p->line);
3843 }
3844 }
3845 break;
3846
3847 case CK_Top:
3848 case CK_MarkToFileBegin:
3849 edit_move_to_top (edit);
3850 break;
3851 case CK_Bottom:
3852 case CK_MarkToFileEnd:
3853 edit_move_to_bottom (edit);
3854 break;
3855
3856 case CK_Copy:
3857 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3858 edit_insert_over (edit);
3859 edit_block_copy_cmd (edit);
3860 break;
3861 case CK_Remove:
3862 edit_block_delete_cmd (edit);
3863 break;
3864 case CK_Move:
3865 edit_block_move_cmd (edit);
3866 break;
3867
3868 case CK_BlockShiftLeft:
3869 if (edit->mark1 != edit->mark2)
3870 edit_move_block_to_left (edit);
3871 break;
3872 case CK_BlockShiftRight:
3873 if (edit->mark1 != edit->mark2)
3874 edit_move_block_to_right (edit);
3875 break;
3876 case CK_Store:
3877 edit_copy_to_X_buf_cmd (edit);
3878 break;
3879 case CK_Cut:
3880 edit_cut_to_X_buf_cmd (edit);
3881 break;
3882 case CK_Paste:
3883
3884 if (!edit_options.persistent_selections && edit->mark1 != edit->mark2)
3885 edit_block_delete_cmd (edit);
3886 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
3887 edit_insert_over (edit);
3888 edit_paste_from_X_buf_cmd (edit);
3889 if (!edit_options.persistent_selections && edit->mark2 >= 0)
3890 {
3891 if (edit->column_highlight != 0)
3892 edit_push_undo_action (edit, COLUMN_ON);
3893 edit->column_highlight = 0;
3894 edit_mark_cmd (edit, TRUE);
3895 }
3896 break;
3897 case CK_History:
3898 edit_paste_from_history (edit);
3899 break;
3900
3901 case CK_SaveAs:
3902 edit_save_as_cmd (edit);
3903 break;
3904 case CK_Save:
3905 edit_save_confirm_cmd (edit);
3906 break;
3907 case CK_BlockSave:
3908 edit_save_block_cmd (edit);
3909 break;
3910 case CK_InsertFile:
3911 edit_insert_file_cmd (edit);
3912 break;
3913
3914 case CK_FilePrev:
3915 edit_load_back_cmd (edit);
3916 break;
3917 case CK_FileNext:
3918 edit_load_forward_cmd (edit);
3919 break;
3920
3921 case CK_SyntaxChoose:
3922 edit_syntax_dialog (edit);
3923 break;
3924
3925 case CK_Search:
3926 edit_search_cmd (edit, FALSE);
3927 break;
3928 case CK_SearchContinue:
3929 edit_search_cmd (edit, TRUE);
3930 break;
3931 case CK_Replace:
3932 edit_replace_cmd (edit, FALSE);
3933 break;
3934 case CK_ReplaceContinue:
3935 edit_replace_cmd (edit, TRUE);
3936 break;
3937 case CK_Complete:
3938
3939 if (edit->mark1 != edit->mark2 && !edit_options.persistent_selections)
3940 edit_move_block_to_left (edit);
3941 else
3942 edit_complete_word_cmd (edit);
3943 break;
3944 case CK_Find:
3945 edit_get_match_keyword_cmd (edit);
3946 break;
3947
3948 #ifdef HAVE_ASPELL
3949 case CK_SpellCheckCurrentWord:
3950 edit_suggest_current_word (edit);
3951 break;
3952 case CK_SpellCheck:
3953 edit_spellcheck_file (edit);
3954 break;
3955 case CK_SpellCheckSelectLang:
3956 edit_set_spell_lang ();
3957 break;
3958 #endif
3959
3960 case CK_Date:
3961 {
3962 char s[BUF_MEDIUM];
3963
3964 char time_format[] = "_c";
3965 time_format[0] = '%';
3966
3967 FMT_LOCALTIME_CURRENT (s, sizeof (s), time_format);
3968 edit_print_string (edit, s);
3969 edit->force |= REDRAW_PAGE;
3970 }
3971 break;
3972 case CK_Goto:
3973 edit_goto_cmd (edit);
3974 break;
3975 case CK_ParagraphFormat:
3976 format_paragraph (edit, TRUE);
3977 edit->force |= REDRAW_PAGE;
3978 break;
3979 case CK_MacroDelete:
3980 edit_delete_macro_cmd (edit);
3981 break;
3982 case CK_MatchBracket:
3983 edit_goto_matching_bracket (edit);
3984 break;
3985 case CK_UserMenu:
3986 edit_user_menu (edit, NULL, -1);
3987 break;
3988 case CK_Sort:
3989 edit_sort_cmd (edit);
3990 break;
3991 case CK_ExternalCommand:
3992 edit_ext_cmd (edit);
3993 break;
3994 case CK_EditMail:
3995 edit_mail_dialog (edit);
3996 break;
3997 case CK_SelectCodepage:
3998 edit_select_codepage_cmd (edit);
3999 break;
4000 case CK_InsertLiteral:
4001 edit_insert_literal_cmd (edit);
4002 break;
4003 case CK_MacroStartStopRecord:
4004 edit_begin_end_macro_cmd (edit);
4005 break;
4006 case CK_RepeatStartStopRecord:
4007 edit_begin_end_repeat_cmd (edit);
4008 break;
4009 case CK_ExtendedKeyMap:
4010 WIDGET (edit)->ext_mode = TRUE;
4011 break;
4012 default:
4013 break;
4014 }
4015
4016
4017 if ((command / CK_PipeBlock (0)) == 1)
4018 edit_block_process_cmd (edit, command - CK_PipeBlock (0));
4019
4020
4021 switch (command)
4022 {
4023 case CK_Search:
4024 case CK_SearchContinue:
4025 case CK_Replace:
4026 case CK_ReplaceContinue:
4027 case CK_Complete:
4028 edit->prev_col = edit_get_col (edit);
4029 break;
4030 case CK_Up:
4031 case CK_MarkUp:
4032 case CK_MarkColumnUp:
4033 case CK_Down:
4034 case CK_MarkDown:
4035 case CK_MarkColumnDown:
4036 case CK_PageUp:
4037 case CK_MarkPageUp:
4038 case CK_MarkColumnPageUp:
4039 case CK_PageDown:
4040 case CK_MarkPageDown:
4041 case CK_MarkColumnPageDown:
4042 case CK_Top:
4043 case CK_MarkToFileBegin:
4044 case CK_Bottom:
4045 case CK_MarkToFileEnd:
4046 case CK_ParagraphUp:
4047 case CK_MarkParagraphUp:
4048 case CK_MarkColumnParagraphUp:
4049 case CK_ParagraphDown:
4050 case CK_MarkParagraphDown:
4051 case CK_MarkColumnParagraphDown:
4052 case CK_ScrollUp:
4053 case CK_MarkScrollUp:
4054 case CK_MarkColumnScrollUp:
4055 case CK_ScrollDown:
4056 case CK_MarkScrollDown:
4057 case CK_MarkColumnScrollDown:
4058 edit->search_start = edit->buffer.curs1;
4059 edit->found_len = 0;
4060 break;
4061 default:
4062 edit->found_len = 0;
4063 edit->prev_col = edit_get_col (edit);
4064 edit->search_start = edit->buffer.curs1;
4065 }
4066 edit_find_bracket (edit);
4067
4068 if (edit_options.auto_para_formatting)
4069 {
4070 switch (command)
4071 {
4072 case CK_BackSpace:
4073 case CK_Delete:
4074 case CK_DeleteToWordBegin:
4075 case CK_DeleteToWordEnd:
4076 case CK_DeleteToHome:
4077 case CK_DeleteToEnd:
4078 format_paragraph (edit, FALSE);
4079 edit->force |= REDRAW_PAGE;
4080 break;
4081 default:
4082 break;
4083 }
4084 }
4085 }
4086
4087
4088
4089 void
4090 edit_stack_init (void)
4091 {
4092 for (edit_stack_iterator = 0; edit_stack_iterator < MAX_HISTORY_MOVETO; edit_stack_iterator++)
4093 edit_arg_init (&edit_history_moveto[edit_stack_iterator], NULL, -1);
4094
4095 edit_stack_iterator = 0;
4096 }
4097
4098
4099
4100 void
4101 edit_stack_free (void)
4102 {
4103 for (edit_stack_iterator = 0; edit_stack_iterator < MAX_HISTORY_MOVETO; edit_stack_iterator++)
4104 vfs_path_free (edit_history_moveto[edit_stack_iterator].file_vpath, TRUE);
4105 }
4106
4107
4108
4109
4110 void
4111 edit_move_up (WEdit *edit, long i, gboolean do_scroll)
4112 {
4113 edit_move_updown (edit, i, do_scroll, TRUE);
4114 }
4115
4116
4117
4118
4119 void
4120 edit_move_down (WEdit *edit, long i, gboolean do_scroll)
4121 {
4122 edit_move_updown (edit, i, do_scroll, FALSE);
4123 }
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134 edit_arg_t *
4135 edit_arg_vpath_new (vfs_path_t *file_vpath, long line_number)
4136 {
4137 edit_arg_t *arg;
4138
4139 arg = g_new (edit_arg_t, 1);
4140 arg->file_vpath = file_vpath;
4141 arg->line_number = line_number;
4142
4143 return arg;
4144 }
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155 edit_arg_t *
4156 edit_arg_new (const char *file_name, long line_number)
4157 {
4158 return edit_arg_vpath_new (vfs_path_from_str (file_name), line_number);
4159 }
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170 void
4171 edit_arg_init (edit_arg_t *arg, vfs_path_t *vpath, long line)
4172 {
4173 arg->file_vpath = (vfs_path_t *) vpath;
4174 arg->line_number = line;
4175 }
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186 void
4187 edit_arg_assign (edit_arg_t *arg, vfs_path_t *vpath, long line)
4188 {
4189 vfs_path_free (arg->file_vpath, TRUE);
4190 edit_arg_init (arg, vpath, line);
4191 }
4192
4193
4194
4195
4196
4197
4198
4199
4200 void
4201 edit_arg_free (edit_arg_t *arg)
4202 {
4203 vfs_path_free (arg->file_vpath, TRUE);
4204 g_free (arg);
4205 }
4206
4207
4208
4209 const char *
4210 edit_get_file_name (const WEdit *edit)
4211 {
4212 return vfs_path_as_str (edit->filename_vpath);
4213 }
4214
4215