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
;
1890 if (edit
->search
!= NULL
)
1892 search_string
= g_strndup (edit
->search
->original
, edit
->search
->original_len
);
1893 search_string_dup
= search_string
;
1898 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1899 if (history
!= NULL
&& history
->data
!= NULL
)
1901 search_string_dup
= search_string
= (char *) g_strdup (history
->data
);
1902 history
= g_list_first (history
);
1903 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1904 g_list_free (history
);
1906 edit
->search_start
= edit
->curs1
;
1913 if (search_string
&& *search_string
)
1915 tmp
= str_convert_to_display (search_string
);
1917 g_free (search_string_dup
);
1918 search_string_dup
= NULL
;
1920 if (tmp
&& tmp
->len
)
1921 search_string
= search_string_dup
= tmp
->str
;
1922 g_string_free (tmp
, FALSE
);
1924 #endif /* HAVE_CHARSET */
1925 editcmd_dialog_search_show (edit
, &search_string
);
1927 if (search_string
&& *search_string
)
1929 tmp
= str_convert_to_input (search_string
);
1930 if (tmp
&& tmp
->len
)
1931 search_string
= tmp
->str
;
1933 g_string_free (tmp
, FALSE
);
1935 if (search_string_dup
)
1936 g_free (search_string_dup
);
1938 #endif /* HAVE_CHARSET */
1940 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1944 edit
->force
|= REDRAW_COMPLETELY
;
1945 edit_scroll_screen_over_cursor (edit
);
1951 mc_search_free (edit
->search
);
1952 edit
->search
= NULL
;
1958 edit
->search
= mc_search_new (search_string
, -1);
1959 if (edit
->search
== NULL
)
1961 edit
->search_start
= edit
->curs1
;
1964 edit
->search
->search_type
= edit_search_options
.type
;
1965 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1966 edit
->search
->is_case_sentitive
= edit_search_options
.case_sens
;
1967 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1968 edit
->search
->search_fn
= edit_search_cmd_callback
;
1971 if (search_create_bookmark
)
1973 edit_search_cmd_search_create_bookmark (edit
);
1977 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1978 && edit_search_options
.backwards
)
1979 edit
->search_start
--;
1981 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1982 && !edit_search_options
.backwards
)
1983 edit
->search_start
++;
1985 if (editcmd_find (edit
, &len
))
1987 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1988 edit
->found_len
= len
;
1990 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1991 edit_scroll_screen_over_cursor (edit
);
1992 if (edit_search_options
.backwards
)
1993 edit
->search_start
--;
1995 edit
->search_start
++;
1999 edit
->search_start
= edit
->curs1
;
2000 if (edit
->search
->error_str
)
2001 edit_error_dialog (_("Search"), edit
->search
->error_str
);
2005 edit
->force
|= REDRAW_COMPLETELY
;
2006 edit_scroll_screen_over_cursor (edit
);
2011 * Check if it's OK to close the editor. If there are unsaved changes,
2012 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
2015 edit_ok_to_exit (WEdit
* edit
)
2017 if (!edit
->modified
)
2020 if (!edit_check_newline (edit
))
2023 switch (edit_query_dialog3
2024 (_("Quit"), _(" File was modified, Save with exit? "),
2025 _("&Cancel quit"), _("&Yes"), _("&No")))
2028 edit_push_markers (edit
);
2029 edit_set_markers (edit
, 0, 0, 0, 0);
2030 if (!edit_save_cmd (edit
))
2043 /* Return a null terminated length of text. Result must be g_free'd */
2044 static unsigned char *
2045 edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
)
2047 unsigned char *s
, *r
;
2048 r
= s
= g_malloc0 (finish
- start
+ 1);
2049 if (column_highlighting
)
2052 /* copy from buffer, excluding chars that are out of the column 'margins' */
2053 while (start
< finish
)
2057 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0, start
);
2058 c
= edit_get_byte (edit
, start
);
2059 if ((x
>= edit
->column1
&& x
< edit
->column2
)
2060 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n')
2070 *l
= finish
- start
;
2071 while (start
< finish
)
2072 *s
++ = edit_get_byte (edit
, start
++);
2078 /* save block, returns 1 on success */
2080 edit_save_block (WEdit
* edit
, const char *filename
, long start
, long finish
)
2085 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
2086 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
2089 if (column_highlighting
)
2092 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof (VERTICAL_MAGIC
));
2095 unsigned char *block
, *p
;
2096 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
2099 r
= mc_write (file
, p
, len
);
2112 len
= finish
- start
;
2113 buf
= g_malloc0 (TEMP_BUF_LEN
);
2114 while (start
!= finish
)
2116 end
= min (finish
, start
+ TEMP_BUF_LEN
);
2117 for (; i
< end
; i
++)
2118 buf
[i
- start
] = edit_get_byte (edit
, i
);
2119 len
-= mc_write (file
, (char *) buf
, end
- start
);
2130 /* copies a block to clipboard file */
2132 edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
2136 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2137 ret
= edit_save_block (edit
, tmp
, start
, finish
);
2144 edit_paste_from_history (WEdit
* edit
)
2147 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
2151 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2153 long start_mark
, end_mark
;
2154 if (eval_marks (edit
, &start_mark
, &end_mark
))
2156 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2158 edit_error_dialog (_(" Copy to clipboard "),
2159 get_sys_error (_(" Unable to save to file. ")));
2162 edit_mark_cmd (edit
, 1);
2167 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2169 long start_mark
, end_mark
;
2170 if (eval_marks (edit
, &start_mark
, &end_mark
))
2172 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2174 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
2177 edit_block_delete_cmd (edit
);
2178 edit_mark_cmd (edit
, 1);
2183 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2186 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2187 edit_insert_file (edit
, tmp
);
2193 * Ask user for the line and go to that line.
2194 * Negative numbers mean line from the end (i.e. -1 is the last line).
2197 edit_goto_cmd (WEdit
* edit
)
2200 static long line
= 0; /* line as typed, saved as default */
2205 g_snprintf (s
, sizeof (s
), "%ld", line
);
2206 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2217 l
= strtol (f
, &error
, 0);
2226 l
= edit
->total_lines
+ l
+ 2;
2227 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2228 edit_move_to_line (edit
, l
- 1);
2229 edit
->force
|= REDRAW_COMPLETELY
;
2234 /* Return 1 on success */
2236 edit_save_block_cmd (WEdit
* edit
)
2238 long start_mark
, end_mark
;
2241 if (eval_marks (edit
, &start_mark
, &end_mark
))
2244 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2246 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2247 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2249 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2259 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2262 edit
->force
|= REDRAW_COMPLETELY
;
2268 edit_error_dialog (_(" Save Block "), get_sys_error (_(" Cannot save file. ")));
2272 edit
->force
|= REDRAW_COMPLETELY
;
2277 /* returns 1 on success */
2279 edit_insert_file_cmd (WEdit
* edit
)
2284 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2285 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2286 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2288 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2298 if (edit_insert_file (edit
, exp
))
2301 edit
->force
|= REDRAW_COMPLETELY
;
2307 edit_error_dialog (_(" Insert File "), get_sys_error (_(" Cannot insert file. ")));
2311 edit
->force
|= REDRAW_COMPLETELY
;
2315 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2317 edit_sort_cmd (WEdit
* edit
)
2319 static char *old
= 0;
2321 long start_mark
, end_mark
;
2324 if (eval_marks (edit
, &start_mark
, &end_mark
))
2326 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2330 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2331 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2334 exp
= input_dialog (_(" Run Sort "),
2335 _(" Enter sort options (see manpage) separated by whitespace: "),
2336 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2342 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2343 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2348 if (e
== -1 || e
== 127)
2350 edit_error_dialog (_(" Sort "), get_sys_error (_(" Cannot execute sort command ")));
2355 sprintf (q
, "%d ", e
);
2356 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2357 edit_error_dialog (_(" Sort "), tmp
);
2363 edit
->force
|= REDRAW_COMPLETELY
;
2365 if (edit_block_delete_cmd (edit
))
2367 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2368 edit_insert_file (edit
, tmp
);
2374 * Ask user for a command, execute it and paste its output back to the
2378 edit_ext_cmd (WEdit
* edit
)
2384 input_dialog (_("Paste output of external command"),
2385 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2390 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2397 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2401 edit
->force
|= REDRAW_COMPLETELY
;
2402 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2403 edit_insert_file (edit
, tmp
);
2408 /* if block is 1, a block must be highlighted and the shell command
2409 processes it. If block is 0 the shell command is a straight system
2410 command, that just produces some output which is to be inserted */
2412 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2414 long start_mark
, end_mark
;
2416 FILE *script_home
= NULL
;
2417 FILE *block_file
= NULL
;
2418 gchar
*o
, *h
, *b
, *tmp
;
2419 char *quoted_name
= NULL
;
2421 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2422 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2423 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2425 script_home
= fopen (h
, "r");
2426 if (script_home
== NULL
)
2428 FILE *script_src
= NULL
;
2430 script_home
= fopen (h
, "w");
2431 if (script_home
== NULL
)
2433 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2434 edit_error_dialog ("", get_sys_error (tmp
));
2436 goto edit_block_process_cmd__EXIT
;
2439 script_src
= fopen (o
, "r");
2440 if (script_src
== NULL
)
2442 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2443 script_src
= fopen (o
, "r");
2444 if (script_src
== NULL
)
2446 fclose (script_home
);
2448 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2449 edit_error_dialog ("", get_sys_error (tmp
));
2451 goto edit_block_process_cmd__EXIT
;
2454 while (fgets (buf
, sizeof (buf
), script_src
))
2455 fputs (buf
, script_home
);
2456 fclose (script_src
);
2458 if (fclose (script_home
))
2460 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2461 edit_error_dialog ("", get_sys_error (tmp
));
2463 goto edit_block_process_cmd__EXIT
;
2466 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2467 edit_error_dialog ("", get_sys_error (tmp
));
2474 { /* for marked block run indent formatter */
2475 if (eval_marks (edit
, &start_mark
, &end_mark
))
2477 edit_error_dialog (_("Process block"),
2478 _(" You must first highlight a block of text. "));
2479 goto edit_block_process_cmd__EXIT
;
2481 edit_save_block (edit
, b
, start_mark
, end_mark
);
2482 quoted_name
= name_quote (edit
->filename
, 0);
2485 * Initial space is to avoid polluting bash history.
2487 * $1 - name of the edited file (to check its extension etc).
2488 * $2 - file containing the current block.
2489 * $3 - file where error messages should be put
2490 * (for compatibility with old scripts).
2492 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2493 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2500 * No block selected, just execute the command for the file.
2502 * $1 - name of the edited file.
2504 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2505 quoted_name
, (char *) NULL
);
2509 g_free (quoted_name
);
2510 close_error_pipe (D_NORMAL
, NULL
);
2512 edit_refresh_cmd (edit
);
2513 edit
->force
|= REDRAW_COMPLETELY
;
2515 /* insert result block */
2516 if (block
&& !edit_block_delete_cmd (edit
))
2518 edit_insert_file (edit
, b
);
2519 block_file
= fopen (b
, "w");
2520 if (block_file
!= NULL
)
2521 fclose (block_file
);
2524 edit_block_process_cmd__EXIT
:
2530 /* prints at the cursor */
2531 /* returns the number of chars printed */
2533 edit_print_string (WEdit
* e
, const char *s
)
2536 while (s
[i
] != '\0')
2537 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2538 e
->force
|= REDRAW_COMPLETELY
;
2539 edit_update_screen (e
);
2545 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
2550 to
= name_quote (to
, 0);
2551 subject
= name_quote (subject
, 0);
2552 cc
= name_quote (cc
, 0);
2553 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
2567 for (i
= 0; i
< edit
->last_byte
; i
++)
2568 fputc (edit_get_byte (edit
, i
), p
);
2573 #define MAIL_DLG_HEIGHT 12
2576 edit_mail_dialog (WEdit
* edit
)
2579 char *tmail_subject
;
2582 static char *mail_cc_last
= 0;
2583 static char *mail_subject_last
= 0;
2584 static char *mail_to_last
= 0;
2586 QuickWidget quick_widgets
[] = {
2587 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2588 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2589 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2590 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2591 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2593 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2594 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2595 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2596 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2600 QuickDialog Quick_input
= {
2601 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2602 "[Input Line Keys]", quick_widgets
, FALSE
2605 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2606 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2607 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2609 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2611 g_free (mail_cc_last
);
2612 g_free (mail_subject_last
);
2613 g_free (mail_to_last
);
2614 mail_cc_last
= tmail_cc
;
2615 mail_subject_last
= tmail_subject
;
2616 mail_to_last
= tmail_to
;
2617 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2622 /*******************/
2623 /* Word Completion */
2624 /*******************/
2627 is_break_char (char c
)
2629 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2632 /* find first character of current word */
2634 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
2639 /* return if at begin of file */
2640 if (edit
->curs1
<= 0)
2643 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2644 /* return if not at end or in word */
2645 if (is_break_char (c
))
2648 /* search start of word to be completed */
2651 /* return if at begin of file */
2652 if ((gsize
) edit
->curs1
< i
)
2656 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2658 if (is_break_char (c
))
2660 /* return if word starts with digit */
2664 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2673 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2675 /* collect the possible completions */
2677 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
2678 char *match_expr
, struct selection
*compl, gsize
* num
)
2689 srch
= mc_search_new (match_expr
, -1);
2693 if (mc_config_get_bool
2694 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
2696 last_byte
= edit
->last_byte
;
2703 srch
->search_type
= MC_SEARCH_T_REGEX
;
2704 srch
->is_case_sentitive
= TRUE
;
2705 srch
->search_fn
= edit_search_cmd_callback
;
2707 /* collect max MAX_WORD_COMPLETIONS completions */
2711 /* get next match */
2712 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
2714 start
= srch
->normal_offset
;
2716 /* add matched completion if not yet added */
2717 temp
= g_string_new ("");
2718 for (i
= 0; i
< len
; i
++)
2720 skip
= edit_get_byte (edit
, start
+ i
);
2723 g_string_append_c (temp
, skip
);
2728 for (i
= 0; i
< (gsize
) * num
; i
++)
2731 ((char *) &compl[i
].text
[word_len
],
2732 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
2734 struct selection
this = compl[i
];
2735 for (++i
; i
< *num
; i
++)
2737 compl[i
- 1] = compl[i
];
2739 compl[*num
- 1] = this;
2741 break; /* skip it, already added */
2746 g_string_free (temp
, TRUE
);
2749 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
2751 g_free (compl[0].text
);
2752 for (i
= 1; i
< *num
; i
++)
2754 compl[i
- 1] = compl[i
];
2761 recoded
= str_convert_to_display (temp
->str
);
2763 if (recoded
&& recoded
->len
)
2765 g_string_free (temp
, TRUE
);
2769 g_string_free (recoded
, TRUE
);
2772 compl[*num
].text
= temp
->str
;
2773 compl[*num
].len
= temp
->len
;
2776 g_string_free (temp
, FALSE
);
2778 /* note the maximal length needed for the completion dialog */
2782 mc_search_free (srch
);
2787 * Complete current word using regular expression search
2788 * backwards beginning at the current cursor position.
2791 edit_complete_word_cmd (WEdit
* edit
)
2793 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2794 long word_start
= 0;
2795 unsigned char *bufpos
;
2797 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2799 /* search start of word to be completed */
2800 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2803 /* prepare match expression */
2804 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2806 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2809 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2810 (int) word_len
, bufpos
);
2812 /* collect the possible completions */
2813 /* start search from begin to end of file */
2815 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2816 (struct selection
*) &compl, &num_compl
);
2820 /* insert completed word if there is only one match */
2823 for (i
= word_len
; i
< compl[0].len
; i
++)
2824 edit_insert (edit
, *(compl[0].text
+ i
));
2826 /* more than one possible completion => ask the user */
2829 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2830 /* !!! pressed again the selection dialog pops up, but that !!! */
2831 /* !!! seems to require a further internal state !!! */
2834 /* let the user select the preferred completion */
2835 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2836 (struct selection
*) &compl, num_compl
);
2840 g_free (match_expr
);
2841 /* release memory before return */
2842 for (i
= 0; i
< num_compl
; i
++)
2843 g_free (compl[i
].text
);
2847 edit_select_codepage_cmd (WEdit
* edit
)
2850 const char *cp_id
= NULL
;
2851 if (do_select_codepage ())
2853 cp_id
= get_codepage_id (source_codepage
>= 0 ? source_codepage
: display_codepage
);
2858 conv
= str_crt_conv_from (cp_id
);
2859 if (conv
!= INVALID_CONV
)
2861 if (edit
->converter
!= str_cnv_from_term
)
2862 str_close_conv (edit
->converter
);
2863 edit
->converter
= conv
;
2868 edit
->utf8
= str_isutf8 (cp_id
);
2871 edit
->force
= REDRAW_COMPLETELY
;
2872 edit_refresh_cmd (edit
);
2879 edit_insert_literal_cmd (WEdit
* edit
)
2881 int char_for_insertion
= editcmd_dialog_raw_key_query (_(" Insert Literal "),
2882 _(" Press any key: "), 0);
2883 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
2887 edit_execute_macro_cmd (WEdit
* edit
)
2890 CK_Macro (editcmd_dialog_raw_key_query (_(" Execute Macro "), _(" Press macro hotkey: "),
2892 if (command
== CK_Macro (0))
2893 command
= CK_Insert_Char
;
2895 edit_execute_key_command (edit
, command
, -1);
2899 edit_begin_end_macro_cmd (WEdit
* edit
)
2901 /* edit is a pointer to the widget */
2904 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2905 edit_execute_key_command (edit
, command
, -1);
2910 edit_load_forward_cmd (WEdit
* edit
)
2914 if (edit_query_dialog2
2916 _(" Current text was modified without a file save. \n"
2917 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2919 edit
->force
|= REDRAW_COMPLETELY
;
2923 if (edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
)
2925 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
2929 edit_stack_iterator
++;
2930 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2932 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2933 edit_history_moveto
[edit_stack_iterator
].line
);
2948 edit_load_back_cmd (WEdit
* edit
)
2952 if (edit_query_dialog2
2954 _(" Current text was modified without a file save. \n"
2955 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2957 edit
->force
|= REDRAW_COMPLETELY
;
2961 if (edit_stack_iterator
> 0)
2963 edit_stack_iterator
--;
2964 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2966 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2967 edit_history_moveto
[edit_stack_iterator
].line
);
2982 edit_get_match_keyword_cmd (WEdit
* edit
)
2984 gsize word_len
= 0, max_len
= 0;
2987 long word_start
= 0;
2988 unsigned char *bufpos
;
2992 char *tagfile
= NULL
;
2994 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2996 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
2998 def_hash
[i
].filename
= NULL
;
3001 /* search start of word to be completed */
3002 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3005 /* prepare match expression */
3006 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3007 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3009 ptr
= g_get_current_dir ();
3010 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3013 /* Recursive search file 'TAGS' in parent dirs */
3016 ptr
= g_path_get_dirname (path
);
3020 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3021 if (exist_file (tagfile
))
3024 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3029 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3034 max_len
= MAX_WIDTH_DEF_DIALOG
;
3038 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3039 (etags_hash_t
*) & def_hash
, num_def
);
3041 g_free (match_expr
);
3045 edit_move_block_to_right (WEdit
* edit
)
3047 long start_mark
, end_mark
;
3048 long cur_bol
, start_bol
;
3050 if (eval_marks (edit
, &start_mark
, &end_mark
))
3053 start_bol
= edit_bol (edit
, start_mark
);
3054 cur_bol
= edit_bol (edit
, end_mark
- 1);
3057 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3058 if (option_fill_tabs_with_spaces
)
3060 if (option_fake_half_tabs
)
3062 insert_spaces_tab (edit
, 1);
3066 insert_spaces_tab (edit
, 0);
3071 edit_insert (edit
, '\t');
3073 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3078 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3080 while (cur_bol
>= start_bol
);
3081 edit
->force
|= REDRAW_PAGE
;
3085 edit_move_block_to_left (WEdit
* edit
)
3087 long start_mark
, end_mark
;
3088 long cur_bol
, start_bol
;
3089 int i
, del_tab_width
;
3092 if (eval_marks (edit
, &start_mark
, &end_mark
))
3095 start_bol
= edit_bol (edit
, start_mark
);
3096 cur_bol
= edit_bol (edit
, end_mark
- 1);
3099 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3100 if (option_fake_half_tabs
)
3102 del_tab_width
= HALF_TAB_SIZE
;
3106 del_tab_width
= option_tab_spacing
;
3108 next_char
= edit_get_byte (edit
, edit
->curs1
);
3109 if (next_char
== '\t')
3111 edit_delete (edit
, 1);
3113 else if (next_char
== ' ')
3115 for (i
= 1; i
<= del_tab_width
; i
++)
3117 if (next_char
== ' ')
3119 edit_delete (edit
, 1);
3121 next_char
= edit_get_byte (edit
, edit
->curs1
);
3128 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3130 while (cur_bol
>= start_bol
);
3131 edit
->force
|= REDRAW_PAGE
;