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 "src/history.h"
56 #include "src/widget.h" /* listbox_new() */
57 #include "src/layout.h" /* clr_scr() */
58 #include "src/main.h" /* mc_home source_codepage */
59 #include "src/help.h" /* interactive_display() */
60 #include "src/wtools.h" /* message() */
61 #include "src/charsets.h"
62 #include "src/selcodepage.h"
63 #include "src/cmddef.h"
65 #include "lib/vfs/mc-vfs/vfs.h"
67 #include "src/editor/edit-impl.h"
68 #include "src/editor/edit.h"
69 #include "src/editor/editlock.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
,
88 edit_search_cmd_search_create_bookmark(WEdit
* edit
)
90 int found
= 0, books
= 0;
91 long l
= 0, l_last
= -1;
95 search_create_bookmark
= 0;
96 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
);
106 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
110 q
= edit
->search
->normal_offset
+ 1;
114 edit_error_dialog (_ ("Search"), _ (" Search string not found "));
116 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
117 edit_scroll_screen_over_cursor (edit
);
122 edit_search_cmd_callback(const void *user_data
, gsize char_offset
)
124 return edit_get_byte ((WEdit
* )user_data
, (long) char_offset
);
127 void edit_help_cmd (WEdit
* edit
)
129 interactive_display (NULL
, "[Internal File Editor]");
130 edit
->force
|= REDRAW_COMPLETELY
;
134 edit_refresh_cmd (WEdit
* edit
)
139 edit_get_syntax_color (edit
, -1, &color
);
147 #endif /* !HAVE_SLANG */
151 /* If 0 (quick save) then a) create/truncate <filename> file,
152 b) save to <filename>;
153 if 1 (safe save) then a) save to <tempnam>,
154 b) rename <tempnam> to <filename>;
155 if 2 (do backups) then a) save to <tempnam>,
156 b) rename <filename> to <filename.backup_ext>,
157 c) rename <tempnam> to <filename>. */
159 /* returns 0 on error, -1 on abort */
161 edit_save_file (WEdit
*edit
, const char *filename
)
167 gchar
*real_filename
;
168 int this_save_mode
, fd
= -1;
175 if (*filename
!= PATH_SEP
&& edit
->dir
) {
176 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
178 real_filename
= g_strdup(filename
);
181 this_save_mode
= option_save_mode
;
182 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
183 if (!vfs_file_is_local (real_filename
) ||
184 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1) {
186 * The file does not exists yet, so no safe save or
187 * backup are necessary.
189 this_save_mode
= EDIT_QUICK_SAVE
;
195 if (this_save_mode
== EDIT_QUICK_SAVE
&&
196 !edit
->skip_detach_prompt
) {
200 rv
= mc_stat (real_filename
, &sb
);
201 if (rv
== 0 && sb
.st_nlink
> 1) {
202 rv
= edit_query_dialog3 (_("Warning"),
203 _(" File has hard-links. Detach before saving? "),
204 _("&Yes"), _("&No"), _("&Cancel"));
207 this_save_mode
= EDIT_SAFE_SAVE
;
210 edit
->skip_detach_prompt
= 1;
213 g_free(real_filename
);
218 /* Prevent overwriting changes from other editor sessions. */
219 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
) {
221 /* The default action is "Cancel". */
224 rv
= edit_query_dialog2 (
226 _("The file has been modified in the meantime. Save anyway?"),
230 g_free(real_filename
);
236 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
237 char *savedir
, *saveprefix
;
238 const char *slashpos
;
239 slashpos
= strrchr (real_filename
, PATH_SEP
);
241 savedir
= g_strdup (real_filename
);
242 savedir
[slashpos
- real_filename
+ 1] = '\0';
244 savedir
= g_strdup (".");
245 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
247 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
250 g_free(real_filename
);
254 * Close for now because mc_mkstemps use pure open system call
255 * to create temporary file and it needs to be reopened by
256 * VFS-aware mc_open().
260 savename
= g_strdup (real_filename
);
262 mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
263 mc_chmod (savename
, edit
->stat1
.st_mode
);
266 mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
,
267 edit
->stat1
.st_mode
)) == -1)
271 if ((p
= edit_get_write_filter (savename
, real_filename
))) {
275 file
= (FILE *) popen (p
, "w");
278 filelen
= edit_write_stream (edit
, file
);
282 if (pclose (file
) != 0) {
283 tmp
= g_strconcat (_(" Error writing to pipe: "),
284 p
, " ", (char *) NULL
);
285 edit_error_dialog (_("Error"), tmp
);
292 tmp
= g_strconcat (_(" Cannot open pipe for writing: "),
293 p
, " ", (char *) NULL
);
295 edit_error_dialog (_("Error"),
296 get_sys_error (tmp
));
302 } else if (edit
->lb
== LB_ASIS
) { /* do not change line breaks */
305 filelen
= edit
->last_byte
;
306 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1) {
307 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
)
315 (fd
, (char *) edit
->buffers1
[buf
],
316 edit
->curs1
& M_EDIT_BUF_SIZE
) !=
317 (edit
->curs1
& M_EDIT_BUF_SIZE
)) {
319 } else if (edit
->curs2
) {
321 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
324 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
325 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
326 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) !=
327 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) {
332 (fd
, (char *) edit
->buffers2
[buf
],
333 EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
) {
344 /* Update the file information, especially the mtime. */
345 if (mc_stat (savename
, &edit
->stat1
) == -1)
347 } else { /* change line breaks */
352 file
= (FILE *) fopen (savename
, "w");
355 filelen
= edit_write_stream (edit
, file
);
360 msg
= g_strdup_printf (_(" Cannot open file for writing: %s "), savename
);
361 edit_error_dialog (_("Error"), msg
);
367 if (filelen
!= edit
->last_byte
)
370 if (this_save_mode
== EDIT_DO_BACKUP
) {
371 assert (option_backup_ext
!= NULL
);
372 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
373 if (mc_rename (real_filename
, tmp
) == -1){
379 if (this_save_mode
!= EDIT_QUICK_SAVE
)
380 if (mc_rename (savename
, real_filename
) == -1)
383 g_free(real_filename
);
386 /* FIXME: Is this safe ?
387 * if (this_save_mode != EDIT_QUICK_SAVE)
388 * mc_unlink (savename);
390 g_free(real_filename
);
396 menu_save_mode_cmd (void)
399 const int DLG_X
= 38;
400 const int DLG_Y
= 13;
408 N_("&Do backups with following extension:")
411 QuickWidget widgets
[] =
414 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
416 QUICK_BUTTON ( 6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
418 QUICK_CHECKBOX ( 4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
420 QUICK_INPUT ( 8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
422 QUICK_RADIO ( 4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
428 DLG_X
, DLG_Y
, -1, -1, N_(" Edit Save Mode "),
429 "[Edit Save Mode]", widgets
, FALSE
434 size_t w0
, w1
, b_len
, w3
;
436 assert (option_backup_ext
!= NULL
);
438 /* OK/Cancel buttons */
439 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
440 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
443 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
446 for (i
= 0; i
< 3; i
++) {
450 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
453 maxlen
= max (maxlen
, w3
+ 4);
455 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
457 widgets
[3].u
.input
.len
= w3
;
458 widgets
[1].relative_x
= (dialog
.xlen
- b_len
)/2;
459 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
461 for (i
= 0; i
< sizeof (widgets
)/sizeof (widgets
[0]); i
++)
462 widgets
[i
].x_divisions
= dialog
.xlen
;
464 if (quick_dialog (&dialog
) != B_CANCEL
) {
465 g_free (option_backup_ext
);
466 option_backup_ext
= str_result
;
471 edit_set_filename (WEdit
*edit
, const char *f
)
473 g_free (edit
->filename
);
476 edit
->filename
= g_strdup (f
);
477 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
479 edit
->dir
= g_strdup (vfs_get_current_dir ());
480 #else /* ENABLE_VFS */
481 edit
->dir
= g_get_current_dir ();
482 #endif /* ENABLE_VFS */
486 edit_check_newline (WEdit
*edit
)
488 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
489 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
490 && edit_query_dialog2 (_("Warning"),
491 _("The file you are saving is not finished with a newline"),
492 _("C&ontinue"), _("&Cancel")));
496 edit_get_save_file_as (WEdit
*edit
)
499 #define DLG_HEIGHT 14
501 static LineBreaks cur_lb
= LB_ASIS
;
503 char *filename
= edit
->filename
;
505 const char *lb_names
[LB_NAMES
] =
507 N_("&Do not change"),
508 N_("&Unix format (LF)"),
509 N_("&Windows/DOS format (CR LF)"),
510 N_("&Macintosh format (CR)")
513 QuickWidget quick_widgets
[] =
515 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
516 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
517 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
518 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
519 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0, "save-as", &filename
),
520 QUICK_LABEL (2, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_(" Enter file name: ")),
524 QuickDialog Quick_options
=
526 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
527 N_(" Save As "), "[Save File As]",
531 if (quick_dialog (&Quick_options
) != B_CANCEL
) {
542 /* Here we want to warn the users of overwriting an existing file,
543 but only if they have made a change to the filename */
544 /* returns 1 on success */
546 edit_save_as_cmd (WEdit
*edit
)
548 /* This heads the 'Save As' dialog box */
551 int different_filename
= 0;
553 if (!edit_check_newline (edit
))
556 exp
= edit_get_save_file_as (edit
);
557 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
562 edit
->force
|= REDRAW_COMPLETELY
;
566 if (strcmp (edit
->filename
, exp
)) {
568 different_filename
= 1;
569 if ((file
= mc_open (exp
, O_RDONLY
| O_BINARY
)) != -1) {
570 /* the file exists */
572 /* Overwrite the current file or cancel the operation */
573 if (edit_query_dialog2
575 _(" A file already exists with this name. "),
576 _("&Overwrite"), _("&Cancel"))) {
577 edit
->force
|= REDRAW_COMPLETELY
;
582 edit
->stat1
.st_mode
|= S_IWUSR
;
584 save_lock
= edit_lock_file (exp
);
586 /* filenames equal, check if already locked */
587 if (!edit
->locked
&& !edit
->delete_file
)
588 save_lock
= edit_lock_file (exp
);
591 if (different_filename
)
594 * Allow user to write into saved (under another name) file
595 * even if original file had r/o user permissions.
597 edit
->stat1
.st_mode
|= S_IWRITE
;
600 rv
= edit_save_file (edit
, exp
);
603 /* Succesful, so unlock both files */
604 if (different_filename
) {
606 edit_unlock_file (exp
);
608 edit
->locked
= edit_unlock_file (edit
->filename
);
610 if (edit
->locked
|| save_lock
)
611 edit
->locked
= edit_unlock_file (edit
->filename
);
614 edit_set_filename (edit
, exp
);
615 if (edit
->lb
!= LB_ASIS
)
616 edit_reload(edit
, exp
);
619 edit
->delete_file
= 0;
620 if (different_filename
)
621 edit_load_syntax (edit
, NULL
, option_syntax_type
);
622 edit
->force
|= REDRAW_COMPLETELY
;
625 edit_error_dialog (_(" Save As "),
627 (" Cannot save file. ")));
630 /* Failed, so maintain modify (not save) lock */
632 edit_unlock_file (exp
);
634 edit
->force
|= REDRAW_COMPLETELY
;
639 edit
->force
|= REDRAW_COMPLETELY
;
643 /* {{{ Macro stuff starts here */
645 /* creates a macro file if it doesn't exist */
646 static FILE *edit_open_macro_file (const char *r
)
651 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
652 if ((file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
)) == -1){
657 fd
= fopen (filename
, r
);
662 #define MAX_MACROS 1024
663 static int saved_macro
[MAX_MACROS
+ 1];
664 static int saved_macros_loaded
= 0;
667 This is just to stop the macro file be loaded over and over for keys
668 that aren't defined to anything. On slow systems this could be annoying.
674 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
675 if (saved_macro
[i
] == k
)
680 /* returns 1 on error */
682 edit_delete_macro (WEdit
* edit
, int k
)
685 struct macro macro
[MAX_MACRO_LENGTH
];
691 if (saved_macros_loaded
)
692 if ((j
= macro_exists (k
)) < 0)
694 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
695 g
= fopen (tmp
, "w");
698 edit_error_dialog (_(" Delete macro "),
699 get_sys_error (_(" Cannot open temp file ")));
702 f
= edit_open_macro_file ("r");
704 edit_error_dialog (_(" Delete macro "),
705 get_sys_error (_(" Cannot open macro file ")));
710 n
= fscanf (f
, ("key '%d 0': "), &s
);
714 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
718 fprintf (g
, ("key '%d 0': "), s
);
719 for (i
= 0; i
< n
; i
++)
720 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
726 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
727 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
728 if (rename ( tmp
, tmp2
) == -1) {
729 edit_error_dialog (_(" Delete macro "),
730 get_sys_error (_(" Cannot overwrite macro file ")));
738 if (saved_macros_loaded
)
739 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
743 /* returns 0 on error */
744 int edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
749 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
750 s
= editcmd_dialog_raw_key_query (_(" Save macro "),
751 _(" Press the macro's new hotkey: "), 1);
752 edit
->force
|= REDRAW_COMPLETELY
;
754 if (edit_delete_macro (edit
, s
))
756 f
= edit_open_macro_file ("a+");
758 fprintf (f
, ("key '%d 0': "), s
);
759 for (i
= 0; i
< n
; i
++)
760 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
763 if (saved_macros_loaded
) {
764 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
769 edit_error_dialog (_(" Save macro "), get_sys_error (_(" Cannot open macro file ")));
775 edit_delete_macro_cmd (WEdit
* edit
)
779 command
= editcmd_dialog_raw_key_query (_ (" Delete macro "),
780 _ (" Press macro hotkey: "), 1);
783 edit_delete_macro (edit
, command
);
786 /* return 0 on error */
787 int edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
790 int s
, i
= 0, found
= 0;
794 if (saved_macros_loaded
)
795 if (macro_exists (k
) < 0)
798 if ((f
= edit_open_macro_file ("r"))) {
802 u
= fscanf (f
, ("key '%d 0': "), &s
);
805 if (!saved_macros_loaded
)
806 saved_macro
[i
++] = s
;
809 while (*n
< MAX_MACRO_LENGTH
&& 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
812 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
817 } while (!found
|| !saved_macros_loaded
);
818 if (!saved_macros_loaded
) {
820 saved_macros_loaded
= 1;
825 edit_error_dialog (_(" Load macro "),
826 get_sys_error (_(" Cannot open macro file ")));
830 /* }}} Macro stuff starts here */
832 /* returns 1 on success */
833 int edit_save_confirm_cmd (WEdit
* edit
)
837 if (!edit_check_newline (edit
))
840 if (edit_confirm_save
) {
841 f
= g_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", (char *) NULL
);
842 if (edit_query_dialog2 (_(" Save file "), f
, _("&Save"), _("&Cancel"))){
848 return edit_save_cmd (edit
);
852 /* returns 1 on success */
854 edit_save_cmd (WEdit
*edit
)
856 int res
, save_lock
= 0;
858 if (!edit
->locked
&& !edit
->delete_file
)
859 save_lock
= edit_lock_file (edit
->filename
);
860 res
= edit_save_file (edit
, edit
->filename
);
862 /* Maintain modify (not save) lock on failure */
863 if ((res
> 0 && edit
->locked
) || save_lock
)
864 edit
->locked
= edit_unlock_file (edit
->filename
);
866 /* On failure try 'save as', it does locking on its own */
868 return edit_save_as_cmd (edit
);
869 edit
->force
|= REDRAW_COMPLETELY
;
871 edit
->delete_file
= 0;
879 /* returns 1 on success */
880 int edit_new_cmd (WEdit
* edit
)
882 if (edit
->modified
) {
883 if (edit_query_dialog2 (_ ("Warning"), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("C&ontinue"), _ ("&Cancel"))) {
884 edit
->force
|= REDRAW_COMPLETELY
;
888 edit
->force
|= REDRAW_COMPLETELY
;
890 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
893 /* returns 1 on error */
895 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
897 int prev_locked
= edit
->locked
;
898 char *prev_filename
= g_strdup (edit
->filename
);
900 if (!edit_reload (edit
, exp
)) {
901 g_free (prev_filename
);
906 edit_unlock_file (prev_filename
);
907 g_free (prev_filename
);
912 edit_load_syntax_file (WEdit
* edit
)
917 if (geteuid () == 0) {
918 dir
= query_dialog (_("Syntax file edit"),
919 _(" Which syntax file you want to edit? "), D_NORMAL
, 2,
920 _("&User"), _("&System Wide"));
923 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
924 if (!exist_file(extdir
)) {
926 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
932 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
933 check_for_default (extdir
, buffer
);
934 edit_load_file_from_filename (edit
, buffer
);
937 edit_load_file_from_filename (edit
, extdir
);
943 edit_load_menu_file (WEdit
* edit
)
951 _(" Which menu file do you want to edit? "), D_NORMAL
,
952 geteuid() ? 2 : 3, _("&Local"), _("&User"), _("&System Wide")
955 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
957 if (!exist_file (menufile
)) {
959 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
964 buffer
= g_strdup (EDIT_LOCAL_MENU
);
965 check_for_default (menufile
, buffer
);
966 chmod (buffer
, 0600);
970 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
971 check_for_default (menufile
, buffer
);
975 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
976 if (!exist_file (buffer
)) {
978 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
987 edit_load_file_from_filename (edit
, buffer
);
994 edit_load_cmd (WEdit
*edit
, edit_current_file_t what
)
999 && (edit_query_dialog2
1001 _(" Current text was modified without a file save. \n"
1002 " Continue discards these changes. "),
1003 _("C&ontinue"), _("&Cancel")) == 1)) {
1004 edit
->force
|= REDRAW_COMPLETELY
;
1009 case EDIT_FILE_COMMON
:
1010 exp
= input_expand_dialog (_(" Load "), _(" Enter file name: "),
1011 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1015 edit_load_file_from_filename (edit
, exp
);
1020 case EDIT_FILE_SYNTAX
:
1021 edit_load_syntax_file (edit
);
1024 case EDIT_FILE_MENU
:
1025 edit_load_menu_file (edit
);
1032 edit
->force
|= REDRAW_COMPLETELY
;
1037 if mark2 is -1 then marking is from mark1 to the cursor.
1038 Otherwise its between the markers. This handles this.
1039 Returns 1 if no text is marked.
1041 int eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1043 if (edit
->mark1
!= edit
->mark2
) {
1044 long start_bol
, start_eol
;
1045 long end_bol
, end_eol
;
1048 if (edit
->mark2
>= 0) {
1049 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1050 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1052 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1053 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1054 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1056 if (column_highlighting
1057 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1058 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
)))) {
1060 start_bol
= edit_bol (edit
, *start_mark
);
1061 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1062 end_bol
= edit_bol (edit
, *end_mark
);
1063 end_eol
= edit_eol (edit
, *end_mark
);
1064 col1
= min (edit
->column1
, edit
->column2
);
1065 col2
= max (edit
->column1
, edit
->column2
);
1067 diff1
= edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
, col1
, 0);
1068 diff2
= edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
, col1
, 0);
1070 *start_mark
-= diff1
;
1072 *start_mark
= max (*start_mark
, start_eol
);
1073 *end_mark
= min (*end_mark
, end_eol
);
1077 *start_mark
= *end_mark
= 0;
1078 edit
->column2
= edit
->column1
= 0;
1083 #define space_width 1
1086 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1090 cursor
= edit
->curs1
;
1091 col
= edit_get_col (edit
);
1092 for (i
= 0; i
< size
; i
++) {
1093 if (data
[i
] == '\n') { /* fill in and move to next line */
1096 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1097 l
= width
- (edit_get_col (edit
) - col
);
1099 edit_insert (edit
, ' ');
1103 for (p
= edit
->curs1
;; p
++) {
1104 if (p
== edit
->last_byte
) {
1105 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1106 edit_insert_ahead (edit
, '\n');
1110 if (edit_get_byte (edit
, p
) == '\n') {
1115 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1116 l
= col
- edit_get_col (edit
);
1117 while (l
>= space_width
) {
1118 edit_insert (edit
, ' ');
1123 edit_insert (edit
, data
[i
]);
1125 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1128 #define TEMP_BUF_LEN 1024
1131 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1135 int blocklen
= -1, width
;
1136 unsigned char *data
;
1137 cursor
= edit
->curs1
;
1138 col
= edit_get_col (edit
);
1139 data
= g_malloc0 (TEMP_BUF_LEN
);
1140 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0) {
1141 for (width
= 0; width
< blocklen
; width
++) {
1142 if (data
[width
] == '\n')
1145 for (i
= 0; i
< blocklen
; i
++) {
1146 if (data
[i
] == '\n') { /* fill in and move to next line */
1149 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1150 l
= width
- (edit_get_col (edit
) - col
);
1152 edit_insert (edit
, ' ');
1156 for (p
= edit
->curs1
;; p
++) {
1157 if (p
== edit
->last_byte
) {
1158 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1159 edit_insert_ahead (edit
, '\n');
1163 if (edit_get_byte (edit
, p
) == '\n') {
1168 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1169 l
= col
- edit_get_col (edit
);
1170 while (l
>= space_width
) {
1171 edit_insert (edit
, ' ');
1176 edit_insert (edit
, data
[i
]);
1179 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1181 edit
->force
|= REDRAW_PAGE
;
1186 edit_block_copy_cmd (WEdit
*edit
)
1188 long start_mark
, end_mark
, current
= edit
->curs1
;
1190 unsigned char *copy_buf
;
1192 edit_update_curs_col (edit
);
1193 if (eval_marks (edit
, &start_mark
, &end_mark
))
1196 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1198 /* all that gets pushed are deletes hence little space is used on the stack */
1200 edit_push_markers (edit
);
1202 if (column_highlighting
) {
1203 edit_insert_column_of_text (edit
, copy_buf
, size
,
1204 abs (edit
->column2
- edit
->column1
));
1207 edit_insert_ahead (edit
, copy_buf
[size
]);
1211 edit_scroll_screen_over_cursor (edit
);
1213 if (column_highlighting
) {
1214 edit_set_markers (edit
, 0, 0, 0, 0);
1215 edit_push_action (edit
, COLUMN_ON
);
1216 column_highlighting
= 0;
1217 } else if (start_mark
< current
&& end_mark
> current
)
1218 edit_set_markers (edit
, start_mark
,
1219 end_mark
+ end_mark
- start_mark
, 0, 0);
1221 edit
->force
|= REDRAW_PAGE
;
1226 edit_block_move_cmd (WEdit
*edit
)
1230 unsigned char *copy_buf
;
1231 long start_mark
, end_mark
;
1235 if (eval_marks (edit
, &start_mark
, &end_mark
))
1237 if (column_highlighting
) {
1238 edit_update_curs_col (edit
);
1240 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1241 if ((x
> edit
->column1
&& x
< edit
->column2
)
1242 || (x
> edit
->column2
&& x
< edit
->column1
))
1244 } else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1247 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1248 if (edit_query_dialog2
1251 (" Block is large, you may not be able to undo this action. "),
1252 _("C&ontinue"), _("&Cancel")))
1255 edit_push_markers (edit
);
1256 current
= edit
->curs1
;
1257 if (column_highlighting
) {
1260 line
= edit
->curs_line
;
1261 if (edit
->mark2
< 0)
1262 edit_mark_cmd (edit
, 0);
1263 c1
= min (edit
->column1
, edit
->column2
);
1264 c2
= max (edit
->column1
, edit
->column2
);
1265 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1267 edit_block_delete_cmd (edit
);
1270 edit_move_to_line (edit
, line
);
1271 edit_cursor_move (edit
,
1272 edit_move_forward3 (edit
,
1273 edit_bol (edit
, edit
->curs1
),
1274 x
, 0) - edit
->curs1
);
1275 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1277 line
= edit
->curs_line
;
1278 edit_update_curs_col (edit
);
1280 edit_block_delete_cmd (edit
);
1281 edit_move_to_line (edit
, line
);
1282 edit_cursor_move (edit
,
1283 edit_move_forward3 (edit
,
1286 x
, 0) - edit
->curs1
);
1288 edit_set_markers (edit
, 0, 0, 0, 0);
1289 edit_push_action (edit
, COLUMN_ON
);
1290 column_highlighting
= 0;
1292 copy_buf
= g_malloc0 (end_mark
- start_mark
);
1293 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1294 edit_scroll_screen_over_cursor (edit
);
1296 while (count
< end_mark
) {
1297 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1300 edit_scroll_screen_over_cursor (edit
);
1301 edit_cursor_move (edit
,
1302 current
- edit
->curs1
-
1303 (((current
- edit
->curs1
) >
1304 0) ? end_mark
- start_mark
: 0));
1305 edit_scroll_screen_over_cursor (edit
);
1306 while (count
-- > start_mark
)
1307 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1308 edit_set_markers (edit
, edit
->curs1
,
1309 edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1311 edit_scroll_screen_over_cursor (edit
);
1313 edit
->force
|= REDRAW_PAGE
;
1317 edit_delete_column_of_text (WEdit
* edit
)
1319 long p
, q
, r
, m1
, m2
;
1322 eval_marks (edit
, &m1
, &m2
);
1323 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1324 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1325 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1326 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
1327 c
= max (c
, max (edit
->column1
, edit
->column2
));
1330 r
= edit_bol (edit
, edit
->curs1
);
1331 p
= edit_move_forward3 (edit
, r
, b
, 0);
1332 q
= edit_move_forward3 (edit
, r
, c
, 0);
1337 edit_cursor_move (edit
, p
- edit
->curs1
);
1339 /* delete line between margins */
1340 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1341 edit_delete (edit
, 1);
1345 /* move to next line except on the last delete */
1346 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1350 /* if success return 0 */
1352 edit_block_delete (WEdit
*edit
)
1355 long start_mark
, end_mark
;
1356 int curs_pos
, line_width
;
1357 long curs_line
, c1
, c2
;
1359 if (eval_marks (edit
, &start_mark
, &end_mark
))
1361 if (column_highlighting
&& edit
->mark2
< 0)
1362 edit_mark_cmd (edit
, 0);
1363 if ((end_mark
- start_mark
) > option_max_undo
/ 2) {
1364 /* Warning message with a query to continue or cancel the operation */
1365 if (edit_query_dialog2
1368 (" Block is large, you may not be able to undo this action. "),
1369 _("C&ontinue"), _("&Cancel"))) {
1373 c1
= min (edit
->column1
, edit
->column2
);
1374 c2
= max (edit
->column1
, edit
->column2
);
1378 edit_push_markers (edit
);
1380 curs_line
= edit
->curs_line
;
1382 /* calculate line width and cursor position before cut */
1383 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1384 edit_eol (edit
, edit
->curs1
));
1385 curs_pos
= edit
->curs_col
+ edit
->over_col
;
1387 /* move cursor to start of selection */
1388 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1389 edit_scroll_screen_over_cursor (edit
);
1391 if (start_mark
< end_mark
) {
1392 if (column_highlighting
) {
1393 if (edit
->mark2
< 0)
1394 edit_mark_cmd (edit
, 0);
1395 edit_delete_column_of_text (edit
);
1396 /* move cursor to the saved position */
1397 edit_move_to_line (edit
, curs_line
);
1398 /* calculate line width after cut */
1399 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1400 edit_eol (edit
, edit
->curs1
));
1401 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
1402 edit
->over_col
= curs_pos
- line_width
;
1404 while (count
< end_mark
) {
1405 edit_delete (edit
, 1);
1410 edit_set_markers (edit
, 0, 0, 0, 0);
1411 edit
->force
|= REDRAW_PAGE
;
1415 /* returns 1 if canceelled by user */
1416 int edit_block_delete_cmd (WEdit
* edit
)
1418 long start_mark
, end_mark
;
1419 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
1420 edit_delete_line (edit
);
1423 return edit_block_delete (edit
);
1426 #define INPUT_INDEX 9
1429 editcmd_find (WEdit
*edit
, gsize
*len
)
1431 off_t search_start
= edit
->search_start
;
1433 long start_mark
= 0;
1434 long end_mark
= edit
->last_byte
;
1437 if (edit
->only_in_selection
) {
1438 mark_res
= eval_marks(edit
, &start_mark
, &end_mark
);
1439 if (mark_res
!= 0) {
1440 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1441 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1444 if (edit
->replace_backwards
) {
1445 if (search_start
> end_mark
|| search_start
<= start_mark
) {
1446 search_start
= end_mark
;
1449 if (search_start
< start_mark
|| search_start
>= end_mark
) {
1450 search_start
= start_mark
;
1454 if (edit
->replace_backwards
)
1455 end_mark
= max(1, edit
->curs1
) - 1;
1457 if (edit
->replace_backwards
) {
1458 search_end
= end_mark
;
1459 while ((int) search_start
>= start_mark
) {
1460 if (search_end
> search_start
+ edit
->search
->original_len
1461 && mc_search_is_fixed_search_str(edit
->search
)) {
1462 search_end
= search_start
+ edit
->search
->original_len
;
1464 if (mc_search_run(edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1465 && edit
->search
->normal_offset
== search_start
) {
1470 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1472 return mc_search_run(edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1478 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1479 (and the above) routines to work properly - paul */
1481 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1484 edit_replace_cmd__conv_to_display (char *str
)
1488 tmp
= str_convert_to_display (str
);
1490 if (tmp
&& tmp
->len
){
1491 return g_string_free (tmp
, FALSE
);
1493 g_string_free (tmp
, TRUE
);
1495 return g_strdup(str
);
1499 edit_replace_cmd__conv_to_input(char *str
)
1503 tmp
= str_convert_to_input (str
);
1505 if (tmp
&& tmp
->len
){
1506 return g_string_free (tmp
, FALSE
);
1508 g_string_free (tmp
, TRUE
);
1509 return g_strdup(str
);
1511 return g_strdup(str
);
1513 /* call with edit = 0 before shutdown to close memory leaks */
1515 edit_replace_cmd (WEdit
*edit
, int again
)
1517 /* 1 = search string, 2 = replace with */
1518 static char *saved1
= NULL
; /* saved default[123] */
1519 static char *saved2
= NULL
;
1520 char *input1
= NULL
; /* user input from the dialog */
1521 char *input2
= NULL
;
1523 long times_replaced
= 0, last_search
;
1524 gboolean once_found
= FALSE
;
1527 g_free (saved1
), saved1
= NULL
;
1528 g_free (saved2
), saved2
= NULL
;
1532 last_search
= edit
->last_byte
;
1534 edit
->force
|= REDRAW_COMPLETELY
;
1536 if (again
&& !saved1
&& !saved2
)
1540 input1
= g_strdup (saved1
? saved1
: "");
1541 input2
= g_strdup (saved2
? saved2
: "");
1543 char *disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1544 char *disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
1545 char *tmp_inp1
, *tmp_inp2
;
1547 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1549 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1554 if (input1
== NULL
|| *input1
== '\0') {
1555 edit
->force
= REDRAW_COMPLETELY
;
1559 tmp_inp1
= input1
; tmp_inp2
= input2
;
1560 input1
= edit_replace_cmd__conv_to_input(input1
);
1561 input2
= edit_replace_cmd__conv_to_input(input2
);
1562 g_free(tmp_inp1
); g_free(tmp_inp2
);
1564 g_free (saved1
), saved1
= g_strdup (input1
);
1565 g_free (saved2
), saved2
= g_strdup (input2
);
1568 mc_search_free(edit
->search
);
1569 edit
->search
= NULL
;
1573 if (!edit
->search
) {
1574 edit
->search
= mc_search_new(input1
, -1);
1575 if (edit
->search
== NULL
) {
1576 edit
->search_start
= edit
->curs1
;
1579 edit
->search
->search_type
= edit
->search_type
;
1580 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1581 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1582 edit
->search
->whole_words
= edit
->whole_words
;
1583 edit
->search
->search_fn
= edit_search_cmd_callback
;
1586 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1587 && edit
->replace_backwards
)
1588 edit
->search_start
--;
1590 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1591 && !edit
->replace_backwards
)
1592 edit
->search_start
++;
1598 if (! editcmd_find(edit
, &len
)) {
1599 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1600 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
))) {
1601 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1606 new_start
= edit
->search
->normal_offset
;
1608 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1609 /*returns negative on not found or error in pattern */
1611 if (edit
->search_start
>= 0) {
1614 edit
->found_start
= edit
->search_start
;
1615 i
= edit
->found_len
= len
;
1617 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1618 edit_scroll_screen_over_cursor (edit
);
1622 if (edit
->replace_mode
== 0) {
1624 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1626 edit_scroll_downward (edit
, l
);
1628 edit_scroll_upward (edit
, -l
);
1630 edit_scroll_screen_over_cursor (edit
);
1631 edit
->force
|= REDRAW_PAGE
;
1632 edit_render_keypress (edit
);
1634 /*so that undo stops at each query */
1635 edit_push_key_press (edit
);
1636 /* and prompt 2/3 down */
1637 switch (editcmd_dialog_replace_prompt_show (edit
, input1
, input2
, -1, -1)) {
1641 case B_SKIP_REPLACE
:
1645 edit
->replace_mode
=1;
1649 edit
->replace_mode
= -1;
1653 if (replace_yes
) { /* delete then insert new */
1654 GString
*repl_str
, *tmp_str
;
1655 tmp_str
= g_string_new(input2
);
1657 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1658 g_string_free(tmp_str
, TRUE
);
1659 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1661 edit_error_dialog (_ ("Replace"), edit
->search
->error_str
);
1666 edit_delete (edit
, 1);
1668 while (++i
< repl_str
->len
)
1669 edit_insert (edit
, repl_str
->str
[i
]);
1671 g_string_free(repl_str
, TRUE
);
1672 edit
->found_len
= i
;
1674 /* so that we don't find the same string again */
1675 if (edit
->replace_backwards
) {
1676 last_search
= edit
->search_start
;
1677 edit
->search_start
--;
1679 edit
->search_start
+= i
;
1680 last_search
= edit
->last_byte
;
1682 edit_scroll_screen_over_cursor (edit
);
1684 const char *msg
= _(" Replace ");
1685 /* try and find from right here for next search */
1686 edit
->search_start
= edit
->curs1
;
1687 edit_update_curs_col (edit
);
1689 edit
->force
|= REDRAW_PAGE
;
1690 edit_render_keypress (edit
);
1691 if (times_replaced
) {
1692 message (D_NORMAL
, msg
, _(" %ld replacements made. "),
1695 query_dialog (msg
, _(" Search string not found "),
1696 D_NORMAL
, 1, _("&OK"));
1697 edit
->replace_mode
= -1;
1699 } while (edit
->replace_mode
>= 0);
1701 edit
->force
= REDRAW_COMPLETELY
;
1702 edit_scroll_screen_over_cursor (edit
);
1709 void edit_search_cmd (WEdit
* edit
, int again
)
1711 char *search_string
= NULL
, *search_string_dup
= NULL
;
1718 if (edit
->search
!= NULL
) {
1719 search_string
= g_strndup(edit
->search
->original
, edit
->search
->original_len
);
1720 search_string_dup
= search_string
;
1723 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1724 if (history
!= NULL
&& history
->data
!= NULL
) {
1725 search_string_dup
= search_string
= (char *) g_strdup(history
->data
);
1726 history
= g_list_first (history
);
1727 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1728 g_list_free (history
);
1730 edit
->search_start
= edit
->curs1
;
1736 if (search_string
&& *search_string
) {
1737 tmp
= str_convert_to_display (search_string
);
1739 g_free(search_string_dup
);
1740 search_string_dup
= NULL
;
1742 if (tmp
&& tmp
->len
)
1743 search_string
= search_string_dup
= tmp
->str
;
1744 g_string_free (tmp
, FALSE
);
1746 #endif /* HAVE_CHARSET */
1747 editcmd_dialog_search_show (edit
, &search_string
);
1749 if (search_string
&& *search_string
) {
1750 tmp
= str_convert_to_input (search_string
);
1751 if (tmp
&& tmp
->len
)
1752 search_string
= tmp
->str
;
1754 g_string_free (tmp
, FALSE
);
1756 if (search_string_dup
)
1757 g_free(search_string_dup
);
1759 #endif /* HAVE_CHARSET */
1761 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1763 if (!search_string
) {
1764 edit
->force
|= REDRAW_COMPLETELY
;
1765 edit_scroll_screen_over_cursor (edit
);
1770 mc_search_free(edit
->search
);
1771 edit
->search
= NULL
;
1775 if (!edit
->search
) {
1776 edit
->search
= mc_search_new(search_string
, -1);
1777 if (edit
->search
== NULL
) {
1778 edit
->search_start
= edit
->curs1
;
1781 edit
->search
->search_type
= edit
->search_type
;
1782 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1783 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1784 edit
->search
->whole_words
= edit
->whole_words
;
1785 edit
->search
->search_fn
= edit_search_cmd_callback
;
1788 if (search_create_bookmark
) {
1789 edit_search_cmd_search_create_bookmark(edit
);
1791 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1 && edit
->replace_backwards
)
1792 edit
->search_start
--;
1794 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1 && !edit
->replace_backwards
)
1795 edit
->search_start
++;
1798 if (editcmd_find(edit
, &len
)) {
1799 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1800 edit
->found_len
= len
;
1802 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1803 edit_scroll_screen_over_cursor (edit
);
1804 if (edit
->replace_backwards
)
1805 edit
->search_start
--;
1807 edit
->search_start
++;
1809 edit
->search_start
= edit
->curs1
;
1810 if (edit
->search
->error_str
)
1811 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1815 edit
->force
|= REDRAW_COMPLETELY
;
1816 edit_scroll_screen_over_cursor (edit
);
1821 * Check if it's OK to close the editor. If there are unsaved changes,
1822 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
1825 edit_ok_to_exit (WEdit
*edit
)
1827 if (!edit
->modified
)
1830 if (!edit_check_newline (edit
))
1833 switch (edit_query_dialog3
1834 (_("Quit"), _(" File was modified, Save with exit? "),
1835 _("&Cancel quit"), _("&Yes"), _("&No"))) {
1837 edit_push_markers (edit
);
1838 edit_set_markers (edit
, 0, 0, 0, 0);
1839 if (!edit_save_cmd (edit
))
1852 /* Return a null terminated length of text. Result must be g_free'd */
1853 static unsigned char *
1854 edit_get_block (WEdit
*edit
, long start
, long finish
, int *l
)
1856 unsigned char *s
, *r
;
1857 r
= s
= g_malloc0 (finish
- start
+ 1);
1858 if (column_highlighting
) {
1860 /* copy from buffer, excluding chars that are out of the column 'margins' */
1861 while (start
< finish
) {
1864 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0,
1866 c
= edit_get_byte (edit
, start
);
1867 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1868 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n') {
1875 *l
= finish
- start
;
1876 while (start
< finish
)
1877 *s
++ = edit_get_byte (edit
, start
++);
1883 /* save block, returns 1 on success */
1885 edit_save_block (WEdit
* edit
, const char *filename
, long start
,
1891 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1892 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
1895 if (column_highlighting
) {
1897 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof(VERTICAL_MAGIC
));
1899 unsigned char *block
, *p
;
1900 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
1902 r
= mc_write (file
, p
, len
);
1913 len
= finish
- start
;
1914 buf
= g_malloc0 (TEMP_BUF_LEN
);
1915 while (start
!= finish
) {
1916 end
= min (finish
, start
+ TEMP_BUF_LEN
);
1917 for (; i
< end
; i
++)
1918 buf
[i
- start
] = edit_get_byte (edit
, i
);
1919 len
-= mc_write (file
, (char *) buf
, end
- start
);
1930 /* copies a block to clipboard file */
1931 static int edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1935 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1936 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1942 void edit_paste_from_history (WEdit
*edit
)
1945 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
1948 int edit_copy_to_X_buf_cmd (WEdit
* edit
)
1950 long start_mark
, end_mark
;
1951 if (eval_marks (edit
, &start_mark
, &end_mark
))
1953 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1954 edit_error_dialog (_(" Copy to clipboard "), get_sys_error (_(" Unable to save to file. ")));
1957 edit_mark_cmd (edit
, 1);
1961 int edit_cut_to_X_buf_cmd (WEdit
* edit
)
1963 long start_mark
, end_mark
;
1964 if (eval_marks (edit
, &start_mark
, &end_mark
))
1966 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1967 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
1970 edit_block_delete_cmd (edit
);
1971 edit_mark_cmd (edit
, 1);
1975 void edit_paste_from_X_buf_cmd (WEdit
* edit
)
1978 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1979 edit_insert_file (edit
, tmp
);
1985 * Ask user for the line and go to that line.
1986 * Negative numbers mean line from the end (i.e. -1 is the last line).
1989 edit_goto_cmd (WEdit
*edit
)
1992 static long line
= 0; /* line as typed, saved as default */
1997 g_snprintf (s
, sizeof (s
), "%ld", line
);
1998 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2008 l
= strtol (f
, &error
, 0);
2016 l
= edit
->total_lines
+ l
+ 2;
2017 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2018 edit_move_to_line (edit
, l
- 1);
2019 edit
->force
|= REDRAW_COMPLETELY
;
2024 /* Return 1 on success */
2026 edit_save_block_cmd (WEdit
*edit
)
2028 long start_mark
, end_mark
;
2031 if (eval_marks (edit
, &start_mark
, &end_mark
))
2034 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2036 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2037 MC_HISTORY_EDIT_SAVE_BLOCK
,
2040 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2046 if (edit_save_block (edit
, exp
, start_mark
, end_mark
)) {
2048 edit
->force
|= REDRAW_COMPLETELY
;
2052 edit_error_dialog (_(" Save Block "),
2054 (" Cannot save file. ")));
2058 edit
->force
|= REDRAW_COMPLETELY
;
2063 /* returns 1 on success */
2065 edit_insert_file_cmd (WEdit
*edit
)
2070 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2071 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2072 MC_HISTORY_EDIT_INSERT_FILE
,
2075 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2081 if (edit_insert_file (edit
, exp
)) {
2083 edit
->force
|= REDRAW_COMPLETELY
;
2087 edit_error_dialog (_(" Insert File "),
2089 (" Cannot insert file. ")));
2093 edit
->force
|= REDRAW_COMPLETELY
;
2097 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2098 int edit_sort_cmd (WEdit
* edit
)
2100 static char *old
= 0;
2102 long start_mark
, end_mark
;
2105 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2106 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2110 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2111 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2114 exp
= input_dialog (_(" Run Sort "),
2115 _(" Enter sort options (see manpage) separated by whitespace: "),
2116 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2122 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2123 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2127 if (e
== -1 || e
== 127) {
2128 edit_error_dialog (_(" Sort "),
2129 get_sys_error (_(" Cannot execute sort command ")));
2132 sprintf (q
, "%d ", e
);
2133 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2134 edit_error_dialog (_(" Sort "), tmp
);
2140 edit
->force
|= REDRAW_COMPLETELY
;
2142 if (edit_block_delete_cmd (edit
))
2144 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2145 edit_insert_file (edit
, tmp
);
2151 * Ask user for a command, execute it and paste its output back to the
2155 edit_ext_cmd (WEdit
*edit
)
2161 input_dialog (_("Paste output of external command"),
2162 _("Enter shell command(s):"),
2163 MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2168 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2174 edit_error_dialog (_("External command"),
2175 get_sys_error (_("Cannot execute command")));
2179 edit
->force
|= REDRAW_COMPLETELY
;
2180 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2181 edit_insert_file (edit
, tmp
);
2186 /* if block is 1, a block must be highlighted and the shell command
2187 processes it. If block is 0 the shell command is a straight system
2188 command, that just produces some output which is to be inserted */
2190 edit_block_process_cmd (WEdit
*edit
, const char *shell_cmd
, int block
)
2192 long start_mark
, end_mark
;
2194 FILE *script_home
= NULL
;
2195 FILE *block_file
= NULL
;
2196 gchar
*o
, *h
, *b
, *tmp
;
2197 char *quoted_name
= NULL
;
2199 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2200 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2201 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2203 script_home
= fopen (h
, "r");
2204 if (script_home
== NULL
) {
2205 FILE *script_src
= NULL
;
2207 script_home
= fopen (h
, "w");
2208 if (script_home
== NULL
) {
2209 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2210 edit_error_dialog ("", get_sys_error (tmp
));
2212 goto edit_block_process_cmd__EXIT
;
2215 script_src
= fopen (o
, "r");
2216 if (script_src
== NULL
) {
2217 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2218 script_src
= fopen (o
, "r");
2219 if (script_src
== NULL
) {
2220 fclose (script_home
);
2222 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2223 edit_error_dialog ("", get_sys_error (tmp
));
2225 goto edit_block_process_cmd__EXIT
;
2228 while (fgets (buf
, sizeof (buf
), script_src
))
2229 fputs (buf
, script_home
);
2230 fclose (script_src
);
2232 if (fclose (script_home
)) {
2233 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2234 edit_error_dialog ("", get_sys_error (tmp
));
2236 goto edit_block_process_cmd__EXIT
;
2239 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2240 edit_error_dialog ("", get_sys_error (tmp
));
2246 if (block
) { /* for marked block run indent formatter */
2247 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2248 edit_error_dialog (_("Process block"),
2250 (" You must first highlight a block of text. "));
2251 goto edit_block_process_cmd__EXIT
;
2253 edit_save_block (edit
, b
, start_mark
, end_mark
);
2254 quoted_name
= name_quote (edit
->filename
, 0);
2257 * Initial space is to avoid polluting bash history.
2259 * $1 - name of the edited file (to check its extension etc).
2260 * $2 - file containing the current block.
2261 * $3 - file where error messages should be put
2262 * (for compatibility with old scripts).
2264 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2265 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2270 * No block selected, just execute the command for the file.
2272 * $1 - name of the edited file.
2274 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2275 quoted_name
, (char *) NULL
);
2279 g_free (quoted_name
);
2280 close_error_pipe (D_NORMAL
, NULL
);
2282 edit_refresh_cmd (edit
);
2283 edit
->force
|= REDRAW_COMPLETELY
;
2285 /* insert result block */
2286 if (block
&& !edit_block_delete_cmd (edit
)) {
2287 edit_insert_file (edit
, b
);
2288 block_file
= fopen (b
, "w");
2289 if (block_file
!= NULL
)
2290 fclose (block_file
);
2293 edit_block_process_cmd__EXIT
:
2299 /* prints at the cursor */
2300 /* returns the number of chars printed */
2301 int edit_print_string (WEdit
* e
, const char *s
)
2304 while (s
[i
] != '\0')
2305 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2306 e
->force
|= REDRAW_COMPLETELY
;
2307 edit_update_screen (e
);
2312 static void pipe_mail (WEdit
*edit
, char *to
, char *subject
, char *cc
)
2317 to
= name_quote (to
, 0);
2318 subject
= name_quote (subject
, 0);
2319 cc
= name_quote (cc
, 0);
2320 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "" , cc
, " ", to
, (char *) NULL
);
2332 for (i
= 0; i
< edit
->last_byte
; i
++)
2333 fputc (edit_get_byte (edit
, i
), p
);
2338 #define MAIL_DLG_HEIGHT 12
2340 void edit_mail_dialog (WEdit
* edit
)
2343 char *tmail_subject
;
2346 static char *mail_cc_last
= 0;
2347 static char *mail_subject_last
= 0;
2348 static char *mail_to_last
= 0;
2350 QuickWidget quick_widgets
[] =
2352 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2353 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2354 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2355 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2356 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2", &tmail_subject
),
2357 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2358 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2359 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2360 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2364 QuickDialog Quick_input
=
2366 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2367 "[Input Line Keys]", quick_widgets
, FALSE
2370 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2371 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2372 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2374 if (quick_dialog (&Quick_input
) != B_CANCEL
) {
2375 g_free (mail_cc_last
);
2376 g_free (mail_subject_last
);
2377 g_free (mail_to_last
);
2378 mail_cc_last
= tmail_cc
;
2379 mail_subject_last
= tmail_subject
;
2380 mail_to_last
= tmail_to
;
2381 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2386 /*******************/
2387 /* Word Completion */
2388 /*******************/
2390 static gboolean
is_break_char(char c
)
2392 return (isspace(c
) || strchr("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2395 /* find first character of current word */
2396 static int edit_find_word_start (WEdit
*edit
, long *word_start
, gsize
*word_len
)
2401 /* return if at begin of file */
2402 if (edit
->curs1
<= 0)
2405 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2406 /* return if not at end or in word */
2407 if (is_break_char(c
))
2410 /* search start of word to be completed */
2412 /* return if at begin of file */
2413 if (edit
->curs1
- i
< 0)
2417 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2419 if (is_break_char(c
)) {
2420 /* return if word starts with digit */
2424 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2433 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2435 /* collect the possible completions */
2437 edit_collect_completions (WEdit
*edit
, long start
, gsize word_len
,
2438 char *match_expr
, struct selection
*compl,
2450 srch
= mc_search_new(match_expr
, -1);
2454 if (mc_config_get_bool(mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0)){
2455 last_byte
= edit
->last_byte
;
2460 srch
->search_type
= MC_SEARCH_T_REGEX
;
2461 srch
->is_case_sentitive
= TRUE
;
2462 srch
->search_fn
= edit_search_cmd_callback
;
2464 /* collect max MAX_WORD_COMPLETIONS completions */
2467 /* get next match */
2468 if (mc_search_run (srch
, (void *) edit
, start
+1, last_byte
, &len
) == FALSE
)
2470 start
= srch
->normal_offset
;
2472 /* add matched completion if not yet added */
2473 temp
= g_string_new("");
2474 for (i
= 0; i
< len
; i
++){
2475 skip
= edit_get_byte(edit
, start
+i
);
2478 g_string_append_c (temp
, skip
);
2483 for (i
= 0; i
< (gsize
) *num
; i
++) {
2486 (char *) &compl[i
].text
[word_len
],
2487 (char *) &temp
->str
[word_len
],
2488 max (len
, compl[i
].len
) - (gsize
)word_len
2490 struct selection
this = compl[i
];
2491 for (++i
; i
< *num
; i
++) {
2492 compl[i
- 1] = compl[i
];
2494 compl[*num
- 1] = this;
2496 break; /* skip it, already added */
2500 g_string_free(temp
, TRUE
);
2503 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
) {
2504 g_free(compl[0].text
);
2505 for (i
= 1; i
< *num
; i
++) {
2506 compl[i
- 1] = compl[i
];
2513 recoded
= str_convert_to_display (temp
->str
);
2515 if (recoded
&& recoded
->len
){
2516 g_string_free(temp
,TRUE
);
2519 g_string_free(recoded
, TRUE
);
2522 compl[*num
].text
= temp
->str
;
2523 compl[*num
].len
= temp
->len
;
2526 g_string_free(temp
, FALSE
);
2528 /* note the maximal length needed for the completion dialog */
2532 mc_search_free(srch
);
2537 * Complete current word using regular expression search
2538 * backwards beginning at the current cursor position.
2541 edit_complete_word_cmd (WEdit
*edit
)
2543 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2544 long word_start
= 0;
2545 unsigned char *bufpos
;
2547 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2549 /* search start of word to be completed */
2550 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2553 /* prepare match expression */
2554 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2555 [word_start
& M_EDIT_BUF_SIZE
];
2557 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2558 match_expr
= g_strdup_printf ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+", (int)word_len
, bufpos
);
2560 /* collect the possible completions */
2561 /* start search from begin to end of file */
2563 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2564 (struct selection
*) &compl, &num_compl
);
2566 if (num_compl
> 0) {
2567 /* insert completed word if there is only one match */
2568 if (num_compl
== 1) {
2569 for (i
= word_len
; i
< compl[0].len
; i
++)
2570 edit_insert (edit
, *(compl[0].text
+ i
));
2572 /* more than one possible completion => ask the user */
2574 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2575 /* !!! pressed again the selection dialog pops up, but that !!! */
2576 /* !!! seems to require a further internal state !!! */
2579 /* let the user select the preferred completion */
2580 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2581 (struct selection
*) &compl,
2586 g_free (match_expr
);
2587 /* release memory before return */
2588 for (i
= 0; i
< num_compl
; i
++)
2589 g_free (compl[i
].text
);
2593 edit_select_codepage_cmd (WEdit
*edit
)
2596 const char *cp_id
= NULL
;
2597 if (do_select_codepage ()) {
2598 cp_id
= get_codepage_id (source_codepage
>= 0 ?
2599 source_codepage
: display_codepage
);
2601 if (cp_id
!= NULL
) {
2603 conv
= str_crt_conv_from (cp_id
);
2604 if (conv
!= INVALID_CONV
) {
2605 if (edit
->converter
!= str_cnv_from_term
)
2606 str_close_conv (edit
->converter
);
2607 edit
->converter
= conv
;
2612 edit
->utf8
= str_isutf8 (cp_id
);
2615 edit
->force
= REDRAW_COMPLETELY
;
2616 edit_refresh_cmd (edit
);
2623 edit_insert_literal_cmd (WEdit
*edit
)
2625 int char_for_insertion
=
2626 editcmd_dialog_raw_key_query (_(" Insert Literal "),
2627 _(" Press any key: "), 0);
2628 edit_execute_key_command (edit
, -1,
2629 ascii_alpha_to_cntrl (char_for_insertion
));
2633 edit_execute_macro_cmd (WEdit
*edit
)
2636 CK_Macro (editcmd_dialog_raw_key_query
2637 (_(" Execute Macro "), _(" Press macro hotkey: "),
2639 if (command
== CK_Macro (0))
2640 command
= CK_Insert_Char
;
2642 edit_execute_key_command (edit
, command
, -1);
2646 edit_begin_end_macro_cmd (WEdit
*edit
)
2648 /* edit is a pointer to the widget */
2650 unsigned long command
= edit
->macro_i
< 0
2651 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2652 edit_execute_key_command (edit
, command
, -1);
2657 edit_load_forward_cmd (WEdit
*edit
)
2659 if (edit
->modified
) {
2660 if (edit_query_dialog2
2662 _(" Current text was modified without a file save. \n"
2663 " Continue discards these changes. "), _("C&ontinue"),
2665 edit
->force
|= REDRAW_COMPLETELY
;
2669 if ( edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
) {
2670 if ( edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1 ) {
2673 edit_stack_iterator
++;
2674 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2675 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2676 edit_history_moveto
[edit_stack_iterator
].line
);
2687 edit_load_back_cmd (WEdit
*edit
)
2689 if (edit
->modified
) {
2690 if (edit_query_dialog2
2692 _(" Current text was modified without a file save. \n"
2693 " Continue discards these changes. "), _("C&ontinue"),
2695 edit
->force
|= REDRAW_COMPLETELY
;
2699 if ( edit_stack_iterator
> 0 ) {
2700 edit_stack_iterator
--;
2701 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2702 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2703 edit_history_moveto
[edit_stack_iterator
].line
);
2714 edit_get_match_keyword_cmd (WEdit
*edit
)
2716 gsize word_len
= 0, max_len
= 0;
2719 long word_start
= 0;
2720 unsigned char *bufpos
;
2724 char *tagfile
= NULL
;
2726 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2728 for ( i
= 0; i
< MAX_DEFINITIONS
; i
++) {
2729 def_hash
[i
].filename
= NULL
;
2732 /* search start of word to be completed */
2733 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2736 /* prepare match expression */
2737 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2738 [word_start
& M_EDIT_BUF_SIZE
];
2739 match_expr
= g_strdup_printf ("%.*s", (int)word_len
, bufpos
);
2741 ptr
= g_get_current_dir ();
2742 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
2745 /* Recursive search file 'TAGS' in parent dirs */
2747 ptr
= g_path_get_dirname (path
);
2748 g_free(path
); path
= ptr
;
2750 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
2751 if ( exist_file (tagfile
) )
2753 } while (strcmp( path
, G_DIR_SEPARATOR_S
) != 0);
2756 num_def
= etags_set_definition_hash(tagfile
, path
, match_expr
, (etags_hash_t
*) &def_hash
);
2761 max_len
= MAX_WIDTH_DEF_DIALOG
;
2763 if ( num_def
> 0 ) {
2764 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
2765 (etags_hash_t
*) &def_hash
,
2768 g_free (match_expr
);
2772 edit_move_block_to_right (WEdit
* edit
)
2774 long start_mark
, end_mark
;
2775 long cur_bol
, start_bol
;
2777 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2780 start_bol
= edit_bol (edit
, start_mark
);
2781 cur_bol
= edit_bol (edit
, end_mark
- 1);
2783 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2784 if ( option_fill_tabs_with_spaces
) {
2785 if ( option_fake_half_tabs
) {
2786 insert_spaces_tab (edit
, 1);
2788 insert_spaces_tab (edit
, 0);
2791 edit_insert (edit
, '\t');
2793 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
2794 if ( cur_bol
== 0 ) {
2797 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2798 } while (cur_bol
>= start_bol
) ;
2799 edit
->force
|= REDRAW_PAGE
;
2803 edit_move_block_to_left (WEdit
* edit
)
2805 long start_mark
, end_mark
;
2806 long cur_bol
, start_bol
;
2807 int i
, del_tab_width
;
2810 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2813 start_bol
= edit_bol (edit
, start_mark
);
2814 cur_bol
= edit_bol (edit
, end_mark
- 1);
2816 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2817 if (option_fake_half_tabs
) {
2818 del_tab_width
= HALF_TAB_SIZE
;
2820 del_tab_width
= option_tab_spacing
;
2822 next_char
= edit_get_byte (edit
, edit
->curs1
);
2823 if ( next_char
== '\t' ) {
2824 edit_delete (edit
, 1);
2825 } else if ( next_char
== ' ' ) {
2826 for (i
= 1; i
<= del_tab_width
; i
++) {
2827 if ( next_char
== ' ' ) {
2828 edit_delete (edit
, 1);
2830 next_char
= edit_get_byte (edit
, edit
->curs1
);
2833 if ( cur_bol
== 0 ) {
2836 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2837 } while (cur_bol
>= start_bol
) ;
2838 edit
->force
|= REDRAW_PAGE
;