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 "lib/global.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h" /* XCTRL */
51 #include "lib/mcconfig.h"
53 #include "lib/strutil.h" /* utf string functions */
54 #include "lib/vfs/mc-vfs/vfs.h"
56 #include "src/history.h"
57 #include "src/widget.h" /* listbox_new() */
58 #include "src/layout.h" /* clr_scr() */
59 #include "src/main.h" /* mc_home source_codepage */
60 #include "src/help.h" /* interactive_display() */
61 #include "src/wtools.h" /* message() */
62 #include "src/charsets.h"
63 #include "src/selcodepage.h"
64 #include "src/cmddef.h"
66 #include "src/editor/edit-impl.h"
67 #include "src/editor/editlock.h"
68 #include "src/editor/edit-widget.h"
69 #include "src/editor/editcmd_dialogs.h"
70 #include "src/editor/etags.h"
74 /* search and replace: */
75 int search_create_bookmark
= 0;
76 /* static int search_in_all_charsets = 0; */
78 /* queries on a save */
79 int edit_confirm_save
= 1;
81 static int edit_save_cmd (WEdit
* edit
);
82 static unsigned char *edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
);
85 edit_search_cmd_search_create_bookmark (WEdit
* edit
)
87 int found
= 0, books
= 0;
88 long l
= 0, l_last
= -1;
92 search_create_bookmark
= 0;
93 book_mark_flush (edit
, -1);
97 if (!mc_search_run (edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
100 edit
->search_start
= edit
->search
->normal_offset
;
102 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
105 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
109 q
= edit
->search
->normal_offset
+ 1;
114 edit_error_dialog (_("Search"), _(" Search string not found "));
118 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
119 edit_scroll_screen_over_cursor (edit
);
124 edit_search_cmd_callback (const void *user_data
, gsize char_offset
)
126 return edit_get_byte ((WEdit
*) user_data
, (long) char_offset
);
130 edit_help_cmd (WEdit
* edit
)
132 interactive_display (NULL
, "[Internal File Editor]");
133 edit
->force
|= REDRAW_COMPLETELY
;
137 edit_refresh_cmd (WEdit
* edit
)
142 edit_get_syntax_color (edit
, -1, &color
);
150 #endif /* !HAVE_SLANG */
154 /* If 0 (quick save) then a) create/truncate <filename> file,
155 b) save to <filename>;
156 if 1 (safe save) then a) save to <tempnam>,
157 b) rename <tempnam> to <filename>;
158 if 2 (do backups) then a) save to <tempnam>,
159 b) rename <filename> to <filename.backup_ext>,
160 c) rename <tempnam> to <filename>. */
162 /* returns 0 on error, -1 on abort */
164 edit_save_file (WEdit
* edit
, const char *filename
)
170 gchar
*real_filename
;
171 int this_save_mode
, fd
= -1;
178 if (*filename
!= PATH_SEP
&& edit
->dir
)
180 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
184 real_filename
= g_strdup (filename
);
187 this_save_mode
= option_save_mode
;
188 if (this_save_mode
!= EDIT_QUICK_SAVE
)
190 if (!vfs_file_is_local (real_filename
) ||
191 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1)
194 * The file does not exists yet, so no safe save or
195 * backup are necessary.
197 this_save_mode
= EDIT_QUICK_SAVE
;
203 if (this_save_mode
== EDIT_QUICK_SAVE
&& !edit
->skip_detach_prompt
)
208 rv
= mc_stat (real_filename
, &sb
);
209 if (rv
== 0 && sb
.st_nlink
> 1)
211 rv
= edit_query_dialog3 (_("Warning"),
212 _(" File has hard-links. Detach before saving? "),
213 _("&Yes"), _("&No"), _("&Cancel"));
217 this_save_mode
= EDIT_SAFE_SAVE
;
220 edit
->skip_detach_prompt
= 1;
223 g_free (real_filename
);
228 /* Prevent overwriting changes from other editor sessions. */
229 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
)
232 /* The default action is "Cancel". */
235 rv
= edit_query_dialog2 (_("Warning"),
236 _("The file has been modified in the meantime. Save anyway?"),
237 _("&Yes"), _("&Cancel"));
240 g_free (real_filename
);
246 if (this_save_mode
!= EDIT_QUICK_SAVE
)
248 char *savedir
, *saveprefix
;
249 const char *slashpos
;
250 slashpos
= strrchr (real_filename
, PATH_SEP
);
253 savedir
= g_strdup (real_filename
);
254 savedir
[slashpos
- real_filename
+ 1] = '\0';
257 savedir
= g_strdup (".");
258 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
260 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
264 g_free (real_filename
);
268 * Close for now because mc_mkstemps use pure open system call
269 * to create temporary file and it needs to be reopened by
270 * VFS-aware mc_open().
275 savename
= g_strdup (real_filename
);
277 mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
278 mc_chmod (savename
, edit
->stat1
.st_mode
);
281 mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
, edit
->stat1
.st_mode
)) == -1)
285 if ((p
= edit_get_write_filter (savename
, real_filename
)))
290 file
= (FILE *) popen (p
, "w");
294 filelen
= edit_write_stream (edit
, file
);
298 if (pclose (file
) != 0)
300 tmp
= g_strconcat (_(" Error writing to pipe: "), p
, " ", (char *) NULL
);
301 edit_error_dialog (_("Error"), tmp
);
310 tmp
= g_strconcat (_(" Cannot open pipe for writing: "), p
, " ", (char *) NULL
);
312 edit_error_dialog (_("Error"), get_sys_error (tmp
));
319 else if (edit
->lb
== LB_ASIS
)
320 { /* do not change line breaks */
323 filelen
= edit
->last_byte
;
324 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1)
326 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
334 (fd
, (char *) edit
->buffers1
[buf
],
335 edit
->curs1
& M_EDIT_BUF_SIZE
) != (edit
->curs1
& M_EDIT_BUF_SIZE
))
339 else if (edit
->curs2
)
342 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
345 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
346 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
347 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) != 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
))
355 if (mc_write (fd
, (char *) edit
->buffers2
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
367 /* Update the file information, especially the mtime. */
368 if (mc_stat (savename
, &edit
->stat1
) == -1)
372 { /* change line breaks */
377 file
= (FILE *) fopen (savename
, "w");
381 filelen
= edit_write_stream (edit
, file
);
388 msg
= g_strdup_printf (_(" Cannot open file for writing: %s "), savename
);
389 edit_error_dialog (_("Error"), msg
);
395 if (filelen
!= edit
->last_byte
)
398 if (this_save_mode
== EDIT_DO_BACKUP
)
400 assert (option_backup_ext
!= NULL
);
401 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
402 if (mc_rename (real_filename
, tmp
) == -1)
409 if (this_save_mode
!= EDIT_QUICK_SAVE
)
410 if (mc_rename (savename
, real_filename
) == -1)
413 g_free (real_filename
);
416 /* FIXME: Is this safe ?
417 * if (this_save_mode != EDIT_QUICK_SAVE)
418 * mc_unlink (savename);
420 g_free (real_filename
);
426 menu_save_mode_cmd (void)
429 const int DLG_X
= 38;
430 const int DLG_Y
= 13;
434 const char *str
[] = {
437 N_("&Do backups with following extension:")
440 QuickWidget widgets
[] = {
442 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
444 QUICK_BUTTON (6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
446 QUICK_CHECKBOX (4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
448 QUICK_INPUT (8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
450 QUICK_RADIO (4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
454 QuickDialog dialog
= {
455 DLG_X
, DLG_Y
, -1, -1, N_(" Edit Save Mode "),
456 "[Edit Save Mode]", widgets
, FALSE
461 size_t w0
, w1
, b_len
, w3
;
463 assert (option_backup_ext
!= NULL
);
465 /* OK/Cancel buttons */
466 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
467 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
470 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
473 for (i
= 0; i
< 3; i
++)
478 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
481 maxlen
= max (maxlen
, w3
+ 4);
483 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
485 widgets
[3].u
.input
.len
= w3
;
486 widgets
[1].relative_x
= (dialog
.xlen
- b_len
) / 2;
487 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
489 for (i
= 0; i
< sizeof (widgets
) / sizeof (widgets
[0]); i
++)
490 widgets
[i
].x_divisions
= dialog
.xlen
;
492 if (quick_dialog (&dialog
) != B_CANCEL
)
494 g_free (option_backup_ext
);
495 option_backup_ext
= str_result
;
500 edit_set_filename (WEdit
* edit
, const char *f
)
502 g_free (edit
->filename
);
505 edit
->filename
= g_strdup (f
);
506 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
508 edit
->dir
= g_strdup (vfs_get_current_dir ());
509 #else /* ENABLE_VFS */
510 edit
->dir
= g_get_current_dir ();
511 #endif /* ENABLE_VFS */
515 edit_check_newline (WEdit
* edit
)
517 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
518 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
519 && edit_query_dialog2 (_("Warning"),
520 _("The file you are saving is not finished with a newline"),
521 _("C&ontinue"), _("&Cancel")));
525 edit_get_save_file_as (WEdit
* edit
)
528 #define DLG_HEIGHT 14
530 static LineBreaks cur_lb
= LB_ASIS
;
532 char *filename
= edit
->filename
;
534 const char *lb_names
[LB_NAMES
] = {
535 N_("&Do not change"),
536 N_("&Unix format (LF)"),
537 N_("&Windows/DOS format (CR LF)"),
538 N_("&Macintosh format (CR)")
541 QuickWidget quick_widgets
[] = {
542 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
543 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
544 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
545 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
546 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0,
547 "save-as", &filename
),
548 QUICK_LABEL (2, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_(" Enter file name: ")),
552 QuickDialog Quick_options
= {
553 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
554 N_(" Save As "), "[Save File As]",
558 if (quick_dialog (&Quick_options
) != B_CANCEL
)
570 /* Here we want to warn the users of overwriting an existing file,
571 but only if they have made a change to the filename */
572 /* returns 1 on success */
574 edit_save_as_cmd (WEdit
* edit
)
576 /* This heads the 'Save As' dialog box */
579 int different_filename
= 0;
581 if (!edit_check_newline (edit
))
584 exp
= edit_get_save_file_as (edit
);
585 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
592 edit
->force
|= REDRAW_COMPLETELY
;
598 if (strcmp (edit
->filename
, exp
))
601 different_filename
= 1;
602 if ((file
= mc_open (exp
, O_RDONLY
| O_BINARY
)) != -1)
604 /* the file exists */
606 /* Overwrite the current file or cancel the operation */
607 if (edit_query_dialog2
609 _(" A file already exists with this name. "),
610 _("&Overwrite"), _("&Cancel")))
612 edit
->force
|= REDRAW_COMPLETELY
;
619 edit
->stat1
.st_mode
|= S_IWUSR
;
621 save_lock
= edit_lock_file (exp
);
625 /* filenames equal, check if already locked */
626 if (!edit
->locked
&& !edit
->delete_file
)
627 save_lock
= edit_lock_file (exp
);
630 if (different_filename
)
633 * Allow user to write into saved (under another name) file
634 * even if original file had r/o user permissions.
636 edit
->stat1
.st_mode
|= S_IWRITE
;
639 rv
= edit_save_file (edit
, exp
);
643 /* Succesful, so unlock both files */
644 if (different_filename
)
647 edit_unlock_file (exp
);
649 edit
->locked
= edit_unlock_file (edit
->filename
);
653 if (edit
->locked
|| save_lock
)
654 edit
->locked
= edit_unlock_file (edit
->filename
);
657 edit_set_filename (edit
, exp
);
658 if (edit
->lb
!= LB_ASIS
)
659 edit_reload (edit
, exp
);
662 edit
->delete_file
= 0;
663 if (different_filename
)
664 edit_load_syntax (edit
, NULL
, option_syntax_type
);
665 edit
->force
|= REDRAW_COMPLETELY
;
668 edit_error_dialog (_(" Save As "), get_sys_error (_(" Cannot save file. ")));
671 /* Failed, so maintain modify (not save) lock */
673 edit_unlock_file (exp
);
675 edit
->force
|= REDRAW_COMPLETELY
;
680 edit
->force
|= REDRAW_COMPLETELY
;
684 /* {{{ Macro stuff starts here */
686 /* creates a macro file if it doesn't exist */
688 edit_open_macro_file (const char *r
)
693 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
694 if ((file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
)) == -1)
700 fd
= fopen (filename
, r
);
705 #define MAX_MACROS 1024
706 static int saved_macro
[MAX_MACROS
+ 1];
707 static int saved_macros_loaded
= 0;
710 This is just to stop the macro file be loaded over and over for keys
711 that aren't defined to anything. On slow systems this could be annoying.
717 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
718 if (saved_macro
[i
] == k
)
723 /* returns 1 on error */
725 edit_delete_macro (WEdit
* edit
, int k
)
728 struct macro macro
[MAX_MACRO_LENGTH
];
734 if (saved_macros_loaded
)
735 if ((j
= macro_exists (k
)) < 0)
737 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
738 g
= fopen (tmp
, "w");
742 edit_error_dialog (_(" Delete macro "), get_sys_error (_(" Cannot open temp file ")));
745 f
= edit_open_macro_file ("r");
748 edit_error_dialog (_(" Delete macro "), get_sys_error (_(" Cannot open macro file ")));
754 n
= fscanf (f
, ("key '%d 0': "), &s
);
758 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
763 fprintf (g
, ("key '%d 0': "), s
);
764 for (i
= 0; i
< n
; i
++)
765 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
771 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
772 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
773 if (rename (tmp
, tmp2
) == -1)
775 edit_error_dialog (_(" Delete macro "), get_sys_error (_(" Cannot overwrite macro file ")));
783 if (saved_macros_loaded
)
784 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
788 /* returns 0 on error */
790 edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
795 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
796 s
= editcmd_dialog_raw_key_query (_(" Save macro "), _(" Press the macro's new hotkey: "), 1);
797 edit
->force
|= REDRAW_COMPLETELY
;
800 if (edit_delete_macro (edit
, s
))
802 f
= edit_open_macro_file ("a+");
805 fprintf (f
, ("key '%d 0': "), s
);
806 for (i
= 0; i
< n
; i
++)
807 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
810 if (saved_macros_loaded
)
812 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
818 edit_error_dialog (_(" Save macro "), get_sys_error (_(" Cannot open macro file ")));
824 edit_delete_macro_cmd (WEdit
* edit
)
828 command
= editcmd_dialog_raw_key_query (_(" Delete macro "), _(" Press macro hotkey: "), 1);
831 edit_delete_macro (edit
, command
);
834 /* return 0 on error */
836 edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
839 int s
, i
= 0, found
= 0;
843 if (saved_macros_loaded
)
844 if (macro_exists (k
) < 0)
847 if ((f
= edit_open_macro_file ("r")))
853 u
= fscanf (f
, ("key '%d 0': "), &s
);
856 if (!saved_macros_loaded
)
857 saved_macro
[i
++] = s
;
861 while (*n
< MAX_MACRO_LENGTH
862 && 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
867 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
873 while (!found
|| !saved_macros_loaded
);
874 if (!saved_macros_loaded
)
877 saved_macros_loaded
= 1;
883 edit_error_dialog (_(" Load macro "), get_sys_error (_(" Cannot open macro file ")));
887 /* }}} Macro stuff starts here */
889 /* returns 1 on success */
891 edit_save_confirm_cmd (WEdit
* edit
)
895 if (!edit_check_newline (edit
))
898 if (edit_confirm_save
)
900 f
= g_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", (char *) NULL
);
901 if (edit_query_dialog2 (_(" Save file "), f
, _("&Save"), _("&Cancel")))
908 return edit_save_cmd (edit
);
912 /* returns 1 on success */
914 edit_save_cmd (WEdit
* edit
)
916 int res
, save_lock
= 0;
918 if (!edit
->locked
&& !edit
->delete_file
)
919 save_lock
= edit_lock_file (edit
->filename
);
920 res
= edit_save_file (edit
, edit
->filename
);
922 /* Maintain modify (not save) lock on failure */
923 if ((res
> 0 && edit
->locked
) || save_lock
)
924 edit
->locked
= edit_unlock_file (edit
->filename
);
926 /* On failure try 'save as', it does locking on its own */
928 return edit_save_as_cmd (edit
);
929 edit
->force
|= REDRAW_COMPLETELY
;
932 edit
->delete_file
= 0;
940 /* returns 1 on success */
942 edit_new_cmd (WEdit
* edit
)
946 if (edit_query_dialog2
949 (" Current text was modified without a file save. \n Continue discards these changes. "),
950 _("C&ontinue"), _("&Cancel")))
952 edit
->force
|= REDRAW_COMPLETELY
;
956 edit
->force
|= REDRAW_COMPLETELY
;
958 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
961 /* returns 1 on error */
963 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
965 int prev_locked
= edit
->locked
;
966 char *prev_filename
= g_strdup (edit
->filename
);
968 if (!edit_reload (edit
, exp
))
970 g_free (prev_filename
);
975 edit_unlock_file (prev_filename
);
976 g_free (prev_filename
);
981 edit_load_syntax_file (WEdit
* edit
)
988 dir
= query_dialog (_("Syntax file edit"),
989 _(" Which syntax file you want to edit? "), D_NORMAL
, 2,
990 _("&User"), _("&System Wide"));
993 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
994 if (!exist_file (extdir
))
997 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
1004 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
1005 check_for_default (extdir
, buffer
);
1006 edit_load_file_from_filename (edit
, buffer
);
1010 edit_load_file_from_filename (edit
, extdir
);
1016 edit_load_menu_file (WEdit
* edit
)
1022 dir
= query_dialog (_(" Menu edit "),
1023 _(" Which menu file do you want to edit? "), D_NORMAL
,
1024 geteuid ()? 2 : 3, _("&Local"), _("&User"), _("&System Wide"));
1026 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1028 if (!exist_file (menufile
))
1031 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1037 buffer
= g_strdup (EDIT_LOCAL_MENU
);
1038 check_for_default (menufile
, buffer
);
1039 chmod (buffer
, 0600);
1043 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
1044 check_for_default (menufile
, buffer
);
1048 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1049 if (!exist_file (buffer
))
1052 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1061 edit_load_file_from_filename (edit
, buffer
);
1068 edit_load_cmd (WEdit
* edit
, edit_current_file_t what
)
1073 && (edit_query_dialog2
1075 _(" Current text was modified without a file save. \n"
1076 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")) == 1))
1078 edit
->force
|= REDRAW_COMPLETELY
;
1084 case EDIT_FILE_COMMON
:
1085 exp
= input_expand_dialog (_(" Load "), _(" Enter file name: "),
1086 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1091 edit_load_file_from_filename (edit
, exp
);
1096 case EDIT_FILE_SYNTAX
:
1097 edit_load_syntax_file (edit
);
1100 case EDIT_FILE_MENU
:
1101 edit_load_menu_file (edit
);
1108 edit
->force
|= REDRAW_COMPLETELY
;
1113 if mark2 is -1 then marking is from mark1 to the cursor.
1114 Otherwise its between the markers. This handles this.
1115 Returns 1 if no text is marked.
1118 eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1120 if (edit
->mark1
!= edit
->mark2
)
1122 long start_bol
, start_eol
;
1123 long end_bol
, end_eol
;
1126 if (edit
->mark2
>= 0)
1128 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1129 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1133 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1134 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1135 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1137 if (column_highlighting
1138 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1139 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
))))
1142 start_bol
= edit_bol (edit
, *start_mark
);
1143 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1144 end_bol
= edit_bol (edit
, *end_mark
);
1145 end_eol
= edit_eol (edit
, *end_mark
);
1146 col1
= min (edit
->column1
, edit
->column2
);
1147 col2
= max (edit
->column1
, edit
->column2
);
1150 edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
,
1153 edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
,
1156 *start_mark
-= diff1
;
1158 *start_mark
= max (*start_mark
, start_eol
);
1159 *end_mark
= min (*end_mark
, end_eol
);
1165 *start_mark
= *end_mark
= 0;
1166 edit
->column2
= edit
->column1
= 0;
1171 #define space_width 1
1174 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1178 cursor
= edit
->curs1
;
1179 col
= edit_get_col (edit
);
1180 for (i
= 0; i
< size
; i
++)
1182 if (data
[i
] == '\n')
1183 { /* fill in and move to next line */
1186 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1188 l
= width
- (edit_get_col (edit
) - col
);
1191 edit_insert (edit
, ' ');
1195 for (p
= edit
->curs1
;; p
++)
1197 if (p
== edit
->last_byte
)
1199 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1200 edit_insert_ahead (edit
, '\n');
1204 if (edit_get_byte (edit
, p
) == '\n')
1210 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1211 l
= col
- edit_get_col (edit
);
1212 while (l
>= space_width
)
1214 edit_insert (edit
, ' ');
1219 edit_insert (edit
, data
[i
]);
1221 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1224 #define TEMP_BUF_LEN 1024
1227 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1231 int blocklen
= -1, width
;
1232 unsigned char *data
;
1233 cursor
= edit
->curs1
;
1234 col
= edit_get_col (edit
);
1235 data
= g_malloc0 (TEMP_BUF_LEN
);
1236 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0)
1238 for (width
= 0; width
< blocklen
; width
++)
1240 if (data
[width
] == '\n')
1243 for (i
= 0; i
< blocklen
; i
++)
1245 if (data
[i
] == '\n')
1246 { /* fill in and move to next line */
1249 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1251 l
= width
- (edit_get_col (edit
) - col
);
1254 edit_insert (edit
, ' ');
1258 for (p
= edit
->curs1
;; p
++)
1260 if (p
== edit
->last_byte
)
1262 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1263 edit_insert_ahead (edit
, '\n');
1267 if (edit_get_byte (edit
, p
) == '\n')
1273 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1274 l
= col
- edit_get_col (edit
);
1275 while (l
>= space_width
)
1277 edit_insert (edit
, ' ');
1282 edit_insert (edit
, data
[i
]);
1285 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1287 edit
->force
|= REDRAW_PAGE
;
1292 edit_block_copy_cmd (WEdit
* edit
)
1294 long start_mark
, end_mark
, current
= edit
->curs1
;
1296 unsigned char *copy_buf
;
1298 edit_update_curs_col (edit
);
1299 if (eval_marks (edit
, &start_mark
, &end_mark
))
1302 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1304 /* all that gets pushed are deletes hence little space is used on the stack */
1306 edit_push_markers (edit
);
1308 if (column_highlighting
)
1310 edit_insert_column_of_text (edit
, copy_buf
, size
, abs (edit
->column2
- edit
->column1
));
1315 edit_insert_ahead (edit
, copy_buf
[size
]);
1319 edit_scroll_screen_over_cursor (edit
);
1321 if (column_highlighting
)
1323 edit_set_markers (edit
, 0, 0, 0, 0);
1324 edit_push_action (edit
, COLUMN_ON
);
1325 column_highlighting
= 0;
1327 else if (start_mark
< current
&& end_mark
> current
)
1328 edit_set_markers (edit
, start_mark
, end_mark
+ end_mark
- start_mark
, 0, 0);
1330 edit
->force
|= REDRAW_PAGE
;
1335 edit_block_move_cmd (WEdit
* edit
)
1339 unsigned char *copy_buf
;
1340 long start_mark
, end_mark
;
1344 if (eval_marks (edit
, &start_mark
, &end_mark
))
1346 if (column_highlighting
)
1348 edit_update_curs_col (edit
);
1350 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1351 if ((x
> edit
->column1
&& x
< edit
->column2
)
1352 || (x
> edit
->column2
&& x
< edit
->column1
))
1355 else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1358 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1359 if (edit_query_dialog2
1362 (" Block is large, you may not be able to undo this action. "),
1363 _("C&ontinue"), _("&Cancel")))
1366 edit_push_markers (edit
);
1367 current
= edit
->curs1
;
1368 if (column_highlighting
)
1372 line
= edit
->curs_line
;
1373 if (edit
->mark2
< 0)
1374 edit_mark_cmd (edit
, 0);
1375 c1
= min (edit
->column1
, edit
->column2
);
1376 c2
= max (edit
->column1
, edit
->column2
);
1377 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1380 edit_block_delete_cmd (edit
);
1383 edit_move_to_line (edit
, line
);
1384 edit_cursor_move (edit
,
1385 edit_move_forward3 (edit
,
1386 edit_bol (edit
, edit
->curs1
), x
, 0) - edit
->curs1
);
1387 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1390 line
= edit
->curs_line
;
1391 edit_update_curs_col (edit
);
1393 edit_block_delete_cmd (edit
);
1394 edit_move_to_line (edit
, line
);
1395 edit_cursor_move (edit
,
1396 edit_move_forward3 (edit
,
1398 edit
->curs1
), x
, 0) - edit
->curs1
);
1400 edit_set_markers (edit
, 0, 0, 0, 0);
1401 edit_push_action (edit
, COLUMN_ON
);
1402 column_highlighting
= 0;
1406 copy_buf
= g_malloc0 (end_mark
- start_mark
);
1407 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1408 edit_scroll_screen_over_cursor (edit
);
1410 while (count
< end_mark
)
1412 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1415 edit_scroll_screen_over_cursor (edit
);
1416 edit_cursor_move (edit
,
1417 current
- edit
->curs1
-
1418 (((current
- edit
->curs1
) > 0) ? end_mark
- start_mark
: 0));
1419 edit_scroll_screen_over_cursor (edit
);
1420 while (count
-- > start_mark
)
1421 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1422 edit_set_markers (edit
, edit
->curs1
, edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1424 edit_scroll_screen_over_cursor (edit
);
1426 edit
->force
|= REDRAW_PAGE
;
1430 edit_delete_column_of_text (WEdit
* edit
)
1432 long p
, q
, r
, m1
, m2
;
1435 eval_marks (edit
, &m1
, &m2
);
1436 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1437 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1438 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1439 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
1440 c
= max (c
, max (edit
->column1
, edit
->column2
));
1444 r
= edit_bol (edit
, edit
->curs1
);
1445 p
= edit_move_forward3 (edit
, r
, b
, 0);
1446 q
= edit_move_forward3 (edit
, r
, c
, 0);
1451 edit_cursor_move (edit
, p
- edit
->curs1
);
1454 /* delete line between margins */
1455 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1456 edit_delete (edit
, 1);
1460 /* move to next line except on the last delete */
1461 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1465 /* if success return 0 */
1467 edit_block_delete (WEdit
* edit
)
1470 long start_mark
, end_mark
;
1471 int curs_pos
, line_width
;
1472 long curs_line
, c1
, c2
;
1474 if (eval_marks (edit
, &start_mark
, &end_mark
))
1476 if (column_highlighting
&& edit
->mark2
< 0)
1477 edit_mark_cmd (edit
, 0);
1478 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1480 /* Warning message with a query to continue or cancel the operation */
1481 if (edit_query_dialog2
1484 (" Block is large, you may not be able to undo this action. "),
1485 _("C&ontinue"), _("&Cancel")))
1490 c1
= min (edit
->column1
, edit
->column2
);
1491 c2
= max (edit
->column1
, edit
->column2
);
1495 edit_push_markers (edit
);
1497 curs_line
= edit
->curs_line
;
1499 /* calculate line width and cursor position before cut */
1500 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1501 edit_eol (edit
, edit
->curs1
));
1502 curs_pos
= edit
->curs_col
+ edit
->over_col
;
1504 /* move cursor to start of selection */
1505 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1506 edit_scroll_screen_over_cursor (edit
);
1508 if (start_mark
< end_mark
)
1510 if (column_highlighting
)
1512 if (edit
->mark2
< 0)
1513 edit_mark_cmd (edit
, 0);
1514 edit_delete_column_of_text (edit
);
1515 /* move cursor to the saved position */
1516 edit_move_to_line (edit
, curs_line
);
1517 /* calculate line width after cut */
1518 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1519 edit_eol (edit
, edit
->curs1
));
1520 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
1521 edit
->over_col
= curs_pos
- line_width
;
1525 while (count
< end_mark
)
1527 edit_delete (edit
, 1);
1532 edit_set_markers (edit
, 0, 0, 0, 0);
1533 edit
->force
|= REDRAW_PAGE
;
1537 /* returns 1 if canceelled by user */
1539 edit_block_delete_cmd (WEdit
* edit
)
1541 long start_mark
, end_mark
;
1542 if (eval_marks (edit
, &start_mark
, &end_mark
))
1544 edit_delete_line (edit
);
1547 return edit_block_delete (edit
);
1550 #define INPUT_INDEX 9
1553 editcmd_find (WEdit
* edit
, gsize
* len
)
1555 off_t search_start
= edit
->search_start
;
1557 long start_mark
= 0;
1558 long end_mark
= edit
->last_byte
;
1561 if (edit_search_options
.only_in_selection
)
1563 mark_res
= eval_marks (edit
, &start_mark
, &end_mark
);
1566 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1567 edit
->search
->error_str
= g_strdup (_(" Search string not found "));
1570 if (edit_search_options
.backwards
)
1572 if (search_start
> end_mark
|| search_start
<= start_mark
)
1574 search_start
= end_mark
;
1579 if (search_start
< start_mark
|| search_start
>= end_mark
)
1581 search_start
= start_mark
;
1587 if (edit_search_options
.backwards
)
1588 end_mark
= max (1, edit
->curs1
) - 1;
1590 if (edit_search_options
.backwards
)
1592 search_end
= end_mark
;
1593 while ((int) search_start
>= start_mark
)
1595 if (search_end
> (off_t
) (search_start
+ edit
->search
->original_len
) &&
1596 mc_search_is_fixed_search_str (edit
->search
))
1598 search_end
= search_start
+ edit
->search
->original_len
;
1600 if (mc_search_run (edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1601 && edit
->search
->normal_offset
== search_start
)
1607 edit
->search
->error_str
= g_strdup (_(" Search string not found "));
1611 return mc_search_run (edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1617 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1618 (and the above) routines to work properly - paul */
1620 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1623 edit_replace_cmd__conv_to_display (char *str
)
1627 tmp
= str_convert_to_display (str
);
1629 if (tmp
&& tmp
->len
)
1631 return g_string_free (tmp
, FALSE
);
1633 g_string_free (tmp
, TRUE
);
1635 return g_strdup (str
);
1639 edit_replace_cmd__conv_to_input (char *str
)
1643 tmp
= str_convert_to_input (str
);
1645 if (tmp
&& tmp
->len
)
1647 return g_string_free (tmp
, FALSE
);
1649 g_string_free (tmp
, TRUE
);
1650 return g_strdup (str
);
1652 return g_strdup (str
);
1655 /* call with edit = 0 before shutdown to close memory leaks */
1657 edit_replace_cmd (WEdit
* edit
, int again
)
1659 /* 1 = search string, 2 = replace with */
1660 static char *saved1
= NULL
; /* saved default[123] */
1661 static char *saved2
= NULL
;
1662 char *input1
= NULL
; /* user input from the dialog */
1663 char *input2
= NULL
;
1667 long times_replaced
= 0, last_search
;
1668 gboolean once_found
= FALSE
;
1672 g_free (saved1
), saved1
= NULL
;
1673 g_free (saved2
), saved2
= NULL
;
1677 last_search
= edit
->last_byte
;
1679 edit
->force
|= REDRAW_COMPLETELY
;
1681 if (again
&& !saved1
&& !saved2
)
1686 input1
= g_strdup (saved1
? saved1
: "");
1687 input2
= g_strdup (saved2
? saved2
: "");
1691 char *tmp_inp1
, *tmp_inp2
;
1692 disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1693 disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
1695 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1697 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1702 if (input1
== NULL
|| *input1
== '\0')
1704 edit
->force
= REDRAW_COMPLETELY
;
1710 input1
= edit_replace_cmd__conv_to_input (input1
);
1711 input2
= edit_replace_cmd__conv_to_input (input2
);
1715 g_free (saved1
), saved1
= g_strdup (input1
);
1716 g_free (saved2
), saved2
= g_strdup (input2
);
1720 mc_search_free (edit
->search
);
1721 edit
->search
= NULL
;
1727 edit
->search
= mc_search_new (input1
, -1);
1728 if (edit
->search
== NULL
)
1730 edit
->search_start
= edit
->curs1
;
1733 edit
->search
->search_type
= edit_search_options
.type
;
1734 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1735 edit
->search
->is_case_sentitive
= edit_search_options
.case_sens
;
1736 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1737 edit
->search
->search_fn
= edit_search_cmd_callback
;
1740 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1741 && edit_search_options
.backwards
)
1742 edit
->search_start
--;
1744 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1745 && !edit_search_options
.backwards
)
1746 edit
->search_start
++;
1753 if (!editcmd_find (edit
, &len
))
1755 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1756 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
)))
1758 edit_error_dialog (_("Search"), edit
->search
->error_str
);
1763 new_start
= edit
->search
->normal_offset
;
1765 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1766 /*returns negative on not found or error in pattern */
1768 if (edit
->search_start
>= 0)
1772 edit
->found_start
= edit
->search_start
;
1773 i
= edit
->found_len
= len
;
1775 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1776 edit_scroll_screen_over_cursor (edit
);
1780 if (edit
->replace_mode
== 0)
1783 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1785 edit_scroll_downward (edit
, l
);
1787 edit_scroll_upward (edit
, -l
);
1789 edit_scroll_screen_over_cursor (edit
);
1790 edit
->force
|= REDRAW_PAGE
;
1791 edit_render_keypress (edit
);
1793 /*so that undo stops at each query */
1794 edit_push_key_press (edit
);
1795 /* and prompt 2/3 down */
1796 disp1
= edit_replace_cmd__conv_to_display (saved1
);
1797 disp2
= edit_replace_cmd__conv_to_display (saved2
);
1798 switch (editcmd_dialog_replace_prompt_show (edit
, disp1
, disp2
, -1, -1))
1803 case B_SKIP_REPLACE
:
1807 edit
->replace_mode
= 1;
1811 edit
->replace_mode
= -1;
1818 { /* delete then insert new */
1819 GString
*repl_str
, *tmp_str
;
1820 tmp_str
= g_string_new (input2
);
1822 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1823 g_string_free (tmp_str
, TRUE
);
1824 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1826 edit_error_dialog (_("Replace"), edit
->search
->error_str
);
1831 edit_delete (edit
, 1);
1833 while (++i
< repl_str
->len
)
1834 edit_insert (edit
, repl_str
->str
[i
]);
1836 g_string_free (repl_str
, TRUE
);
1837 edit
->found_len
= i
;
1839 /* so that we don't find the same string again */
1840 if (edit_search_options
.backwards
)
1842 last_search
= edit
->search_start
;
1843 edit
->search_start
--;
1847 edit
->search_start
+= i
;
1848 last_search
= edit
->last_byte
;
1850 edit_scroll_screen_over_cursor (edit
);
1854 const char *msg
= _(" Replace ");
1855 /* try and find from right here for next search */
1856 edit
->search_start
= edit
->curs1
;
1857 edit_update_curs_col (edit
);
1859 edit
->force
|= REDRAW_PAGE
;
1860 edit_render_keypress (edit
);
1863 message (D_NORMAL
, msg
, _(" %ld replacements made. "), times_replaced
);
1866 query_dialog (msg
, _(" Search string not found "), D_NORMAL
, 1, _("&OK"));
1867 edit
->replace_mode
= -1;
1870 while (edit
->replace_mode
>= 0);
1872 edit
->force
= REDRAW_COMPLETELY
;
1873 edit_scroll_screen_over_cursor (edit
);
1881 edit_search_cmd (WEdit
* edit
, int again
)
1883 char *search_string
= NULL
, *search_string_dup
= NULL
;
1889 if (edit
->search
!= NULL
)
1891 search_string
= g_strndup (edit
->search
->original
, edit
->search
->original_len
);
1892 search_string_dup
= search_string
;
1897 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1898 if (history
!= NULL
&& history
->data
!= NULL
)
1900 search_string_dup
= search_string
= (char *) g_strdup (history
->data
);
1901 history
= g_list_first (history
);
1902 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1903 g_list_free (history
);
1905 edit
->search_start
= edit
->curs1
;
1913 if (search_string
&& *search_string
)
1915 tmp
= str_convert_to_display (search_string
);
1919 g_string_free (tmp
, TRUE
);
1922 g_free (search_string
);
1923 search_string
= search_string_dup
= g_string_free (tmp
, FALSE
);
1927 #endif /* HAVE_CHARSET */
1928 editcmd_dialog_search_show (edit
, &search_string
);
1929 g_free (search_string_dup
);
1930 search_string_dup
= NULL
;
1932 if (search_string
&& *search_string
)
1934 tmp
= str_convert_to_input (search_string
);
1938 g_string_free (tmp
, TRUE
);
1941 g_free (search_string
);
1942 search_string
= g_string_free (tmp
, FALSE
);
1946 #endif /* HAVE_CHARSET */
1948 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1950 if (search_string
== NULL
)
1952 edit
->force
|= REDRAW_COMPLETELY
;
1953 edit_scroll_screen_over_cursor (edit
);
1959 mc_search_free (edit
->search
);
1960 edit
->search
= NULL
;
1966 edit
->search
= mc_search_new (search_string
, -1);
1967 if (edit
->search
== NULL
)
1969 edit
->search_start
= edit
->curs1
;
1970 g_free (search_string
);
1974 edit
->search
->search_type
= edit_search_options
.type
;
1975 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1976 edit
->search
->is_case_sentitive
= edit_search_options
.case_sens
;
1977 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1978 edit
->search
->search_fn
= edit_search_cmd_callback
;
1981 g_free (search_string
);
1983 if (search_create_bookmark
)
1985 edit_search_cmd_search_create_bookmark (edit
);
1989 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1990 && edit_search_options
.backwards
)
1991 edit
->search_start
--;
1993 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1994 && !edit_search_options
.backwards
)
1995 edit
->search_start
++;
1997 if (editcmd_find (edit
, &len
))
1999 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
2000 edit
->found_len
= len
;
2002 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
2003 edit_scroll_screen_over_cursor (edit
);
2004 if (edit_search_options
.backwards
)
2005 edit
->search_start
--;
2007 edit
->search_start
++;
2011 edit
->search_start
= edit
->curs1
;
2012 if (edit
->search
->error_str
)
2013 edit_error_dialog (_("Search"), edit
->search
->error_str
);
2017 edit
->force
|= REDRAW_COMPLETELY
;
2018 edit_scroll_screen_over_cursor (edit
);
2023 * Check if it's OK to close the editor. If there are unsaved changes,
2024 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
2027 edit_ok_to_exit (WEdit
* edit
)
2029 if (!edit
->modified
)
2032 if (!edit_check_newline (edit
))
2035 switch (edit_query_dialog3
2036 (_("Quit"), _(" File was modified, Save with exit? "),
2037 _("&Cancel quit"), _("&Yes"), _("&No")))
2040 edit_push_markers (edit
);
2041 edit_set_markers (edit
, 0, 0, 0, 0);
2042 if (!edit_save_cmd (edit
))
2055 /* Return a null terminated length of text. Result must be g_free'd */
2056 static unsigned char *
2057 edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
)
2059 unsigned char *s
, *r
;
2060 r
= s
= g_malloc0 (finish
- start
+ 1);
2061 if (column_highlighting
)
2064 /* copy from buffer, excluding chars that are out of the column 'margins' */
2065 while (start
< finish
)
2069 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0, start
);
2070 c
= edit_get_byte (edit
, start
);
2071 if ((x
>= edit
->column1
&& x
< edit
->column2
)
2072 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n')
2082 *l
= finish
- start
;
2083 while (start
< finish
)
2084 *s
++ = edit_get_byte (edit
, start
++);
2090 /* save block, returns 1 on success */
2092 edit_save_block (WEdit
* edit
, const char *filename
, long start
, long finish
)
2097 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
2098 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
2101 if (column_highlighting
)
2104 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof (VERTICAL_MAGIC
));
2107 unsigned char *block
, *p
;
2108 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
2111 r
= mc_write (file
, p
, len
);
2124 len
= finish
- start
;
2125 buf
= g_malloc0 (TEMP_BUF_LEN
);
2126 while (start
!= finish
)
2128 end
= min (finish
, start
+ TEMP_BUF_LEN
);
2129 for (; i
< end
; i
++)
2130 buf
[i
- start
] = edit_get_byte (edit
, i
);
2131 len
-= mc_write (file
, (char *) buf
, end
- start
);
2142 /* copies a block to clipboard file */
2144 edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
2148 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2149 ret
= edit_save_block (edit
, tmp
, start
, finish
);
2156 edit_paste_from_history (WEdit
* edit
)
2159 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
2163 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2165 long start_mark
, end_mark
;
2166 if (eval_marks (edit
, &start_mark
, &end_mark
))
2168 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2170 edit_error_dialog (_(" Copy to clipboard "),
2171 get_sys_error (_(" Unable to save to file. ")));
2174 edit_mark_cmd (edit
, 1);
2179 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2181 long start_mark
, end_mark
;
2182 if (eval_marks (edit
, &start_mark
, &end_mark
))
2184 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2186 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
2189 edit_block_delete_cmd (edit
);
2190 edit_mark_cmd (edit
, 1);
2195 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2198 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2199 edit_insert_file (edit
, tmp
);
2205 * Ask user for the line and go to that line.
2206 * Negative numbers mean line from the end (i.e. -1 is the last line).
2209 edit_goto_cmd (WEdit
* edit
)
2212 static long line
= 0; /* line as typed, saved as default */
2217 g_snprintf (s
, sizeof (s
), "%ld", line
);
2218 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2229 l
= strtol (f
, &error
, 0);
2238 l
= edit
->total_lines
+ l
+ 2;
2239 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2240 edit_move_to_line (edit
, l
- 1);
2241 edit
->force
|= REDRAW_COMPLETELY
;
2246 /* Return 1 on success */
2248 edit_save_block_cmd (WEdit
* edit
)
2250 long start_mark
, end_mark
;
2253 if (eval_marks (edit
, &start_mark
, &end_mark
))
2256 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2258 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2259 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2261 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2271 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2274 edit
->force
|= REDRAW_COMPLETELY
;
2280 edit_error_dialog (_(" Save Block "), get_sys_error (_(" Cannot save file. ")));
2284 edit
->force
|= REDRAW_COMPLETELY
;
2289 /* returns 1 on success */
2291 edit_insert_file_cmd (WEdit
* edit
)
2296 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2297 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2298 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2300 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2310 if (edit_insert_file (edit
, exp
))
2313 edit
->force
|= REDRAW_COMPLETELY
;
2319 edit_error_dialog (_(" Insert File "), get_sys_error (_(" Cannot insert file. ")));
2323 edit
->force
|= REDRAW_COMPLETELY
;
2327 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2329 edit_sort_cmd (WEdit
* edit
)
2331 static char *old
= 0;
2333 long start_mark
, end_mark
;
2336 if (eval_marks (edit
, &start_mark
, &end_mark
))
2338 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2342 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2343 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2346 exp
= input_dialog (_(" Run Sort "),
2347 _(" Enter sort options (see manpage) separated by whitespace: "),
2348 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2354 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2355 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2360 if (e
== -1 || e
== 127)
2362 edit_error_dialog (_(" Sort "), get_sys_error (_(" Cannot execute sort command ")));
2367 sprintf (q
, "%d ", e
);
2368 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2369 edit_error_dialog (_(" Sort "), tmp
);
2375 edit
->force
|= REDRAW_COMPLETELY
;
2377 if (edit_block_delete_cmd (edit
))
2379 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2380 edit_insert_file (edit
, tmp
);
2386 * Ask user for a command, execute it and paste its output back to the
2390 edit_ext_cmd (WEdit
* edit
)
2396 input_dialog (_("Paste output of external command"),
2397 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2402 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2409 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2413 edit
->force
|= REDRAW_COMPLETELY
;
2414 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2415 edit_insert_file (edit
, tmp
);
2420 /* if block is 1, a block must be highlighted and the shell command
2421 processes it. If block is 0 the shell command is a straight system
2422 command, that just produces some output which is to be inserted */
2424 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2426 long start_mark
, end_mark
;
2428 FILE *script_home
= NULL
;
2429 FILE *block_file
= NULL
;
2430 gchar
*o
, *h
, *b
, *tmp
;
2431 char *quoted_name
= NULL
;
2433 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2434 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2435 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2437 script_home
= fopen (h
, "r");
2438 if (script_home
== NULL
)
2440 FILE *script_src
= NULL
;
2442 script_home
= fopen (h
, "w");
2443 if (script_home
== NULL
)
2445 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2446 edit_error_dialog ("", get_sys_error (tmp
));
2448 goto edit_block_process_cmd__EXIT
;
2451 script_src
= fopen (o
, "r");
2452 if (script_src
== NULL
)
2454 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2455 script_src
= fopen (o
, "r");
2456 if (script_src
== NULL
)
2458 fclose (script_home
);
2460 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2461 edit_error_dialog ("", get_sys_error (tmp
));
2463 goto edit_block_process_cmd__EXIT
;
2466 while (fgets (buf
, sizeof (buf
), script_src
))
2467 fputs (buf
, script_home
);
2468 fclose (script_src
);
2470 if (fclose (script_home
))
2472 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2473 edit_error_dialog ("", get_sys_error (tmp
));
2475 goto edit_block_process_cmd__EXIT
;
2478 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2479 edit_error_dialog ("", get_sys_error (tmp
));
2486 { /* for marked block run indent formatter */
2487 if (eval_marks (edit
, &start_mark
, &end_mark
))
2489 edit_error_dialog (_("Process block"),
2490 _(" You must first highlight a block of text. "));
2491 goto edit_block_process_cmd__EXIT
;
2493 edit_save_block (edit
, b
, start_mark
, end_mark
);
2494 quoted_name
= name_quote (edit
->filename
, 0);
2497 * Initial space is to avoid polluting bash history.
2499 * $1 - name of the edited file (to check its extension etc).
2500 * $2 - file containing the current block.
2501 * $3 - file where error messages should be put
2502 * (for compatibility with old scripts).
2504 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2505 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2512 * No block selected, just execute the command for the file.
2514 * $1 - name of the edited file.
2516 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2517 quoted_name
, (char *) NULL
);
2521 g_free (quoted_name
);
2522 close_error_pipe (D_NORMAL
, NULL
);
2524 edit_refresh_cmd (edit
);
2525 edit
->force
|= REDRAW_COMPLETELY
;
2527 /* insert result block */
2528 if (block
&& !edit_block_delete_cmd (edit
))
2530 edit_insert_file (edit
, b
);
2531 block_file
= fopen (b
, "w");
2532 if (block_file
!= NULL
)
2533 fclose (block_file
);
2536 edit_block_process_cmd__EXIT
:
2542 /* prints at the cursor */
2543 /* returns the number of chars printed */
2545 edit_print_string (WEdit
* e
, const char *s
)
2548 while (s
[i
] != '\0')
2549 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2550 e
->force
|= REDRAW_COMPLETELY
;
2551 edit_update_screen (e
);
2557 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
2562 to
= name_quote (to
, 0);
2563 subject
= name_quote (subject
, 0);
2564 cc
= name_quote (cc
, 0);
2565 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
2579 for (i
= 0; i
< edit
->last_byte
; i
++)
2580 fputc (edit_get_byte (edit
, i
), p
);
2585 #define MAIL_DLG_HEIGHT 12
2588 edit_mail_dialog (WEdit
* edit
)
2591 char *tmail_subject
;
2594 static char *mail_cc_last
= 0;
2595 static char *mail_subject_last
= 0;
2596 static char *mail_to_last
= 0;
2598 QuickWidget quick_widgets
[] = {
2599 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2600 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2601 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2602 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2603 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2605 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2606 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2607 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2608 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2612 QuickDialog Quick_input
= {
2613 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2614 "[Input Line Keys]", quick_widgets
, FALSE
2617 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2618 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2619 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2621 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2623 g_free (mail_cc_last
);
2624 g_free (mail_subject_last
);
2625 g_free (mail_to_last
);
2626 mail_cc_last
= tmail_cc
;
2627 mail_subject_last
= tmail_subject
;
2628 mail_to_last
= tmail_to
;
2629 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2634 /*******************/
2635 /* Word Completion */
2636 /*******************/
2639 is_break_char (char c
)
2641 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2644 /* find first character of current word */
2646 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
2651 /* return if at begin of file */
2652 if (edit
->curs1
<= 0)
2655 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2656 /* return if not at end or in word */
2657 if (is_break_char (c
))
2660 /* search start of word to be completed */
2663 /* return if at begin of file */
2664 if ((gsize
) edit
->curs1
< i
)
2668 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2670 if (is_break_char (c
))
2672 /* return if word starts with digit */
2676 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2685 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2687 /* collect the possible completions */
2689 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
2690 char *match_expr
, struct selection
*compl, gsize
* num
)
2701 srch
= mc_search_new (match_expr
, -1);
2705 if (mc_config_get_bool
2706 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
2708 last_byte
= edit
->last_byte
;
2715 srch
->search_type
= MC_SEARCH_T_REGEX
;
2716 srch
->is_case_sentitive
= TRUE
;
2717 srch
->search_fn
= edit_search_cmd_callback
;
2719 /* collect max MAX_WORD_COMPLETIONS completions */
2723 /* get next match */
2724 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
2726 start
= srch
->normal_offset
;
2728 /* add matched completion if not yet added */
2729 temp
= g_string_new ("");
2730 for (i
= 0; i
< len
; i
++)
2732 skip
= edit_get_byte (edit
, start
+ i
);
2735 g_string_append_c (temp
, skip
);
2740 for (i
= 0; i
< (gsize
) * num
; i
++)
2743 ((char *) &compl[i
].text
[word_len
],
2744 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
2746 struct selection
this = compl[i
];
2747 for (++i
; i
< *num
; i
++)
2749 compl[i
- 1] = compl[i
];
2751 compl[*num
- 1] = this;
2753 break; /* skip it, already added */
2758 g_string_free (temp
, TRUE
);
2761 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
2763 g_free (compl[0].text
);
2764 for (i
= 1; i
< *num
; i
++)
2766 compl[i
- 1] = compl[i
];
2773 recoded
= str_convert_to_display (temp
->str
);
2775 if (recoded
&& recoded
->len
)
2777 g_string_free (temp
, TRUE
);
2781 g_string_free (recoded
, TRUE
);
2784 compl[*num
].text
= temp
->str
;
2785 compl[*num
].len
= temp
->len
;
2788 g_string_free (temp
, FALSE
);
2790 /* note the maximal length needed for the completion dialog */
2794 mc_search_free (srch
);
2799 * Complete current word using regular expression search
2800 * backwards beginning at the current cursor position.
2803 edit_complete_word_cmd (WEdit
* edit
)
2805 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2806 long word_start
= 0;
2807 unsigned char *bufpos
;
2809 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2811 /* search start of word to be completed */
2812 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2815 /* prepare match expression */
2816 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2818 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2821 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2822 (int) word_len
, bufpos
);
2824 /* collect the possible completions */
2825 /* start search from begin to end of file */
2827 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2828 (struct selection
*) &compl, &num_compl
);
2832 /* insert completed word if there is only one match */
2835 for (i
= word_len
; i
< compl[0].len
; i
++)
2836 edit_insert (edit
, *(compl[0].text
+ i
));
2838 /* more than one possible completion => ask the user */
2841 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2842 /* !!! pressed again the selection dialog pops up, but that !!! */
2843 /* !!! seems to require a further internal state !!! */
2846 /* let the user select the preferred completion */
2847 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2848 (struct selection
*) &compl, num_compl
);
2852 g_free (match_expr
);
2853 /* release memory before return */
2854 for (i
= 0; i
< num_compl
; i
++)
2855 g_free (compl[i
].text
);
2859 edit_select_codepage_cmd (WEdit
* edit
)
2862 const char *cp_id
= NULL
;
2863 if (do_select_codepage ())
2865 cp_id
= get_codepage_id (source_codepage
>= 0 ? source_codepage
: display_codepage
);
2870 conv
= str_crt_conv_from (cp_id
);
2871 if (conv
!= INVALID_CONV
)
2873 if (edit
->converter
!= str_cnv_from_term
)
2874 str_close_conv (edit
->converter
);
2875 edit
->converter
= conv
;
2880 edit
->utf8
= str_isutf8 (cp_id
);
2883 edit
->force
= REDRAW_COMPLETELY
;
2884 edit_refresh_cmd (edit
);
2891 edit_insert_literal_cmd (WEdit
* edit
)
2893 int char_for_insertion
= editcmd_dialog_raw_key_query (_(" Insert Literal "),
2894 _(" Press any key: "), 0);
2895 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
2899 edit_execute_macro_cmd (WEdit
* edit
)
2902 CK_Macro (editcmd_dialog_raw_key_query (_(" Execute Macro "), _(" Press macro hotkey: "),
2904 if (command
== CK_Macro (0))
2905 command
= CK_Insert_Char
;
2907 edit_execute_key_command (edit
, command
, -1);
2911 edit_begin_end_macro_cmd (WEdit
* edit
)
2913 /* edit is a pointer to the widget */
2916 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2917 edit_execute_key_command (edit
, command
, -1);
2922 edit_load_forward_cmd (WEdit
* edit
)
2926 if (edit_query_dialog2
2928 _(" Current text was modified without a file save. \n"
2929 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2931 edit
->force
|= REDRAW_COMPLETELY
;
2935 if (edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
)
2937 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
2941 edit_stack_iterator
++;
2942 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2944 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2945 edit_history_moveto
[edit_stack_iterator
].line
);
2960 edit_load_back_cmd (WEdit
* edit
)
2964 if (edit_query_dialog2
2966 _(" Current text was modified without a file save. \n"
2967 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2969 edit
->force
|= REDRAW_COMPLETELY
;
2973 if (edit_stack_iterator
> 0)
2975 edit_stack_iterator
--;
2976 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2978 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2979 edit_history_moveto
[edit_stack_iterator
].line
);
2994 edit_get_match_keyword_cmd (WEdit
* edit
)
2996 gsize word_len
= 0, max_len
= 0;
2999 long word_start
= 0;
3000 unsigned char *bufpos
;
3004 char *tagfile
= NULL
;
3006 etags_hash_t def_hash
[MAX_DEFINITIONS
];
3008 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
3010 def_hash
[i
].filename
= NULL
;
3013 /* search start of word to be completed */
3014 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3017 /* prepare match expression */
3018 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3019 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3021 ptr
= g_get_current_dir ();
3022 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3025 /* Recursive search file 'TAGS' in parent dirs */
3028 ptr
= g_path_get_dirname (path
);
3032 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3033 if (exist_file (tagfile
))
3036 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3041 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3046 max_len
= MAX_WIDTH_DEF_DIALOG
;
3050 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3051 (etags_hash_t
*) & def_hash
, num_def
);
3053 g_free (match_expr
);
3057 edit_move_block_to_right (WEdit
* edit
)
3059 long start_mark
, end_mark
;
3060 long cur_bol
, start_bol
;
3062 if (eval_marks (edit
, &start_mark
, &end_mark
))
3065 start_bol
= edit_bol (edit
, start_mark
);
3066 cur_bol
= edit_bol (edit
, end_mark
- 1);
3069 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3070 if (option_fill_tabs_with_spaces
)
3072 if (option_fake_half_tabs
)
3074 insert_spaces_tab (edit
, 1);
3078 insert_spaces_tab (edit
, 0);
3083 edit_insert (edit
, '\t');
3085 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3090 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3092 while (cur_bol
>= start_bol
);
3093 edit
->force
|= REDRAW_PAGE
;
3097 edit_move_block_to_left (WEdit
* edit
)
3099 long start_mark
, end_mark
;
3100 long cur_bol
, start_bol
;
3101 int i
, del_tab_width
;
3104 if (eval_marks (edit
, &start_mark
, &end_mark
))
3107 start_bol
= edit_bol (edit
, start_mark
);
3108 cur_bol
= edit_bol (edit
, end_mark
- 1);
3111 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3112 if (option_fake_half_tabs
)
3114 del_tab_width
= HALF_TAB_SIZE
;
3118 del_tab_width
= option_tab_spacing
;
3120 next_char
= edit_get_byte (edit
, edit
->curs1
);
3121 if (next_char
== '\t')
3123 edit_delete (edit
, 1);
3125 else if (next_char
== ' ')
3127 for (i
= 1; i
<= del_tab_width
; i
++)
3129 if (next_char
== ' ')
3131 edit_delete (edit
, 1);
3133 next_char
= edit_get_byte (edit
, edit
->curs1
);
3140 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3142 while (cur_bol
>= start_bol
);
3143 edit
->force
|= REDRAW_PAGE
;