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