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