1 /* editor high level editing commands
3 Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * \brief Source: editor high level editing commands
31 /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */
40 #include <sys/types.h>
48 #include "lib/global.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h" /* XCTRL */
51 #include "lib/mcconfig.h"
53 #include "lib/strutil.h" /* utf string functions */
54 #include "lib/vfs/mc-vfs/vfs.h"
56 #include "src/history.h"
57 #include "src/widget.h" /* listbox_new() */
58 #include "src/layout.h" /* clr_scr() */
59 #include "src/main.h" /* mc_home source_codepage */
60 #include "src/help.h" /* interactive_display() */
61 #include "src/wtools.h" /* message() */
62 #include "src/charsets.h"
63 #include "src/selcodepage.h"
64 #include "src/cmddef.h"
66 #include "src/editor/edit-impl.h"
67 #include "src/editor/editlock.h"
68 #include "src/editor/edit-widget.h"
69 #include "src/editor/editcmd_dialogs.h"
70 #include "src/editor/etags.h"
74 /* search and replace: */
75 int search_create_bookmark
= 0;
76 /* static int search_in_all_charsets = 0; */
78 /* queries on a save */
79 int edit_confirm_save
= 1;
81 static int edit_save_cmd (WEdit
*edit
);
82 static unsigned char *edit_get_block (WEdit
*edit
, long start
,
86 edit_search_cmd_search_create_bookmark(WEdit
* edit
)
88 int found
= 0, books
= 0;
89 long l
= 0, l_last
= -1;
93 search_create_bookmark
= 0;
94 book_mark_flush (edit
, -1);
97 if (!mc_search_run(edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
100 edit
->search_start
= edit
->search
->normal_offset
;
102 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
104 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
108 q
= edit
->search
->normal_offset
+ 1;
112 edit_error_dialog (_ ("Search"), _ (" Search string not found "));
114 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
115 edit_scroll_screen_over_cursor (edit
);
120 edit_search_cmd_callback(const void *user_data
, gsize char_offset
)
122 return edit_get_byte ((WEdit
* )user_data
, (long) char_offset
);
125 void edit_help_cmd (WEdit
* edit
)
127 interactive_display (NULL
, "[Internal File Editor]");
128 edit
->force
|= REDRAW_COMPLETELY
;
132 edit_refresh_cmd (WEdit
* edit
)
137 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_search_options
.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_search_options
.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_search_options
.backwards
)
1453 end_mark
= max(1, edit
->curs1
) - 1;
1455 if (edit_search_options
.backwards
) {
1456 search_end
= end_mark
;
1457 while ((int) search_start
>= start_mark
) {
1458 if (search_end
> (off_t
) (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
;
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 *tmp_inp1
, *tmp_inp2
;
1544 disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1545 disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
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_options
.type
;
1580 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1581 edit
->search
->is_case_sentitive
= edit_search_options
.case_sens
;
1582 edit
->search
->whole_words
= edit_search_options
.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_search_options
.backwards
)
1588 edit
->search_start
--;
1590 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1591 && !edit_search_options
.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 disp1
= edit_replace_cmd__conv_to_display (saved1
);
1638 disp2
= edit_replace_cmd__conv_to_display (saved2
);
1639 switch (editcmd_dialog_replace_prompt_show (edit
, disp1
, disp2
, -1, -1)) {
1643 case B_SKIP_REPLACE
:
1647 edit
->replace_mode
=1;
1651 edit
->replace_mode
= -1;
1657 if (replace_yes
) { /* delete then insert new */
1658 GString
*repl_str
, *tmp_str
;
1659 tmp_str
= g_string_new(input2
);
1661 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1662 g_string_free(tmp_str
, TRUE
);
1663 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1665 edit_error_dialog (_ ("Replace"), edit
->search
->error_str
);
1670 edit_delete (edit
, 1);
1672 while (++i
< repl_str
->len
)
1673 edit_insert (edit
, repl_str
->str
[i
]);
1675 g_string_free(repl_str
, TRUE
);
1676 edit
->found_len
= i
;
1678 /* so that we don't find the same string again */
1679 if (edit_search_options
.backwards
) {
1680 last_search
= edit
->search_start
;
1681 edit
->search_start
--;
1683 edit
->search_start
+= i
;
1684 last_search
= edit
->last_byte
;
1686 edit_scroll_screen_over_cursor (edit
);
1688 const char *msg
= _(" Replace ");
1689 /* try and find from right here for next search */
1690 edit
->search_start
= edit
->curs1
;
1691 edit_update_curs_col (edit
);
1693 edit
->force
|= REDRAW_PAGE
;
1694 edit_render_keypress (edit
);
1695 if (times_replaced
) {
1696 message (D_NORMAL
, msg
, _(" %ld replacements made. "),
1699 query_dialog (msg
, _(" Search string not found "),
1700 D_NORMAL
, 1, _("&OK"));
1701 edit
->replace_mode
= -1;
1703 } while (edit
->replace_mode
>= 0);
1705 edit
->force
= REDRAW_COMPLETELY
;
1706 edit_scroll_screen_over_cursor (edit
);
1713 void edit_search_cmd (WEdit
* edit
, int again
)
1715 char *search_string
= NULL
, *search_string_dup
= NULL
;
1722 if (edit
->search
!= NULL
) {
1723 search_string
= g_strndup(edit
->search
->original
, edit
->search
->original_len
);
1724 search_string_dup
= search_string
;
1727 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1728 if (history
!= NULL
&& history
->data
!= NULL
) {
1729 search_string_dup
= search_string
= (char *) g_strdup(history
->data
);
1730 history
= g_list_first (history
);
1731 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1732 g_list_free (history
);
1734 edit
->search_start
= edit
->curs1
;
1740 if (search_string
&& *search_string
) {
1741 tmp
= str_convert_to_display (search_string
);
1743 g_free(search_string_dup
);
1744 search_string_dup
= NULL
;
1746 if (tmp
&& tmp
->len
)
1747 search_string
= search_string_dup
= tmp
->str
;
1748 g_string_free (tmp
, FALSE
);
1750 #endif /* HAVE_CHARSET */
1751 editcmd_dialog_search_show (edit
, &search_string
);
1753 if (search_string
&& *search_string
) {
1754 tmp
= str_convert_to_input (search_string
);
1755 if (tmp
&& tmp
->len
)
1756 search_string
= tmp
->str
;
1758 g_string_free (tmp
, FALSE
);
1760 if (search_string_dup
)
1761 g_free(search_string_dup
);
1763 #endif /* HAVE_CHARSET */
1765 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1767 if (!search_string
) {
1768 edit
->force
|= REDRAW_COMPLETELY
;
1769 edit_scroll_screen_over_cursor (edit
);
1774 mc_search_free(edit
->search
);
1775 edit
->search
= NULL
;
1779 if (!edit
->search
) {
1780 edit
->search
= mc_search_new(search_string
, -1);
1781 if (edit
->search
== NULL
) {
1782 edit
->search_start
= edit
->curs1
;
1785 edit
->search
->search_type
= edit_search_options
.type
;
1786 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1787 edit
->search
->is_case_sentitive
= edit_search_options
.case_sens
;
1788 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1789 edit
->search
->search_fn
= edit_search_cmd_callback
;
1792 if (search_create_bookmark
) {
1793 edit_search_cmd_search_create_bookmark(edit
);
1795 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1796 && edit_search_options
.backwards
)
1797 edit
->search_start
--;
1799 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1800 && !edit_search_options
.backwards
)
1801 edit
->search_start
++;
1803 if (editcmd_find(edit
, &len
)) {
1804 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1805 edit
->found_len
= len
;
1807 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1808 edit_scroll_screen_over_cursor (edit
);
1809 if (edit_search_options
.backwards
)
1810 edit
->search_start
--;
1812 edit
->search_start
++;
1814 edit
->search_start
= edit
->curs1
;
1815 if (edit
->search
->error_str
)
1816 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1820 edit
->force
|= REDRAW_COMPLETELY
;
1821 edit_scroll_screen_over_cursor (edit
);
1826 * Check if it's OK to close the editor. If there are unsaved changes,
1827 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
1830 edit_ok_to_exit (WEdit
*edit
)
1832 if (!edit
->modified
)
1835 if (!edit_check_newline (edit
))
1838 switch (edit_query_dialog3
1839 (_("Quit"), _(" File was modified, Save with exit? "),
1840 _("&Cancel quit"), _("&Yes"), _("&No"))) {
1842 edit_push_markers (edit
);
1843 edit_set_markers (edit
, 0, 0, 0, 0);
1844 if (!edit_save_cmd (edit
))
1857 /* Return a null terminated length of text. Result must be g_free'd */
1858 static unsigned char *
1859 edit_get_block (WEdit
*edit
, long start
, long finish
, int *l
)
1861 unsigned char *s
, *r
;
1862 r
= s
= g_malloc0 (finish
- start
+ 1);
1863 if (column_highlighting
) {
1865 /* copy from buffer, excluding chars that are out of the column 'margins' */
1866 while (start
< finish
) {
1869 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0,
1871 c
= edit_get_byte (edit
, start
);
1872 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1873 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n') {
1880 *l
= finish
- start
;
1881 while (start
< finish
)
1882 *s
++ = edit_get_byte (edit
, start
++);
1888 /* save block, returns 1 on success */
1890 edit_save_block (WEdit
* edit
, const char *filename
, long start
,
1896 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1897 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
1900 if (column_highlighting
) {
1902 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof(VERTICAL_MAGIC
));
1904 unsigned char *block
, *p
;
1905 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
1907 r
= mc_write (file
, p
, len
);
1918 len
= finish
- start
;
1919 buf
= g_malloc0 (TEMP_BUF_LEN
);
1920 while (start
!= finish
) {
1921 end
= min (finish
, start
+ TEMP_BUF_LEN
);
1922 for (; i
< end
; i
++)
1923 buf
[i
- start
] = edit_get_byte (edit
, i
);
1924 len
-= mc_write (file
, (char *) buf
, end
- start
);
1935 /* copies a block to clipboard file */
1936 static int edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1940 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1941 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1947 void edit_paste_from_history (WEdit
*edit
)
1950 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
1953 int edit_copy_to_X_buf_cmd (WEdit
* edit
)
1955 long start_mark
, end_mark
;
1956 if (eval_marks (edit
, &start_mark
, &end_mark
))
1958 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1959 edit_error_dialog (_(" Copy to clipboard "), get_sys_error (_(" Unable to save to file. ")));
1962 edit_mark_cmd (edit
, 1);
1966 int edit_cut_to_X_buf_cmd (WEdit
* edit
)
1968 long start_mark
, end_mark
;
1969 if (eval_marks (edit
, &start_mark
, &end_mark
))
1971 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1972 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
1975 edit_block_delete_cmd (edit
);
1976 edit_mark_cmd (edit
, 1);
1980 void edit_paste_from_X_buf_cmd (WEdit
* edit
)
1983 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1984 edit_insert_file (edit
, tmp
);
1990 * Ask user for the line and go to that line.
1991 * Negative numbers mean line from the end (i.e. -1 is the last line).
1994 edit_goto_cmd (WEdit
*edit
)
1997 static long line
= 0; /* line as typed, saved as default */
2002 g_snprintf (s
, sizeof (s
), "%ld", line
);
2003 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2013 l
= strtol (f
, &error
, 0);
2021 l
= edit
->total_lines
+ l
+ 2;
2022 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2023 edit_move_to_line (edit
, l
- 1);
2024 edit
->force
|= REDRAW_COMPLETELY
;
2029 /* Return 1 on success */
2031 edit_save_block_cmd (WEdit
*edit
)
2033 long start_mark
, end_mark
;
2036 if (eval_marks (edit
, &start_mark
, &end_mark
))
2039 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2041 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2042 MC_HISTORY_EDIT_SAVE_BLOCK
,
2045 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2051 if (edit_save_block (edit
, exp
, start_mark
, end_mark
)) {
2053 edit
->force
|= REDRAW_COMPLETELY
;
2057 edit_error_dialog (_(" Save Block "),
2059 (" Cannot save file. ")));
2063 edit
->force
|= REDRAW_COMPLETELY
;
2068 /* returns 1 on success */
2070 edit_insert_file_cmd (WEdit
*edit
)
2075 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2076 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2077 MC_HISTORY_EDIT_INSERT_FILE
,
2080 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2086 if (edit_insert_file (edit
, exp
)) {
2088 edit
->force
|= REDRAW_COMPLETELY
;
2092 edit_error_dialog (_(" Insert File "),
2094 (" Cannot insert file. ")));
2098 edit
->force
|= REDRAW_COMPLETELY
;
2102 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2103 int edit_sort_cmd (WEdit
* edit
)
2105 static char *old
= 0;
2107 long start_mark
, end_mark
;
2110 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2111 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2115 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2116 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2119 exp
= input_dialog (_(" Run Sort "),
2120 _(" Enter sort options (see manpage) separated by whitespace: "),
2121 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2127 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2128 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2132 if (e
== -1 || e
== 127) {
2133 edit_error_dialog (_(" Sort "),
2134 get_sys_error (_(" Cannot execute sort command ")));
2137 sprintf (q
, "%d ", e
);
2138 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2139 edit_error_dialog (_(" Sort "), tmp
);
2145 edit
->force
|= REDRAW_COMPLETELY
;
2147 if (edit_block_delete_cmd (edit
))
2149 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2150 edit_insert_file (edit
, tmp
);
2156 * Ask user for a command, execute it and paste its output back to the
2160 edit_ext_cmd (WEdit
*edit
)
2166 input_dialog (_("Paste output of external command"),
2167 _("Enter shell command(s):"),
2168 MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2173 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2179 edit_error_dialog (_("External command"),
2180 get_sys_error (_("Cannot execute command")));
2184 edit
->force
|= REDRAW_COMPLETELY
;
2185 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2186 edit_insert_file (edit
, tmp
);
2191 /* if block is 1, a block must be highlighted and the shell command
2192 processes it. If block is 0 the shell command is a straight system
2193 command, that just produces some output which is to be inserted */
2195 edit_block_process_cmd (WEdit
*edit
, const char *shell_cmd
, int block
)
2197 long start_mark
, end_mark
;
2199 FILE *script_home
= NULL
;
2200 FILE *block_file
= NULL
;
2201 gchar
*o
, *h
, *b
, *tmp
;
2202 char *quoted_name
= NULL
;
2204 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2205 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2206 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2208 script_home
= fopen (h
, "r");
2209 if (script_home
== NULL
) {
2210 FILE *script_src
= NULL
;
2212 script_home
= fopen (h
, "w");
2213 if (script_home
== NULL
) {
2214 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2215 edit_error_dialog ("", get_sys_error (tmp
));
2217 goto edit_block_process_cmd__EXIT
;
2220 script_src
= fopen (o
, "r");
2221 if (script_src
== NULL
) {
2222 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2223 script_src
= fopen (o
, "r");
2224 if (script_src
== NULL
) {
2225 fclose (script_home
);
2227 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2228 edit_error_dialog ("", get_sys_error (tmp
));
2230 goto edit_block_process_cmd__EXIT
;
2233 while (fgets (buf
, sizeof (buf
), script_src
))
2234 fputs (buf
, script_home
);
2235 fclose (script_src
);
2237 if (fclose (script_home
)) {
2238 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2239 edit_error_dialog ("", get_sys_error (tmp
));
2241 goto edit_block_process_cmd__EXIT
;
2244 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2245 edit_error_dialog ("", get_sys_error (tmp
));
2251 if (block
) { /* for marked block run indent formatter */
2252 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2253 edit_error_dialog (_("Process block"),
2255 (" You must first highlight a block of text. "));
2256 goto edit_block_process_cmd__EXIT
;
2258 edit_save_block (edit
, b
, start_mark
, end_mark
);
2259 quoted_name
= name_quote (edit
->filename
, 0);
2262 * Initial space is to avoid polluting bash history.
2264 * $1 - name of the edited file (to check its extension etc).
2265 * $2 - file containing the current block.
2266 * $3 - file where error messages should be put
2267 * (for compatibility with old scripts).
2269 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2270 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2275 * No block selected, just execute the command for the file.
2277 * $1 - name of the edited file.
2279 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2280 quoted_name
, (char *) NULL
);
2284 g_free (quoted_name
);
2285 close_error_pipe (D_NORMAL
, NULL
);
2287 edit_refresh_cmd (edit
);
2288 edit
->force
|= REDRAW_COMPLETELY
;
2290 /* insert result block */
2291 if (block
&& !edit_block_delete_cmd (edit
)) {
2292 edit_insert_file (edit
, b
);
2293 block_file
= fopen (b
, "w");
2294 if (block_file
!= NULL
)
2295 fclose (block_file
);
2298 edit_block_process_cmd__EXIT
:
2304 /* prints at the cursor */
2305 /* returns the number of chars printed */
2306 int edit_print_string (WEdit
* e
, const char *s
)
2309 while (s
[i
] != '\0')
2310 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2311 e
->force
|= REDRAW_COMPLETELY
;
2312 edit_update_screen (e
);
2317 static void pipe_mail (WEdit
*edit
, char *to
, char *subject
, char *cc
)
2322 to
= name_quote (to
, 0);
2323 subject
= name_quote (subject
, 0);
2324 cc
= name_quote (cc
, 0);
2325 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "" , cc
, " ", to
, (char *) NULL
);
2337 for (i
= 0; i
< edit
->last_byte
; i
++)
2338 fputc (edit_get_byte (edit
, i
), p
);
2343 #define MAIL_DLG_HEIGHT 12
2345 void edit_mail_dialog (WEdit
* edit
)
2348 char *tmail_subject
;
2351 static char *mail_cc_last
= 0;
2352 static char *mail_subject_last
= 0;
2353 static char *mail_to_last
= 0;
2355 QuickWidget quick_widgets
[] =
2357 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2358 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2359 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2360 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2361 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2", &tmail_subject
),
2362 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2363 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2364 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2365 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2369 QuickDialog Quick_input
=
2371 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2372 "[Input Line Keys]", quick_widgets
, FALSE
2375 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2376 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2377 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2379 if (quick_dialog (&Quick_input
) != B_CANCEL
) {
2380 g_free (mail_cc_last
);
2381 g_free (mail_subject_last
);
2382 g_free (mail_to_last
);
2383 mail_cc_last
= tmail_cc
;
2384 mail_subject_last
= tmail_subject
;
2385 mail_to_last
= tmail_to
;
2386 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2391 /*******************/
2392 /* Word Completion */
2393 /*******************/
2395 static gboolean
is_break_char(char c
)
2397 return (isspace(c
) || strchr("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2400 /* find first character of current word */
2401 static int edit_find_word_start (WEdit
*edit
, long *word_start
, gsize
*word_len
)
2406 /* return if at begin of file */
2407 if (edit
->curs1
<= 0)
2410 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2411 /* return if not at end or in word */
2412 if (is_break_char(c
))
2415 /* search start of word to be completed */
2417 /* return if at begin of file */
2418 if ((gsize
)edit
->curs1
< i
)
2422 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2424 if (is_break_char(c
)) {
2425 /* return if word starts with digit */
2429 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2438 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2440 /* collect the possible completions */
2442 edit_collect_completions (WEdit
*edit
, long start
, gsize word_len
,
2443 char *match_expr
, struct selection
*compl,
2455 srch
= mc_search_new(match_expr
, -1);
2459 if (mc_config_get_bool(mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0)){
2460 last_byte
= edit
->last_byte
;
2465 srch
->search_type
= MC_SEARCH_T_REGEX
;
2466 srch
->is_case_sentitive
= TRUE
;
2467 srch
->search_fn
= edit_search_cmd_callback
;
2469 /* collect max MAX_WORD_COMPLETIONS completions */
2472 /* get next match */
2473 if (mc_search_run (srch
, (void *) edit
, start
+1, last_byte
, &len
) == FALSE
)
2475 start
= srch
->normal_offset
;
2477 /* add matched completion if not yet added */
2478 temp
= g_string_new("");
2479 for (i
= 0; i
< len
; i
++){
2480 skip
= edit_get_byte(edit
, start
+i
);
2483 g_string_append_c (temp
, skip
);
2488 for (i
= 0; i
< (gsize
) *num
; i
++) {
2491 (char *) &compl[i
].text
[word_len
],
2492 (char *) &temp
->str
[word_len
],
2493 max (len
, compl[i
].len
) - (gsize
)word_len
2495 struct selection
this = compl[i
];
2496 for (++i
; i
< *num
; i
++) {
2497 compl[i
- 1] = compl[i
];
2499 compl[*num
- 1] = this;
2501 break; /* skip it, already added */
2505 g_string_free(temp
, TRUE
);
2508 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
) {
2509 g_free(compl[0].text
);
2510 for (i
= 1; i
< *num
; i
++) {
2511 compl[i
- 1] = compl[i
];
2518 recoded
= str_convert_to_display (temp
->str
);
2520 if (recoded
&& recoded
->len
){
2521 g_string_free(temp
,TRUE
);
2524 g_string_free(recoded
, TRUE
);
2527 compl[*num
].text
= temp
->str
;
2528 compl[*num
].len
= temp
->len
;
2531 g_string_free(temp
, FALSE
);
2533 /* note the maximal length needed for the completion dialog */
2537 mc_search_free(srch
);
2542 * Complete current word using regular expression search
2543 * backwards beginning at the current cursor position.
2546 edit_complete_word_cmd (WEdit
*edit
)
2548 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2549 long word_start
= 0;
2550 unsigned char *bufpos
;
2552 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2554 /* search start of word to be completed */
2555 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2558 /* prepare match expression */
2559 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2560 [word_start
& M_EDIT_BUF_SIZE
];
2562 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2563 match_expr
= g_strdup_printf ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+", (int)word_len
, bufpos
);
2565 /* collect the possible completions */
2566 /* start search from begin to end of file */
2568 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2569 (struct selection
*) &compl, &num_compl
);
2571 if (num_compl
> 0) {
2572 /* insert completed word if there is only one match */
2573 if (num_compl
== 1) {
2574 for (i
= word_len
; i
< compl[0].len
; i
++)
2575 edit_insert (edit
, *(compl[0].text
+ i
));
2577 /* more than one possible completion => ask the user */
2579 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2580 /* !!! pressed again the selection dialog pops up, but that !!! */
2581 /* !!! seems to require a further internal state !!! */
2584 /* let the user select the preferred completion */
2585 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2586 (struct selection
*) &compl,
2591 g_free (match_expr
);
2592 /* release memory before return */
2593 for (i
= 0; i
< num_compl
; i
++)
2594 g_free (compl[i
].text
);
2598 edit_select_codepage_cmd (WEdit
*edit
)
2601 const char *cp_id
= NULL
;
2602 if (do_select_codepage ()) {
2603 cp_id
= get_codepage_id (source_codepage
>= 0 ?
2604 source_codepage
: display_codepage
);
2606 if (cp_id
!= NULL
) {
2608 conv
= str_crt_conv_from (cp_id
);
2609 if (conv
!= INVALID_CONV
) {
2610 if (edit
->converter
!= str_cnv_from_term
)
2611 str_close_conv (edit
->converter
);
2612 edit
->converter
= conv
;
2617 edit
->utf8
= str_isutf8 (cp_id
);
2620 edit
->force
= REDRAW_COMPLETELY
;
2621 edit_refresh_cmd (edit
);
2628 edit_insert_literal_cmd (WEdit
*edit
)
2630 int char_for_insertion
=
2631 editcmd_dialog_raw_key_query (_(" Insert Literal "),
2632 _(" Press any key: "), 0);
2633 edit_execute_key_command (edit
, -1,
2634 ascii_alpha_to_cntrl (char_for_insertion
));
2638 edit_execute_macro_cmd (WEdit
*edit
)
2641 CK_Macro (editcmd_dialog_raw_key_query
2642 (_(" Execute Macro "), _(" Press macro hotkey: "),
2644 if (command
== CK_Macro (0))
2645 command
= CK_Insert_Char
;
2647 edit_execute_key_command (edit
, command
, -1);
2651 edit_begin_end_macro_cmd (WEdit
*edit
)
2653 /* edit is a pointer to the widget */
2655 unsigned long command
= edit
->macro_i
< 0
2656 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2657 edit_execute_key_command (edit
, command
, -1);
2662 edit_load_forward_cmd (WEdit
*edit
)
2664 if (edit
->modified
) {
2665 if (edit_query_dialog2
2667 _(" Current text was modified without a file save. \n"
2668 " Continue discards these changes. "), _("C&ontinue"),
2670 edit
->force
|= REDRAW_COMPLETELY
;
2674 if ( edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
) {
2675 if ( edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1 ) {
2678 edit_stack_iterator
++;
2679 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2680 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2681 edit_history_moveto
[edit_stack_iterator
].line
);
2692 edit_load_back_cmd (WEdit
*edit
)
2694 if (edit
->modified
) {
2695 if (edit_query_dialog2
2697 _(" Current text was modified without a file save. \n"
2698 " Continue discards these changes. "), _("C&ontinue"),
2700 edit
->force
|= REDRAW_COMPLETELY
;
2704 if ( edit_stack_iterator
> 0 ) {
2705 edit_stack_iterator
--;
2706 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2707 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2708 edit_history_moveto
[edit_stack_iterator
].line
);
2719 edit_get_match_keyword_cmd (WEdit
*edit
)
2721 gsize word_len
= 0, max_len
= 0;
2724 long word_start
= 0;
2725 unsigned char *bufpos
;
2729 char *tagfile
= NULL
;
2731 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2733 for ( i
= 0; i
< MAX_DEFINITIONS
; i
++) {
2734 def_hash
[i
].filename
= NULL
;
2737 /* search start of word to be completed */
2738 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2741 /* prepare match expression */
2742 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2743 [word_start
& M_EDIT_BUF_SIZE
];
2744 match_expr
= g_strdup_printf ("%.*s", (int)word_len
, bufpos
);
2746 ptr
= g_get_current_dir ();
2747 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
2750 /* Recursive search file 'TAGS' in parent dirs */
2752 ptr
= g_path_get_dirname (path
);
2753 g_free(path
); path
= ptr
;
2755 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
2756 if ( exist_file (tagfile
) )
2758 } while (strcmp( path
, G_DIR_SEPARATOR_S
) != 0);
2761 num_def
= etags_set_definition_hash(tagfile
, path
, match_expr
, (etags_hash_t
*) &def_hash
);
2766 max_len
= MAX_WIDTH_DEF_DIALOG
;
2768 if ( num_def
> 0 ) {
2769 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
2770 (etags_hash_t
*) &def_hash
,
2773 g_free (match_expr
);
2777 edit_move_block_to_right (WEdit
* edit
)
2779 long start_mark
, end_mark
;
2780 long cur_bol
, start_bol
;
2782 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2785 start_bol
= edit_bol (edit
, start_mark
);
2786 cur_bol
= edit_bol (edit
, end_mark
- 1);
2788 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2789 if ( option_fill_tabs_with_spaces
) {
2790 if ( option_fake_half_tabs
) {
2791 insert_spaces_tab (edit
, 1);
2793 insert_spaces_tab (edit
, 0);
2796 edit_insert (edit
, '\t');
2798 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
2799 if ( cur_bol
== 0 ) {
2802 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2803 } while (cur_bol
>= start_bol
) ;
2804 edit
->force
|= REDRAW_PAGE
;
2808 edit_move_block_to_left (WEdit
* edit
)
2810 long start_mark
, end_mark
;
2811 long cur_bol
, start_bol
;
2812 int i
, del_tab_width
;
2815 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2818 start_bol
= edit_bol (edit
, start_mark
);
2819 cur_bol
= edit_bol (edit
, end_mark
- 1);
2821 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2822 if (option_fake_half_tabs
) {
2823 del_tab_width
= HALF_TAB_SIZE
;
2825 del_tab_width
= option_tab_spacing
;
2827 next_char
= edit_get_byte (edit
, edit
->curs1
);
2828 if ( next_char
== '\t' ) {
2829 edit_delete (edit
, 1);
2830 } else if ( next_char
== ' ' ) {
2831 for (i
= 1; i
<= del_tab_width
; i
++) {
2832 if ( next_char
== ' ' ) {
2833 edit_delete (edit
, 1);
2835 next_char
= edit_get_byte (edit
, edit
->curs1
);
2838 if ( cur_bol
== 0 ) {
2841 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2842 } while (cur_bol
>= start_bol
) ;
2843 edit
->force
|= REDRAW_PAGE
;