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