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