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