1 /* editor high level editing commands
3 Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * \brief Source: editor high level editing commands
31 /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */
40 #include <sys/types.h>
48 #include "../src/global.h"
50 #include "../src/tty/tty.h"
51 #include "../src/tty/key.h" /* XCTRL */
53 #include "../src/history.h"
54 #include "../src/widget.h" /* listbox_new() */
55 #include "../src/layout.h" /* clr_scr() */
56 #include "../src/main.h" /* mc_home source_codepage */
57 #include "../src/help.h" /* interactive_display() */
58 #include "../src/wtools.h" /* message() */
59 #include "../src/charsets.h"
60 #include "../src/selcodepage.h"
61 #include "../src/strutil.h" /* utf string functions */
63 #include "../edit/edit-impl.h"
64 #include "../edit/edit.h"
65 #include "../edit/editlock.h"
66 #include "../edit/editcmddef.h"
67 #include "../edit/edit-widget.h"
68 #include "../edit/editcmd_dialogs.h"
69 #include "../edit/etags.h"
73 /* search and replace: */
74 int search_create_bookmark
= 0;
75 /* static int search_in_all_charsets = 0; */
77 /* queries on a save */
78 int edit_confirm_save
= 1;
80 static int edit_save_cmd (WEdit
*edit
);
81 static unsigned char *edit_get_block (WEdit
*edit
, long start
,
85 edit_search_cmd_search_create_bookmark(WEdit
* edit
)
87 int found
= 0, books
= 0;
88 int l
= 0, l_last
= -1;
92 search_create_bookmark
= 0;
93 book_mark_flush (edit
, -1);
96 if (!mc_search_run(edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
99 edit
->search_start
= edit
->search
->normal_offset
;
101 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
103 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
107 q
= edit
->search
->normal_offset
+ 1;
111 edit_error_dialog (_ ("Search"), _ (" Search string not found "));
113 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
114 edit_scroll_screen_over_cursor (edit
);
119 edit_search_cmd_callback(const void *user_data
, gsize char_offset
)
121 return edit_get_byte ((WEdit
* )user_data
, (long) char_offset
);
124 void edit_help_cmd (WEdit
* edit
)
126 interactive_display (NULL
, "[Internal File Editor]");
127 edit
->force
|= REDRAW_COMPLETELY
;
131 edit_refresh_cmd (WEdit
* edit
)
136 edit_get_syntax_color (edit
, -1, &color
);
142 #endif /* !HAVE_SLANG */
146 /* If 0 (quick save) then a) create/truncate <filename> file,
147 b) save to <filename>;
148 if 1 (safe save) then a) save to <tempnam>,
149 b) rename <tempnam> to <filename>;
150 if 2 (do backups) then a) save to <tempnam>,
151 b) rename <filename> to <filename.backup_ext>,
152 c) rename <tempnam> to <filename>. */
154 /* returns 0 on error, -1 on abort */
156 edit_save_file (WEdit
*edit
, const char *filename
)
162 gchar
*real_filename
;
163 int this_save_mode
, fd
= -1;
170 if (*filename
!= PATH_SEP
&& edit
->dir
) {
171 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
173 real_filename
= g_strdup(filename
);
176 this_save_mode
= option_save_mode
;
177 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
178 if (!vfs_file_is_local (real_filename
) ||
179 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1) {
181 * The file does not exists yet, so no safe save or
182 * backup are necessary.
184 this_save_mode
= EDIT_QUICK_SAVE
;
190 if (this_save_mode
== EDIT_QUICK_SAVE
&&
191 !edit
->skip_detach_prompt
) {
195 rv
= mc_stat (real_filename
, &sb
);
196 if (rv
== 0 && sb
.st_nlink
> 1) {
197 rv
= edit_query_dialog3 (_("Warning"),
198 _(" File has hard-links. Detach before saving? "),
199 _("&Yes"), _("&No"), _("&Cancel"));
202 this_save_mode
= EDIT_SAFE_SAVE
;
205 edit
->skip_detach_prompt
= 1;
208 g_free(real_filename
);
213 /* Prevent overwriting changes from other editor sessions. */
214 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
) {
216 /* The default action is "Cancel". */
219 rv
= edit_query_dialog2 (
221 _("The file has been modified in the meantime. Save anyway?"),
225 g_free(real_filename
);
231 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
232 char *savedir
, *saveprefix
;
233 const char *slashpos
;
234 slashpos
= strrchr (real_filename
, PATH_SEP
);
236 savedir
= g_strdup (real_filename
);
237 savedir
[slashpos
- real_filename
+ 1] = '\0';
239 savedir
= g_strdup (".");
240 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
242 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
245 g_free(real_filename
);
249 * Close for now because mc_mkstemps use pure open system call
250 * to create temporary file and it needs to be reopened by
251 * VFS-aware mc_open().
255 savename
= g_strdup (real_filename
);
257 mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
258 mc_chmod (savename
, edit
->stat1
.st_mode
);
261 mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
,
262 edit
->stat1
.st_mode
)) == -1)
266 if ((p
= edit_get_write_filter (savename
, real_filename
))) {
270 file
= (FILE *) popen (p
, "w");
273 filelen
= edit_write_stream (edit
, file
);
277 if (pclose (file
) != 0) {
278 tmp
= g_strconcat (_(" Error writing to pipe: "),
279 p
, " ", (char *) NULL
);
280 edit_error_dialog (_("Error"), tmp
);
287 tmp
= g_strconcat (_(" Cannot open pipe for writing: "),
288 p
, " ", (char *) NULL
);
290 edit_error_dialog (_("Error"),
291 get_sys_error (tmp
));
297 } else if (edit
->lb
== LB_ASIS
) { /* do not change line breaks */
300 filelen
= edit
->last_byte
;
301 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1) {
302 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
)
310 (fd
, (char *) edit
->buffers1
[buf
],
311 edit
->curs1
& M_EDIT_BUF_SIZE
) !=
312 (edit
->curs1
& M_EDIT_BUF_SIZE
)) {
314 } else if (edit
->curs2
) {
316 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
319 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
320 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
321 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) !=
322 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) {
327 (fd
, (char *) edit
->buffers2
[buf
],
328 EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
) {
339 /* Update the file information, especially the mtime. */
340 if (mc_stat (savename
, &edit
->stat1
) == -1)
342 } else { /* change line breaks */
347 file
= (FILE *) fopen (savename
, "w");
350 filelen
= edit_write_stream (edit
, file
);
355 msg
= g_strdup_printf (_(" Cannot open file for writing: %s "), savename
);
356 edit_error_dialog (_("Error"), msg
);
362 if (filelen
!= edit
->last_byte
)
365 if (this_save_mode
== EDIT_DO_BACKUP
) {
366 assert (option_backup_ext
!= NULL
);
367 tmp
= g_strconcat (real_filename
, option_backup_ext
,(char *) NULL
);
368 if (mc_rename (real_filename
, tmp
) == -1){
374 if (this_save_mode
!= EDIT_QUICK_SAVE
)
375 if (mc_rename (savename
, real_filename
) == -1)
378 g_free(real_filename
);
381 /* FIXME: Is this safe ?
382 * if (this_save_mode != EDIT_QUICK_SAVE)
383 * mc_unlink (savename);
385 g_free(real_filename
);
391 menu_save_mode_cmd (void)
394 const int DLG_X
= 38;
395 const int DLG_Y
= 10;
406 QuickWidget widgets
[] =
408 /* 0 */ QUICK_BUTTON (18, DLG_X
, 7, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
409 /* 1 */ QUICK_BUTTON ( 6, DLG_X
, 7, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
410 /* 2 */ QUICK_INPUT (23, DLG_X
, 5, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
411 /* 3 */ QUICK_LABEL (22, DLG_X
, 4, DLG_Y
, N_("Extension:")),
412 /* 4 */ QUICK_RADIO ( 4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
418 DLG_X
, DLG_Y
, -1, -1, N_(" Edit Save Mode "),
419 "[Edit Save Mode]", widgets
, FALSE
425 size_t l1
, w0
, w1
, w3
;
427 assert (option_backup_ext
!= NULL
);
429 /* OK/Cancel buttons */
430 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 2;
431 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 4; /* default batton */
433 w3
= str_term_width1 (_(widgets
[3].u
.label
.text
));
435 maxlen
= l1
= w0
+ w1
+ 6;
437 for (i
= 0; i
< 3; i
++) {
441 maxlen
= max (maxlen
, (size_t) str_term_width1 (str
[i
]) + 7);
444 dlg_x
= maxlen
+ w3
+ 5 + 2;
445 widgets
[2].u
.input
.len
= w3
; /* input field length */
446 dlg_x
= min (COLS
, dlg_x
);
449 widgets
[0].relative_x
= dlg_x
* 2/3 - w0
/2;
450 widgets
[1].relative_x
= dlg_x
/3 - w1
/2;
451 widgets
[2].relative_x
= widgets
[3].relative_x
= maxlen
+ 3;
453 for (i
= 0; i
< sizeof (widgets
)/sizeof (widgets
[0]); i
++)
454 widgets
[i
].x_divisions
= dlg_x
;
456 if (quick_dialog (&dialog
) != B_CANCEL
) {
457 g_free (option_backup_ext
);
458 option_backup_ext
= str_result
;
463 edit_set_filename (WEdit
*edit
, const char *f
)
465 g_free (edit
->filename
);
468 edit
->filename
= g_strdup (f
);
469 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
471 edit
->dir
= g_strdup (vfs_get_current_dir ());
473 edit
->dir
= g_get_current_dir ();
478 edit_get_save_file_as (WEdit
*edit
)
481 #define DLG_HEIGHT 14
483 static LineBreaks cur_lb
= LB_ASIS
;
485 char *filename
= edit
->filename
;
487 char *lb_names
[LB_NAMES
] =
489 N_("&Do not change"),
490 N_("&Unix format (LF)"),
491 N_("&Windows/DOS format (CR LF)"),
492 N_("&Macintosh format (CR)")
495 QuickWidget quick_widgets
[] =
497 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
498 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
499 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, (const char **) lb_names
, &cur_lb
),
500 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
501 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0, "save-as", &filename
),
502 QUICK_LABEL (2, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_(" Enter file name: ")),
506 QuickDialog Quick_options
=
508 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
509 N_(" Save As "), "[Save File As]",
513 if (quick_dialog (&Quick_options
) != B_CANCEL
) {
524 /* Here we want to warn the users of overwriting an existing file,
525 but only if they have made a change to the filename */
526 /* returns 1 on success */
528 edit_save_as_cmd (WEdit
*edit
)
530 /* This heads the 'Save As' dialog box */
533 int different_filename
= 0;
535 exp
= edit_get_save_file_as (edit
);
536 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
541 edit
->force
|= REDRAW_COMPLETELY
;
545 if (strcmp (edit
->filename
, exp
)) {
547 different_filename
= 1;
548 if ((file
= mc_open (exp
, O_RDONLY
| O_BINARY
)) != -1) {
549 /* the file exists */
551 /* Overwrite the current file or cancel the operation */
552 if (edit_query_dialog2
554 _(" A file already exists with this name. "),
555 _("&Overwrite"), _("&Cancel"))) {
556 edit
->force
|= REDRAW_COMPLETELY
;
561 edit
->stat1
.st_mode
|= S_IWUSR
;
563 save_lock
= edit_lock_file (exp
);
565 /* filenames equal, check if already locked */
566 if (!edit
->locked
&& !edit
->delete_file
)
567 save_lock
= edit_lock_file (exp
);
570 if (different_filename
)
573 * Allow user to write into saved (under another name) file
574 * even if original file had r/o user permissions.
576 edit
->stat1
.st_mode
|= S_IWRITE
;
579 rv
= edit_save_file (edit
, exp
);
582 /* Succesful, so unlock both files */
583 if (different_filename
) {
585 edit_unlock_file (exp
);
587 edit
->locked
= edit_unlock_file (edit
->filename
);
589 if (edit
->locked
|| save_lock
)
590 edit
->locked
= edit_unlock_file (edit
->filename
);
593 edit_set_filename (edit
, exp
);
594 if (edit
->lb
!= LB_ASIS
)
595 edit_reload(edit
, exp
);
598 edit
->delete_file
= 0;
599 if (different_filename
)
600 edit_load_syntax (edit
, NULL
, option_syntax_type
);
601 edit
->force
|= REDRAW_COMPLETELY
;
604 edit_error_dialog (_(" Save As "),
606 (" Cannot save file. ")));
609 /* Failed, so maintain modify (not save) lock */
611 edit_unlock_file (exp
);
613 edit
->force
|= REDRAW_COMPLETELY
;
618 edit
->force
|= REDRAW_COMPLETELY
;
622 /* {{{ Macro stuff starts here */
624 /* creates a macro file if it doesn't exist */
625 static FILE *edit_open_macro_file (const char *r
)
630 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
631 if ((file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
)) == -1){
636 fd
= fopen (filename
, r
);
641 #define MAX_MACROS 1024
642 static int saved_macro
[MAX_MACROS
+ 1];
643 static int saved_macros_loaded
= 0;
646 This is just to stop the macro file be loaded over and over for keys
647 that aren't defined to anything. On slow systems this could be annoying.
653 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
654 if (saved_macro
[i
] == k
)
659 /* returns 1 on error */
661 edit_delete_macro (WEdit
* edit
, int k
)
664 struct macro macro
[MAX_MACRO_LENGTH
];
670 if (saved_macros_loaded
)
671 if ((j
= macro_exists (k
)) < 0)
673 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
674 g
= fopen (tmp
, "w");
677 edit_error_dialog (_(" Delete macro "),
678 get_sys_error (_(" Cannot open temp file ")));
681 f
= edit_open_macro_file ("r");
683 edit_error_dialog (_(" Delete macro "),
684 get_sys_error (_(" Cannot open macro file ")));
689 n
= fscanf (f
, ("key '%d 0': "), &s
);
693 while (fscanf (f
, "%hd %hd, ", ¯o
[n
].command
, ¯o
[n
].ch
))
697 fprintf (g
, ("key '%d 0': "), s
);
698 for (i
= 0; i
< n
; i
++)
699 fprintf (g
, "%hd %hd, ", macro
[i
].command
, macro
[i
].ch
);
705 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
706 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
707 if (rename ( tmp
, tmp2
) == -1) {
708 edit_error_dialog (_(" Delete macro "),
709 get_sys_error (_(" Cannot overwrite macro file ")));
717 if (saved_macros_loaded
)
718 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
722 /* returns 0 on error */
723 int edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
728 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
729 s
= editcmd_dialog_raw_key_query (_(" Save macro "),
730 _(" Press the macro's new hotkey: "), 1);
731 edit
->force
|= REDRAW_COMPLETELY
;
733 if (edit_delete_macro (edit
, s
))
735 f
= edit_open_macro_file ("a+");
737 fprintf (f
, ("key '%d 0': "), s
);
738 for (i
= 0; i
< n
; i
++)
739 fprintf (f
, "%hd %hd, ", macro
[i
].command
, macro
[i
].ch
);
742 if (saved_macros_loaded
) {
743 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
748 edit_error_dialog (_(" Save macro "), get_sys_error (_(" Cannot open macro file ")));
753 void edit_delete_macro_cmd (WEdit
* edit
)
757 command
= editcmd_dialog_raw_key_query (_ (" Delete macro "),
758 _ (" Press macro hotkey: "), 1);
763 edit_delete_macro (edit
, command
);
766 /* return 0 on error */
767 int edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
770 int s
, i
= 0, found
= 0;
774 if (saved_macros_loaded
)
775 if (macro_exists (k
) < 0)
778 if ((f
= edit_open_macro_file ("r"))) {
782 u
= fscanf (f
, ("key '%d 0': "), &s
);
785 if (!saved_macros_loaded
)
786 saved_macro
[i
++] = s
;
789 while (*n
< MAX_MACRO_LENGTH
&& 2 == fscanf (f
, "%hd %hd, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
792 while (2 == fscanf (f
, "%hd %hd, ", &dummy
.command
, &dummy
.ch
));
797 } while (!found
|| !saved_macros_loaded
);
798 if (!saved_macros_loaded
) {
800 saved_macros_loaded
= 1;
805 edit_error_dialog (_(" Load macro "),
806 get_sys_error (_(" Cannot open macro file ")));
810 /* }}} Macro stuff starts here */
812 /* returns 1 on success */
813 int edit_save_confirm_cmd (WEdit
* edit
)
817 if (edit_confirm_save
) {
818 f
= g_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", NULL
);
819 if (edit_query_dialog2 (_(" Save file "), f
, _("&Save"), _("&Cancel"))){
825 return edit_save_cmd (edit
);
829 /* returns 1 on success */
831 edit_save_cmd (WEdit
*edit
)
833 int res
, save_lock
= 0;
835 if (!edit
->locked
&& !edit
->delete_file
)
836 save_lock
= edit_lock_file (edit
->filename
);
837 res
= edit_save_file (edit
, edit
->filename
);
839 /* Maintain modify (not save) lock on failure */
840 if ((res
> 0 && edit
->locked
) || save_lock
)
841 edit
->locked
= edit_unlock_file (edit
->filename
);
843 /* On failure try 'save as', it does locking on its own */
845 return edit_save_as_cmd (edit
);
846 edit
->force
|= REDRAW_COMPLETELY
;
848 edit
->delete_file
= 0;
856 /* returns 1 on success */
857 int edit_new_cmd (WEdit
* edit
)
859 if (edit
->modified
) {
860 if (edit_query_dialog2 (_ ("Warning"), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("C&ontinue"), _ ("&Cancel"))) {
861 edit
->force
|= REDRAW_COMPLETELY
;
865 edit
->force
|= REDRAW_COMPLETELY
;
867 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
870 /* returns 1 on error */
872 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
874 int prev_locked
= edit
->locked
;
875 char *prev_filename
= g_strdup (edit
->filename
);
877 if (!edit_reload (edit
, exp
)) {
878 g_free (prev_filename
);
883 edit_unlock_file (prev_filename
);
884 g_free (prev_filename
);
889 edit_load_syntax_file (WEdit
* edit
)
894 if (geteuid () == 0) {
895 dir
= query_dialog (_("Syntax file edit"),
896 _(" Which syntax file you want to edit? "), D_NORMAL
, 2,
897 _("&User"), _("&System Wide"));
900 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
901 if (!exist_file(extdir
)) {
903 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
909 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
910 check_for_default (extdir
, buffer
);
911 edit_load_file_from_filename (edit
, buffer
);
914 edit_load_file_from_filename (edit
, extdir
);
920 edit_load_menu_file (WEdit
* edit
)
928 _(" Which menu file do you want to edit? "), D_NORMAL
,
929 geteuid() ? 2 : 3, _("&Local"), _("&User"), _("&System Wide")
932 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
934 if (!exist_file (menufile
)) {
936 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
941 buffer
= g_strdup (EDIT_LOCAL_MENU
);
942 check_for_default (menufile
, buffer
);
943 chmod (buffer
, 0600);
947 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
948 check_for_default (menufile
, buffer
);
952 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
953 if (!exist_file (buffer
)) {
955 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
964 edit_load_file_from_filename (edit
, buffer
);
971 edit_load_cmd (WEdit
*edit
, edit_current_file_t what
)
976 && (edit_query_dialog2
978 _(" Current text was modified without a file save. \n"
979 " Continue discards these changes. "),
980 _("C&ontinue"), _("&Cancel")) == 1)) {
981 edit
->force
|= REDRAW_COMPLETELY
;
986 case EDIT_FILE_COMMON
:
987 exp
= input_expand_dialog (_(" Load "), _(" Enter file name: "),
988 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
992 edit_load_file_from_filename (edit
, exp
);
997 case EDIT_FILE_SYNTAX
:
998 edit_load_syntax_file (edit
);
1001 case EDIT_FILE_MENU
:
1002 edit_load_menu_file (edit
);
1009 edit
->force
|= REDRAW_COMPLETELY
;
1014 if mark2 is -1 then marking is from mark1 to the cursor.
1015 Otherwise its between the markers. This handles this.
1016 Returns 1 if no text is marked.
1018 int eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1020 if (edit
->mark1
!= edit
->mark2
) {
1021 if (edit
->mark2
>= 0) {
1022 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1023 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1025 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1026 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1027 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1031 *start_mark
= *end_mark
= 0;
1032 edit
->column2
= edit
->column1
= 0;
1037 #define space_width 1
1040 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1044 cursor
= edit
->curs1
;
1045 col
= edit_get_col (edit
);
1046 for (i
= 0; i
< size
; i
++) {
1047 if (data
[i
] == '\n') { /* fill in and move to next line */
1050 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1051 l
= width
- (edit_get_col (edit
) - col
);
1053 edit_insert (edit
, ' ');
1057 for (p
= edit
->curs1
;; p
++) {
1058 if (p
== edit
->last_byte
) {
1059 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1060 edit_insert_ahead (edit
, '\n');
1064 if (edit_get_byte (edit
, p
) == '\n') {
1069 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1070 l
= col
- edit_get_col (edit
);
1071 while (l
>= space_width
) {
1072 edit_insert (edit
, ' ');
1077 edit_insert (edit
, data
[i
]);
1079 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1082 #define TEMP_BUF_LEN 1024
1085 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1089 int blocklen
= -1, width
;
1090 unsigned char *data
;
1091 cursor
= edit
->curs1
;
1092 col
= edit_get_col (edit
);
1093 data
= g_malloc (TEMP_BUF_LEN
);
1094 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0) {
1095 for (width
= 0; width
< blocklen
; width
++) {
1096 if (data
[width
] == '\n')
1099 for (i
= 0; i
< blocklen
; i
++) {
1100 if (data
[i
] == '\n') { /* fill in and move to next line */
1103 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1104 l
= width
- (edit_get_col (edit
) - col
);
1106 edit_insert (edit
, ' ');
1110 for (p
= edit
->curs1
;; p
++) {
1111 if (p
== edit
->last_byte
) {
1112 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1113 edit_insert_ahead (edit
, '\n');
1117 if (edit_get_byte (edit
, p
) == '\n') {
1122 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1123 l
= col
- edit_get_col (edit
);
1124 while (l
>= space_width
) {
1125 edit_insert (edit
, ' ');
1130 edit_insert (edit
, data
[i
]);
1133 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1135 edit
->force
|= REDRAW_PAGE
;
1140 edit_block_copy_cmd (WEdit
*edit
)
1142 long start_mark
, end_mark
, current
= edit
->curs1
;
1144 unsigned char *copy_buf
;
1146 edit_update_curs_col (edit
);
1147 if (eval_marks (edit
, &start_mark
, &end_mark
))
1150 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1152 /* all that gets pushed are deletes hence little space is used on the stack */
1154 edit_push_markers (edit
);
1156 if (column_highlighting
) {
1157 edit_insert_column_of_text (edit
, copy_buf
, size
,
1158 abs (edit
->column2
- edit
->column1
));
1161 edit_insert_ahead (edit
, copy_buf
[size
]);
1165 edit_scroll_screen_over_cursor (edit
);
1167 if (column_highlighting
) {
1168 edit_set_markers (edit
, 0, 0, 0, 0);
1169 edit_push_action (edit
, COLUMN_ON
);
1170 column_highlighting
= 0;
1171 } else if (start_mark
< current
&& end_mark
> current
)
1172 edit_set_markers (edit
, start_mark
,
1173 end_mark
+ end_mark
- start_mark
, 0, 0);
1175 edit
->force
|= REDRAW_PAGE
;
1180 edit_block_move_cmd (WEdit
*edit
)
1184 unsigned char *copy_buf
;
1185 long start_mark
, end_mark
;
1189 if (eval_marks (edit
, &start_mark
, &end_mark
))
1191 if (column_highlighting
) {
1192 edit_update_curs_col (edit
);
1194 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1195 if ((x
> edit
->column1
&& x
< edit
->column2
)
1196 || (x
> edit
->column2
&& x
< edit
->column1
))
1198 } else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1201 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1202 if (edit_query_dialog2
1205 (" Block is large, you may not be able to undo this action. "),
1206 _("C&ontinue"), _("&Cancel")))
1209 edit_push_markers (edit
);
1210 current
= edit
->curs1
;
1211 if (column_highlighting
) {
1212 int size
, c1
, c2
, line
;
1213 line
= edit
->curs_line
;
1214 if (edit
->mark2
< 0)
1215 edit_mark_cmd (edit
, 0);
1216 c1
= min (edit
->column1
, edit
->column2
);
1217 c2
= max (edit
->column1
, edit
->column2
);
1218 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1220 edit_block_delete_cmd (edit
);
1223 edit_move_to_line (edit
, line
);
1224 edit_cursor_move (edit
,
1225 edit_move_forward3 (edit
,
1226 edit_bol (edit
, edit
->curs1
),
1227 x
, 0) - edit
->curs1
);
1228 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1230 line
= edit
->curs_line
;
1231 edit_update_curs_col (edit
);
1233 edit_block_delete_cmd (edit
);
1234 edit_move_to_line (edit
, line
);
1235 edit_cursor_move (edit
,
1236 edit_move_forward3 (edit
,
1239 x
, 0) - edit
->curs1
);
1241 edit_set_markers (edit
, 0, 0, 0, 0);
1242 edit_push_action (edit
, COLUMN_ON
);
1243 column_highlighting
= 0;
1245 copy_buf
= g_malloc (end_mark
- start_mark
);
1246 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1247 edit_scroll_screen_over_cursor (edit
);
1249 while (count
< end_mark
) {
1250 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1253 edit_scroll_screen_over_cursor (edit
);
1254 edit_cursor_move (edit
,
1255 current
- edit
->curs1
-
1256 (((current
- edit
->curs1
) >
1257 0) ? end_mark
- start_mark
: 0));
1258 edit_scroll_screen_over_cursor (edit
);
1259 while (count
-- > start_mark
)
1260 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1261 edit_set_markers (edit
, edit
->curs1
,
1262 edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1264 edit_scroll_screen_over_cursor (edit
);
1266 edit
->force
|= REDRAW_PAGE
;
1270 edit_delete_column_of_text (WEdit
* edit
)
1272 long p
, q
, r
, m1
, m2
;
1276 eval_marks (edit
, &m1
, &m2
);
1277 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1278 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1279 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1281 b
= max(min (c
, d
), min (edit
->column1
, edit
->column2
));
1282 c
= max (c
, d
+ edit
->over_col
);
1285 r
= edit_bol (edit
, edit
->curs1
);
1286 p
= edit_move_forward3 (edit
, r
, b
, 0);
1287 q
= edit_move_forward3 (edit
, r
, c
, 0);
1292 edit_cursor_move (edit
, p
- edit
->curs1
);
1293 while (q
> p
) { /* delete line between margins */
1294 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1295 edit_delete (edit
, 1);
1298 if (n
) /* move to next line except on the last delete */
1299 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1303 /* if success return 0 */
1305 edit_block_delete (WEdit
*edit
)
1308 long start_mark
, end_mark
;
1309 if (eval_marks (edit
, &start_mark
, &end_mark
))
1311 if (column_highlighting
&& edit
->mark2
< 0)
1312 edit_mark_cmd (edit
, 0);
1313 if ((end_mark
- start_mark
) > option_max_undo
/ 2) {
1314 /* Warning message with a query to continue or cancel the operation */
1315 if (edit_query_dialog2
1318 (" Block is large, you may not be able to undo this action. "),
1319 _("C&ontinue"), _("&Cancel"))) {
1323 edit_push_markers (edit
);
1324 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1325 edit_scroll_screen_over_cursor (edit
);
1327 if (start_mark
< end_mark
) {
1328 if (column_highlighting
) {
1329 if (edit
->mark2
< 0)
1330 edit_mark_cmd (edit
, 0);
1331 edit_delete_column_of_text (edit
);
1333 while (count
< end_mark
) {
1334 edit_delete (edit
, 1);
1339 edit_set_markers (edit
, 0, 0, 0, 0);
1340 edit
->force
|= REDRAW_PAGE
;
1344 /* returns 1 if canceelled by user */
1345 int edit_block_delete_cmd (WEdit
* edit
)
1347 long start_mark
, end_mark
;
1348 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
1349 edit_delete_line (edit
);
1352 return edit_block_delete (edit
);
1355 #define INPUT_INDEX 9
1358 editcmd_find (WEdit
*edit
, gsize
*len
)
1360 off_t search_start
= edit
->search_start
;
1362 long start_mark
= 0;
1363 long end_mark
= edit
->last_byte
;
1366 if (edit
->only_in_selection
) {
1367 mark_res
= eval_marks(edit
, &start_mark
, &end_mark
);
1368 if (mark_res
!= 0) {
1369 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1370 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1373 if (edit
->replace_backwards
) {
1374 if (search_start
> end_mark
|| search_start
<= start_mark
) {
1375 search_start
= end_mark
;
1378 if (search_start
< start_mark
|| search_start
>= end_mark
) {
1379 search_start
= start_mark
;
1383 if (edit
->replace_backwards
)
1384 end_mark
= max(1, edit
->curs1
) - 1;
1386 if (edit
->replace_backwards
) {
1387 search_end
= end_mark
;
1388 while ((int) search_start
>= start_mark
) {
1389 if (search_end
> search_start
+ edit
->search
->original_len
1390 && mc_search_is_fixed_search_str(edit
->search
)) {
1391 search_end
= search_start
+ edit
->search
->original_len
;
1393 if (mc_search_run(edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1394 && edit
->search
->normal_offset
== search_start
) {
1399 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1401 return mc_search_run(edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1407 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1408 (and the above) routines to work properly - paul */
1410 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1413 edit_replace_cmd__conv_to_display(char *str
)
1417 tmp
= str_convert_to_display (str
);
1419 if (tmp
&& tmp
->len
){
1423 g_string_free (tmp
, FALSE
);
1426 return g_strdup(str
);
1431 edit_replace_cmd__conv_to_input(char *str
)
1435 tmp
= str_convert_to_input (str
);
1437 if (tmp
&& tmp
->len
){
1441 g_string_free (tmp
, FALSE
);
1444 return g_strdup(str
);
1447 /* call with edit = 0 before shutdown to close memory leaks */
1449 edit_replace_cmd (WEdit
*edit
, int again
)
1451 /* 1 = search string, 2 = replace with */
1452 static char *saved1
= NULL
; /* saved default[123] */
1453 static char *saved2
= NULL
;
1454 char *input1
= NULL
; /* user input from the dialog */
1455 char *input2
= NULL
;
1457 long times_replaced
= 0, last_search
;
1458 gboolean once_found
= FALSE
;
1461 g_free (saved1
), saved1
= NULL
;
1462 g_free (saved2
), saved2
= NULL
;
1466 last_search
= edit
->last_byte
;
1468 edit
->force
|= REDRAW_COMPLETELY
;
1470 if (again
&& !saved1
&& !saved2
)
1474 input1
= g_strdup (saved1
? saved1
: "");
1475 input2
= g_strdup (saved2
? saved2
: "");
1477 char *disp1
= edit_replace_cmd__conv_to_display(g_strdup (saved1
? saved1
: ""));
1478 char *disp2
= edit_replace_cmd__conv_to_display(g_strdup (saved2
? saved2
: ""));
1480 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1482 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1487 if (input1
== NULL
|| *input1
== '\0') {
1488 edit
->force
= REDRAW_COMPLETELY
;
1492 input1
= edit_replace_cmd__conv_to_input(input1
);
1493 input2
= edit_replace_cmd__conv_to_input(input2
);
1495 g_free (saved1
), saved1
= g_strdup (input1
);
1496 g_free (saved2
), saved2
= g_strdup (input2
);
1499 mc_search_free(edit
->search
);
1500 edit
->search
= NULL
;
1504 if (!edit
->search
) {
1505 edit
->search
= mc_search_new(input1
, -1);
1506 if (edit
->search
== NULL
) {
1507 edit
->search_start
= edit
->curs1
;
1510 edit
->search
->search_type
= edit
->search_type
;
1511 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1512 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1513 edit
->search
->whole_words
= edit
->whole_words
;
1514 edit
->search
->search_fn
= edit_search_cmd_callback
;
1517 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1518 && edit
->replace_backwards
)
1519 edit
->search_start
--;
1521 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1522 && !edit
->replace_backwards
)
1523 edit
->search_start
++;
1529 if (! editcmd_find(edit
, &len
)) {
1530 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1531 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
))) {
1532 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1537 new_start
= edit
->search
->normal_offset
;
1539 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1540 /*returns negative on not found or error in pattern */
1542 if (edit
->search_start
>= 0) {
1545 edit
->found_start
= edit
->search_start
;
1546 i
= edit
->found_len
= len
;
1548 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1549 edit_scroll_screen_over_cursor (edit
);
1553 if (edit
->replace_mode
== 0) {
1555 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1557 edit_scroll_downward (edit
, l
);
1559 edit_scroll_upward (edit
, -l
);
1561 edit_scroll_screen_over_cursor (edit
);
1562 edit
->force
|= REDRAW_PAGE
;
1563 edit_render_keypress (edit
);
1565 /*so that undo stops at each query */
1566 edit_push_key_press (edit
);
1567 /* and prompt 2/3 down */
1568 switch (editcmd_dialog_replace_prompt_show (edit
, input1
, input2
, -1, -1)) {
1572 case B_SKIP_REPLACE
:
1576 edit
->replace_mode
=1;
1580 edit
->replace_mode
= -1;
1584 if (replace_yes
) { /* delete then insert new */
1585 GString
*repl_str
, *tmp_str
;
1586 tmp_str
= g_string_new(input2
);
1588 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1589 g_string_free(tmp_str
, TRUE
);
1590 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1592 edit_error_dialog (_ ("Replace"), edit
->search
->error_str
);
1597 edit_delete (edit
, 1);
1599 while (++i
< repl_str
->len
)
1600 edit_insert (edit
, repl_str
->str
[i
]);
1602 g_string_free(repl_str
, TRUE
);
1603 edit
->found_len
= i
;
1605 /* so that we don't find the same string again */
1606 if (edit
->replace_backwards
) {
1607 last_search
= edit
->search_start
;
1608 edit
->search_start
--;
1610 edit
->search_start
+= i
;
1611 last_search
= edit
->last_byte
;
1613 edit_scroll_screen_over_cursor (edit
);
1615 const char *msg
= _(" Replace ");
1616 /* try and find from right here for next search */
1617 edit
->search_start
= edit
->curs1
;
1618 edit_update_curs_col (edit
);
1620 edit
->force
|= REDRAW_PAGE
;
1621 edit_render_keypress (edit
);
1622 if (times_replaced
) {
1623 message (D_NORMAL
, msg
, _(" %ld replacements made. "),
1626 query_dialog (msg
, _(" Search string not found "),
1627 D_NORMAL
, 1, _("&OK"));
1628 edit
->replace_mode
= -1;
1630 } while (edit
->replace_mode
>= 0);
1632 edit
->force
= REDRAW_COMPLETELY
;
1633 edit_scroll_screen_over_cursor (edit
);
1640 void edit_search_cmd (WEdit
* edit
, int again
)
1642 char *search_string
= NULL
, *search_string_dup
= NULL
;
1649 if (edit
->search
!= NULL
) {
1650 search_string
= g_strndup(edit
->search
->original
, edit
->search
->original_len
);
1651 search_string_dup
= search_string
;
1654 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1655 if (history
!= NULL
&& history
->data
!= NULL
) {
1656 search_string_dup
= search_string
= (char *) g_strdup(history
->data
);
1657 history
= g_list_first (history
);
1658 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1659 g_list_free (history
);
1661 edit
->search_start
= edit
->curs1
;
1667 if (search_string
&& *search_string
) {
1668 tmp
= str_convert_to_display (search_string
);
1670 g_free(search_string_dup
);
1671 search_string_dup
= NULL
;
1673 if (tmp
&& tmp
->len
)
1674 search_string
= search_string_dup
= tmp
->str
;
1675 g_string_free (tmp
, FALSE
);
1677 #endif /* HAVE_CHARSET */
1678 editcmd_dialog_search_show (edit
, &search_string
);
1680 if (search_string
&& *search_string
) {
1681 tmp
= str_convert_to_input (search_string
);
1682 if (tmp
&& tmp
->len
)
1683 search_string
= tmp
->str
;
1685 g_string_free (tmp
, FALSE
);
1687 if (search_string_dup
)
1688 g_free(search_string_dup
);
1690 #endif /* HAVE_CHARSET */
1692 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1694 if (!search_string
) {
1695 edit
->force
|= REDRAW_COMPLETELY
;
1696 edit_scroll_screen_over_cursor (edit
);
1701 mc_search_free(edit
->search
);
1702 edit
->search
= NULL
;
1706 if (!edit
->search
) {
1707 edit
->search
= mc_search_new(search_string
, -1);
1708 if (edit
->search
== NULL
) {
1709 edit
->search_start
= edit
->curs1
;
1712 edit
->search
->search_type
= edit
->search_type
;
1713 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1714 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1715 edit
->search
->whole_words
= edit
->whole_words
;
1716 edit
->search
->search_fn
= edit_search_cmd_callback
;
1719 if (search_create_bookmark
) {
1720 edit_search_cmd_search_create_bookmark(edit
);
1722 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1 && edit
->replace_backwards
)
1723 edit
->search_start
--;
1725 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1 && !edit
->replace_backwards
)
1726 edit
->search_start
++;
1729 if (editcmd_find(edit
, &len
)) {
1730 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1731 edit
->found_len
= len
;
1733 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1734 edit_scroll_screen_over_cursor (edit
);
1735 if (edit
->replace_backwards
)
1736 edit
->search_start
--;
1738 edit
->search_start
++;
1740 edit
->search_start
= edit
->curs1
;
1741 if (edit
->search
->error_str
)
1742 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1746 edit
->force
|= REDRAW_COMPLETELY
;
1747 edit_scroll_screen_over_cursor (edit
);
1752 * Check if it's OK to close the editor. If there are unsaved changes,
1753 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
1756 edit_ok_to_exit (WEdit
*edit
)
1758 if (!edit
->modified
)
1761 switch (edit_query_dialog3
1762 (_("Quit"), _(" File was modified, Save with exit? "),
1763 _("&Cancel quit"), _("&Yes"), _("&No"))) {
1765 edit_push_markers (edit
);
1766 edit_set_markers (edit
, 0, 0, 0, 0);
1767 if (!edit_save_cmd (edit
))
1780 /* Return a null terminated length of text. Result must be g_free'd */
1781 static unsigned char *
1782 edit_get_block (WEdit
*edit
, long start
, long finish
, int *l
)
1784 unsigned char *s
, *r
;
1785 r
= s
= g_malloc (finish
- start
+ 1);
1786 if (column_highlighting
) {
1788 /* copy from buffer, excluding chars that are out of the column 'margins' */
1789 while (start
< finish
) {
1791 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0,
1793 c
= edit_get_byte (edit
, start
);
1794 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1795 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n') {
1802 *l
= finish
- start
;
1803 while (start
< finish
)
1804 *s
++ = edit_get_byte (edit
, start
++);
1810 /* save block, returns 1 on success */
1812 edit_save_block (WEdit
* edit
, const char *filename
, long start
,
1818 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1819 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
1822 if (column_highlighting
) {
1824 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof(VERTICAL_MAGIC
));
1826 unsigned char *block
, *p
;
1827 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
1829 r
= mc_write (file
, p
, len
);
1840 len
= finish
- start
;
1841 buf
= g_malloc (TEMP_BUF_LEN
);
1842 while (start
!= finish
) {
1843 end
= min (finish
, start
+ TEMP_BUF_LEN
);
1844 for (; i
< end
; i
++)
1845 buf
[i
- start
] = edit_get_byte (edit
, i
);
1846 len
-= mc_write (file
, (char *) buf
, end
- start
);
1857 /* copies a block to clipboard file */
1858 static int edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1862 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1863 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1869 void edit_paste_from_history (WEdit
*edit
)
1872 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
1875 int edit_copy_to_X_buf_cmd (WEdit
* edit
)
1877 long start_mark
, end_mark
;
1878 if (eval_marks (edit
, &start_mark
, &end_mark
))
1880 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1881 edit_error_dialog (_(" Copy to clipboard "), get_sys_error (_(" Unable to save to file. ")));
1884 edit_mark_cmd (edit
, 1);
1888 int edit_cut_to_X_buf_cmd (WEdit
* edit
)
1890 long start_mark
, end_mark
;
1891 if (eval_marks (edit
, &start_mark
, &end_mark
))
1893 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1894 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
1897 edit_block_delete_cmd (edit
);
1898 edit_mark_cmd (edit
, 1);
1902 void edit_paste_from_X_buf_cmd (WEdit
* edit
)
1905 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1906 edit_insert_file (edit
, tmp
);
1912 * Ask user for the line and go to that line.
1913 * Negative numbers mean line from the end (i.e. -1 is the last line).
1916 edit_goto_cmd (WEdit
*edit
)
1919 static long line
= 0; /* line as typed, saved as default */
1924 g_snprintf (s
, sizeof (s
), "%ld", line
);
1925 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
1935 l
= strtol (f
, &error
, 0);
1943 l
= edit
->total_lines
+ l
+ 2;
1944 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
1945 edit_move_to_line (edit
, l
- 1);
1946 edit
->force
|= REDRAW_COMPLETELY
;
1951 /* Return 1 on success */
1953 edit_save_block_cmd (WEdit
*edit
)
1955 long start_mark
, end_mark
;
1958 if (eval_marks (edit
, &start_mark
, &end_mark
))
1961 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1963 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
1964 MC_HISTORY_EDIT_SAVE_BLOCK
,
1967 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1973 if (edit_save_block (edit
, exp
, start_mark
, end_mark
)) {
1975 edit
->force
|= REDRAW_COMPLETELY
;
1979 edit_error_dialog (_(" Save Block "),
1981 (" Cannot save file. ")));
1985 edit
->force
|= REDRAW_COMPLETELY
;
1990 /* returns 1 on success */
1992 edit_insert_file_cmd (WEdit
*edit
)
1997 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1998 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
1999 MC_HISTORY_EDIT_INSERT_FILE
,
2002 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2008 if (edit_insert_file (edit
, exp
)) {
2010 edit
->force
|= REDRAW_COMPLETELY
;
2014 edit_error_dialog (_(" Insert File "),
2016 (" Cannot insert file. ")));
2020 edit
->force
|= REDRAW_COMPLETELY
;
2024 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2025 int edit_sort_cmd (WEdit
* edit
)
2027 static char *old
= 0;
2029 long start_mark
, end_mark
;
2032 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2033 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2037 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2038 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2041 exp
= input_dialog (_(" Run Sort "),
2042 _(" Enter sort options (see manpage) separated by whitespace: "),
2043 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2049 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2050 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2054 if (e
== -1 || e
== 127) {
2055 edit_error_dialog (_(" Sort "),
2056 get_sys_error (_(" Cannot execute sort command ")));
2059 sprintf (q
, "%d ", e
);
2060 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2061 edit_error_dialog (_(" Sort "), tmp
);
2067 edit
->force
|= REDRAW_COMPLETELY
;
2069 if (edit_block_delete_cmd (edit
))
2071 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2072 edit_insert_file (edit
, tmp
);
2078 * Ask user for a command, execute it and paste its output back to the
2082 edit_ext_cmd (WEdit
*edit
)
2088 input_dialog (_("Paste output of external command"),
2089 _("Enter shell command(s):"),
2090 MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2095 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2101 edit_error_dialog (_("External command"),
2102 get_sys_error (_("Cannot execute command")));
2106 edit
->force
|= REDRAW_COMPLETELY
;
2107 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2108 edit_insert_file (edit
, tmp
);
2113 /* if block is 1, a block must be highlighted and the shell command
2114 processes it. If block is 0 the shell command is a straight system
2115 command, that just produces some output which is to be inserted */
2117 edit_block_process_cmd (WEdit
*edit
, const char *shell_cmd
, int block
)
2119 long start_mark
, end_mark
;
2121 FILE *script_home
= NULL
;
2122 FILE *script_src
= NULL
;
2123 FILE *block_file
= NULL
;
2124 gchar
*o
, *h
, *b
, *tmp
;
2125 char *quoted_name
= NULL
;
2127 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2128 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2129 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2131 if (!(script_home
= fopen (h
, "r"))) {
2132 if (!(script_home
= fopen (h
, "w"))) {
2133 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2134 edit_error_dialog ("", get_sys_error (tmp
));
2136 goto edit_block_process_cmd__EXIT
;
2138 if (!(script_src
= fopen (o
, "r"))) {
2139 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2140 if (!(script_src
= fopen (o
, "r"))) {
2141 fclose (script_home
);
2143 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2144 edit_error_dialog ("", get_sys_error (tmp
));
2146 goto edit_block_process_cmd__EXIT
;
2149 while (fgets (buf
, sizeof (buf
), script_src
))
2150 fputs (buf
, script_home
);
2151 if (fclose (script_home
)) {
2152 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2153 edit_error_dialog ("", get_sys_error (tmp
));
2155 goto edit_block_process_cmd__EXIT
;
2158 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2159 edit_error_dialog ("", get_sys_error (tmp
));
2165 if (block
) { /* for marked block run indent formatter */
2166 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2167 edit_error_dialog (_("Process block"),
2169 (" You must first highlight a block of text. "));
2170 goto edit_block_process_cmd__EXIT
;
2172 edit_save_block (edit
, b
, start_mark
, end_mark
);
2173 quoted_name
= name_quote (edit
->filename
, 0);
2176 * Initial space is to avoid polluting bash history.
2178 * $1 - name of the edited file (to check its extension etc).
2179 * $2 - file containing the current block.
2180 * $3 - file where error messages should be put
2181 * (for compatibility with old scripts).
2183 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2184 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2189 * No block selected, just execute the command for the file.
2191 * $1 - name of the edited file.
2193 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2194 quoted_name
, (char *) NULL
);
2198 g_free (quoted_name
);
2199 close_error_pipe (D_NORMAL
, NULL
);
2201 edit_refresh_cmd (edit
);
2202 edit
->force
|= REDRAW_COMPLETELY
;
2204 /* insert result block */
2206 if (edit_block_delete_cmd (edit
))
2207 goto edit_block_process_cmd__EXIT
;
2208 edit_insert_file (edit
, b
);
2209 if ((block_file
= fopen (b
, "w")))
2210 fclose (block_file
);
2211 goto edit_block_process_cmd__EXIT
;
2213 edit_block_process_cmd__EXIT
:
2220 /* prints at the cursor */
2221 /* returns the number of chars printed */
2222 int edit_print_string (WEdit
* e
, const char *s
)
2226 edit_execute_cmd (e
, -1, (unsigned char) s
[i
++]);
2227 e
->force
|= REDRAW_COMPLETELY
;
2228 edit_update_screen (e
);
2233 static void pipe_mail (WEdit
*edit
, char *to
, char *subject
, char *cc
)
2238 to
= name_quote (to
, 0);
2239 subject
= name_quote (subject
, 0);
2240 cc
= name_quote (cc
, 0);
2241 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "" , cc
, " ", to
, (char *) NULL
);
2253 for (i
= 0; i
< edit
->last_byte
; i
++)
2254 fputc (edit_get_byte (edit
, i
), p
);
2259 #define MAIL_DLG_HEIGHT 12
2261 void edit_mail_dialog (WEdit
* edit
)
2264 char *tmail_subject
;
2267 static char *mail_cc_last
= 0;
2268 static char *mail_subject_last
= 0;
2269 static char *mail_to_last
= 0;
2271 QuickWidget quick_widgets
[] =
2273 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2274 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2275 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2276 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2277 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2", &tmail_subject
),
2278 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2279 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2280 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2281 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2285 QuickDialog Quick_input
=
2287 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2288 "[Input Line Keys]", quick_widgets
, FALSE
2291 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2292 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2293 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2295 if (quick_dialog (&Quick_input
) != B_CANCEL
) {
2296 g_free (mail_cc_last
);
2297 g_free (mail_subject_last
);
2298 g_free (mail_to_last
);
2299 mail_cc_last
= tmail_cc
;
2300 mail_subject_last
= tmail_subject
;
2301 mail_to_last
= tmail_to
;
2302 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2307 /*******************/
2308 /* Word Completion */
2309 /*******************/
2311 static gboolean
is_break_char(char c
)
2313 return (isspace(c
) || strchr("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2316 /* find first character of current word */
2317 static int edit_find_word_start (WEdit
*edit
, long *word_start
, int *word_len
)
2321 /* return if at begin of file */
2322 if (edit
->curs1
<= 0)
2325 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2326 /* return if not at end or in word */
2327 if (is_break_char(c
))
2330 /* search start of word to be completed */
2332 /* return if at begin of file */
2333 if (edit
->curs1
- i
< 0)
2337 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2339 if (is_break_char(c
)) {
2340 /* return if word starts with digit */
2344 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2353 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2355 /* collect the possible completions */
2357 edit_collect_completions (WEdit
*edit
, long start
, int word_len
,
2358 char *match_expr
, struct selection
*compl,
2368 srch
= mc_search_new(match_expr
, -1);
2372 srch
->search_type
= MC_SEARCH_T_REGEX
;
2373 srch
->is_case_sentitive
= TRUE
;
2374 srch
->search_fn
= edit_search_cmd_callback
;
2376 /* collect max MAX_WORD_COMPLETIONS completions */
2378 while (*num
< MAX_WORD_COMPLETIONS
) {
2379 /* get next match */
2380 if (mc_search_run (srch
, (void *) edit
, start
+1, edit
->last_byte
, &len
) == FALSE
)
2382 start
= srch
->normal_offset
;
2384 /* add matched completion if not yet added */
2385 temp
= g_string_new("");
2386 for (i
= 0; i
< len
; i
++){
2387 skip
= edit_get_byte(edit
, start
+i
);
2390 g_string_append_c (temp
, skip
);
2395 for (i
= 0; i
< (gsize
) *num
; i
++) {
2398 (char *) &compl[i
].text
[word_len
],
2399 (char *) &temp
->str
[word_len
],
2400 max (len
, compl[i
].len
) - (gsize
)word_len
2403 break; /* skip it, already added */
2407 g_string_free(temp
, TRUE
);
2411 compl[*num
].text
= temp
->str
;
2412 compl[*num
].len
= temp
->len
;
2414 g_string_free(temp
, FALSE
);
2416 /* note the maximal length needed for the completion dialog */
2420 mc_search_free(srch
);
2425 * Complete current word using regular expression search
2426 * backwards beginning at the current cursor position.
2429 edit_complete_word_cmd (WEdit
*edit
)
2431 int word_len
= 0, num_compl
= 0;
2433 long word_start
= 0;
2434 unsigned char *bufpos
;
2436 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2438 /* search start of word to be completed */
2439 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2442 /* prepare match expression */
2443 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2444 [word_start
& M_EDIT_BUF_SIZE
];
2446 match_expr
= g_strdup_printf ("(^|\\s)%.*s[^\\s\\.=\\+\\{\\}\\[\\]\\(\\)\\\\\\!\\,<>\\?\\/@#\\$%%\\^&\\*\\~\\|\\\"'\\:\\;]+", word_len
, bufpos
);
2448 /* collect the possible completions */
2449 /* start search from begin to end of file */
2451 edit_collect_completions (edit
, 0, word_len
, match_expr
,
2452 (struct selection
*) &compl, &num_compl
);
2454 if (num_compl
> 0) {
2455 /* insert completed word if there is only one match */
2456 if (num_compl
== 1) {
2457 for (i
= word_len
; i
< compl[0].len
; i
++)
2458 edit_insert (edit
, *(compl[0].text
+ i
));
2460 /* more than one possible completion => ask the user */
2462 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2463 /* !!! pressed again the selection dialog pops up, but that !!! */
2464 /* !!! seems to require a further internal state !!! */
2467 /* let the user select the preferred completion */
2468 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2469 (struct selection
*) &compl,
2474 g_free (match_expr
);
2475 /* release memory before return */
2476 for (i
= 0; i
< (gsize
) num_compl
; i
++)
2477 g_free (compl[i
].text
);
2482 edit_select_codepage_cmd (WEdit
*edit
)
2485 const char *cp_id
= NULL
;
2486 if (do_select_codepage ()) {
2487 cp_id
= get_codepage_id (source_codepage
>= 0 ?
2488 source_codepage
: display_codepage
);
2490 if (cp_id
!= NULL
) {
2492 conv
= str_crt_conv_from (cp_id
);
2493 if (conv
!= INVALID_CONV
) {
2494 if (edit
->converter
!= str_cnv_from_term
)
2495 str_close_conv (edit
->converter
);
2496 edit
->converter
= conv
;
2502 edit
->utf8
= str_isutf8 (cp_id
);
2505 edit
->force
= REDRAW_COMPLETELY
;
2506 edit_refresh_cmd (edit
);
2511 edit_insert_literal_cmd (WEdit
*edit
)
2513 int char_for_insertion
=
2514 editcmd_dialog_raw_key_query (_(" Insert Literal "),
2515 _(" Press any key: "), 0);
2516 edit_execute_key_command (edit
, -1,
2517 ascii_alpha_to_cntrl (char_for_insertion
));
2521 edit_execute_macro_cmd (WEdit
*edit
)
2524 CK_Macro (editcmd_dialog_raw_key_query
2525 (_(" Execute Macro "), _(" Press macro hotkey: "),
2527 if (command
== CK_Macro (0))
2528 command
= CK_Insert_Char
;
2530 edit_execute_key_command (edit
, command
, -1);
2534 edit_begin_end_macro_cmd(WEdit
*edit
)
2538 /* edit is a pointer to the widget */
2542 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2543 edit_execute_key_command (edit
, command
, -1);
2548 edit_load_forward_cmd (WEdit
*edit
)
2550 if (edit
->modified
) {
2551 if (edit_query_dialog2
2553 _(" Current text was modified without a file save. \n"
2554 " Continue discards these changes. "), _("C&ontinue"),
2556 edit
->force
|= REDRAW_COMPLETELY
;
2560 if ( edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
) {
2561 if ( edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1 ) {
2564 edit_stack_iterator
++;
2565 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2566 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2567 edit_history_moveto
[edit_stack_iterator
].line
);
2578 edit_load_back_cmd (WEdit
*edit
)
2580 if (edit
->modified
) {
2581 if (edit_query_dialog2
2583 _(" Current text was modified without a file save. \n"
2584 " Continue discards these changes. "), _("C&ontinue"),
2586 edit
->force
|= REDRAW_COMPLETELY
;
2590 if ( edit_stack_iterator
> 0 ) {
2591 edit_stack_iterator
--;
2592 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2593 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2594 edit_history_moveto
[edit_stack_iterator
].line
);
2605 edit_get_match_keyword_cmd (WEdit
*edit
)
2611 long word_start
= 0;
2612 unsigned char *bufpos
;
2616 char *tagfile
= NULL
;
2618 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2620 for ( i
= 0; i
< MAX_DEFINITIONS
; i
++) {
2621 def_hash
[i
].filename
= NULL
;
2624 /* search start of word to be completed */
2625 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2628 /* prepare match expression */
2629 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2630 [word_start
& M_EDIT_BUF_SIZE
];
2631 match_expr
= g_strdup_printf ("%.*s", word_len
, bufpos
);
2633 ptr
= g_get_current_dir ();
2634 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
2637 /* Recursive search file 'TAGS' in parent dirs */
2639 ptr
= g_path_get_dirname (path
);
2640 g_free(path
); path
= ptr
;
2642 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
2643 if ( exist_file (tagfile
) )
2645 } while (strcmp( path
, G_DIR_SEPARATOR_S
) != 0);
2648 num_def
= etags_set_definition_hash(tagfile
, path
, match_expr
, (etags_hash_t
*) &def_hash
);
2653 max_len
= MAX_WIDTH_DEF_DIALOG
;
2655 if ( num_def
> 0 ) {
2656 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
2657 (etags_hash_t
*) &def_hash
,
2660 g_free (match_expr
);
2664 edit_move_block_to_right (WEdit
* edit
)
2666 long start_mark
, end_mark
;
2667 long cur_bol
, start_bol
;
2669 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2672 start_bol
= edit_bol (edit
, start_mark
);
2673 cur_bol
= edit_bol (edit
, end_mark
- 1);
2675 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2676 if ( option_fill_tabs_with_spaces
) {
2677 if ( option_fake_half_tabs
) {
2678 insert_spaces_tab (edit
, 1);
2680 insert_spaces_tab (edit
, 0);
2683 edit_insert (edit
, '\t');
2685 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
2686 if ( cur_bol
== 0 ) {
2689 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2690 } while (cur_bol
>= start_bol
) ;
2691 edit
->force
|= REDRAW_PAGE
;
2695 edit_move_block_to_left (WEdit
* edit
)
2697 long start_mark
, end_mark
;
2698 long cur_bol
, start_bol
;
2699 int i
, del_tab_width
;
2702 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2705 start_bol
= edit_bol (edit
, start_mark
);
2706 cur_bol
= edit_bol (edit
, end_mark
- 1);
2708 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2709 if (option_fake_half_tabs
) {
2710 del_tab_width
= HALF_TAB_SIZE
;
2712 del_tab_width
= option_tab_spacing
;
2714 next_char
= edit_get_byte (edit
, edit
->curs1
);
2715 if ( next_char
== '\t' ) {
2716 edit_delete (edit
, 1);
2717 } else if ( next_char
== ' ' ) {
2718 for (i
= 1; i
<= del_tab_width
; i
++) {
2719 if ( next_char
== ' ' ) {
2720 edit_delete (edit
, 1);
2722 next_char
= edit_get_byte (edit
, edit
->curs1
);
2725 if ( cur_bol
== 0 ) {
2728 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2729 } while (cur_bol
>= start_bol
) ;
2730 edit
->force
|= REDRAW_PAGE
;