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
);
145 #endif /* !HAVE_SLANG */
149 /* If 0 (quick save) then a) create/truncate <filename> file,
150 b) save to <filename>;
151 if 1 (safe save) then a) save to <tempnam>,
152 b) rename <tempnam> to <filename>;
153 if 2 (do backups) then a) save to <tempnam>,
154 b) rename <filename> to <filename.backup_ext>,
155 c) rename <tempnam> to <filename>. */
157 /* returns 0 on error, -1 on abort */
159 edit_save_file (WEdit
*edit
, const char *filename
)
165 gchar
*real_filename
;
166 int this_save_mode
, fd
= -1;
173 if (*filename
!= PATH_SEP
&& edit
->dir
) {
174 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
176 real_filename
= g_strdup(filename
);
179 this_save_mode
= option_save_mode
;
180 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
181 if (!vfs_file_is_local (real_filename
) ||
182 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1) {
184 * The file does not exists yet, so no safe save or
185 * backup are necessary.
187 this_save_mode
= EDIT_QUICK_SAVE
;
193 if (this_save_mode
== EDIT_QUICK_SAVE
&&
194 !edit
->skip_detach_prompt
) {
198 rv
= mc_stat (real_filename
, &sb
);
199 if (rv
== 0 && sb
.st_nlink
> 1) {
200 rv
= edit_query_dialog3 (_("Warning"),
201 _(" File has hard-links. Detach before saving? "),
202 _("&Yes"), _("&No"), _("&Cancel"));
205 this_save_mode
= EDIT_SAFE_SAVE
;
208 edit
->skip_detach_prompt
= 1;
211 g_free(real_filename
);
216 /* Prevent overwriting changes from other editor sessions. */
217 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
) {
219 /* The default action is "Cancel". */
222 rv
= edit_query_dialog2 (
224 _("The file has been modified in the meantime. Save anyway?"),
228 g_free(real_filename
);
234 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
235 char *savedir
, *saveprefix
;
236 const char *slashpos
;
237 slashpos
= strrchr (real_filename
, PATH_SEP
);
239 savedir
= g_strdup (real_filename
);
240 savedir
[slashpos
- real_filename
+ 1] = '\0';
242 savedir
= g_strdup (".");
243 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
245 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
248 g_free(real_filename
);
252 * Close for now because mc_mkstemps use pure open system call
253 * to create temporary file and it needs to be reopened by
254 * VFS-aware mc_open().
258 savename
= g_strdup (real_filename
);
260 mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
261 mc_chmod (savename
, edit
->stat1
.st_mode
);
264 mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
,
265 edit
->stat1
.st_mode
)) == -1)
269 if ((p
= edit_get_write_filter (savename
, real_filename
))) {
273 file
= (FILE *) popen (p
, "w");
276 filelen
= edit_write_stream (edit
, file
);
280 if (pclose (file
) != 0) {
281 tmp
= g_strconcat (_(" Error writing to pipe: "),
282 p
, " ", (char *) NULL
);
283 edit_error_dialog (_("Error"), tmp
);
290 tmp
= g_strconcat (_(" Cannot open pipe for writing: "),
291 p
, " ", (char *) NULL
);
293 edit_error_dialog (_("Error"),
294 get_sys_error (tmp
));
300 } else if (edit
->lb
== LB_ASIS
) { /* do not change line breaks */
303 filelen
= edit
->last_byte
;
304 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1) {
305 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
)
313 (fd
, (char *) edit
->buffers1
[buf
],
314 edit
->curs1
& M_EDIT_BUF_SIZE
) !=
315 (edit
->curs1
& M_EDIT_BUF_SIZE
)) {
317 } else if (edit
->curs2
) {
319 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
322 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
323 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
324 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) !=
325 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) {
330 (fd
, (char *) edit
->buffers2
[buf
],
331 EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
) {
342 /* Update the file information, especially the mtime. */
343 if (mc_stat (savename
, &edit
->stat1
) == -1)
345 } else { /* change line breaks */
350 file
= (FILE *) fopen (savename
, "w");
353 filelen
= edit_write_stream (edit
, file
);
358 msg
= g_strdup_printf (_(" Cannot open file for writing: %s "), savename
);
359 edit_error_dialog (_("Error"), msg
);
365 if (filelen
!= edit
->last_byte
)
368 if (this_save_mode
== EDIT_DO_BACKUP
) {
369 assert (option_backup_ext
!= NULL
);
370 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
371 if (mc_rename (real_filename
, tmp
) == -1){
377 if (this_save_mode
!= EDIT_QUICK_SAVE
)
378 if (mc_rename (savename
, real_filename
) == -1)
381 g_free(real_filename
);
384 /* FIXME: Is this safe ?
385 * if (this_save_mode != EDIT_QUICK_SAVE)
386 * mc_unlink (savename);
388 g_free(real_filename
);
394 menu_save_mode_cmd (void)
397 const int DLG_X
= 38;
398 const int DLG_Y
= 13;
406 N_("&Do backups with following extension:")
409 QuickWidget widgets
[] =
412 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
414 QUICK_BUTTON ( 6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
416 QUICK_CHECKBOX ( 4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
418 QUICK_INPUT ( 8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
420 QUICK_RADIO ( 4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
426 DLG_X
, DLG_Y
, -1, -1, N_(" Edit Save Mode "),
427 "[Edit Save Mode]", widgets
, FALSE
432 size_t w0
, w1
, b_len
, w3
;
434 assert (option_backup_ext
!= NULL
);
436 /* OK/Cancel buttons */
437 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
438 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
441 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
444 for (i
= 0; i
< 3; i
++) {
448 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
451 maxlen
= max (maxlen
, w3
+ 4);
453 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
455 widgets
[3].u
.input
.len
= w3
;
456 widgets
[1].relative_x
= (dialog
.xlen
- b_len
)/2;
457 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
459 for (i
= 0; i
< sizeof (widgets
)/sizeof (widgets
[0]); i
++)
460 widgets
[i
].x_divisions
= dialog
.xlen
;
462 if (quick_dialog (&dialog
) != B_CANCEL
) {
463 g_free (option_backup_ext
);
464 option_backup_ext
= str_result
;
469 edit_set_filename (WEdit
*edit
, const char *f
)
471 g_free (edit
->filename
);
474 edit
->filename
= g_strdup (f
);
475 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
477 edit
->dir
= g_strdup (vfs_get_current_dir ());
478 #else /* ENABLE_VFS */
479 edit
->dir
= g_get_current_dir ();
480 #endif /* ENABLE_VFS */
484 edit_check_newline (WEdit
*edit
)
486 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
487 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
488 && edit_query_dialog2 (_("Warning"),
489 _("The file you are saving is not finished with a newline"),
490 _("C&ontinue"), _("&Cancel")));
494 edit_get_save_file_as (WEdit
*edit
)
497 #define DLG_HEIGHT 14
499 static LineBreaks cur_lb
= LB_ASIS
;
501 char *filename
= edit
->filename
;
503 const char *lb_names
[LB_NAMES
] =
505 N_("&Do not change"),
506 N_("&Unix format (LF)"),
507 N_("&Windows/DOS format (CR LF)"),
508 N_("&Macintosh format (CR)")
511 QuickWidget quick_widgets
[] =
513 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
514 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
515 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
516 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
517 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0, "save-as", &filename
),
518 QUICK_LABEL (2, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_(" Enter file name: ")),
522 QuickDialog Quick_options
=
524 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
525 N_(" Save As "), "[Save File As]",
529 if (quick_dialog (&Quick_options
) != B_CANCEL
) {
540 /* Here we want to warn the users of overwriting an existing file,
541 but only if they have made a change to the filename */
542 /* returns 1 on success */
544 edit_save_as_cmd (WEdit
*edit
)
546 /* This heads the 'Save As' dialog box */
549 int different_filename
= 0;
551 if (!edit_check_newline (edit
))
554 exp
= edit_get_save_file_as (edit
);
555 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
560 edit
->force
|= REDRAW_COMPLETELY
;
564 if (strcmp (edit
->filename
, exp
)) {
566 different_filename
= 1;
567 if ((file
= mc_open (exp
, O_RDONLY
| O_BINARY
)) != -1) {
568 /* the file exists */
570 /* Overwrite the current file or cancel the operation */
571 if (edit_query_dialog2
573 _(" A file already exists with this name. "),
574 _("&Overwrite"), _("&Cancel"))) {
575 edit
->force
|= REDRAW_COMPLETELY
;
580 edit
->stat1
.st_mode
|= S_IWUSR
;
582 save_lock
= edit_lock_file (exp
);
584 /* filenames equal, check if already locked */
585 if (!edit
->locked
&& !edit
->delete_file
)
586 save_lock
= edit_lock_file (exp
);
589 if (different_filename
)
592 * Allow user to write into saved (under another name) file
593 * even if original file had r/o user permissions.
595 edit
->stat1
.st_mode
|= S_IWRITE
;
598 rv
= edit_save_file (edit
, exp
);
601 /* Succesful, so unlock both files */
602 if (different_filename
) {
604 edit_unlock_file (exp
);
606 edit
->locked
= edit_unlock_file (edit
->filename
);
608 if (edit
->locked
|| save_lock
)
609 edit
->locked
= edit_unlock_file (edit
->filename
);
612 edit_set_filename (edit
, exp
);
613 if (edit
->lb
!= LB_ASIS
)
614 edit_reload(edit
, exp
);
617 edit
->delete_file
= 0;
618 if (different_filename
)
619 edit_load_syntax (edit
, NULL
, option_syntax_type
);
620 edit
->force
|= REDRAW_COMPLETELY
;
623 edit_error_dialog (_(" Save As "),
625 (" Cannot save file. ")));
628 /* Failed, so maintain modify (not save) lock */
630 edit_unlock_file (exp
);
632 edit
->force
|= REDRAW_COMPLETELY
;
637 edit
->force
|= REDRAW_COMPLETELY
;
641 /* {{{ Macro stuff starts here */
643 /* creates a macro file if it doesn't exist */
644 static FILE *edit_open_macro_file (const char *r
)
649 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
650 if ((file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
)) == -1){
655 fd
= fopen (filename
, r
);
660 #define MAX_MACROS 1024
661 static int saved_macro
[MAX_MACROS
+ 1];
662 static int saved_macros_loaded
= 0;
665 This is just to stop the macro file be loaded over and over for keys
666 that aren't defined to anything. On slow systems this could be annoying.
672 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
673 if (saved_macro
[i
] == k
)
678 /* returns 1 on error */
680 edit_delete_macro (WEdit
* edit
, int k
)
683 struct macro macro
[MAX_MACRO_LENGTH
];
689 if (saved_macros_loaded
)
690 if ((j
= macro_exists (k
)) < 0)
692 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
693 g
= fopen (tmp
, "w");
696 edit_error_dialog (_(" Delete macro "),
697 get_sys_error (_(" Cannot open temp file ")));
700 f
= edit_open_macro_file ("r");
702 edit_error_dialog (_(" Delete macro "),
703 get_sys_error (_(" Cannot open macro file ")));
708 n
= fscanf (f
, ("key '%d 0': "), &s
);
712 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
716 fprintf (g
, ("key '%d 0': "), s
);
717 for (i
= 0; i
< n
; i
++)
718 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
724 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
725 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
726 if (rename ( tmp
, tmp2
) == -1) {
727 edit_error_dialog (_(" Delete macro "),
728 get_sys_error (_(" Cannot overwrite macro file ")));
736 if (saved_macros_loaded
)
737 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
741 /* returns 0 on error */
742 int edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
747 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
748 s
= editcmd_dialog_raw_key_query (_(" Save macro "),
749 _(" Press the macro's new hotkey: "), 1);
750 edit
->force
|= REDRAW_COMPLETELY
;
752 if (edit_delete_macro (edit
, s
))
754 f
= edit_open_macro_file ("a+");
756 fprintf (f
, ("key '%d 0': "), s
);
757 for (i
= 0; i
< n
; i
++)
758 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
761 if (saved_macros_loaded
) {
762 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
767 edit_error_dialog (_(" Save macro "), get_sys_error (_(" Cannot open macro file ")));
773 edit_delete_macro_cmd (WEdit
* edit
)
777 command
= editcmd_dialog_raw_key_query (_ (" Delete macro "),
778 _ (" Press macro hotkey: "), 1);
781 edit_delete_macro (edit
, command
);
784 /* return 0 on error */
785 int edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
788 int s
, i
= 0, found
= 0;
792 if (saved_macros_loaded
)
793 if (macro_exists (k
) < 0)
796 if ((f
= edit_open_macro_file ("r"))) {
800 u
= fscanf (f
, ("key '%d 0': "), &s
);
803 if (!saved_macros_loaded
)
804 saved_macro
[i
++] = s
;
807 while (*n
< MAX_MACRO_LENGTH
&& 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
810 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
815 } while (!found
|| !saved_macros_loaded
);
816 if (!saved_macros_loaded
) {
818 saved_macros_loaded
= 1;
823 edit_error_dialog (_(" Load macro "),
824 get_sys_error (_(" Cannot open macro file ")));
828 /* }}} Macro stuff starts here */
830 /* returns 1 on success */
831 int edit_save_confirm_cmd (WEdit
* edit
)
835 if (!edit_check_newline (edit
))
838 if (edit_confirm_save
) {
839 f
= g_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", (char *) NULL
);
840 if (edit_query_dialog2 (_(" Save file "), f
, _("&Save"), _("&Cancel"))){
846 return edit_save_cmd (edit
);
850 /* returns 1 on success */
852 edit_save_cmd (WEdit
*edit
)
854 int res
, save_lock
= 0;
856 if (!edit
->locked
&& !edit
->delete_file
)
857 save_lock
= edit_lock_file (edit
->filename
);
858 res
= edit_save_file (edit
, edit
->filename
);
860 /* Maintain modify (not save) lock on failure */
861 if ((res
> 0 && edit
->locked
) || save_lock
)
862 edit
->locked
= edit_unlock_file (edit
->filename
);
864 /* On failure try 'save as', it does locking on its own */
866 return edit_save_as_cmd (edit
);
867 edit
->force
|= REDRAW_COMPLETELY
;
869 edit
->delete_file
= 0;
877 /* returns 1 on success */
878 int edit_new_cmd (WEdit
* edit
)
880 if (edit
->modified
) {
881 if (edit_query_dialog2 (_ ("Warning"), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("C&ontinue"), _ ("&Cancel"))) {
882 edit
->force
|= REDRAW_COMPLETELY
;
886 edit
->force
|= REDRAW_COMPLETELY
;
888 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
891 /* returns 1 on error */
893 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
895 int prev_locked
= edit
->locked
;
896 char *prev_filename
= g_strdup (edit
->filename
);
898 if (!edit_reload (edit
, exp
)) {
899 g_free (prev_filename
);
904 edit_unlock_file (prev_filename
);
905 g_free (prev_filename
);
910 edit_load_syntax_file (WEdit
* edit
)
915 if (geteuid () == 0) {
916 dir
= query_dialog (_("Syntax file edit"),
917 _(" Which syntax file you want to edit? "), D_NORMAL
, 2,
918 _("&User"), _("&System Wide"));
921 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
922 if (!exist_file(extdir
)) {
924 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
930 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
931 check_for_default (extdir
, buffer
);
932 edit_load_file_from_filename (edit
, buffer
);
935 edit_load_file_from_filename (edit
, extdir
);
941 edit_load_menu_file (WEdit
* edit
)
949 _(" Which menu file do you want to edit? "), D_NORMAL
,
950 geteuid() ? 2 : 3, _("&Local"), _("&User"), _("&System Wide")
953 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
955 if (!exist_file (menufile
)) {
957 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
962 buffer
= g_strdup (EDIT_LOCAL_MENU
);
963 check_for_default (menufile
, buffer
);
964 chmod (buffer
, 0600);
968 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
969 check_for_default (menufile
, buffer
);
973 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
974 if (!exist_file (buffer
)) {
976 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
985 edit_load_file_from_filename (edit
, buffer
);
992 edit_load_cmd (WEdit
*edit
, edit_current_file_t what
)
997 && (edit_query_dialog2
999 _(" Current text was modified without a file save. \n"
1000 " Continue discards these changes. "),
1001 _("C&ontinue"), _("&Cancel")) == 1)) {
1002 edit
->force
|= REDRAW_COMPLETELY
;
1007 case EDIT_FILE_COMMON
:
1008 exp
= input_expand_dialog (_(" Load "), _(" Enter file name: "),
1009 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1013 edit_load_file_from_filename (edit
, exp
);
1018 case EDIT_FILE_SYNTAX
:
1019 edit_load_syntax_file (edit
);
1022 case EDIT_FILE_MENU
:
1023 edit_load_menu_file (edit
);
1030 edit
->force
|= REDRAW_COMPLETELY
;
1035 if mark2 is -1 then marking is from mark1 to the cursor.
1036 Otherwise its between the markers. This handles this.
1037 Returns 1 if no text is marked.
1039 int eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1041 if (edit
->mark1
!= edit
->mark2
) {
1042 long start_bol
, start_eol
;
1043 long end_bol
, end_eol
;
1046 if (edit
->mark2
>= 0) {
1047 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1048 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1050 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1051 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1052 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1054 if (column_highlighting
1055 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1056 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
)))) {
1058 start_bol
= edit_bol (edit
, *start_mark
);
1059 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1060 end_bol
= edit_bol (edit
, *end_mark
);
1061 end_eol
= edit_eol (edit
, *end_mark
);
1062 col1
= min (edit
->column1
, edit
->column2
);
1063 col2
= max (edit
->column1
, edit
->column2
);
1065 diff1
= edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
, col1
, 0);
1066 diff2
= edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
, col1
, 0);
1068 *start_mark
-= diff1
;
1070 *start_mark
= max (*start_mark
, start_eol
);
1071 *end_mark
= min (*end_mark
, end_eol
);
1075 *start_mark
= *end_mark
= 0;
1076 edit
->column2
= edit
->column1
= 0;
1081 #define space_width 1
1084 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1088 cursor
= edit
->curs1
;
1089 col
= edit_get_col (edit
);
1090 for (i
= 0; i
< size
; i
++) {
1091 if (data
[i
] == '\n') { /* fill in and move to next line */
1094 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1095 l
= width
- (edit_get_col (edit
) - col
);
1097 edit_insert (edit
, ' ');
1101 for (p
= edit
->curs1
;; p
++) {
1102 if (p
== edit
->last_byte
) {
1103 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1104 edit_insert_ahead (edit
, '\n');
1108 if (edit_get_byte (edit
, p
) == '\n') {
1113 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1114 l
= col
- edit_get_col (edit
);
1115 while (l
>= space_width
) {
1116 edit_insert (edit
, ' ');
1121 edit_insert (edit
, data
[i
]);
1123 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1126 #define TEMP_BUF_LEN 1024
1129 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1133 int blocklen
= -1, width
;
1134 unsigned char *data
;
1135 cursor
= edit
->curs1
;
1136 col
= edit_get_col (edit
);
1137 data
= g_malloc0 (TEMP_BUF_LEN
);
1138 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0) {
1139 for (width
= 0; width
< blocklen
; width
++) {
1140 if (data
[width
] == '\n')
1143 for (i
= 0; i
< blocklen
; i
++) {
1144 if (data
[i
] == '\n') { /* fill in and move to next line */
1147 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1148 l
= width
- (edit_get_col (edit
) - col
);
1150 edit_insert (edit
, ' ');
1154 for (p
= edit
->curs1
;; p
++) {
1155 if (p
== edit
->last_byte
) {
1156 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1157 edit_insert_ahead (edit
, '\n');
1161 if (edit_get_byte (edit
, p
) == '\n') {
1166 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1167 l
= col
- edit_get_col (edit
);
1168 while (l
>= space_width
) {
1169 edit_insert (edit
, ' ');
1174 edit_insert (edit
, data
[i
]);
1177 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1179 edit
->force
|= REDRAW_PAGE
;
1184 edit_block_copy_cmd (WEdit
*edit
)
1186 long start_mark
, end_mark
, current
= edit
->curs1
;
1188 unsigned char *copy_buf
;
1190 edit_update_curs_col (edit
);
1191 if (eval_marks (edit
, &start_mark
, &end_mark
))
1194 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1196 /* all that gets pushed are deletes hence little space is used on the stack */
1198 edit_push_markers (edit
);
1200 if (column_highlighting
) {
1201 edit_insert_column_of_text (edit
, copy_buf
, size
,
1202 abs (edit
->column2
- edit
->column1
));
1205 edit_insert_ahead (edit
, copy_buf
[size
]);
1209 edit_scroll_screen_over_cursor (edit
);
1211 if (column_highlighting
) {
1212 edit_set_markers (edit
, 0, 0, 0, 0);
1213 edit_push_action (edit
, COLUMN_ON
);
1214 column_highlighting
= 0;
1215 } else if (start_mark
< current
&& end_mark
> current
)
1216 edit_set_markers (edit
, start_mark
,
1217 end_mark
+ end_mark
- start_mark
, 0, 0);
1219 edit
->force
|= REDRAW_PAGE
;
1224 edit_block_move_cmd (WEdit
*edit
)
1228 unsigned char *copy_buf
;
1229 long start_mark
, end_mark
;
1233 if (eval_marks (edit
, &start_mark
, &end_mark
))
1235 if (column_highlighting
) {
1236 edit_update_curs_col (edit
);
1238 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1239 if ((x
> edit
->column1
&& x
< edit
->column2
)
1240 || (x
> edit
->column2
&& x
< edit
->column1
))
1242 } else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1245 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1246 if (edit_query_dialog2
1249 (" Block is large, you may not be able to undo this action. "),
1250 _("C&ontinue"), _("&Cancel")))
1253 edit_push_markers (edit
);
1254 current
= edit
->curs1
;
1255 if (column_highlighting
) {
1258 line
= edit
->curs_line
;
1259 if (edit
->mark2
< 0)
1260 edit_mark_cmd (edit
, 0);
1261 c1
= min (edit
->column1
, edit
->column2
);
1262 c2
= max (edit
->column1
, edit
->column2
);
1263 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1265 edit_block_delete_cmd (edit
);
1268 edit_move_to_line (edit
, line
);
1269 edit_cursor_move (edit
,
1270 edit_move_forward3 (edit
,
1271 edit_bol (edit
, edit
->curs1
),
1272 x
, 0) - edit
->curs1
);
1273 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1275 line
= edit
->curs_line
;
1276 edit_update_curs_col (edit
);
1278 edit_block_delete_cmd (edit
);
1279 edit_move_to_line (edit
, line
);
1280 edit_cursor_move (edit
,
1281 edit_move_forward3 (edit
,
1284 x
, 0) - edit
->curs1
);
1286 edit_set_markers (edit
, 0, 0, 0, 0);
1287 edit_push_action (edit
, COLUMN_ON
);
1288 column_highlighting
= 0;
1290 copy_buf
= g_malloc0 (end_mark
- start_mark
);
1291 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1292 edit_scroll_screen_over_cursor (edit
);
1294 while (count
< end_mark
) {
1295 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1298 edit_scroll_screen_over_cursor (edit
);
1299 edit_cursor_move (edit
,
1300 current
- edit
->curs1
-
1301 (((current
- edit
->curs1
) >
1302 0) ? end_mark
- start_mark
: 0));
1303 edit_scroll_screen_over_cursor (edit
);
1304 while (count
-- > start_mark
)
1305 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1306 edit_set_markers (edit
, edit
->curs1
,
1307 edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1309 edit_scroll_screen_over_cursor (edit
);
1311 edit
->force
|= REDRAW_PAGE
;
1315 edit_delete_column_of_text (WEdit
* edit
)
1317 long p
, q
, r
, m1
, m2
;
1320 eval_marks (edit
, &m1
, &m2
);
1321 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1322 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1323 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1324 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
1325 c
= max (c
, max (edit
->column1
, edit
->column2
));
1328 r
= edit_bol (edit
, edit
->curs1
);
1329 p
= edit_move_forward3 (edit
, r
, b
, 0);
1330 q
= edit_move_forward3 (edit
, r
, c
, 0);
1335 edit_cursor_move (edit
, p
- edit
->curs1
);
1337 /* delete line between margins */
1338 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1339 edit_delete (edit
, 1);
1343 /* move to next line except on the last delete */
1344 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1348 /* if success return 0 */
1350 edit_block_delete (WEdit
*edit
)
1353 long start_mark
, end_mark
;
1354 int curs_pos
, line_width
;
1355 long curs_line
, c1
, c2
;
1357 if (eval_marks (edit
, &start_mark
, &end_mark
))
1359 if (column_highlighting
&& edit
->mark2
< 0)
1360 edit_mark_cmd (edit
, 0);
1361 if ((end_mark
- start_mark
) > option_max_undo
/ 2) {
1362 /* Warning message with a query to continue or cancel the operation */
1363 if (edit_query_dialog2
1366 (" Block is large, you may not be able to undo this action. "),
1367 _("C&ontinue"), _("&Cancel"))) {
1371 c1
= min (edit
->column1
, edit
->column2
);
1372 c2
= max (edit
->column1
, edit
->column2
);
1376 edit_push_markers (edit
);
1378 curs_line
= edit
->curs_line
;
1380 /* calculate line width and cursor position before cut */
1381 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1382 edit_eol (edit
, edit
->curs1
));
1383 curs_pos
= edit
->curs_col
+ edit
->over_col
;
1385 /* move cursor to start of selection */
1386 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1387 edit_scroll_screen_over_cursor (edit
);
1389 if (start_mark
< end_mark
) {
1390 if (column_highlighting
) {
1391 if (edit
->mark2
< 0)
1392 edit_mark_cmd (edit
, 0);
1393 edit_delete_column_of_text (edit
);
1394 /* move cursor to the saved position */
1395 edit_move_to_line (edit
, curs_line
);
1396 /* calculate line width after cut */
1397 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1398 edit_eol (edit
, edit
->curs1
));
1399 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
1400 edit
->over_col
= curs_pos
- line_width
;
1402 while (count
< end_mark
) {
1403 edit_delete (edit
, 1);
1408 edit_set_markers (edit
, 0, 0, 0, 0);
1409 edit
->force
|= REDRAW_PAGE
;
1413 /* returns 1 if canceelled by user */
1414 int edit_block_delete_cmd (WEdit
* edit
)
1416 long start_mark
, end_mark
;
1417 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
1418 edit_delete_line (edit
);
1421 return edit_block_delete (edit
);
1424 #define INPUT_INDEX 9
1427 editcmd_find (WEdit
*edit
, gsize
*len
)
1429 off_t search_start
= edit
->search_start
;
1431 long start_mark
= 0;
1432 long end_mark
= edit
->last_byte
;
1435 if (edit
->only_in_selection
) {
1436 mark_res
= eval_marks(edit
, &start_mark
, &end_mark
);
1437 if (mark_res
!= 0) {
1438 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1439 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1442 if (edit
->replace_backwards
) {
1443 if (search_start
> end_mark
|| search_start
<= start_mark
) {
1444 search_start
= end_mark
;
1447 if (search_start
< start_mark
|| search_start
>= end_mark
) {
1448 search_start
= start_mark
;
1452 if (edit
->replace_backwards
)
1453 end_mark
= max(1, edit
->curs1
) - 1;
1455 if (edit
->replace_backwards
) {
1456 search_end
= end_mark
;
1457 while ((int) search_start
>= start_mark
) {
1458 if (search_end
> search_start
+ edit
->search
->original_len
1459 && mc_search_is_fixed_search_str(edit
->search
)) {
1460 search_end
= search_start
+ edit
->search
->original_len
;
1462 if (mc_search_run(edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1463 && edit
->search
->normal_offset
== search_start
) {
1468 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1470 return mc_search_run(edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1476 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1477 (and the above) routines to work properly - paul */
1479 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1482 edit_replace_cmd__conv_to_display (char *str
)
1486 tmp
= str_convert_to_display (str
);
1488 if (tmp
&& tmp
->len
){
1489 return g_string_free (tmp
, FALSE
);
1491 g_string_free (tmp
, TRUE
);
1493 return g_strdup(str
);
1497 edit_replace_cmd__conv_to_input(char *str
)
1501 tmp
= str_convert_to_input (str
);
1503 if (tmp
&& tmp
->len
){
1504 return g_string_free (tmp
, FALSE
);
1506 g_string_free (tmp
, TRUE
);
1507 return g_strdup(str
);
1509 return g_strdup(str
);
1511 /* call with edit = 0 before shutdown to close memory leaks */
1513 edit_replace_cmd (WEdit
*edit
, int again
)
1515 /* 1 = search string, 2 = replace with */
1516 static char *saved1
= NULL
; /* saved default[123] */
1517 static char *saved2
= NULL
;
1518 char *input1
= NULL
; /* user input from the dialog */
1519 char *input2
= NULL
;
1521 long times_replaced
= 0, last_search
;
1522 gboolean once_found
= FALSE
;
1525 g_free (saved1
), saved1
= NULL
;
1526 g_free (saved2
), saved2
= NULL
;
1530 last_search
= edit
->last_byte
;
1532 edit
->force
|= REDRAW_COMPLETELY
;
1534 if (again
&& !saved1
&& !saved2
)
1538 input1
= g_strdup (saved1
? saved1
: "");
1539 input2
= g_strdup (saved2
? saved2
: "");
1541 char *disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1542 char *disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
1543 char *tmp_inp1
, *tmp_inp2
;
1545 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1547 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1552 if (input1
== NULL
|| *input1
== '\0') {
1553 edit
->force
= REDRAW_COMPLETELY
;
1557 tmp_inp1
= input1
; tmp_inp2
= input2
;
1558 input1
= edit_replace_cmd__conv_to_input(input1
);
1559 input2
= edit_replace_cmd__conv_to_input(input2
);
1560 g_free(tmp_inp1
); g_free(tmp_inp2
);
1562 g_free (saved1
), saved1
= g_strdup (input1
);
1563 g_free (saved2
), saved2
= g_strdup (input2
);
1566 mc_search_free(edit
->search
);
1567 edit
->search
= NULL
;
1571 if (!edit
->search
) {
1572 edit
->search
= mc_search_new(input1
, -1);
1573 if (edit
->search
== NULL
) {
1574 edit
->search_start
= edit
->curs1
;
1577 edit
->search
->search_type
= edit
->search_type
;
1578 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1579 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1580 edit
->search
->whole_words
= edit
->whole_words
;
1581 edit
->search
->search_fn
= edit_search_cmd_callback
;
1584 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1585 && edit
->replace_backwards
)
1586 edit
->search_start
--;
1588 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1589 && !edit
->replace_backwards
)
1590 edit
->search_start
++;
1596 if (! editcmd_find(edit
, &len
)) {
1597 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1598 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
))) {
1599 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1604 new_start
= edit
->search
->normal_offset
;
1606 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1607 /*returns negative on not found or error in pattern */
1609 if (edit
->search_start
>= 0) {
1612 edit
->found_start
= edit
->search_start
;
1613 i
= edit
->found_len
= len
;
1615 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1616 edit_scroll_screen_over_cursor (edit
);
1620 if (edit
->replace_mode
== 0) {
1622 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1624 edit_scroll_downward (edit
, l
);
1626 edit_scroll_upward (edit
, -l
);
1628 edit_scroll_screen_over_cursor (edit
);
1629 edit
->force
|= REDRAW_PAGE
;
1630 edit_render_keypress (edit
);
1632 /*so that undo stops at each query */
1633 edit_push_key_press (edit
);
1634 /* and prompt 2/3 down */
1635 switch (editcmd_dialog_replace_prompt_show (edit
, input1
, input2
, -1, -1)) {
1639 case B_SKIP_REPLACE
:
1643 edit
->replace_mode
=1;
1647 edit
->replace_mode
= -1;
1651 if (replace_yes
) { /* delete then insert new */
1652 GString
*repl_str
, *tmp_str
;
1653 tmp_str
= g_string_new(input2
);
1655 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1656 g_string_free(tmp_str
, TRUE
);
1657 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1659 edit_error_dialog (_ ("Replace"), edit
->search
->error_str
);
1664 edit_delete (edit
, 1);
1666 while (++i
< repl_str
->len
)
1667 edit_insert (edit
, repl_str
->str
[i
]);
1669 g_string_free(repl_str
, TRUE
);
1670 edit
->found_len
= i
;
1672 /* so that we don't find the same string again */
1673 if (edit
->replace_backwards
) {
1674 last_search
= edit
->search_start
;
1675 edit
->search_start
--;
1677 edit
->search_start
+= i
;
1678 last_search
= edit
->last_byte
;
1680 edit_scroll_screen_over_cursor (edit
);
1682 const char *msg
= _(" Replace ");
1683 /* try and find from right here for next search */
1684 edit
->search_start
= edit
->curs1
;
1685 edit_update_curs_col (edit
);
1687 edit
->force
|= REDRAW_PAGE
;
1688 edit_render_keypress (edit
);
1689 if (times_replaced
) {
1690 message (D_NORMAL
, msg
, _(" %ld replacements made. "),
1693 query_dialog (msg
, _(" Search string not found "),
1694 D_NORMAL
, 1, _("&OK"));
1695 edit
->replace_mode
= -1;
1697 } while (edit
->replace_mode
>= 0);
1699 edit
->force
= REDRAW_COMPLETELY
;
1700 edit_scroll_screen_over_cursor (edit
);
1707 void edit_search_cmd (WEdit
* edit
, int again
)
1709 char *search_string
= NULL
, *search_string_dup
= NULL
;
1716 if (edit
->search
!= NULL
) {
1717 search_string
= g_strndup(edit
->search
->original
, edit
->search
->original_len
);
1718 search_string_dup
= search_string
;
1721 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1722 if (history
!= NULL
&& history
->data
!= NULL
) {
1723 search_string_dup
= search_string
= (char *) g_strdup(history
->data
);
1724 history
= g_list_first (history
);
1725 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1726 g_list_free (history
);
1728 edit
->search_start
= edit
->curs1
;
1734 if (search_string
&& *search_string
) {
1735 tmp
= str_convert_to_display (search_string
);
1737 g_free(search_string_dup
);
1738 search_string_dup
= NULL
;
1740 if (tmp
&& tmp
->len
)
1741 search_string
= search_string_dup
= tmp
->str
;
1742 g_string_free (tmp
, FALSE
);
1744 #endif /* HAVE_CHARSET */
1745 editcmd_dialog_search_show (edit
, &search_string
);
1747 if (search_string
&& *search_string
) {
1748 tmp
= str_convert_to_input (search_string
);
1749 if (tmp
&& tmp
->len
)
1750 search_string
= tmp
->str
;
1752 g_string_free (tmp
, FALSE
);
1754 if (search_string_dup
)
1755 g_free(search_string_dup
);
1757 #endif /* HAVE_CHARSET */
1759 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1761 if (!search_string
) {
1762 edit
->force
|= REDRAW_COMPLETELY
;
1763 edit_scroll_screen_over_cursor (edit
);
1768 mc_search_free(edit
->search
);
1769 edit
->search
= NULL
;
1773 if (!edit
->search
) {
1774 edit
->search
= mc_search_new(search_string
, -1);
1775 if (edit
->search
== NULL
) {
1776 edit
->search_start
= edit
->curs1
;
1779 edit
->search
->search_type
= edit
->search_type
;
1780 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1781 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1782 edit
->search
->whole_words
= edit
->whole_words
;
1783 edit
->search
->search_fn
= edit_search_cmd_callback
;
1786 if (search_create_bookmark
) {
1787 edit_search_cmd_search_create_bookmark(edit
);
1789 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1 && edit
->replace_backwards
)
1790 edit
->search_start
--;
1792 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1 && !edit
->replace_backwards
)
1793 edit
->search_start
++;
1796 if (editcmd_find(edit
, &len
)) {
1797 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1798 edit
->found_len
= len
;
1800 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1801 edit_scroll_screen_over_cursor (edit
);
1802 if (edit
->replace_backwards
)
1803 edit
->search_start
--;
1805 edit
->search_start
++;
1807 edit
->search_start
= edit
->curs1
;
1808 if (edit
->search
->error_str
)
1809 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1813 edit
->force
|= REDRAW_COMPLETELY
;
1814 edit_scroll_screen_over_cursor (edit
);
1819 * Check if it's OK to close the editor. If there are unsaved changes,
1820 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
1823 edit_ok_to_exit (WEdit
*edit
)
1825 if (!edit
->modified
)
1828 if (!edit_check_newline (edit
))
1831 switch (edit_query_dialog3
1832 (_("Quit"), _(" File was modified, Save with exit? "),
1833 _("&Cancel quit"), _("&Yes"), _("&No"))) {
1835 edit_push_markers (edit
);
1836 edit_set_markers (edit
, 0, 0, 0, 0);
1837 if (!edit_save_cmd (edit
))
1850 /* Return a null terminated length of text. Result must be g_free'd */
1851 static unsigned char *
1852 edit_get_block (WEdit
*edit
, long start
, long finish
, int *l
)
1854 unsigned char *s
, *r
;
1855 r
= s
= g_malloc0 (finish
- start
+ 1);
1856 if (column_highlighting
) {
1858 /* copy from buffer, excluding chars that are out of the column 'margins' */
1859 while (start
< finish
) {
1862 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0,
1864 c
= edit_get_byte (edit
, start
);
1865 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1866 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n') {
1873 *l
= finish
- start
;
1874 while (start
< finish
)
1875 *s
++ = edit_get_byte (edit
, start
++);
1881 /* save block, returns 1 on success */
1883 edit_save_block (WEdit
* edit
, const char *filename
, long start
,
1889 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1890 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
1893 if (column_highlighting
) {
1895 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof(VERTICAL_MAGIC
));
1897 unsigned char *block
, *p
;
1898 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
1900 r
= mc_write (file
, p
, len
);
1911 len
= finish
- start
;
1912 buf
= g_malloc0 (TEMP_BUF_LEN
);
1913 while (start
!= finish
) {
1914 end
= min (finish
, start
+ TEMP_BUF_LEN
);
1915 for (; i
< end
; i
++)
1916 buf
[i
- start
] = edit_get_byte (edit
, i
);
1917 len
-= mc_write (file
, (char *) buf
, end
- start
);
1928 /* copies a block to clipboard file */
1929 static int edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1933 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1934 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1940 void edit_paste_from_history (WEdit
*edit
)
1943 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
1946 int edit_copy_to_X_buf_cmd (WEdit
* edit
)
1948 long start_mark
, end_mark
;
1949 if (eval_marks (edit
, &start_mark
, &end_mark
))
1951 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1952 edit_error_dialog (_(" Copy to clipboard "), get_sys_error (_(" Unable to save to file. ")));
1955 edit_mark_cmd (edit
, 1);
1959 int edit_cut_to_X_buf_cmd (WEdit
* edit
)
1961 long start_mark
, end_mark
;
1962 if (eval_marks (edit
, &start_mark
, &end_mark
))
1964 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1965 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
1968 edit_block_delete_cmd (edit
);
1969 edit_mark_cmd (edit
, 1);
1973 void edit_paste_from_X_buf_cmd (WEdit
* edit
)
1976 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1977 edit_insert_file (edit
, tmp
);
1983 * Ask user for the line and go to that line.
1984 * Negative numbers mean line from the end (i.e. -1 is the last line).
1987 edit_goto_cmd (WEdit
*edit
)
1990 static long line
= 0; /* line as typed, saved as default */
1995 g_snprintf (s
, sizeof (s
), "%ld", line
);
1996 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2006 l
= strtol (f
, &error
, 0);
2014 l
= edit
->total_lines
+ l
+ 2;
2015 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2016 edit_move_to_line (edit
, l
- 1);
2017 edit
->force
|= REDRAW_COMPLETELY
;
2022 /* Return 1 on success */
2024 edit_save_block_cmd (WEdit
*edit
)
2026 long start_mark
, end_mark
;
2029 if (eval_marks (edit
, &start_mark
, &end_mark
))
2032 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2034 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2035 MC_HISTORY_EDIT_SAVE_BLOCK
,
2038 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2044 if (edit_save_block (edit
, exp
, start_mark
, end_mark
)) {
2046 edit
->force
|= REDRAW_COMPLETELY
;
2050 edit_error_dialog (_(" Save Block "),
2052 (" Cannot save file. ")));
2056 edit
->force
|= REDRAW_COMPLETELY
;
2061 /* returns 1 on success */
2063 edit_insert_file_cmd (WEdit
*edit
)
2068 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2069 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2070 MC_HISTORY_EDIT_INSERT_FILE
,
2073 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2079 if (edit_insert_file (edit
, exp
)) {
2081 edit
->force
|= REDRAW_COMPLETELY
;
2085 edit_error_dialog (_(" Insert File "),
2087 (" Cannot insert file. ")));
2091 edit
->force
|= REDRAW_COMPLETELY
;
2095 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2096 int edit_sort_cmd (WEdit
* edit
)
2098 static char *old
= 0;
2100 long start_mark
, end_mark
;
2103 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2104 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2108 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2109 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2112 exp
= input_dialog (_(" Run Sort "),
2113 _(" Enter sort options (see manpage) separated by whitespace: "),
2114 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2120 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2121 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2125 if (e
== -1 || e
== 127) {
2126 edit_error_dialog (_(" Sort "),
2127 get_sys_error (_(" Cannot execute sort command ")));
2130 sprintf (q
, "%d ", e
);
2131 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2132 edit_error_dialog (_(" Sort "), tmp
);
2138 edit
->force
|= REDRAW_COMPLETELY
;
2140 if (edit_block_delete_cmd (edit
))
2142 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2143 edit_insert_file (edit
, tmp
);
2149 * Ask user for a command, execute it and paste its output back to the
2153 edit_ext_cmd (WEdit
*edit
)
2159 input_dialog (_("Paste output of external command"),
2160 _("Enter shell command(s):"),
2161 MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2166 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2172 edit_error_dialog (_("External command"),
2173 get_sys_error (_("Cannot execute command")));
2177 edit
->force
|= REDRAW_COMPLETELY
;
2178 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2179 edit_insert_file (edit
, tmp
);
2184 /* if block is 1, a block must be highlighted and the shell command
2185 processes it. If block is 0 the shell command is a straight system
2186 command, that just produces some output which is to be inserted */
2188 edit_block_process_cmd (WEdit
*edit
, const char *shell_cmd
, int block
)
2190 long start_mark
, end_mark
;
2192 FILE *script_home
= NULL
;
2193 FILE *block_file
= NULL
;
2194 gchar
*o
, *h
, *b
, *tmp
;
2195 char *quoted_name
= NULL
;
2197 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2198 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2199 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2201 script_home
= fopen (h
, "r");
2202 if (script_home
== NULL
) {
2203 FILE *script_src
= NULL
;
2205 script_home
= fopen (h
, "w");
2206 if (script_home
== NULL
) {
2207 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2208 edit_error_dialog ("", get_sys_error (tmp
));
2210 goto edit_block_process_cmd__EXIT
;
2213 script_src
= fopen (o
, "r");
2214 if (script_src
== NULL
) {
2215 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2216 script_src
= fopen (o
, "r");
2217 if (script_src
== NULL
) {
2218 fclose (script_home
);
2220 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2221 edit_error_dialog ("", get_sys_error (tmp
));
2223 goto edit_block_process_cmd__EXIT
;
2226 while (fgets (buf
, sizeof (buf
), script_src
))
2227 fputs (buf
, script_home
);
2228 fclose (script_src
);
2230 if (fclose (script_home
)) {
2231 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2232 edit_error_dialog ("", get_sys_error (tmp
));
2234 goto edit_block_process_cmd__EXIT
;
2237 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2238 edit_error_dialog ("", get_sys_error (tmp
));
2244 if (block
) { /* for marked block run indent formatter */
2245 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2246 edit_error_dialog (_("Process block"),
2248 (" You must first highlight a block of text. "));
2249 goto edit_block_process_cmd__EXIT
;
2251 edit_save_block (edit
, b
, start_mark
, end_mark
);
2252 quoted_name
= name_quote (edit
->filename
, 0);
2255 * Initial space is to avoid polluting bash history.
2257 * $1 - name of the edited file (to check its extension etc).
2258 * $2 - file containing the current block.
2259 * $3 - file where error messages should be put
2260 * (for compatibility with old scripts).
2262 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2263 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2268 * No block selected, just execute the command for the file.
2270 * $1 - name of the edited file.
2272 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2273 quoted_name
, (char *) NULL
);
2277 g_free (quoted_name
);
2278 close_error_pipe (D_NORMAL
, NULL
);
2280 edit_refresh_cmd (edit
);
2281 edit
->force
|= REDRAW_COMPLETELY
;
2283 /* insert result block */
2284 if (block
&& !edit_block_delete_cmd (edit
)) {
2285 edit_insert_file (edit
, b
);
2286 block_file
= fopen (b
, "w");
2287 if (block_file
!= NULL
)
2288 fclose (block_file
);
2291 edit_block_process_cmd__EXIT
:
2297 /* prints at the cursor */
2298 /* returns the number of chars printed */
2299 int edit_print_string (WEdit
* e
, const char *s
)
2302 while (s
[i
] != '\0')
2303 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2304 e
->force
|= REDRAW_COMPLETELY
;
2305 edit_update_screen (e
);
2310 static void pipe_mail (WEdit
*edit
, char *to
, char *subject
, char *cc
)
2315 to
= name_quote (to
, 0);
2316 subject
= name_quote (subject
, 0);
2317 cc
= name_quote (cc
, 0);
2318 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "" , cc
, " ", to
, (char *) NULL
);
2330 for (i
= 0; i
< edit
->last_byte
; i
++)
2331 fputc (edit_get_byte (edit
, i
), p
);
2336 #define MAIL_DLG_HEIGHT 12
2338 void edit_mail_dialog (WEdit
* edit
)
2341 char *tmail_subject
;
2344 static char *mail_cc_last
= 0;
2345 static char *mail_subject_last
= 0;
2346 static char *mail_to_last
= 0;
2348 QuickWidget quick_widgets
[] =
2350 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2351 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2352 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2353 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2354 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2", &tmail_subject
),
2355 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2356 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2357 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2358 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2362 QuickDialog Quick_input
=
2364 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2365 "[Input Line Keys]", quick_widgets
, FALSE
2368 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2369 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2370 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2372 if (quick_dialog (&Quick_input
) != B_CANCEL
) {
2373 g_free (mail_cc_last
);
2374 g_free (mail_subject_last
);
2375 g_free (mail_to_last
);
2376 mail_cc_last
= tmail_cc
;
2377 mail_subject_last
= tmail_subject
;
2378 mail_to_last
= tmail_to
;
2379 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2384 /*******************/
2385 /* Word Completion */
2386 /*******************/
2388 static gboolean
is_break_char(char c
)
2390 return (isspace(c
) || strchr("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2393 /* find first character of current word */
2394 static int edit_find_word_start (WEdit
*edit
, long *word_start
, gsize
*word_len
)
2399 /* return if at begin of file */
2400 if (edit
->curs1
<= 0)
2403 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2404 /* return if not at end or in word */
2405 if (is_break_char(c
))
2408 /* search start of word to be completed */
2410 /* return if at begin of file */
2411 if (edit
->curs1
- i
< 0)
2415 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2417 if (is_break_char(c
)) {
2418 /* return if word starts with digit */
2422 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2431 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2433 /* collect the possible completions */
2435 edit_collect_completions (WEdit
*edit
, long start
, gsize word_len
,
2436 char *match_expr
, struct selection
*compl,
2448 srch
= mc_search_new(match_expr
, -1);
2452 if (mc_config_get_bool(mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0)){
2453 last_byte
= edit
->last_byte
;
2458 srch
->search_type
= MC_SEARCH_T_REGEX
;
2459 srch
->is_case_sentitive
= TRUE
;
2460 srch
->search_fn
= edit_search_cmd_callback
;
2462 /* collect max MAX_WORD_COMPLETIONS completions */
2465 /* get next match */
2466 if (mc_search_run (srch
, (void *) edit
, start
+1, last_byte
, &len
) == FALSE
)
2468 start
= srch
->normal_offset
;
2470 /* add matched completion if not yet added */
2471 temp
= g_string_new("");
2472 for (i
= 0; i
< len
; i
++){
2473 skip
= edit_get_byte(edit
, start
+i
);
2476 g_string_append_c (temp
, skip
);
2481 for (i
= 0; i
< (gsize
) *num
; i
++) {
2484 (char *) &compl[i
].text
[word_len
],
2485 (char *) &temp
->str
[word_len
],
2486 max (len
, compl[i
].len
) - (gsize
)word_len
2488 struct selection
this = compl[i
];
2489 for (++i
; i
< *num
; i
++) {
2490 compl[i
- 1] = compl[i
];
2492 compl[*num
- 1] = this;
2494 break; /* skip it, already added */
2498 g_string_free(temp
, TRUE
);
2501 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
) {
2502 g_free(compl[0].text
);
2503 for (i
= 1; i
< *num
; i
++) {
2504 compl[i
- 1] = compl[i
];
2511 recoded
= str_convert_to_display (temp
->str
);
2513 if (recoded
&& recoded
->len
){
2514 g_string_free(temp
,TRUE
);
2517 g_string_free(recoded
, TRUE
);
2520 compl[*num
].text
= temp
->str
;
2521 compl[*num
].len
= temp
->len
;
2524 g_string_free(temp
, FALSE
);
2526 /* note the maximal length needed for the completion dialog */
2530 mc_search_free(srch
);
2535 * Complete current word using regular expression search
2536 * backwards beginning at the current cursor position.
2539 edit_complete_word_cmd (WEdit
*edit
)
2541 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2542 long word_start
= 0;
2543 unsigned char *bufpos
;
2545 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2547 /* search start of word to be completed */
2548 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2551 /* prepare match expression */
2552 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2553 [word_start
& M_EDIT_BUF_SIZE
];
2555 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2556 match_expr
= g_strdup_printf ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+", (int)word_len
, bufpos
);
2558 /* collect the possible completions */
2559 /* start search from begin to end of file */
2561 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2562 (struct selection
*) &compl, &num_compl
);
2564 if (num_compl
> 0) {
2565 /* insert completed word if there is only one match */
2566 if (num_compl
== 1) {
2567 for (i
= word_len
; i
< compl[0].len
; i
++)
2568 edit_insert (edit
, *(compl[0].text
+ i
));
2570 /* more than one possible completion => ask the user */
2572 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2573 /* !!! pressed again the selection dialog pops up, but that !!! */
2574 /* !!! seems to require a further internal state !!! */
2577 /* let the user select the preferred completion */
2578 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2579 (struct selection
*) &compl,
2584 g_free (match_expr
);
2585 /* release memory before return */
2586 for (i
= 0; i
< num_compl
; i
++)
2587 g_free (compl[i
].text
);
2591 edit_select_codepage_cmd (WEdit
*edit
)
2594 const char *cp_id
= NULL
;
2595 if (do_select_codepage ()) {
2596 cp_id
= get_codepage_id (source_codepage
>= 0 ?
2597 source_codepage
: display_codepage
);
2599 if (cp_id
!= NULL
) {
2601 conv
= str_crt_conv_from (cp_id
);
2602 if (conv
!= INVALID_CONV
) {
2603 if (edit
->converter
!= str_cnv_from_term
)
2604 str_close_conv (edit
->converter
);
2605 edit
->converter
= conv
;
2610 edit
->utf8
= str_isutf8 (cp_id
);
2613 edit
->force
= REDRAW_COMPLETELY
;
2614 edit_refresh_cmd (edit
);
2621 edit_insert_literal_cmd (WEdit
*edit
)
2623 int char_for_insertion
=
2624 editcmd_dialog_raw_key_query (_(" Insert Literal "),
2625 _(" Press any key: "), 0);
2626 edit_execute_key_command (edit
, -1,
2627 ascii_alpha_to_cntrl (char_for_insertion
));
2631 edit_execute_macro_cmd (WEdit
*edit
)
2634 CK_Macro (editcmd_dialog_raw_key_query
2635 (_(" Execute Macro "), _(" Press macro hotkey: "),
2637 if (command
== CK_Macro (0))
2638 command
= CK_Insert_Char
;
2640 edit_execute_key_command (edit
, command
, -1);
2644 edit_begin_end_macro_cmd (WEdit
*edit
)
2646 /* edit is a pointer to the widget */
2648 unsigned long command
= edit
->macro_i
< 0
2649 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2650 edit_execute_key_command (edit
, command
, -1);
2655 edit_load_forward_cmd (WEdit
*edit
)
2657 if (edit
->modified
) {
2658 if (edit_query_dialog2
2660 _(" Current text was modified without a file save. \n"
2661 " Continue discards these changes. "), _("C&ontinue"),
2663 edit
->force
|= REDRAW_COMPLETELY
;
2667 if ( edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
) {
2668 if ( edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1 ) {
2671 edit_stack_iterator
++;
2672 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2673 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2674 edit_history_moveto
[edit_stack_iterator
].line
);
2685 edit_load_back_cmd (WEdit
*edit
)
2687 if (edit
->modified
) {
2688 if (edit_query_dialog2
2690 _(" Current text was modified without a file save. \n"
2691 " Continue discards these changes. "), _("C&ontinue"),
2693 edit
->force
|= REDRAW_COMPLETELY
;
2697 if ( edit_stack_iterator
> 0 ) {
2698 edit_stack_iterator
--;
2699 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2700 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2701 edit_history_moveto
[edit_stack_iterator
].line
);
2712 edit_get_match_keyword_cmd (WEdit
*edit
)
2714 gsize word_len
= 0, max_len
= 0;
2717 long word_start
= 0;
2718 unsigned char *bufpos
;
2722 char *tagfile
= NULL
;
2724 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2726 for ( i
= 0; i
< MAX_DEFINITIONS
; i
++) {
2727 def_hash
[i
].filename
= NULL
;
2730 /* search start of word to be completed */
2731 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2734 /* prepare match expression */
2735 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2736 [word_start
& M_EDIT_BUF_SIZE
];
2737 match_expr
= g_strdup_printf ("%.*s", (int)word_len
, bufpos
);
2739 ptr
= g_get_current_dir ();
2740 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
2743 /* Recursive search file 'TAGS' in parent dirs */
2745 ptr
= g_path_get_dirname (path
);
2746 g_free(path
); path
= ptr
;
2748 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
2749 if ( exist_file (tagfile
) )
2751 } while (strcmp( path
, G_DIR_SEPARATOR_S
) != 0);
2754 num_def
= etags_set_definition_hash(tagfile
, path
, match_expr
, (etags_hash_t
*) &def_hash
);
2759 max_len
= MAX_WIDTH_DEF_DIALOG
;
2761 if ( num_def
> 0 ) {
2762 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
2763 (etags_hash_t
*) &def_hash
,
2766 g_free (match_expr
);
2770 edit_move_block_to_right (WEdit
* edit
)
2772 long start_mark
, end_mark
;
2773 long cur_bol
, start_bol
;
2775 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2778 start_bol
= edit_bol (edit
, start_mark
);
2779 cur_bol
= edit_bol (edit
, end_mark
- 1);
2781 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2782 if ( option_fill_tabs_with_spaces
) {
2783 if ( option_fake_half_tabs
) {
2784 insert_spaces_tab (edit
, 1);
2786 insert_spaces_tab (edit
, 0);
2789 edit_insert (edit
, '\t');
2791 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
2792 if ( cur_bol
== 0 ) {
2795 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2796 } while (cur_bol
>= start_bol
) ;
2797 edit
->force
|= REDRAW_PAGE
;
2801 edit_move_block_to_left (WEdit
* edit
)
2803 long start_mark
, end_mark
;
2804 long cur_bol
, start_bol
;
2805 int i
, del_tab_width
;
2808 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2811 start_bol
= edit_bol (edit
, start_mark
);
2812 cur_bol
= edit_bol (edit
, end_mark
- 1);
2814 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2815 if (option_fake_half_tabs
) {
2816 del_tab_width
= HALF_TAB_SIZE
;
2818 del_tab_width
= option_tab_spacing
;
2820 next_char
= edit_get_byte (edit
, edit
->curs1
);
2821 if ( next_char
== '\t' ) {
2822 edit_delete (edit
, 1);
2823 } else if ( next_char
== ' ' ) {
2824 for (i
= 1; i
<= del_tab_width
; i
++) {
2825 if ( next_char
== ' ' ) {
2826 edit_delete (edit
, 1);
2828 next_char
= edit_get_byte (edit
, edit
->curs1
);
2831 if ( cur_bol
== 0 ) {
2834 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2835 } while (cur_bol
>= start_bol
) ;
2836 edit
->force
|= REDRAW_PAGE
;