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