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 */
55 #include "lib/vfs/mc-vfs/vfs.h"
57 #include "src/history.h"
58 #include "src/widget.h" /* listbox_new() */
59 #include "src/layout.h" /* clr_scr() */
60 #include "src/main.h" /* mc_home, midnight_shutdown */
61 #include "src/setup.h" /* option_tab_spacing */
62 #include "src/help.h" /* interactive_display() */
63 #include "src/wtools.h" /* message() */
64 #include "src/charsets.h"
65 #include "src/selcodepage.h"
66 #include "src/cmddef.h"
67 #include "src/clipboard.h" /* copy_file_to_ext_clip, paste_to_file_from_ext_clip */
69 #include "src/editor/edit-impl.h"
70 #include "src/editor/edit-widget.h"
71 #include "src/editor/editcmd_dialogs.h"
72 #include "src/editor/etags.h"
76 /* search and replace: */
77 int search_create_bookmark
= 0;
78 /* static int search_in_all_charsets = 0; */
80 /* queries on a save */
81 int edit_confirm_save
= 1;
83 static int edit_save_cmd (WEdit
* edit
);
84 static unsigned char *edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
);
87 edit_search_cmd_search_create_bookmark (WEdit
* edit
)
89 int found
= 0, books
= 0;
90 long l
= 0, l_last
= -1;
94 search_create_bookmark
= 0;
95 book_mark_flush (edit
, -1);
99 if (!mc_search_run (edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
102 edit
->search_start
= edit
->search
->normal_offset
;
104 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
107 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
111 q
= edit
->search
->normal_offset
+ 1;
116 edit_error_dialog (_("Search"), _("Search string not found"));
120 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
121 edit_scroll_screen_over_cursor (edit
);
126 edit_search_cmd_callback (const void *user_data
, gsize char_offset
)
128 return edit_get_byte ((WEdit
*) user_data
, (long) char_offset
);
132 edit_help_cmd (WEdit
* edit
)
134 interactive_display (NULL
, "[Internal File Editor]");
135 edit
->force
|= REDRAW_COMPLETELY
;
139 edit_refresh_cmd (WEdit
* edit
)
144 edit_get_syntax_color (edit
, -1, &color
);
152 #endif /* !HAVE_SLANG */
156 /* If 0 (quick save) then a) create/truncate <filename> file,
157 b) save to <filename>;
158 if 1 (safe save) then a) save to <tempnam>,
159 b) rename <tempnam> to <filename>;
160 if 2 (do backups) then a) save to <tempnam>,
161 b) rename <filename> to <filename.backup_ext>,
162 c) rename <tempnam> to <filename>. */
164 /* returns 0 on error, -1 on abort */
166 edit_save_file (WEdit
* edit
, const char *filename
)
172 gchar
*real_filename
;
173 int this_save_mode
, fd
= -1;
180 if (*filename
!= PATH_SEP
&& edit
->dir
)
182 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
186 real_filename
= g_strdup (filename
);
189 this_save_mode
= option_save_mode
;
190 if (this_save_mode
!= EDIT_QUICK_SAVE
)
192 if (!vfs_file_is_local (real_filename
) ||
193 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1)
196 * The file does not exists yet, so no safe save or
197 * backup are necessary.
199 this_save_mode
= EDIT_QUICK_SAVE
;
205 if (this_save_mode
== EDIT_QUICK_SAVE
&& !edit
->skip_detach_prompt
)
210 rv
= mc_stat (real_filename
, &sb
);
211 if (rv
== 0 && sb
.st_nlink
> 1)
213 rv
= edit_query_dialog3 (_("Warning"),
214 _("File has hard-links. Detach before saving?"),
215 _("&Yes"), _("&No"), _("&Cancel"));
219 this_save_mode
= EDIT_SAFE_SAVE
;
222 edit
->skip_detach_prompt
= 1;
225 g_free (real_filename
);
230 /* Prevent overwriting changes from other editor sessions. */
231 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
)
234 /* The default action is "Cancel". */
237 rv
= edit_query_dialog2 (_("Warning"),
238 _("The file has been modified in the meantime. Save anyway?"),
239 _("&Yes"), _("&Cancel"));
242 g_free (real_filename
);
248 if (this_save_mode
!= EDIT_QUICK_SAVE
)
250 char *savedir
, *saveprefix
;
251 const char *slashpos
;
252 slashpos
= strrchr (real_filename
, PATH_SEP
);
255 savedir
= g_strdup (real_filename
);
256 savedir
[slashpos
- real_filename
+ 1] = '\0';
259 savedir
= g_strdup (".");
260 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
262 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
266 g_free (real_filename
);
270 * Close for now because mc_mkstemps use pure open system call
271 * to create temporary file and it needs to be reopened by
272 * VFS-aware mc_open().
277 savename
= g_strdup (real_filename
);
280 ret
= mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
281 ret
= mc_chmod (savename
, edit
->stat1
.st_mode
);
284 fd
= mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
, edit
->stat1
.st_mode
);
289 p
= edit_get_write_filter (savename
, real_filename
);
295 file
= (FILE *) popen (p
, "w");
299 filelen
= edit_write_stream (edit
, file
);
303 if (pclose (file
) != 0)
305 tmp
= g_strdup_printf (_("Error writing to pipe: %s"), p
);
306 edit_error_dialog (_("Error"), tmp
);
315 tmp
= g_strdup_printf (_("Cannot open pipe for writing: %s"), p
);
316 edit_error_dialog (_("Error"), get_sys_error (tmp
));
323 else if (edit
->lb
== LB_ASIS
)
324 { /* do not change line breaks */
327 filelen
= edit
->last_byte
;
328 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1)
330 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
338 (fd
, (char *) edit
->buffers1
[buf
],
339 edit
->curs1
& M_EDIT_BUF_SIZE
) != (edit
->curs1
& M_EDIT_BUF_SIZE
))
343 else if (edit
->curs2
)
346 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
349 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
350 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
351 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) != 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
))
359 if (mc_write (fd
, (char *) edit
->buffers2
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
371 /* Update the file information, especially the mtime. */
372 if (mc_stat (savename
, &edit
->stat1
) == -1)
376 { /* change line breaks */
381 file
= (FILE *) fopen (savename
, "w");
385 filelen
= edit_write_stream (edit
, file
);
392 msg
= g_strdup_printf (_("Cannot open file for writing: %s"), savename
);
393 edit_error_dialog (_("Error"), msg
);
399 if (filelen
!= edit
->last_byte
)
402 if (this_save_mode
== EDIT_DO_BACKUP
)
404 assert (option_backup_ext
!= NULL
);
405 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
406 if (mc_rename (real_filename
, tmp
) == -1)
413 if (this_save_mode
!= EDIT_QUICK_SAVE
)
414 if (mc_rename (savename
, real_filename
) == -1)
417 g_free (real_filename
);
420 /* FIXME: Is this safe ?
421 * if (this_save_mode != EDIT_QUICK_SAVE)
422 * mc_unlink (savename);
424 g_free (real_filename
);
430 menu_save_mode_cmd (void)
433 const int DLG_X
= 38;
434 const int DLG_Y
= 13;
438 const char *str
[] = {
441 N_("&Do backups with following extension:")
444 QuickWidget widgets
[] = {
446 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
448 QUICK_BUTTON (6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
450 QUICK_CHECKBOX (4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
452 QUICK_INPUT (8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
454 QUICK_RADIO (4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
458 QuickDialog dialog
= {
459 DLG_X
, DLG_Y
, -1, -1, N_("Edit Save Mode"),
460 "[Edit Save Mode]", widgets
, NULL
, FALSE
465 size_t w0
, w1
, b_len
, w3
;
467 assert (option_backup_ext
!= NULL
);
469 /* OK/Cancel buttons */
470 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
471 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
474 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
477 for (i
= 0; i
< 3; i
++)
482 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
485 maxlen
= max (maxlen
, w3
+ 4);
487 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
489 widgets
[3].u
.input
.len
= w3
;
490 widgets
[1].relative_x
= (dialog
.xlen
- b_len
) / 2;
491 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
493 for (i
= 0; i
< sizeof (widgets
) / sizeof (widgets
[0]); i
++)
494 widgets
[i
].x_divisions
= dialog
.xlen
;
496 if (quick_dialog (&dialog
) != B_CANCEL
)
498 g_free (option_backup_ext
);
499 option_backup_ext
= str_result
;
504 edit_set_filename (WEdit
* edit
, const char *f
)
506 g_free (edit
->filename
);
509 edit
->filename
= g_strdup (f
);
510 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
512 edit
->dir
= g_strdup (vfs_get_current_dir ());
513 #else /* ENABLE_VFS */
514 edit
->dir
= g_get_current_dir ();
515 #endif /* ENABLE_VFS */
519 edit_check_newline (WEdit
* edit
)
521 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
522 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
523 && edit_query_dialog2 (_("Warning"),
524 _("The file you are saving is not finished with a newline"),
525 _("C&ontinue"), _("&Cancel")));
529 edit_get_save_file_as (WEdit
* edit
)
532 #define DLG_HEIGHT 14
534 static LineBreaks cur_lb
= LB_ASIS
;
536 char *filename
= edit
->filename
;
538 const char *lb_names
[LB_NAMES
] = {
539 N_("&Do not change"),
540 N_("&Unix format (LF)"),
541 N_("&Windows/DOS format (CR LF)"),
542 N_("&Macintosh format (CR)")
545 QuickWidget quick_widgets
[] = {
546 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
547 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
548 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
549 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
550 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0,
551 "save-as", &filename
),
552 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_("Enter file name:")),
556 QuickDialog Quick_options
= {
557 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
558 N_("Save As"), "[Save File As]",
559 quick_widgets
, NULL
, FALSE
562 if (quick_dialog (&Quick_options
) != B_CANCEL
)
574 /* Here we want to warn the users of overwriting an existing file,
575 but only if they have made a change to the filename */
576 /* returns 1 on success */
578 edit_save_as_cmd (WEdit
* edit
)
580 /* This heads the 'Save As' dialog box */
583 int different_filename
= 0;
585 if (!edit_check_newline (edit
))
588 exp
= edit_get_save_file_as (edit
);
589 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
596 edit
->force
|= REDRAW_COMPLETELY
;
602 if (strcmp (edit
->filename
, exp
))
605 different_filename
= 1;
606 file
= mc_open (exp
, O_RDONLY
| O_BINARY
);
609 /* the file exists */
611 /* Overwrite the current file or cancel the operation */
612 if (edit_query_dialog2
614 _("A file already exists with this name"),
615 _("&Overwrite"), _("&Cancel")))
617 edit
->force
|= REDRAW_COMPLETELY
;
624 edit
->stat1
.st_mode
|= S_IWUSR
;
626 save_lock
= lock_file (exp
);
630 /* filenames equal, check if already locked */
631 if (!edit
->locked
&& !edit
->delete_file
)
632 save_lock
= lock_file (exp
);
635 if (different_filename
)
638 * Allow user to write into saved (under another name) file
639 * even if original file had r/o user permissions.
641 edit
->stat1
.st_mode
|= S_IWRITE
;
644 rv
= edit_save_file (edit
, exp
);
648 /* Succesful, so unlock both files */
649 if (different_filename
)
654 edit
->locked
= edit_unlock_file (edit
);
658 if (edit
->locked
|| save_lock
)
659 edit
->locked
= edit_unlock_file (edit
);
662 edit_set_filename (edit
, exp
);
663 if (edit
->lb
!= LB_ASIS
)
664 edit_reload (edit
, exp
);
667 edit
->delete_file
= 0;
668 if (different_filename
)
669 edit_load_syntax (edit
, NULL
, edit
->syntax_type
);
670 edit
->force
|= REDRAW_COMPLETELY
;
673 edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
676 /* Failed, so maintain modify (not save) lock */
680 edit
->force
|= REDRAW_COMPLETELY
;
685 edit
->force
|= REDRAW_COMPLETELY
;
689 /* {{{ Macro stuff starts here */
691 /* creates a macro file if it doesn't exist */
693 edit_open_macro_file (const char *r
)
698 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
699 file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
706 fd
= fopen (filename
, r
);
711 #define MAX_MACROS 1024
712 static int saved_macro
[MAX_MACROS
+ 1];
713 static int saved_macros_loaded
= 0;
716 This is just to stop the macro file be loaded over and over for keys
717 that aren't defined to anything. On slow systems this could be annoying.
723 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
724 if (saved_macro
[i
] == k
)
729 /* returns 1 on error */
731 edit_delete_macro (WEdit
* edit
, int k
)
734 struct macro macro
[MAX_MACRO_LENGTH
];
740 if (saved_macros_loaded
)
742 j
= macro_exists (k
);
746 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
747 g
= fopen (tmp
, "w");
751 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open temp file")));
754 f
= edit_open_macro_file ("r");
757 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open macro file")));
763 n
= fscanf (f
, ("key '%d 0': "), &s
);
767 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
771 ret
= fscanf (f
, ";\n");
775 fprintf (g
, ("key '%d 0': "), s
);
776 for (i
= 0; i
< n
; i
++)
777 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
783 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
784 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
785 if (rename (tmp
, tmp2
) == -1)
787 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot overwrite macro file")));
795 if (saved_macros_loaded
)
796 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
800 /* returns 0 on error */
802 edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
807 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
808 s
= editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1);
809 edit
->force
|= REDRAW_COMPLETELY
;
812 if (edit_delete_macro (edit
, s
))
814 f
= edit_open_macro_file ("a+");
817 fprintf (f
, ("key '%d 0': "), s
);
818 for (i
= 0; i
< n
; i
++)
819 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
822 if (saved_macros_loaded
)
824 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
830 edit_error_dialog (_("Save macro"), get_sys_error (_("Cannot open macro file")));
836 edit_delete_macro_cmd (WEdit
* edit
)
840 command
= editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), 1);
843 edit_delete_macro (edit
, command
);
846 /* return 0 on error */
848 edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
851 int s
, i
= 0, found
= 0;
855 if (saved_macros_loaded
)
856 if (macro_exists (k
) < 0)
859 f
= edit_open_macro_file ("r");
866 u
= fscanf (f
, ("key '%d 0': "), &s
);
869 if (!saved_macros_loaded
)
870 saved_macro
[i
++] = s
;
874 while (*n
< MAX_MACRO_LENGTH
875 && 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
880 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
884 ret
= fscanf (f
, ";\n");
889 while (!found
|| !saved_macros_loaded
);
890 if (!saved_macros_loaded
)
893 saved_macros_loaded
= 1;
899 edit_error_dialog (_("Load macro"), get_sys_error (_("Cannot open macro file")));
903 /* }}} Macro stuff starts here */
905 /* returns 1 on success */
907 edit_save_confirm_cmd (WEdit
* edit
)
911 if (!edit_check_newline (edit
))
914 if (edit_confirm_save
)
916 f
= g_strdup_printf (_("Confirm save file: \"%s\""), edit
->filename
);
917 if (edit_query_dialog2 (_("Save file"), f
, _("&Save"), _("&Cancel")))
924 return edit_save_cmd (edit
);
928 /* returns 1 on success */
930 edit_save_cmd (WEdit
* edit
)
932 int res
, save_lock
= 0;
934 if (!edit
->locked
&& !edit
->delete_file
)
935 save_lock
= edit_lock_file (edit
);
936 res
= edit_save_file (edit
, edit
->filename
);
938 /* Maintain modify (not save) lock on failure */
939 if ((res
> 0 && edit
->locked
) || save_lock
)
940 edit
->locked
= edit_unlock_file (edit
);
942 /* On failure try 'save as', it does locking on its own */
944 return edit_save_as_cmd (edit
);
945 edit
->force
|= REDRAW_COMPLETELY
;
948 edit
->delete_file
= 0;
956 /* returns 1 on success */
958 edit_new_cmd (WEdit
* edit
)
962 if (edit_query_dialog2
965 ("Current text was modified without a file save.\nContinue discards these changes"),
966 _("C&ontinue"), _("&Cancel")))
968 edit
->force
|= REDRAW_COMPLETELY
;
972 edit
->force
|= REDRAW_COMPLETELY
;
974 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
977 /* returns 1 on error */
979 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
981 int prev_locked
= edit
->locked
;
982 char *prev_filename
= g_strdup (edit
->filename
);
984 if (!edit_reload (edit
, exp
))
986 g_free (prev_filename
);
994 fullpath
= g_build_filename (edit
->dir
, prev_filename
, (char *) NULL
);
995 unlock_file (fullpath
);
998 g_free (prev_filename
);
1003 edit_load_syntax_file (WEdit
* edit
)
1008 if (geteuid () == 0)
1010 dir
= query_dialog (_("Syntax file edit"),
1011 _("Which syntax file you want to edit?"), D_NORMAL
, 2,
1012 _("&User"), _("&System Wide"));
1015 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
1016 if (!exist_file (extdir
))
1019 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
1026 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
1027 check_for_default (extdir
, buffer
);
1028 edit_load_file_from_filename (edit
, buffer
);
1032 edit_load_file_from_filename (edit
, extdir
);
1038 edit_load_menu_file (WEdit
* edit
)
1044 dir
= query_dialog (_("Menu edit"),
1045 _("Which menu file do you want to edit?"), D_NORMAL
,
1046 geteuid () != 0 ? 2 : 3, _("&Local"), _("&User"), _("&System Wide"));
1048 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1050 if (!exist_file (menufile
))
1053 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1059 buffer
= g_strdup (EDIT_LOCAL_MENU
);
1060 check_for_default (menufile
, buffer
);
1061 chmod (buffer
, 0600);
1065 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
1066 check_for_default (menufile
, buffer
);
1070 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1071 if (!exist_file (buffer
))
1074 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1083 edit_load_file_from_filename (edit
, buffer
);
1090 edit_load_cmd (WEdit
* edit
, edit_current_file_t what
)
1095 && (edit_query_dialog2
1097 _("Current text was modified without a file save.\n"
1098 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")) == 1))
1100 edit
->force
|= REDRAW_COMPLETELY
;
1106 case EDIT_FILE_COMMON
:
1107 exp
= input_expand_dialog (_("Load"), _("Enter file name:"),
1108 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1113 edit_load_file_from_filename (edit
, exp
);
1118 case EDIT_FILE_SYNTAX
:
1119 edit_load_syntax_file (edit
);
1122 case EDIT_FILE_MENU
:
1123 edit_load_menu_file (edit
);
1130 edit
->force
|= REDRAW_COMPLETELY
;
1135 if mark2 is -1 then marking is from mark1 to the cursor.
1136 Otherwise its between the markers. This handles this.
1137 Returns 1 if no text is marked.
1140 eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1142 if (edit
->mark1
!= edit
->mark2
)
1144 long start_bol
, start_eol
;
1145 long end_bol
, end_eol
;
1148 if (edit
->mark2
>= 0)
1150 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1151 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1155 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1156 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1157 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1159 if (edit
->column_highlight
1160 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1161 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
))))
1164 start_bol
= edit_bol (edit
, *start_mark
);
1165 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1166 end_bol
= edit_bol (edit
, *end_mark
);
1167 end_eol
= edit_eol (edit
, *end_mark
);
1168 col1
= min (edit
->column1
, edit
->column2
);
1169 col2
= max (edit
->column1
, edit
->column2
);
1172 edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
,
1175 edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
,
1178 *start_mark
-= diff1
;
1180 *start_mark
= max (*start_mark
, start_eol
);
1181 *end_mark
= min (*end_mark
, end_eol
);
1187 *start_mark
= *end_mark
= 0;
1188 edit
->column2
= edit
->column1
= 0;
1193 #define space_width 1
1196 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1200 cursor
= edit
->curs1
;
1201 col
= edit_get_col (edit
);
1202 for (i
= 0; i
< size
; i
++)
1204 if (data
[i
] == '\n')
1205 { /* fill in and move to next line */
1208 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1210 l
= width
- (edit_get_col (edit
) - col
);
1213 edit_insert (edit
, ' ');
1217 for (p
= edit
->curs1
;; p
++)
1219 if (p
== edit
->last_byte
)
1221 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1222 edit_insert_ahead (edit
, '\n');
1226 if (edit_get_byte (edit
, p
) == '\n')
1232 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1233 l
= col
- edit_get_col (edit
);
1234 while (l
>= space_width
)
1236 edit_insert (edit
, ' ');
1241 edit_insert (edit
, data
[i
]);
1243 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1246 #define TEMP_BUF_LEN 1024
1249 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1253 int blocklen
= -1, width
;
1254 unsigned char *data
;
1255 cursor
= edit
->curs1
;
1256 col
= edit_get_col (edit
);
1257 data
= g_malloc0 (TEMP_BUF_LEN
);
1258 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0)
1260 for (width
= 0; width
< blocklen
; width
++)
1262 if (data
[width
] == '\n')
1265 for (i
= 0; i
< blocklen
; i
++)
1267 if (data
[i
] == '\n')
1268 { /* fill in and move to next line */
1271 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1273 l
= width
- (edit_get_col (edit
) - col
);
1276 edit_insert (edit
, ' ');
1280 for (p
= edit
->curs1
;; p
++)
1282 if (p
== edit
->last_byte
)
1284 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1285 edit_insert_ahead (edit
, '\n');
1289 if (edit_get_byte (edit
, p
) == '\n')
1295 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1296 l
= col
- edit_get_col (edit
);
1297 while (l
>= space_width
)
1299 edit_insert (edit
, ' ');
1304 edit_insert (edit
, data
[i
]);
1307 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1309 edit
->force
|= REDRAW_PAGE
;
1314 edit_block_copy_cmd (WEdit
* edit
)
1316 long start_mark
, end_mark
, current
= edit
->curs1
;
1318 unsigned char *copy_buf
;
1320 edit_update_curs_col (edit
);
1321 if (eval_marks (edit
, &start_mark
, &end_mark
))
1324 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1326 /* all that gets pushed are deletes hence little space is used on the stack */
1328 edit_push_markers (edit
);
1330 if (edit
->column_highlight
)
1332 edit_insert_column_of_text (edit
, copy_buf
, size
, abs (edit
->column2
- edit
->column1
));
1337 edit_insert_ahead (edit
, copy_buf
[size
]);
1341 edit_scroll_screen_over_cursor (edit
);
1343 if (edit
->column_highlight
)
1345 edit_set_markers (edit
, 0, 0, 0, 0);
1346 edit_push_action (edit
, COLUMN_ON
);
1347 edit
->column_highlight
= 0;
1349 else if (start_mark
< current
&& end_mark
> current
)
1350 edit_set_markers (edit
, start_mark
, end_mark
+ end_mark
- start_mark
, 0, 0);
1352 edit
->force
|= REDRAW_PAGE
;
1357 edit_block_move_cmd (WEdit
* edit
)
1361 unsigned char *copy_buf
;
1362 long start_mark
, end_mark
;
1366 if (eval_marks (edit
, &start_mark
, &end_mark
))
1368 if (edit
->column_highlight
)
1370 edit_update_curs_col (edit
);
1372 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1373 if ((x
> edit
->column1
&& x
< edit
->column2
)
1374 || (x
> edit
->column2
&& x
< edit
->column1
))
1377 else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1380 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1381 if (edit_query_dialog2
1384 ("Block is large, you may not be able to undo this action"),
1385 _("C&ontinue"), _("&Cancel")))
1388 edit_push_markers (edit
);
1389 current
= edit
->curs1
;
1390 if (edit
->column_highlight
)
1394 line
= edit
->curs_line
;
1395 if (edit
->mark2
< 0)
1396 edit_mark_cmd (edit
, 0);
1397 c1
= min (edit
->column1
, edit
->column2
);
1398 c2
= max (edit
->column1
, edit
->column2
);
1399 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1402 edit_block_delete_cmd (edit
);
1405 edit_move_to_line (edit
, line
);
1406 edit_cursor_move (edit
,
1407 edit_move_forward3 (edit
,
1408 edit_bol (edit
, edit
->curs1
), x
, 0) - edit
->curs1
);
1409 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1412 line
= edit
->curs_line
;
1413 edit_update_curs_col (edit
);
1415 edit_block_delete_cmd (edit
);
1416 edit_move_to_line (edit
, line
);
1417 edit_cursor_move (edit
,
1418 edit_move_forward3 (edit
,
1420 edit
->curs1
), x
, 0) - edit
->curs1
);
1422 edit_set_markers (edit
, 0, 0, 0, 0);
1423 edit_push_action (edit
, COLUMN_ON
);
1424 edit
->column_highlight
= 0;
1428 copy_buf
= g_malloc0 (end_mark
- start_mark
);
1429 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1430 edit_scroll_screen_over_cursor (edit
);
1432 while (count
< end_mark
)
1434 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1437 edit_scroll_screen_over_cursor (edit
);
1438 edit_cursor_move (edit
,
1439 current
- edit
->curs1
-
1440 (((current
- edit
->curs1
) > 0) ? end_mark
- start_mark
: 0));
1441 edit_scroll_screen_over_cursor (edit
);
1442 while (count
-- > start_mark
)
1443 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1444 edit_set_markers (edit
, edit
->curs1
, edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1446 edit_scroll_screen_over_cursor (edit
);
1448 edit
->force
|= REDRAW_PAGE
;
1452 edit_delete_column_of_text (WEdit
* edit
)
1454 long p
, q
, r
, m1
, m2
;
1457 eval_marks (edit
, &m1
, &m2
);
1458 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1459 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1460 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1461 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
1462 c
= max (c
, max (edit
->column1
, edit
->column2
));
1466 r
= edit_bol (edit
, edit
->curs1
);
1467 p
= edit_move_forward3 (edit
, r
, b
, 0);
1468 q
= edit_move_forward3 (edit
, r
, c
, 0);
1473 edit_cursor_move (edit
, p
- edit
->curs1
);
1476 /* delete line between margins */
1477 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1478 edit_delete (edit
, 1);
1482 /* move to next line except on the last delete */
1483 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1487 /* if success return 0 */
1489 edit_block_delete (WEdit
* edit
)
1492 long start_mark
, end_mark
;
1493 int curs_pos
, line_width
;
1494 long curs_line
, c1
, c2
;
1496 if (eval_marks (edit
, &start_mark
, &end_mark
))
1498 if (edit
->column_highlight
&& edit
->mark2
< 0)
1499 edit_mark_cmd (edit
, 0);
1500 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1502 /* Warning message with a query to continue or cancel the operation */
1503 if (edit_query_dialog2
1506 ("Block is large, you may not be able to undo this action"),
1507 _("C&ontinue"), _("&Cancel")))
1512 c1
= min (edit
->column1
, edit
->column2
);
1513 c2
= max (edit
->column1
, edit
->column2
);
1517 edit_push_markers (edit
);
1519 curs_line
= edit
->curs_line
;
1521 /* calculate line width and cursor position before cut */
1522 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1523 edit_eol (edit
, edit
->curs1
));
1524 curs_pos
= edit
->curs_col
+ edit
->over_col
;
1526 /* move cursor to start of selection */
1527 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1528 edit_scroll_screen_over_cursor (edit
);
1530 if (start_mark
< end_mark
)
1532 if (edit
->column_highlight
)
1534 if (edit
->mark2
< 0)
1535 edit_mark_cmd (edit
, 0);
1536 edit_delete_column_of_text (edit
);
1537 /* move cursor to the saved position */
1538 edit_move_to_line (edit
, curs_line
);
1539 /* calculate line width after cut */
1540 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1541 edit_eol (edit
, edit
->curs1
));
1542 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
1543 edit
->over_col
= curs_pos
- line_width
;
1547 while (count
< end_mark
)
1549 edit_delete (edit
, 1);
1554 edit_set_markers (edit
, 0, 0, 0, 0);
1555 edit
->force
|= REDRAW_PAGE
;
1559 /* returns 1 if canceelled by user */
1561 edit_block_delete_cmd (WEdit
* edit
)
1563 long start_mark
, end_mark
;
1564 if (eval_marks (edit
, &start_mark
, &end_mark
))
1566 edit_delete_line (edit
);
1569 return edit_block_delete (edit
);
1572 #define INPUT_INDEX 9
1575 editcmd_find (WEdit
* edit
, gsize
* len
)
1577 off_t search_start
= edit
->search_start
;
1579 long start_mark
= 0;
1580 long end_mark
= edit
->last_byte
;
1583 if (edit_search_options
.only_in_selection
)
1585 mark_res
= eval_marks (edit
, &start_mark
, &end_mark
);
1588 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1589 edit
->search
->error_str
= g_strdup (_("Search string not found"));
1592 if (edit_search_options
.backwards
)
1594 if (search_start
> end_mark
|| search_start
<= start_mark
)
1596 search_start
= end_mark
;
1601 if (search_start
< start_mark
|| search_start
>= end_mark
)
1603 search_start
= start_mark
;
1609 if (edit_search_options
.backwards
)
1610 end_mark
= max (1, edit
->curs1
) - 1;
1612 if (edit_search_options
.backwards
)
1614 search_end
= end_mark
;
1615 while ((int) search_start
>= start_mark
)
1617 if (search_end
> (off_t
) (search_start
+ edit
->search
->original_len
) &&
1618 mc_search_is_fixed_search_str (edit
->search
))
1620 search_end
= search_start
+ edit
->search
->original_len
;
1622 if (mc_search_run (edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1623 && edit
->search
->normal_offset
== search_start
)
1629 edit
->search
->error_str
= g_strdup (_("Search string not found"));
1633 return mc_search_run (edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1639 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1640 (and the above) routines to work properly - paul */
1642 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1645 edit_replace_cmd__conv_to_display (char *str
)
1649 tmp
= str_convert_to_display (str
);
1651 if (tmp
&& tmp
->len
)
1653 return g_string_free (tmp
, FALSE
);
1655 g_string_free (tmp
, TRUE
);
1657 return g_strdup (str
);
1661 edit_replace_cmd__conv_to_input (char *str
)
1665 tmp
= str_convert_to_input (str
);
1667 if (tmp
&& tmp
->len
)
1669 return g_string_free (tmp
, FALSE
);
1671 g_string_free (tmp
, TRUE
);
1672 return g_strdup (str
);
1674 return g_strdup (str
);
1677 /* call with edit = 0 before shutdown to close memory leaks */
1679 edit_replace_cmd (WEdit
* edit
, int again
)
1681 /* 1 = search string, 2 = replace with */
1682 static char *saved1
= NULL
; /* saved default[123] */
1683 static char *saved2
= NULL
;
1684 char *input1
= NULL
; /* user input from the dialog */
1685 char *input2
= NULL
;
1688 long times_replaced
= 0;
1689 gboolean once_found
= FALSE
;
1690 GString
*repl_str
= NULL
, *tmp_str
= NULL
;
1694 g_free (saved1
), saved1
= NULL
;
1695 g_free (saved2
), saved2
= NULL
;
1699 edit
->force
|= REDRAW_COMPLETELY
;
1701 if (again
&& !saved1
&& !saved2
)
1706 input1
= g_strdup (saved1
? saved1
: "");
1707 input2
= g_strdup (saved2
? saved2
: "");
1711 char *tmp_inp1
, *tmp_inp2
;
1712 disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1713 disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
1715 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1717 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1722 if (input1
== NULL
|| *input1
== '\0')
1724 edit
->force
= REDRAW_COMPLETELY
;
1730 input1
= edit_replace_cmd__conv_to_input (input1
);
1731 input2
= edit_replace_cmd__conv_to_input (input2
);
1735 g_free (saved1
), saved1
= g_strdup (input1
);
1736 g_free (saved2
), saved2
= g_strdup (input2
);
1740 mc_search_free (edit
->search
);
1741 edit
->search
= NULL
;
1747 edit
->search
= mc_search_new (input1
, -1);
1748 if (edit
->search
== NULL
)
1750 edit
->search_start
= edit
->curs1
;
1753 edit
->search
->search_type
= edit_search_options
.type
;
1754 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1755 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
1756 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1757 edit
->search
->search_fn
= edit_search_cmd_callback
;
1760 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1761 && edit_search_options
.backwards
)
1762 edit
->search_start
--;
1764 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1765 && !edit_search_options
.backwards
)
1766 edit
->search_start
++;
1772 if (!editcmd_find (edit
, &len
))
1774 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1775 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
)))
1777 edit_error_dialog (_("Search"), edit
->search
->error_str
);
1783 edit
->search_start
= edit
->search
->normal_offset
;
1784 /*returns negative on not found or error in pattern */
1786 if ((edit
->search_start
>= 0) && (edit
->search_start
< edit
->last_byte
))
1790 edit
->found_start
= edit
->search_start
;
1791 i
= edit
->found_len
= len
;
1793 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1794 edit_scroll_screen_over_cursor (edit
);
1796 if (edit
->replace_mode
== 0)
1801 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1803 edit_scroll_downward (edit
, l
);
1805 edit_scroll_upward (edit
, -l
);
1807 edit_scroll_screen_over_cursor (edit
);
1808 edit
->force
|= REDRAW_PAGE
;
1809 edit_render_keypress (edit
);
1811 /*so that undo stops at each query */
1812 edit_push_key_press (edit
);
1813 /* and prompt 2/3 down */
1814 disp1
= edit_replace_cmd__conv_to_display (saved1
);
1815 disp2
= edit_replace_cmd__conv_to_display (saved2
);
1816 prompt
= editcmd_dialog_replace_prompt_show (edit
, disp1
, disp2
, -1, -1);
1820 if (prompt
== B_REPLACE_ALL
)
1821 edit
->replace_mode
= 1;
1822 else if (prompt
== B_SKIP_REPLACE
)
1824 if (edit_search_options
.backwards
)
1825 edit
->search_start
--;
1827 edit
->search_start
++;
1828 continue; /* loop */
1830 else if (prompt
== B_CANCEL
)
1832 edit
->replace_mode
= -1;
1837 /* don't process string each time */
1838 if (tmp_str
== NULL
)
1840 tmp_str
= g_string_new (input2
);
1841 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1843 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1845 edit_error_dialog (_("Replace"), edit
->search
->error_str
);
1850 /* delete then insert new */
1851 for (i
= 0; i
< len
; i
++)
1852 edit_delete (edit
, 1);
1854 for (i
= 0; i
< repl_str
->len
; i
++)
1855 edit_insert (edit
, repl_str
->str
[i
]);
1857 edit
->found_len
= repl_str
->len
;
1860 /* so that we don't find the same string again */
1861 if (edit_search_options
.backwards
)
1862 edit
->search_start
--;
1865 edit
->search_start
+= repl_str
->len
;
1867 if (edit
->search_start
>= edit
->last_byte
)
1871 edit_scroll_screen_over_cursor (edit
);
1875 /* try and find from right here for next search */
1876 edit
->search_start
= edit
->curs1
;
1877 edit_update_curs_col (edit
);
1879 edit
->force
|= REDRAW_PAGE
;
1880 edit_render_keypress (edit
);
1882 if (times_replaced
== 0)
1883 query_dialog (_("Replace"), _("Search string not found"), D_NORMAL
, 1, _("&OK"));
1887 while (edit
->replace_mode
>= 0);
1889 if (tmp_str
!= NULL
)
1890 g_string_free (tmp_str
, TRUE
);
1891 if (repl_str
!= NULL
)
1892 g_string_free (repl_str
, TRUE
);
1894 edit_scroll_screen_over_cursor (edit
);
1895 edit
->force
|= REDRAW_COMPLETELY
;
1896 edit_render_keypress (edit
);
1898 if ((edit
->replace_mode
== 1) && (times_replaced
!= 0))
1899 message (D_NORMAL
, _("Replace"), _("%ld replacements made"), times_replaced
);
1908 edit_search_cmd (WEdit
* edit
, int again
)
1910 char *search_string
= NULL
, *search_string_dup
= NULL
;
1916 if (edit
->search
!= NULL
)
1918 search_string
= g_strndup (edit
->search
->original
, edit
->search
->original_len
);
1919 search_string_dup
= search_string
;
1924 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1925 if (history
!= NULL
&& history
->data
!= NULL
)
1927 search_string_dup
= search_string
= (char *) g_strdup (history
->data
);
1928 history
= g_list_first (history
);
1929 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1930 g_list_free (history
);
1932 edit
->search_start
= edit
->curs1
;
1940 if (search_string
&& *search_string
)
1942 tmp
= str_convert_to_display (search_string
);
1946 g_string_free (tmp
, TRUE
);
1949 g_free (search_string
);
1950 search_string
= search_string_dup
= g_string_free (tmp
, FALSE
);
1954 #endif /* HAVE_CHARSET */
1955 editcmd_dialog_search_show (edit
, &search_string
);
1956 g_free (search_string_dup
);
1957 search_string_dup
= NULL
;
1959 if (search_string
&& *search_string
)
1961 tmp
= str_convert_to_input (search_string
);
1965 g_string_free (tmp
, TRUE
);
1968 g_free (search_string
);
1969 search_string
= g_string_free (tmp
, FALSE
);
1973 #endif /* HAVE_CHARSET */
1975 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1977 if (search_string
== NULL
)
1979 edit
->force
|= REDRAW_COMPLETELY
;
1980 edit_scroll_screen_over_cursor (edit
);
1986 mc_search_free (edit
->search
);
1987 edit
->search
= NULL
;
1993 edit
->search
= mc_search_new (search_string
, -1);
1994 if (edit
->search
== NULL
)
1996 edit
->search_start
= edit
->curs1
;
1997 g_free (search_string
);
2001 edit
->search
->search_type
= edit_search_options
.type
;
2002 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
2003 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
2004 edit
->search
->whole_words
= edit_search_options
.whole_words
;
2005 edit
->search
->search_fn
= edit_search_cmd_callback
;
2008 g_free (search_string
);
2010 if (search_create_bookmark
)
2012 edit_search_cmd_search_create_bookmark (edit
);
2016 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
2017 && edit_search_options
.backwards
)
2018 edit
->search_start
--;
2020 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
2021 && !edit_search_options
.backwards
)
2022 edit
->search_start
++;
2024 if (editcmd_find (edit
, &len
))
2026 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
2027 edit
->found_len
= len
;
2029 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
2030 edit_scroll_screen_over_cursor (edit
);
2031 if (edit_search_options
.backwards
)
2032 edit
->search_start
--;
2034 edit
->search_start
++;
2038 edit
->search_start
= edit
->curs1
;
2039 if (edit
->search
->error_str
)
2040 edit_error_dialog (_("Search"), edit
->search
->error_str
);
2044 edit
->force
|= REDRAW_COMPLETELY
;
2045 edit_scroll_screen_over_cursor (edit
);
2050 * Check if it's OK to close the editor. If there are unsaved changes,
2051 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
2054 edit_ok_to_exit (WEdit
* edit
)
2058 if (!edit
->modified
)
2061 if (!midnight_shutdown
)
2063 if (!edit_check_newline (edit
))
2067 act
= edit_query_dialog3 (_("Quit"), _("File was modified. Save with exit?"),
2068 _("&Yes"), _("&No"), _("&Cancel quit"));
2072 act
= edit_query_dialog2 (_("Quit"), _("Midnight Commander is being shut down.\nSave modified file?"),
2073 _("&Yes"), _("&No"));
2083 edit_push_markers (edit
);
2084 edit_set_markers (edit
, 0, 0, 0, 0);
2085 if (!edit_save_cmd (edit
) || midnight_shutdown
)
2086 return (gboolean
) midnight_shutdown
;
2090 case 2: /* Cancel quit */
2098 /* Return a null terminated length of text. Result must be g_free'd */
2099 static unsigned char *
2100 edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
)
2102 unsigned char *s
, *r
;
2103 r
= s
= g_malloc0 (finish
- start
+ 1);
2104 if (edit
->column_highlight
)
2107 /* copy from buffer, excluding chars that are out of the column 'margins' */
2108 while (start
< finish
)
2112 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0, start
);
2113 c
= edit_get_byte (edit
, start
);
2114 if ((x
>= edit
->column1
&& x
< edit
->column2
)
2115 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n')
2125 *l
= finish
- start
;
2126 while (start
< finish
)
2127 *s
++ = edit_get_byte (edit
, start
++);
2133 /* save block, returns 1 on success */
2135 edit_save_block (WEdit
* edit
, const char *filename
, long start
, long finish
)
2139 file
= mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
2140 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
);
2144 if (edit
->column_highlight
)
2147 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof (VERTICAL_MAGIC
));
2150 unsigned char *block
, *p
;
2151 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
2154 r
= mc_write (file
, p
, len
);
2167 len
= finish
- start
;
2168 buf
= g_malloc0 (TEMP_BUF_LEN
);
2169 while (start
!= finish
)
2171 end
= min (finish
, start
+ TEMP_BUF_LEN
);
2172 for (; i
< end
; i
++)
2173 buf
[i
- start
] = edit_get_byte (edit
, i
);
2174 len
-= mc_write (file
, (char *) buf
, end
- start
);
2185 /* copies a block to clipboard file */
2187 edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
2191 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2192 ret
= edit_save_block (edit
, tmp
, start
, finish
);
2198 edit_paste_from_history (WEdit
* edit
)
2201 edit_error_dialog (_("Error"), _("This function is not implemented"));
2205 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2207 long start_mark
, end_mark
;
2208 if (eval_marks (edit
, &start_mark
, &end_mark
))
2210 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2212 edit_error_dialog (_("Copy to clipboard"),
2213 get_sys_error (_("Unable to save to file")));
2216 /* try use external clipboard utility */
2217 copy_file_to_ext_clip ();
2219 edit_mark_cmd (edit
, 1);
2224 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2226 long start_mark
, end_mark
;
2227 if (eval_marks (edit
, &start_mark
, &end_mark
))
2229 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2231 edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file"));
2234 /* try use external clipboard utility */
2235 copy_file_to_ext_clip ();
2237 edit_block_delete_cmd (edit
);
2238 edit_mark_cmd (edit
, 1);
2243 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2246 /* try use external clipboard utility */
2247 paste_to_file_from_ext_clip ();
2248 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2249 edit_insert_file (edit
, tmp
);
2255 * Ask user for the line and go to that line.
2256 * Negative numbers mean line from the end (i.e. -1 is the last line).
2259 edit_goto_cmd (WEdit
* edit
)
2262 static long line
= 0; /* line as typed, saved as default */
2267 g_snprintf (s
, sizeof (s
), "%ld", line
);
2268 f
= input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE
,
2279 l
= strtol (f
, &error
, 0);
2288 l
= edit
->total_lines
+ l
+ 2;
2289 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2290 edit_move_to_line (edit
, l
- 1);
2291 edit
->force
|= REDRAW_COMPLETELY
;
2296 /* Return 1 on success */
2298 edit_save_block_cmd (WEdit
* edit
)
2300 long start_mark
, end_mark
;
2303 if (eval_marks (edit
, &start_mark
, &end_mark
))
2306 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2308 input_expand_dialog (_("Save block"), _("Enter file name:"),
2309 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2311 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2321 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2324 edit
->force
|= REDRAW_COMPLETELY
;
2330 edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file")));
2334 edit
->force
|= REDRAW_COMPLETELY
;
2339 /* returns 1 on success */
2341 edit_insert_file_cmd (WEdit
* edit
)
2346 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2347 exp
= input_expand_dialog (_("Insert file"), _("Enter file name:"),
2348 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2350 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2360 if (edit_insert_file (edit
, exp
))
2363 edit
->force
|= REDRAW_COMPLETELY
;
2369 edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file")));
2373 edit
->force
|= REDRAW_COMPLETELY
;
2377 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2379 edit_sort_cmd (WEdit
* edit
)
2381 static char *old
= 0;
2383 long start_mark
, end_mark
;
2386 if (eval_marks (edit
, &start_mark
, &end_mark
))
2388 edit_error_dialog (_("Sort block"), _("You must first highlight a block of text"));
2392 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2393 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2396 exp
= input_dialog (_("Run sort"),
2397 _("Enter sort options (see manpage) separated by whitespace:"),
2398 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2404 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2405 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2410 if (e
== -1 || e
== 127)
2412 edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command")));
2417 sprintf (q
, "%d ", e
);
2418 tmp
= g_strdup_printf (_("Sort returned non-zero: %s"), q
);
2419 edit_error_dialog (_("Sort"), tmp
);
2425 edit
->force
|= REDRAW_COMPLETELY
;
2427 if (edit_block_delete_cmd (edit
))
2429 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2430 edit_insert_file (edit
, tmp
);
2436 * Ask user for a command, execute it and paste its output back to the
2440 edit_ext_cmd (WEdit
* edit
)
2446 input_dialog (_("Paste output of external command"),
2447 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2452 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2459 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2463 edit
->force
|= REDRAW_COMPLETELY
;
2464 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2465 edit_insert_file (edit
, tmp
);
2470 /* if block is 1, a block must be highlighted and the shell command
2471 processes it. If block is 0 the shell command is a straight system
2472 command, that just produces some output which is to be inserted */
2474 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2476 long start_mark
, end_mark
;
2478 FILE *script_home
= NULL
;
2479 FILE *block_file
= NULL
;
2480 gchar
*o
, *h
, *b
, *tmp
;
2481 char *quoted_name
= NULL
;
2483 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2484 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2485 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2487 script_home
= fopen (h
, "r");
2488 if (script_home
== NULL
)
2490 FILE *script_src
= NULL
;
2492 script_home
= fopen (h
, "w");
2493 if (script_home
== NULL
)
2495 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2496 edit_error_dialog ("", get_sys_error (tmp
));
2498 goto edit_block_process_cmd__EXIT
;
2501 script_src
= fopen (o
, "r");
2502 if (script_src
== NULL
)
2504 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2505 script_src
= fopen (o
, "r");
2506 if (script_src
== NULL
)
2508 fclose (script_home
);
2510 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2511 edit_error_dialog ("", get_sys_error (tmp
));
2513 goto edit_block_process_cmd__EXIT
;
2516 while (fgets (buf
, sizeof (buf
), script_src
))
2517 fputs (buf
, script_home
);
2518 fclose (script_src
);
2520 if (fclose (script_home
))
2522 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2523 edit_error_dialog ("", get_sys_error (tmp
));
2525 goto edit_block_process_cmd__EXIT
;
2528 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2529 edit_error_dialog ("", get_sys_error (tmp
));
2536 { /* for marked block run indent formatter */
2537 if (eval_marks (edit
, &start_mark
, &end_mark
))
2539 edit_error_dialog (_("Process block"),
2540 _("You must first highlight a block of text"));
2541 goto edit_block_process_cmd__EXIT
;
2543 edit_save_block (edit
, b
, start_mark
, end_mark
);
2544 quoted_name
= name_quote (edit
->filename
, 0);
2547 * Initial space is to avoid polluting bash history.
2549 * $1 - name of the edited file (to check its extension etc).
2550 * $2 - file containing the current block.
2551 * $3 - file where error messages should be put
2552 * (for compatibility with old scripts).
2554 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2555 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2560 * No block selected, just execute the command for the file.
2562 * $1 - name of the edited file.
2564 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2565 quoted_name
, (char *) NULL
);
2568 if (system (tmp
) == -1)
2570 edit_error_dialog (_("Process block"), _("Error calling program"));
2575 g_free (quoted_name
);
2576 close_error_pipe (D_NORMAL
, NULL
);
2578 edit_refresh_cmd (edit
);
2579 edit
->force
|= REDRAW_COMPLETELY
;
2581 /* insert result block */
2582 if (block
&& !edit_block_delete_cmd (edit
))
2584 edit_insert_file (edit
, b
);
2585 block_file
= fopen (b
, "w");
2586 if (block_file
!= NULL
)
2587 fclose (block_file
);
2592 edit_block_process_cmd__EXIT
:
2598 /* prints at the cursor */
2599 /* returns the number of chars printed */
2601 edit_print_string (WEdit
* e
, const char *s
)
2604 while (s
[i
] != '\0')
2605 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2606 e
->force
|= REDRAW_COMPLETELY
;
2607 edit_update_screen (e
);
2613 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
2618 to
= name_quote (to
, 0);
2619 subject
= name_quote (subject
, 0);
2620 cc
= name_quote (cc
, 0);
2621 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
2635 for (i
= 0; i
< edit
->last_byte
; i
++)
2636 fputc (edit_get_byte (edit
, i
), p
);
2641 #define MAIL_DLG_HEIGHT 12
2644 edit_mail_dialog (WEdit
* edit
)
2647 char *tmail_subject
;
2650 static char *mail_cc_last
= 0;
2651 static char *mail_subject_last
= 0;
2652 static char *mail_to_last
= 0;
2654 QuickWidget quick_widgets
[] = {
2655 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2656 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2657 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2658 /* 3 */ QUICK_LABEL (3, 50, 7, MAIL_DLG_HEIGHT
, N_("Copies to")),
2659 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2661 /* 5 */ QUICK_LABEL (3, 50, 5, MAIL_DLG_HEIGHT
, N_("Subject")),
2662 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2663 /* 7 */ QUICK_LABEL (3, 50, 3, MAIL_DLG_HEIGHT
, N_("To")),
2664 /* 8 */ QUICK_LABEL (3, 50, 2, MAIL_DLG_HEIGHT
, N_("mail -s <subject> -c <cc> <to>")),
2668 QuickDialog Quick_input
= {
2669 50, MAIL_DLG_HEIGHT
, -1, -1, N_("Mail"),
2670 "[Input Line Keys]", quick_widgets
, NULL
, FALSE
2673 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2674 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2675 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2677 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2679 g_free (mail_cc_last
);
2680 g_free (mail_subject_last
);
2681 g_free (mail_to_last
);
2682 mail_cc_last
= tmail_cc
;
2683 mail_subject_last
= tmail_subject
;
2684 mail_to_last
= tmail_to
;
2685 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2690 /*******************/
2691 /* Word Completion */
2692 /*******************/
2695 is_break_char (char c
)
2697 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2700 /* find first character of current word */
2702 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
2707 /* return if at begin of file */
2708 if (edit
->curs1
<= 0)
2711 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2712 /* return if not at end or in word */
2713 if (is_break_char (c
))
2716 /* search start of word to be completed */
2719 /* return if at begin of file */
2720 if ((gsize
) edit
->curs1
< i
)
2724 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2726 if (is_break_char (c
))
2728 /* return if word starts with digit */
2732 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2741 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2743 /* collect the possible completions */
2745 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
2746 char *match_expr
, struct selection
*compl, gsize
* num
)
2757 srch
= mc_search_new (match_expr
, -1);
2761 if (mc_config_get_bool
2762 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
2764 last_byte
= edit
->last_byte
;
2771 srch
->search_type
= MC_SEARCH_T_REGEX
;
2772 srch
->is_case_sensitive
= TRUE
;
2773 srch
->search_fn
= edit_search_cmd_callback
;
2775 /* collect max MAX_WORD_COMPLETIONS completions */
2779 /* get next match */
2780 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
2782 start
= srch
->normal_offset
;
2784 /* add matched completion if not yet added */
2785 temp
= g_string_new ("");
2786 for (i
= 0; i
< len
; i
++)
2788 skip
= edit_get_byte (edit
, start
+ i
);
2791 g_string_append_c (temp
, skip
);
2796 for (i
= 0; i
< (gsize
) * num
; i
++)
2799 ((char *) &compl[i
].text
[word_len
],
2800 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
2802 struct selection
this = compl[i
];
2803 for (++i
; i
< *num
; i
++)
2805 compl[i
- 1] = compl[i
];
2807 compl[*num
- 1] = this;
2809 break; /* skip it, already added */
2814 g_string_free (temp
, TRUE
);
2817 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
2819 g_free (compl[0].text
);
2820 for (i
= 1; i
< *num
; i
++)
2822 compl[i
- 1] = compl[i
];
2829 recoded
= str_convert_to_display (temp
->str
);
2831 if (recoded
&& recoded
->len
)
2833 g_string_free (temp
, TRUE
);
2837 g_string_free (recoded
, TRUE
);
2840 compl[*num
].text
= temp
->str
;
2841 compl[*num
].len
= temp
->len
;
2844 g_string_free (temp
, FALSE
);
2846 /* note the maximal length needed for the completion dialog */
2850 mc_search_free (srch
);
2855 * Complete current word using regular expression search
2856 * backwards beginning at the current cursor position.
2859 edit_complete_word_cmd (WEdit
* edit
)
2861 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2862 long word_start
= 0;
2863 unsigned char *bufpos
;
2865 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2867 /* search start of word to be completed */
2868 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2871 /* prepare match expression */
2872 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2874 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2877 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2878 (int) word_len
, bufpos
);
2880 /* collect the possible completions */
2881 /* start search from begin to end of file */
2883 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2884 (struct selection
*) &compl, &num_compl
);
2888 /* insert completed word if there is only one match */
2891 for (i
= word_len
; i
< compl[0].len
; i
++)
2892 edit_insert (edit
, *(compl[0].text
+ i
));
2894 /* more than one possible completion => ask the user */
2897 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2898 /* !!! pressed again the selection dialog pops up, but that !!! */
2899 /* !!! seems to require a further internal state !!! */
2902 /* let the user select the preferred completion */
2903 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2904 (struct selection
*) &compl, num_compl
);
2908 g_free (match_expr
);
2909 /* release memory before return */
2910 for (i
= 0; i
< num_compl
; i
++)
2911 g_free (compl[i
].text
);
2915 edit_select_codepage_cmd (WEdit
* edit
)
2918 if (do_select_codepage ())
2919 edit_set_codeset (edit
);
2921 edit
->force
= REDRAW_COMPLETELY
;
2922 edit_refresh_cmd (edit
);
2929 edit_insert_literal_cmd (WEdit
* edit
)
2931 int char_for_insertion
= editcmd_dialog_raw_key_query (_("Insert literal"),
2932 _("Press any key:"), 0);
2933 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
2937 edit_execute_macro_cmd (WEdit
* edit
)
2940 CK_Macro (editcmd_dialog_raw_key_query (_("Execute macro"), _("Press macro hotkey:"),
2942 if (command
== CK_Macro (0))
2943 command
= CK_Insert_Char
;
2945 edit_execute_key_command (edit
, command
, -1);
2949 edit_begin_end_macro_cmd (WEdit
* edit
)
2951 /* edit is a pointer to the widget */
2954 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2955 edit_execute_key_command (edit
, command
, -1);
2960 edit_load_forward_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
+ 1 < MAX_HISTORY_MOVETO
)
2975 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
2979 edit_stack_iterator
++;
2980 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2982 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2983 edit_history_moveto
[edit_stack_iterator
].line
);
2998 edit_load_back_cmd (WEdit
* edit
)
3002 if (edit_query_dialog2
3004 _("Current text was modified without a file save\n"
3005 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")))
3007 edit
->force
|= REDRAW_COMPLETELY
;
3011 if (edit_stack_iterator
> 0)
3013 edit_stack_iterator
--;
3014 if (edit_history_moveto
[edit_stack_iterator
].filename
)
3016 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
3017 edit_history_moveto
[edit_stack_iterator
].line
);
3032 edit_get_match_keyword_cmd (WEdit
* edit
)
3034 gsize word_len
= 0, max_len
= 0;
3037 long word_start
= 0;
3038 unsigned char *bufpos
;
3042 char *tagfile
= NULL
;
3044 etags_hash_t def_hash
[MAX_DEFINITIONS
];
3046 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
3048 def_hash
[i
].filename
= NULL
;
3051 /* search start of word to be completed */
3052 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3055 /* prepare match expression */
3056 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3057 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3059 ptr
= g_get_current_dir ();
3060 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3063 /* Recursive search file 'TAGS' in parent dirs */
3066 ptr
= g_path_get_dirname (path
);
3070 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3071 if (exist_file (tagfile
))
3074 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3079 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3084 max_len
= MAX_WIDTH_DEF_DIALOG
;
3088 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3089 (etags_hash_t
*) & def_hash
, num_def
);
3091 g_free (match_expr
);
3095 edit_move_block_to_right (WEdit
* edit
)
3097 long start_mark
, end_mark
;
3098 long cur_bol
, start_bol
;
3100 if (eval_marks (edit
, &start_mark
, &end_mark
))
3103 start_bol
= edit_bol (edit
, start_mark
);
3104 cur_bol
= edit_bol (edit
, end_mark
- 1);
3107 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3108 if (option_fill_tabs_with_spaces
)
3110 if (option_fake_half_tabs
)
3112 insert_spaces_tab (edit
, 1);
3116 insert_spaces_tab (edit
, 0);
3121 edit_insert (edit
, '\t');
3123 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3128 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3130 while (cur_bol
>= start_bol
);
3131 edit
->force
|= REDRAW_PAGE
;
3135 edit_move_block_to_left (WEdit
* edit
)
3137 long start_mark
, end_mark
;
3138 long cur_bol
, start_bol
;
3139 int i
, del_tab_width
;
3142 if (eval_marks (edit
, &start_mark
, &end_mark
))
3145 start_bol
= edit_bol (edit
, start_mark
);
3146 cur_bol
= edit_bol (edit
, end_mark
- 1);
3149 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3150 if (option_fake_half_tabs
)
3152 del_tab_width
= HALF_TAB_SIZE
;
3156 del_tab_width
= option_tab_spacing
;
3158 next_char
= edit_get_byte (edit
, edit
->curs1
);
3159 if (next_char
== '\t')
3161 edit_delete (edit
, 1);
3163 else if (next_char
== ' ')
3165 for (i
= 1; i
<= del_tab_width
; i
++)
3167 if (next_char
== ' ')
3169 edit_delete (edit
, 1);
3171 next_char
= edit_get_byte (edit
, edit
->curs1
);
3178 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3180 while (cur_bol
>= start_bol
);
3181 edit
->force
|= REDRAW_PAGE
;