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 */
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"
65 #include "src/clipboard.h" /* copy_file_to_ext_clip, paste_to_file_from_ext_clip */
67 #include "src/editor/edit-impl.h"
68 #include "src/editor/editlock.h"
69 #include "src/editor/edit-widget.h"
70 #include "src/editor/editcmd_dialogs.h"
71 #include "src/editor/etags.h"
75 /* search and replace: */
76 int search_create_bookmark
= 0;
77 /* static int search_in_all_charsets = 0; */
79 /* queries on a save */
80 int edit_confirm_save
= 1;
82 static int edit_save_cmd (WEdit
* edit
);
83 static unsigned char *edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
);
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);
98 if (!mc_search_run (edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
101 edit
->search_start
= edit
->search
->normal_offset
;
103 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;
115 edit_error_dialog (_("Search"), _("Search string not found"));
119 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
120 edit_scroll_screen_over_cursor (edit
);
125 edit_search_cmd_callback (const void *user_data
, gsize char_offset
)
127 return edit_get_byte ((WEdit
*) user_data
, (long) char_offset
);
131 edit_help_cmd (WEdit
* edit
)
133 interactive_display (NULL
, "[Internal File Editor]");
134 edit
->force
|= REDRAW_COMPLETELY
;
138 edit_refresh_cmd (WEdit
* edit
)
143 edit_get_syntax_color (edit
, -1, &color
);
151 #endif /* !HAVE_SLANG */
155 /* If 0 (quick save) then a) create/truncate <filename> file,
156 b) save to <filename>;
157 if 1 (safe save) then a) save to <tempnam>,
158 b) rename <tempnam> to <filename>;
159 if 2 (do backups) then a) save to <tempnam>,
160 b) rename <filename> to <filename.backup_ext>,
161 c) rename <tempnam> to <filename>. */
163 /* returns 0 on error, -1 on abort */
165 edit_save_file (WEdit
* edit
, const char *filename
)
171 gchar
*real_filename
;
172 int this_save_mode
, fd
= -1;
179 if (*filename
!= PATH_SEP
&& edit
->dir
)
181 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
185 real_filename
= g_strdup (filename
);
188 this_save_mode
= option_save_mode
;
189 if (this_save_mode
!= EDIT_QUICK_SAVE
)
191 if (!vfs_file_is_local (real_filename
) ||
192 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1)
195 * The file does not exists yet, so no safe save or
196 * backup are necessary.
198 this_save_mode
= EDIT_QUICK_SAVE
;
204 if (this_save_mode
== EDIT_QUICK_SAVE
&& !edit
->skip_detach_prompt
)
209 rv
= mc_stat (real_filename
, &sb
);
210 if (rv
== 0 && sb
.st_nlink
> 1)
212 rv
= edit_query_dialog3 (_("Warning"),
213 _("File has hard-links. Detach before saving?"),
214 _("&Yes"), _("&No"), _("&Cancel"));
218 this_save_mode
= EDIT_SAFE_SAVE
;
221 edit
->skip_detach_prompt
= 1;
224 g_free (real_filename
);
229 /* Prevent overwriting changes from other editor sessions. */
230 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
)
233 /* The default action is "Cancel". */
236 rv
= edit_query_dialog2 (_("Warning"),
237 _("The file has been modified in the meantime. Save anyway?"),
238 _("&Yes"), _("&Cancel"));
241 g_free (real_filename
);
247 if (this_save_mode
!= EDIT_QUICK_SAVE
)
249 char *savedir
, *saveprefix
;
250 const char *slashpos
;
251 slashpos
= strrchr (real_filename
, PATH_SEP
);
254 savedir
= g_strdup (real_filename
);
255 savedir
[slashpos
- real_filename
+ 1] = '\0';
258 savedir
= g_strdup (".");
259 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
261 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
265 g_free (real_filename
);
269 * Close for now because mc_mkstemps use pure open system call
270 * to create temporary file and it needs to be reopened by
271 * VFS-aware mc_open().
276 savename
= g_strdup (real_filename
);
279 ret
= mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
280 ret
= mc_chmod (savename
, edit
->stat1
.st_mode
);
283 fd
= mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
, edit
->stat1
.st_mode
);
288 p
= edit_get_write_filter (savename
, real_filename
);
294 file
= (FILE *) popen (p
, "w");
298 filelen
= edit_write_stream (edit
, file
);
302 if (pclose (file
) != 0)
304 tmp
= g_strdup_printf (_("Error writing to pipe: %s"), p
);
305 edit_error_dialog (_("Error"), tmp
);
314 tmp
= g_strdup_printf (_("Cannot open pipe for writing: %s"), p
);
315 edit_error_dialog (_("Error"), get_sys_error (tmp
));
322 else if (edit
->lb
== LB_ASIS
)
323 { /* do not change line breaks */
326 filelen
= edit
->last_byte
;
327 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1)
329 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
337 (fd
, (char *) edit
->buffers1
[buf
],
338 edit
->curs1
& M_EDIT_BUF_SIZE
) != (edit
->curs1
& M_EDIT_BUF_SIZE
))
342 else if (edit
->curs2
)
345 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
348 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
349 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
350 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) != 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
))
358 if (mc_write (fd
, (char *) edit
->buffers2
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
370 /* Update the file information, especially the mtime. */
371 if (mc_stat (savename
, &edit
->stat1
) == -1)
375 { /* change line breaks */
380 file
= (FILE *) fopen (savename
, "w");
384 filelen
= edit_write_stream (edit
, file
);
391 msg
= g_strdup_printf (_("Cannot open file for writing: %s"), savename
);
392 edit_error_dialog (_("Error"), msg
);
398 if (filelen
!= edit
->last_byte
)
401 if (this_save_mode
== EDIT_DO_BACKUP
)
403 assert (option_backup_ext
!= NULL
);
404 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
405 if (mc_rename (real_filename
, tmp
) == -1)
412 if (this_save_mode
!= EDIT_QUICK_SAVE
)
413 if (mc_rename (savename
, real_filename
) == -1)
416 g_free (real_filename
);
419 /* FIXME: Is this safe ?
420 * if (this_save_mode != EDIT_QUICK_SAVE)
421 * mc_unlink (savename);
423 g_free (real_filename
);
429 menu_save_mode_cmd (void)
432 const int DLG_X
= 38;
433 const int DLG_Y
= 13;
437 const char *str
[] = {
440 N_("&Do backups with following extension:")
443 QuickWidget widgets
[] = {
445 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
447 QUICK_BUTTON (6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
449 QUICK_CHECKBOX (4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
451 QUICK_INPUT (8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
453 QUICK_RADIO (4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
457 QuickDialog dialog
= {
458 DLG_X
, DLG_Y
, -1, -1, N_("Edit Save Mode"),
459 "[Edit Save Mode]", widgets
, FALSE
464 size_t w0
, w1
, b_len
, w3
;
466 assert (option_backup_ext
!= NULL
);
468 /* OK/Cancel buttons */
469 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
470 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
473 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
476 for (i
= 0; i
< 3; i
++)
481 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
484 maxlen
= max (maxlen
, w3
+ 4);
486 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
488 widgets
[3].u
.input
.len
= w3
;
489 widgets
[1].relative_x
= (dialog
.xlen
- b_len
) / 2;
490 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
492 for (i
= 0; i
< sizeof (widgets
) / sizeof (widgets
[0]); i
++)
493 widgets
[i
].x_divisions
= dialog
.xlen
;
495 if (quick_dialog (&dialog
) != B_CANCEL
)
497 g_free (option_backup_ext
);
498 option_backup_ext
= str_result
;
503 edit_set_filename (WEdit
* edit
, const char *f
)
505 g_free (edit
->filename
);
508 edit
->filename
= g_strdup (f
);
509 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
511 edit
->dir
= g_strdup (vfs_get_current_dir ());
512 #else /* ENABLE_VFS */
513 edit
->dir
= g_get_current_dir ();
514 #endif /* ENABLE_VFS */
518 edit_check_newline (WEdit
* edit
)
520 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
521 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
522 && edit_query_dialog2 (_("Warning"),
523 _("The file you are saving is not finished with a newline"),
524 _("C&ontinue"), _("&Cancel")));
528 edit_get_save_file_as (WEdit
* edit
)
531 #define DLG_HEIGHT 14
533 static LineBreaks cur_lb
= LB_ASIS
;
535 char *filename
= edit
->filename
;
537 const char *lb_names
[LB_NAMES
] = {
538 N_("&Do not change"),
539 N_("&Unix format (LF)"),
540 N_("&Windows/DOS format (CR LF)"),
541 N_("&Macintosh format (CR)")
544 QuickWidget quick_widgets
[] = {
545 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
546 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
547 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
548 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
549 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0,
550 "save-as", &filename
),
551 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_("Enter file name:")),
555 QuickDialog Quick_options
= {
556 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
557 N_("Save As"), "[Save File As]",
561 if (quick_dialog (&Quick_options
) != B_CANCEL
)
573 /* Here we want to warn the users of overwriting an existing file,
574 but only if they have made a change to the filename */
575 /* returns 1 on success */
577 edit_save_as_cmd (WEdit
* edit
)
579 /* This heads the 'Save As' dialog box */
582 int different_filename
= 0;
584 if (!edit_check_newline (edit
))
587 exp
= edit_get_save_file_as (edit
);
588 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
595 edit
->force
|= REDRAW_COMPLETELY
;
601 if (strcmp (edit
->filename
, exp
))
604 different_filename
= 1;
605 file
= mc_open (exp
, O_RDONLY
| O_BINARY
);
608 /* the file exists */
610 /* Overwrite the current file or cancel the operation */
611 if (edit_query_dialog2
613 _("A file already exists with this name"),
614 _("&Overwrite"), _("&Cancel")))
616 edit
->force
|= REDRAW_COMPLETELY
;
623 edit
->stat1
.st_mode
|= S_IWUSR
;
625 save_lock
= edit_lock_file (exp
);
629 /* filenames equal, check if already locked */
630 if (!edit
->locked
&& !edit
->delete_file
)
631 save_lock
= edit_lock_file (exp
);
634 if (different_filename
)
637 * Allow user to write into saved (under another name) file
638 * even if original file had r/o user permissions.
640 edit
->stat1
.st_mode
|= S_IWRITE
;
643 rv
= edit_save_file (edit
, exp
);
647 /* Succesful, so unlock both files */
648 if (different_filename
)
651 edit_unlock_file (exp
);
653 edit
->locked
= edit_unlock_file (edit
->filename
);
657 if (edit
->locked
|| save_lock
)
658 edit
->locked
= edit_unlock_file (edit
->filename
);
661 edit_set_filename (edit
, exp
);
662 if (edit
->lb
!= LB_ASIS
)
663 edit_reload (edit
, exp
);
666 edit
->delete_file
= 0;
667 if (different_filename
)
668 edit_load_syntax (edit
, NULL
, edit
->syntax_type
);
669 edit
->force
|= REDRAW_COMPLETELY
;
672 edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
675 /* Failed, so maintain modify (not save) lock */
677 edit_unlock_file (exp
);
679 edit
->force
|= REDRAW_COMPLETELY
;
684 edit
->force
|= REDRAW_COMPLETELY
;
688 /* {{{ Macro stuff starts here */
690 /* creates a macro file if it doesn't exist */
692 edit_open_macro_file (const char *r
)
697 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
698 file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
705 fd
= fopen (filename
, r
);
710 #define MAX_MACROS 1024
711 static int saved_macro
[MAX_MACROS
+ 1];
712 static int saved_macros_loaded
= 0;
715 This is just to stop the macro file be loaded over and over for keys
716 that aren't defined to anything. On slow systems this could be annoying.
722 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
723 if (saved_macro
[i
] == k
)
728 /* returns 1 on error */
730 edit_delete_macro (WEdit
* edit
, int k
)
733 struct macro macro
[MAX_MACRO_LENGTH
];
739 if (saved_macros_loaded
)
741 j
= macro_exists (k
);
745 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
746 g
= fopen (tmp
, "w");
750 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open temp file")));
753 f
= edit_open_macro_file ("r");
756 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open macro file")));
762 n
= fscanf (f
, ("key '%d 0': "), &s
);
766 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
770 ret
= fscanf (f
, ";\n");
774 fprintf (g
, ("key '%d 0': "), s
);
775 for (i
= 0; i
< n
; i
++)
776 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
782 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
783 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
784 if (rename (tmp
, tmp2
) == -1)
786 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot overwrite macro file")));
794 if (saved_macros_loaded
)
795 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
799 /* returns 0 on error */
801 edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
806 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
807 s
= editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1);
808 edit
->force
|= REDRAW_COMPLETELY
;
811 if (edit_delete_macro (edit
, s
))
813 f
= edit_open_macro_file ("a+");
816 fprintf (f
, ("key '%d 0': "), s
);
817 for (i
= 0; i
< n
; i
++)
818 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
821 if (saved_macros_loaded
)
823 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
829 edit_error_dialog (_("Save macro"), get_sys_error (_("Cannot open macro file")));
835 edit_delete_macro_cmd (WEdit
* edit
)
839 command
= editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), 1);
842 edit_delete_macro (edit
, command
);
845 /* return 0 on error */
847 edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
850 int s
, i
= 0, found
= 0;
854 if (saved_macros_loaded
)
855 if (macro_exists (k
) < 0)
858 f
= edit_open_macro_file ("r");
865 u
= fscanf (f
, ("key '%d 0': "), &s
);
868 if (!saved_macros_loaded
)
869 saved_macro
[i
++] = s
;
873 while (*n
< MAX_MACRO_LENGTH
874 && 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
879 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
883 ret
= fscanf (f
, ";\n");
888 while (!found
|| !saved_macros_loaded
);
889 if (!saved_macros_loaded
)
892 saved_macros_loaded
= 1;
898 edit_error_dialog (_("Load macro"), get_sys_error (_("Cannot open macro file")));
902 /* }}} Macro stuff starts here */
904 /* returns 1 on success */
906 edit_save_confirm_cmd (WEdit
* edit
)
910 if (!edit_check_newline (edit
))
913 if (edit_confirm_save
)
915 f
= g_strdup_printf (_("Confirm save file: \"%s\""), edit
->filename
);
916 if (edit_query_dialog2 (_("Save file"), f
, _("&Save"), _("&Cancel")))
923 return edit_save_cmd (edit
);
927 /* returns 1 on success */
929 edit_save_cmd (WEdit
* edit
)
931 int res
, save_lock
= 0;
933 if (!edit
->locked
&& !edit
->delete_file
)
934 save_lock
= edit_lock_file (edit
->filename
);
935 res
= edit_save_file (edit
, edit
->filename
);
937 /* Maintain modify (not save) lock on failure */
938 if ((res
> 0 && edit
->locked
) || save_lock
)
939 edit
->locked
= edit_unlock_file (edit
->filename
);
941 /* On failure try 'save as', it does locking on its own */
943 return edit_save_as_cmd (edit
);
944 edit
->force
|= REDRAW_COMPLETELY
;
947 edit
->delete_file
= 0;
955 /* returns 1 on success */
957 edit_new_cmd (WEdit
* edit
)
961 if (edit_query_dialog2
964 ("Current text was modified without a file save.\nContinue discards these changes"),
965 _("C&ontinue"), _("&Cancel")))
967 edit
->force
|= REDRAW_COMPLETELY
;
971 edit
->force
|= REDRAW_COMPLETELY
;
973 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
976 /* returns 1 on error */
978 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
980 int prev_locked
= edit
->locked
;
981 char *prev_filename
= g_strdup (edit
->filename
);
983 if (!edit_reload (edit
, exp
))
985 g_free (prev_filename
);
990 edit_unlock_file (prev_filename
);
991 g_free (prev_filename
);
996 edit_load_syntax_file (WEdit
* edit
)
1001 if (geteuid () == 0)
1003 dir
= query_dialog (_("Syntax file edit"),
1004 _("Which syntax file you want to edit?"), D_NORMAL
, 2,
1005 _("&User"), _("&System Wide"));
1008 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
1009 if (!exist_file (extdir
))
1012 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
1019 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
1020 check_for_default (extdir
, buffer
);
1021 edit_load_file_from_filename (edit
, buffer
);
1025 edit_load_file_from_filename (edit
, extdir
);
1031 edit_load_menu_file (WEdit
* edit
)
1037 dir
= query_dialog (_("Menu edit"),
1038 _("Which menu file do you want to edit?"), D_NORMAL
,
1039 geteuid () != 0 ? 2 : 3, _("&Local"), _("&User"), _("&System Wide"));
1041 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1043 if (!exist_file (menufile
))
1046 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1052 buffer
= g_strdup (EDIT_LOCAL_MENU
);
1053 check_for_default (menufile
, buffer
);
1054 chmod (buffer
, 0600);
1058 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
1059 check_for_default (menufile
, buffer
);
1063 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
1064 if (!exist_file (buffer
))
1067 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
1076 edit_load_file_from_filename (edit
, buffer
);
1083 edit_load_cmd (WEdit
* edit
, edit_current_file_t what
)
1088 && (edit_query_dialog2
1090 _("Current text was modified without a file save.\n"
1091 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")) == 1))
1093 edit
->force
|= REDRAW_COMPLETELY
;
1099 case EDIT_FILE_COMMON
:
1100 exp
= input_expand_dialog (_("Load"), _("Enter file name:"),
1101 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1106 edit_load_file_from_filename (edit
, exp
);
1111 case EDIT_FILE_SYNTAX
:
1112 edit_load_syntax_file (edit
);
1115 case EDIT_FILE_MENU
:
1116 edit_load_menu_file (edit
);
1123 edit
->force
|= REDRAW_COMPLETELY
;
1128 if mark2 is -1 then marking is from mark1 to the cursor.
1129 Otherwise its between the markers. This handles this.
1130 Returns 1 if no text is marked.
1133 eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1135 if (edit
->mark1
!= edit
->mark2
)
1137 long start_bol
, start_eol
;
1138 long end_bol
, end_eol
;
1141 if (edit
->mark2
>= 0)
1143 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1144 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1148 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1149 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1150 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1152 if (column_highlighting
1153 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1154 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
))))
1157 start_bol
= edit_bol (edit
, *start_mark
);
1158 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1159 end_bol
= edit_bol (edit
, *end_mark
);
1160 end_eol
= edit_eol (edit
, *end_mark
);
1161 col1
= min (edit
->column1
, edit
->column2
);
1162 col2
= max (edit
->column1
, edit
->column2
);
1165 edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
,
1168 edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
,
1171 *start_mark
-= diff1
;
1173 *start_mark
= max (*start_mark
, start_eol
);
1174 *end_mark
= min (*end_mark
, end_eol
);
1180 *start_mark
= *end_mark
= 0;
1181 edit
->column2
= edit
->column1
= 0;
1186 #define space_width 1
1189 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1193 cursor
= edit
->curs1
;
1194 col
= edit_get_col (edit
);
1195 for (i
= 0; i
< size
; i
++)
1197 if (data
[i
] == '\n')
1198 { /* fill in and move to next line */
1201 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1203 l
= width
- (edit_get_col (edit
) - col
);
1206 edit_insert (edit
, ' ');
1210 for (p
= edit
->curs1
;; p
++)
1212 if (p
== edit
->last_byte
)
1214 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1215 edit_insert_ahead (edit
, '\n');
1219 if (edit_get_byte (edit
, p
) == '\n')
1225 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1226 l
= col
- edit_get_col (edit
);
1227 while (l
>= space_width
)
1229 edit_insert (edit
, ' ');
1234 edit_insert (edit
, data
[i
]);
1236 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1239 #define TEMP_BUF_LEN 1024
1242 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1246 int blocklen
= -1, width
;
1247 unsigned char *data
;
1248 cursor
= edit
->curs1
;
1249 col
= edit_get_col (edit
);
1250 data
= g_malloc0 (TEMP_BUF_LEN
);
1251 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0)
1253 for (width
= 0; width
< blocklen
; width
++)
1255 if (data
[width
] == '\n')
1258 for (i
= 0; i
< blocklen
; i
++)
1260 if (data
[i
] == '\n')
1261 { /* fill in and move to next line */
1264 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1266 l
= width
- (edit_get_col (edit
) - col
);
1269 edit_insert (edit
, ' ');
1273 for (p
= edit
->curs1
;; p
++)
1275 if (p
== edit
->last_byte
)
1277 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1278 edit_insert_ahead (edit
, '\n');
1282 if (edit_get_byte (edit
, p
) == '\n')
1288 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1289 l
= col
- edit_get_col (edit
);
1290 while (l
>= space_width
)
1292 edit_insert (edit
, ' ');
1297 edit_insert (edit
, data
[i
]);
1300 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1302 edit
->force
|= REDRAW_PAGE
;
1307 edit_block_copy_cmd (WEdit
* edit
)
1309 long start_mark
, end_mark
, current
= edit
->curs1
;
1311 unsigned char *copy_buf
;
1313 edit_update_curs_col (edit
);
1314 if (eval_marks (edit
, &start_mark
, &end_mark
))
1317 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1319 /* all that gets pushed are deletes hence little space is used on the stack */
1321 edit_push_markers (edit
);
1323 if (column_highlighting
)
1325 edit_insert_column_of_text (edit
, copy_buf
, size
, abs (edit
->column2
- edit
->column1
));
1330 edit_insert_ahead (edit
, copy_buf
[size
]);
1334 edit_scroll_screen_over_cursor (edit
);
1336 if (column_highlighting
)
1338 edit_set_markers (edit
, 0, 0, 0, 0);
1339 edit_push_action (edit
, COLUMN_ON
);
1340 column_highlighting
= 0;
1342 else if (start_mark
< current
&& end_mark
> current
)
1343 edit_set_markers (edit
, start_mark
, end_mark
+ end_mark
- start_mark
, 0, 0);
1345 edit
->force
|= REDRAW_PAGE
;
1350 edit_block_move_cmd (WEdit
* edit
)
1354 unsigned char *copy_buf
;
1355 long start_mark
, end_mark
;
1359 if (eval_marks (edit
, &start_mark
, &end_mark
))
1361 if (column_highlighting
)
1363 edit_update_curs_col (edit
);
1365 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1366 if ((x
> edit
->column1
&& x
< edit
->column2
)
1367 || (x
> edit
->column2
&& x
< edit
->column1
))
1370 else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1373 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1374 if (edit_query_dialog2
1377 ("Block is large, you may not be able to undo this action"),
1378 _("C&ontinue"), _("&Cancel")))
1381 edit_push_markers (edit
);
1382 current
= edit
->curs1
;
1383 if (column_highlighting
)
1387 line
= edit
->curs_line
;
1388 if (edit
->mark2
< 0)
1389 edit_mark_cmd (edit
, 0);
1390 c1
= min (edit
->column1
, edit
->column2
);
1391 c2
= max (edit
->column1
, edit
->column2
);
1392 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1395 edit_block_delete_cmd (edit
);
1398 edit_move_to_line (edit
, line
);
1399 edit_cursor_move (edit
,
1400 edit_move_forward3 (edit
,
1401 edit_bol (edit
, edit
->curs1
), x
, 0) - edit
->curs1
);
1402 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1405 line
= edit
->curs_line
;
1406 edit_update_curs_col (edit
);
1408 edit_block_delete_cmd (edit
);
1409 edit_move_to_line (edit
, line
);
1410 edit_cursor_move (edit
,
1411 edit_move_forward3 (edit
,
1413 edit
->curs1
), x
, 0) - edit
->curs1
);
1415 edit_set_markers (edit
, 0, 0, 0, 0);
1416 edit_push_action (edit
, COLUMN_ON
);
1417 column_highlighting
= 0;
1421 copy_buf
= g_malloc0 (end_mark
- start_mark
);
1422 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1423 edit_scroll_screen_over_cursor (edit
);
1425 while (count
< end_mark
)
1427 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1430 edit_scroll_screen_over_cursor (edit
);
1431 edit_cursor_move (edit
,
1432 current
- edit
->curs1
-
1433 (((current
- edit
->curs1
) > 0) ? end_mark
- start_mark
: 0));
1434 edit_scroll_screen_over_cursor (edit
);
1435 while (count
-- > start_mark
)
1436 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1437 edit_set_markers (edit
, edit
->curs1
, edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1439 edit_scroll_screen_over_cursor (edit
);
1441 edit
->force
|= REDRAW_PAGE
;
1445 edit_delete_column_of_text (WEdit
* edit
)
1447 long p
, q
, r
, m1
, m2
;
1450 eval_marks (edit
, &m1
, &m2
);
1451 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1452 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1453 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1454 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
1455 c
= max (c
, max (edit
->column1
, edit
->column2
));
1459 r
= edit_bol (edit
, edit
->curs1
);
1460 p
= edit_move_forward3 (edit
, r
, b
, 0);
1461 q
= edit_move_forward3 (edit
, r
, c
, 0);
1466 edit_cursor_move (edit
, p
- edit
->curs1
);
1469 /* delete line between margins */
1470 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1471 edit_delete (edit
, 1);
1475 /* move to next line except on the last delete */
1476 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1480 /* if success return 0 */
1482 edit_block_delete (WEdit
* edit
)
1485 long start_mark
, end_mark
;
1486 int curs_pos
, line_width
;
1487 long curs_line
, c1
, c2
;
1489 if (eval_marks (edit
, &start_mark
, &end_mark
))
1491 if (column_highlighting
&& edit
->mark2
< 0)
1492 edit_mark_cmd (edit
, 0);
1493 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1495 /* Warning message with a query to continue or cancel the operation */
1496 if (edit_query_dialog2
1499 ("Block is large, you may not be able to undo this action"),
1500 _("C&ontinue"), _("&Cancel")))
1505 c1
= min (edit
->column1
, edit
->column2
);
1506 c2
= max (edit
->column1
, edit
->column2
);
1510 edit_push_markers (edit
);
1512 curs_line
= edit
->curs_line
;
1514 /* calculate line width and cursor position before cut */
1515 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1516 edit_eol (edit
, edit
->curs1
));
1517 curs_pos
= edit
->curs_col
+ edit
->over_col
;
1519 /* move cursor to start of selection */
1520 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1521 edit_scroll_screen_over_cursor (edit
);
1523 if (start_mark
< end_mark
)
1525 if (column_highlighting
)
1527 if (edit
->mark2
< 0)
1528 edit_mark_cmd (edit
, 0);
1529 edit_delete_column_of_text (edit
);
1530 /* move cursor to the saved position */
1531 edit_move_to_line (edit
, curs_line
);
1532 /* calculate line width after cut */
1533 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
1534 edit_eol (edit
, edit
->curs1
));
1535 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
1536 edit
->over_col
= curs_pos
- line_width
;
1540 while (count
< end_mark
)
1542 edit_delete (edit
, 1);
1547 edit_set_markers (edit
, 0, 0, 0, 0);
1548 edit
->force
|= REDRAW_PAGE
;
1552 /* returns 1 if canceelled by user */
1554 edit_block_delete_cmd (WEdit
* edit
)
1556 long start_mark
, end_mark
;
1557 if (eval_marks (edit
, &start_mark
, &end_mark
))
1559 edit_delete_line (edit
);
1562 return edit_block_delete (edit
);
1565 #define INPUT_INDEX 9
1568 editcmd_find (WEdit
* edit
, gsize
* len
)
1570 off_t search_start
= edit
->search_start
;
1572 long start_mark
= 0;
1573 long end_mark
= edit
->last_byte
;
1576 if (edit_search_options
.only_in_selection
)
1578 mark_res
= eval_marks (edit
, &start_mark
, &end_mark
);
1581 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1582 edit
->search
->error_str
= g_strdup (_("Search string not found"));
1585 if (edit_search_options
.backwards
)
1587 if (search_start
> end_mark
|| search_start
<= start_mark
)
1589 search_start
= end_mark
;
1594 if (search_start
< start_mark
|| search_start
>= end_mark
)
1596 search_start
= start_mark
;
1602 if (edit_search_options
.backwards
)
1603 end_mark
= max (1, edit
->curs1
) - 1;
1605 if (edit_search_options
.backwards
)
1607 search_end
= end_mark
;
1608 while ((int) search_start
>= start_mark
)
1610 if (search_end
> (off_t
) (search_start
+ edit
->search
->original_len
) &&
1611 mc_search_is_fixed_search_str (edit
->search
))
1613 search_end
= search_start
+ edit
->search
->original_len
;
1615 if (mc_search_run (edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1616 && edit
->search
->normal_offset
== search_start
)
1622 edit
->search
->error_str
= g_strdup (_("Search string not found"));
1626 return mc_search_run (edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1632 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1633 (and the above) routines to work properly - paul */
1635 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1638 edit_replace_cmd__conv_to_display (char *str
)
1642 tmp
= str_convert_to_display (str
);
1644 if (tmp
&& tmp
->len
)
1646 return g_string_free (tmp
, FALSE
);
1648 g_string_free (tmp
, TRUE
);
1650 return g_strdup (str
);
1654 edit_replace_cmd__conv_to_input (char *str
)
1658 tmp
= str_convert_to_input (str
);
1660 if (tmp
&& tmp
->len
)
1662 return g_string_free (tmp
, FALSE
);
1664 g_string_free (tmp
, TRUE
);
1665 return g_strdup (str
);
1667 return g_strdup (str
);
1670 /* call with edit = 0 before shutdown to close memory leaks */
1672 edit_replace_cmd (WEdit
* edit
, int again
)
1674 /* 1 = search string, 2 = replace with */
1675 static char *saved1
= NULL
; /* saved default[123] */
1676 static char *saved2
= NULL
;
1677 char *input1
= NULL
; /* user input from the dialog */
1678 char *input2
= NULL
;
1682 long times_replaced
= 0, last_search
;
1683 gboolean once_found
= FALSE
;
1687 g_free (saved1
), saved1
= NULL
;
1688 g_free (saved2
), saved2
= NULL
;
1692 last_search
= edit
->last_byte
;
1694 edit
->force
|= REDRAW_COMPLETELY
;
1696 if (again
&& !saved1
&& !saved2
)
1701 input1
= g_strdup (saved1
? saved1
: "");
1702 input2
= g_strdup (saved2
? saved2
: "");
1706 char *tmp_inp1
, *tmp_inp2
;
1707 disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
1708 disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
1710 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1712 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1717 if (input1
== NULL
|| *input1
== '\0')
1719 edit
->force
= REDRAW_COMPLETELY
;
1725 input1
= edit_replace_cmd__conv_to_input (input1
);
1726 input2
= edit_replace_cmd__conv_to_input (input2
);
1730 g_free (saved1
), saved1
= g_strdup (input1
);
1731 g_free (saved2
), saved2
= g_strdup (input2
);
1735 mc_search_free (edit
->search
);
1736 edit
->search
= NULL
;
1742 edit
->search
= mc_search_new (input1
, -1);
1743 if (edit
->search
== NULL
)
1745 edit
->search_start
= edit
->curs1
;
1748 edit
->search
->search_type
= edit_search_options
.type
;
1749 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1750 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
1751 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1752 edit
->search
->search_fn
= edit_search_cmd_callback
;
1755 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1756 && edit_search_options
.backwards
)
1757 edit
->search_start
--;
1759 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1760 && !edit_search_options
.backwards
)
1761 edit
->search_start
++;
1768 if (!editcmd_find (edit
, &len
))
1770 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1771 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
)))
1773 edit_error_dialog (_("Search"), edit
->search
->error_str
);
1778 new_start
= edit
->search
->normal_offset
;
1780 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1781 /*returns negative on not found or error in pattern */
1783 if (edit
->search_start
>= 0)
1787 edit
->found_start
= edit
->search_start
;
1788 i
= edit
->found_len
= len
;
1790 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1791 edit_scroll_screen_over_cursor (edit
);
1795 if (edit
->replace_mode
== 0)
1798 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1800 edit_scroll_downward (edit
, l
);
1802 edit_scroll_upward (edit
, -l
);
1804 edit_scroll_screen_over_cursor (edit
);
1805 edit
->force
|= REDRAW_PAGE
;
1806 edit_render_keypress (edit
);
1808 /*so that undo stops at each query */
1809 edit_push_key_press (edit
);
1810 /* and prompt 2/3 down */
1811 disp1
= edit_replace_cmd__conv_to_display (saved1
);
1812 disp2
= edit_replace_cmd__conv_to_display (saved2
);
1813 switch (editcmd_dialog_replace_prompt_show (edit
, disp1
, disp2
, -1, -1))
1818 case B_SKIP_REPLACE
:
1822 edit
->replace_mode
= 1;
1826 edit
->replace_mode
= -1;
1833 { /* delete then insert new */
1834 GString
*repl_str
, *tmp_str
;
1835 tmp_str
= g_string_new (input2
);
1837 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1838 g_string_free (tmp_str
, TRUE
);
1839 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1841 edit_error_dialog (_("Replace"), edit
->search
->error_str
);
1846 edit_delete (edit
, 1);
1848 while (++i
< repl_str
->len
)
1849 edit_insert (edit
, repl_str
->str
[i
]);
1851 g_string_free (repl_str
, TRUE
);
1852 edit
->found_len
= i
;
1854 /* so that we don't find the same string again */
1855 if (edit_search_options
.backwards
)
1857 last_search
= edit
->search_start
;
1858 edit
->search_start
--;
1862 edit
->search_start
+= i
;
1863 last_search
= edit
->last_byte
;
1865 edit_scroll_screen_over_cursor (edit
);
1869 const char *msg
= _("Replace");
1870 /* try and find from right here for next search */
1871 edit
->search_start
= edit
->curs1
;
1872 edit_update_curs_col (edit
);
1874 edit
->force
|= REDRAW_PAGE
;
1875 edit_render_keypress (edit
);
1878 message (D_NORMAL
, msg
, _("%ld replacements made"), times_replaced
);
1881 query_dialog (msg
, _("Search string not found"), D_NORMAL
, 1, _("&OK"));
1882 edit
->replace_mode
= -1;
1885 while (edit
->replace_mode
>= 0);
1887 edit
->force
= REDRAW_COMPLETELY
;
1888 edit_scroll_screen_over_cursor (edit
);
1896 edit_search_cmd (WEdit
* edit
, int again
)
1898 char *search_string
= NULL
, *search_string_dup
= NULL
;
1904 if (edit
->search
!= NULL
)
1906 search_string
= g_strndup (edit
->search
->original
, edit
->search
->original_len
);
1907 search_string_dup
= search_string
;
1912 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1913 if (history
!= NULL
&& history
->data
!= NULL
)
1915 search_string_dup
= search_string
= (char *) g_strdup (history
->data
);
1916 history
= g_list_first (history
);
1917 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1918 g_list_free (history
);
1920 edit
->search_start
= edit
->curs1
;
1928 if (search_string
&& *search_string
)
1930 tmp
= str_convert_to_display (search_string
);
1934 g_string_free (tmp
, TRUE
);
1937 g_free (search_string
);
1938 search_string
= search_string_dup
= g_string_free (tmp
, FALSE
);
1942 #endif /* HAVE_CHARSET */
1943 editcmd_dialog_search_show (edit
, &search_string
);
1944 g_free (search_string_dup
);
1945 search_string_dup
= NULL
;
1947 if (search_string
&& *search_string
)
1949 tmp
= str_convert_to_input (search_string
);
1953 g_string_free (tmp
, TRUE
);
1956 g_free (search_string
);
1957 search_string
= g_string_free (tmp
, FALSE
);
1961 #endif /* HAVE_CHARSET */
1963 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1965 if (search_string
== NULL
)
1967 edit
->force
|= REDRAW_COMPLETELY
;
1968 edit_scroll_screen_over_cursor (edit
);
1974 mc_search_free (edit
->search
);
1975 edit
->search
= NULL
;
1981 edit
->search
= mc_search_new (search_string
, -1);
1982 if (edit
->search
== NULL
)
1984 edit
->search_start
= edit
->curs1
;
1985 g_free (search_string
);
1989 edit
->search
->search_type
= edit_search_options
.type
;
1990 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
1991 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
1992 edit
->search
->whole_words
= edit_search_options
.whole_words
;
1993 edit
->search
->search_fn
= edit_search_cmd_callback
;
1996 g_free (search_string
);
1998 if (search_create_bookmark
)
2000 edit_search_cmd_search_create_bookmark (edit
);
2004 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
2005 && edit_search_options
.backwards
)
2006 edit
->search_start
--;
2008 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
2009 && !edit_search_options
.backwards
)
2010 edit
->search_start
++;
2012 if (editcmd_find (edit
, &len
))
2014 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
2015 edit
->found_len
= len
;
2017 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
2018 edit_scroll_screen_over_cursor (edit
);
2019 if (edit_search_options
.backwards
)
2020 edit
->search_start
--;
2022 edit
->search_start
++;
2026 edit
->search_start
= edit
->curs1
;
2027 if (edit
->search
->error_str
)
2028 edit_error_dialog (_("Search"), edit
->search
->error_str
);
2032 edit
->force
|= REDRAW_COMPLETELY
;
2033 edit_scroll_screen_over_cursor (edit
);
2038 * Check if it's OK to close the editor. If there are unsaved changes,
2039 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
2042 edit_ok_to_exit (WEdit
* edit
)
2044 if (!edit
->modified
)
2047 if (!edit_check_newline (edit
))
2050 switch (edit_query_dialog3
2051 (_("Quit"), _("File was modified, save with exit?"),
2052 _("&Cancel quit"), _("&Yes"), _("&No")))
2055 edit_push_markers (edit
);
2056 edit_set_markers (edit
, 0, 0, 0, 0);
2057 if (!edit_save_cmd (edit
))
2070 /* Return a null terminated length of text. Result must be g_free'd */
2071 static unsigned char *
2072 edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
)
2074 unsigned char *s
, *r
;
2075 r
= s
= g_malloc0 (finish
- start
+ 1);
2076 if (column_highlighting
)
2079 /* copy from buffer, excluding chars that are out of the column 'margins' */
2080 while (start
< finish
)
2084 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0, start
);
2085 c
= edit_get_byte (edit
, start
);
2086 if ((x
>= edit
->column1
&& x
< edit
->column2
)
2087 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n')
2097 *l
= finish
- start
;
2098 while (start
< finish
)
2099 *s
++ = edit_get_byte (edit
, start
++);
2105 /* save block, returns 1 on success */
2107 edit_save_block (WEdit
* edit
, const char *filename
, long start
, long finish
)
2111 file
= mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
2112 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
);
2116 if (column_highlighting
)
2119 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof (VERTICAL_MAGIC
));
2122 unsigned char *block
, *p
;
2123 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
2126 r
= mc_write (file
, p
, len
);
2139 len
= finish
- start
;
2140 buf
= g_malloc0 (TEMP_BUF_LEN
);
2141 while (start
!= finish
)
2143 end
= min (finish
, start
+ TEMP_BUF_LEN
);
2144 for (; i
< end
; i
++)
2145 buf
[i
- start
] = edit_get_byte (edit
, i
);
2146 len
-= mc_write (file
, (char *) buf
, end
- start
);
2157 /* copies a block to clipboard file */
2159 edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
2163 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2164 ret
= edit_save_block (edit
, tmp
, start
, finish
);
2170 edit_paste_from_history (WEdit
* edit
)
2173 edit_error_dialog (_("Error"), _("This function is not implemented"));
2177 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2179 long start_mark
, end_mark
;
2180 if (eval_marks (edit
, &start_mark
, &end_mark
))
2182 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2184 edit_error_dialog (_("Copy to clipboard"),
2185 get_sys_error (_("Unable to save to file")));
2188 /* try use external clipboard utility */
2189 copy_file_to_ext_clip ();
2191 edit_mark_cmd (edit
, 1);
2196 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2198 long start_mark
, end_mark
;
2199 if (eval_marks (edit
, &start_mark
, &end_mark
))
2201 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2203 edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file"));
2206 /* try use external clipboard utility */
2207 copy_file_to_ext_clip ();
2209 edit_block_delete_cmd (edit
);
2210 edit_mark_cmd (edit
, 1);
2215 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2218 /* try use external clipboard utility */
2219 paste_to_file_from_ext_clip ();
2220 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2221 edit_insert_file (edit
, tmp
);
2227 * Ask user for the line and go to that line.
2228 * Negative numbers mean line from the end (i.e. -1 is the last line).
2231 edit_goto_cmd (WEdit
* edit
)
2234 static long line
= 0; /* line as typed, saved as default */
2239 g_snprintf (s
, sizeof (s
), "%ld", line
);
2240 f
= input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE
,
2251 l
= strtol (f
, &error
, 0);
2260 l
= edit
->total_lines
+ l
+ 2;
2261 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2262 edit_move_to_line (edit
, l
- 1);
2263 edit
->force
|= REDRAW_COMPLETELY
;
2268 /* Return 1 on success */
2270 edit_save_block_cmd (WEdit
* edit
)
2272 long start_mark
, end_mark
;
2275 if (eval_marks (edit
, &start_mark
, &end_mark
))
2278 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2280 input_expand_dialog (_("Save block"), _("Enter file name:"),
2281 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2283 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2293 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2296 edit
->force
|= REDRAW_COMPLETELY
;
2302 edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file")));
2306 edit
->force
|= REDRAW_COMPLETELY
;
2311 /* returns 1 on success */
2313 edit_insert_file_cmd (WEdit
* edit
)
2318 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2319 exp
= input_expand_dialog (_("Insert file"), _("Enter file name:"),
2320 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2322 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2332 if (edit_insert_file (edit
, exp
))
2335 edit
->force
|= REDRAW_COMPLETELY
;
2341 edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file")));
2345 edit
->force
|= REDRAW_COMPLETELY
;
2349 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2351 edit_sort_cmd (WEdit
* edit
)
2353 static char *old
= 0;
2355 long start_mark
, end_mark
;
2358 if (eval_marks (edit
, &start_mark
, &end_mark
))
2360 edit_error_dialog (_("Sort block"), _("You must first highlight a block of text"));
2364 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2365 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2368 exp
= input_dialog (_("Run sort"),
2369 _("Enter sort options (see manpage) separated by whitespace:"),
2370 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2376 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2377 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2382 if (e
== -1 || e
== 127)
2384 edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command")));
2389 sprintf (q
, "%d ", e
);
2390 tmp
= g_strdup_printf (_("Sort returned non-zero: %s"), q
);
2391 edit_error_dialog (_("Sort"), tmp
);
2397 edit
->force
|= REDRAW_COMPLETELY
;
2399 if (edit_block_delete_cmd (edit
))
2401 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2402 edit_insert_file (edit
, tmp
);
2408 * Ask user for a command, execute it and paste its output back to the
2412 edit_ext_cmd (WEdit
* edit
)
2418 input_dialog (_("Paste output of external command"),
2419 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2424 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2431 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2435 edit
->force
|= REDRAW_COMPLETELY
;
2436 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2437 edit_insert_file (edit
, tmp
);
2442 /* if block is 1, a block must be highlighted and the shell command
2443 processes it. If block is 0 the shell command is a straight system
2444 command, that just produces some output which is to be inserted */
2446 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2448 long start_mark
, end_mark
;
2450 FILE *script_home
= NULL
;
2451 FILE *block_file
= NULL
;
2452 gchar
*o
, *h
, *b
, *tmp
;
2453 char *quoted_name
= NULL
;
2455 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2456 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2457 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2459 script_home
= fopen (h
, "r");
2460 if (script_home
== NULL
)
2462 FILE *script_src
= NULL
;
2464 script_home
= fopen (h
, "w");
2465 if (script_home
== NULL
)
2467 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2468 edit_error_dialog ("", get_sys_error (tmp
));
2470 goto edit_block_process_cmd__EXIT
;
2473 script_src
= fopen (o
, "r");
2474 if (script_src
== NULL
)
2476 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2477 script_src
= fopen (o
, "r");
2478 if (script_src
== NULL
)
2480 fclose (script_home
);
2482 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2483 edit_error_dialog ("", get_sys_error (tmp
));
2485 goto edit_block_process_cmd__EXIT
;
2488 while (fgets (buf
, sizeof (buf
), script_src
))
2489 fputs (buf
, script_home
);
2490 fclose (script_src
);
2492 if (fclose (script_home
))
2494 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2495 edit_error_dialog ("", get_sys_error (tmp
));
2497 goto edit_block_process_cmd__EXIT
;
2500 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2501 edit_error_dialog ("", get_sys_error (tmp
));
2508 { /* for marked block run indent formatter */
2509 if (eval_marks (edit
, &start_mark
, &end_mark
))
2511 edit_error_dialog (_("Process block"),
2512 _("You must first highlight a block of text"));
2513 goto edit_block_process_cmd__EXIT
;
2515 edit_save_block (edit
, b
, start_mark
, end_mark
);
2516 quoted_name
= name_quote (edit
->filename
, 0);
2519 * Initial space is to avoid polluting bash history.
2521 * $1 - name of the edited file (to check its extension etc).
2522 * $2 - file containing the current block.
2523 * $3 - file where error messages should be put
2524 * (for compatibility with old scripts).
2526 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2527 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2532 * No block selected, just execute the command for the file.
2534 * $1 - name of the edited file.
2536 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2537 quoted_name
, (char *) NULL
);
2540 if (system (tmp
) == -1)
2542 edit_error_dialog (_("Process block"), _("Error calling program"));
2547 g_free (quoted_name
);
2548 close_error_pipe (D_NORMAL
, NULL
);
2550 edit_refresh_cmd (edit
);
2551 edit
->force
|= REDRAW_COMPLETELY
;
2553 /* insert result block */
2554 if (block
&& !edit_block_delete_cmd (edit
))
2556 edit_insert_file (edit
, b
);
2557 block_file
= fopen (b
, "w");
2558 if (block_file
!= NULL
)
2559 fclose (block_file
);
2564 edit_block_process_cmd__EXIT
:
2570 /* prints at the cursor */
2571 /* returns the number of chars printed */
2573 edit_print_string (WEdit
* e
, const char *s
)
2576 while (s
[i
] != '\0')
2577 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2578 e
->force
|= REDRAW_COMPLETELY
;
2579 edit_update_screen (e
);
2585 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
2590 to
= name_quote (to
, 0);
2591 subject
= name_quote (subject
, 0);
2592 cc
= name_quote (cc
, 0);
2593 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
2607 for (i
= 0; i
< edit
->last_byte
; i
++)
2608 fputc (edit_get_byte (edit
, i
), p
);
2613 #define MAIL_DLG_HEIGHT 12
2616 edit_mail_dialog (WEdit
* edit
)
2619 char *tmail_subject
;
2622 static char *mail_cc_last
= 0;
2623 static char *mail_subject_last
= 0;
2624 static char *mail_to_last
= 0;
2626 QuickWidget quick_widgets
[] = {
2627 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2628 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2629 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2630 /* 3 */ QUICK_LABEL (3, 50, 7, MAIL_DLG_HEIGHT
, N_("Copies to")),
2631 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2633 /* 5 */ QUICK_LABEL (3, 50, 5, MAIL_DLG_HEIGHT
, N_("Subject")),
2634 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2635 /* 7 */ QUICK_LABEL (3, 50, 3, MAIL_DLG_HEIGHT
, N_("To")),
2636 /* 8 */ QUICK_LABEL (3, 50, 2, MAIL_DLG_HEIGHT
, N_("mail -s <subject> -c <cc> <to>")),
2640 QuickDialog Quick_input
= {
2641 50, MAIL_DLG_HEIGHT
, -1, -1, N_("Mail"),
2642 "[Input Line Keys]", quick_widgets
, FALSE
2645 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2646 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2647 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2649 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2651 g_free (mail_cc_last
);
2652 g_free (mail_subject_last
);
2653 g_free (mail_to_last
);
2654 mail_cc_last
= tmail_cc
;
2655 mail_subject_last
= tmail_subject
;
2656 mail_to_last
= tmail_to
;
2657 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2662 /*******************/
2663 /* Word Completion */
2664 /*******************/
2667 is_break_char (char c
)
2669 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2672 /* find first character of current word */
2674 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
2679 /* return if at begin of file */
2680 if (edit
->curs1
<= 0)
2683 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2684 /* return if not at end or in word */
2685 if (is_break_char (c
))
2688 /* search start of word to be completed */
2691 /* return if at begin of file */
2692 if ((gsize
) edit
->curs1
< i
)
2696 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2698 if (is_break_char (c
))
2700 /* return if word starts with digit */
2704 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2713 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2715 /* collect the possible completions */
2717 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
2718 char *match_expr
, struct selection
*compl, gsize
* num
)
2729 srch
= mc_search_new (match_expr
, -1);
2733 if (mc_config_get_bool
2734 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
2736 last_byte
= edit
->last_byte
;
2743 srch
->search_type
= MC_SEARCH_T_REGEX
;
2744 srch
->is_case_sensitive
= TRUE
;
2745 srch
->search_fn
= edit_search_cmd_callback
;
2747 /* collect max MAX_WORD_COMPLETIONS completions */
2751 /* get next match */
2752 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
2754 start
= srch
->normal_offset
;
2756 /* add matched completion if not yet added */
2757 temp
= g_string_new ("");
2758 for (i
= 0; i
< len
; i
++)
2760 skip
= edit_get_byte (edit
, start
+ i
);
2763 g_string_append_c (temp
, skip
);
2768 for (i
= 0; i
< (gsize
) * num
; i
++)
2771 ((char *) &compl[i
].text
[word_len
],
2772 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
2774 struct selection
this = compl[i
];
2775 for (++i
; i
< *num
; i
++)
2777 compl[i
- 1] = compl[i
];
2779 compl[*num
- 1] = this;
2781 break; /* skip it, already added */
2786 g_string_free (temp
, TRUE
);
2789 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
2791 g_free (compl[0].text
);
2792 for (i
= 1; i
< *num
; i
++)
2794 compl[i
- 1] = compl[i
];
2801 recoded
= str_convert_to_display (temp
->str
);
2803 if (recoded
&& recoded
->len
)
2805 g_string_free (temp
, TRUE
);
2809 g_string_free (recoded
, TRUE
);
2812 compl[*num
].text
= temp
->str
;
2813 compl[*num
].len
= temp
->len
;
2816 g_string_free (temp
, FALSE
);
2818 /* note the maximal length needed for the completion dialog */
2822 mc_search_free (srch
);
2827 * Complete current word using regular expression search
2828 * backwards beginning at the current cursor position.
2831 edit_complete_word_cmd (WEdit
* edit
)
2833 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2834 long word_start
= 0;
2835 unsigned char *bufpos
;
2837 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2839 /* search start of word to be completed */
2840 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2843 /* prepare match expression */
2844 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2846 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2849 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2850 (int) word_len
, bufpos
);
2852 /* collect the possible completions */
2853 /* start search from begin to end of file */
2855 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2856 (struct selection
*) &compl, &num_compl
);
2860 /* insert completed word if there is only one match */
2863 for (i
= word_len
; i
< compl[0].len
; i
++)
2864 edit_insert (edit
, *(compl[0].text
+ i
));
2866 /* more than one possible completion => ask the user */
2869 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2870 /* !!! pressed again the selection dialog pops up, but that !!! */
2871 /* !!! seems to require a further internal state !!! */
2874 /* let the user select the preferred completion */
2875 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2876 (struct selection
*) &compl, num_compl
);
2880 g_free (match_expr
);
2881 /* release memory before return */
2882 for (i
= 0; i
< num_compl
; i
++)
2883 g_free (compl[i
].text
);
2887 edit_select_codepage_cmd (WEdit
* edit
)
2890 if (do_select_codepage ())
2891 edit_set_codeset (edit
);
2893 edit
->force
= REDRAW_COMPLETELY
;
2894 edit_refresh_cmd (edit
);
2901 edit_insert_literal_cmd (WEdit
* edit
)
2903 int char_for_insertion
= editcmd_dialog_raw_key_query (_("Insert literal"),
2904 _("Press any key:"), 0);
2905 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
2909 edit_execute_macro_cmd (WEdit
* edit
)
2912 CK_Macro (editcmd_dialog_raw_key_query (_("Execute macro"), _("Press macro hotkey:"),
2914 if (command
== CK_Macro (0))
2915 command
= CK_Insert_Char
;
2917 edit_execute_key_command (edit
, command
, -1);
2921 edit_begin_end_macro_cmd (WEdit
* edit
)
2923 /* edit is a pointer to the widget */
2926 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2927 edit_execute_key_command (edit
, command
, -1);
2932 edit_load_forward_cmd (WEdit
* edit
)
2936 if (edit_query_dialog2
2938 _("Current text was modified without a file save\n"
2939 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")))
2941 edit
->force
|= REDRAW_COMPLETELY
;
2945 if (edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
)
2947 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
2951 edit_stack_iterator
++;
2952 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2954 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2955 edit_history_moveto
[edit_stack_iterator
].line
);
2970 edit_load_back_cmd (WEdit
* edit
)
2974 if (edit_query_dialog2
2976 _("Current text was modified without a file save\n"
2977 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")))
2979 edit
->force
|= REDRAW_COMPLETELY
;
2983 if (edit_stack_iterator
> 0)
2985 edit_stack_iterator
--;
2986 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2988 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2989 edit_history_moveto
[edit_stack_iterator
].line
);
3004 edit_get_match_keyword_cmd (WEdit
* edit
)
3006 gsize word_len
= 0, max_len
= 0;
3009 long word_start
= 0;
3010 unsigned char *bufpos
;
3014 char *tagfile
= NULL
;
3016 etags_hash_t def_hash
[MAX_DEFINITIONS
];
3018 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
3020 def_hash
[i
].filename
= NULL
;
3023 /* search start of word to be completed */
3024 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3027 /* prepare match expression */
3028 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3029 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3031 ptr
= g_get_current_dir ();
3032 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3035 /* Recursive search file 'TAGS' in parent dirs */
3038 ptr
= g_path_get_dirname (path
);
3042 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3043 if (exist_file (tagfile
))
3046 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3051 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3056 max_len
= MAX_WIDTH_DEF_DIALOG
;
3060 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3061 (etags_hash_t
*) & def_hash
, num_def
);
3063 g_free (match_expr
);
3067 edit_move_block_to_right (WEdit
* edit
)
3069 long start_mark
, end_mark
;
3070 long cur_bol
, start_bol
;
3072 if (eval_marks (edit
, &start_mark
, &end_mark
))
3075 start_bol
= edit_bol (edit
, start_mark
);
3076 cur_bol
= edit_bol (edit
, end_mark
- 1);
3079 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3080 if (option_fill_tabs_with_spaces
)
3082 if (option_fake_half_tabs
)
3084 insert_spaces_tab (edit
, 1);
3088 insert_spaces_tab (edit
, 0);
3093 edit_insert (edit
, '\t');
3095 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3100 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3102 while (cur_bol
>= start_bol
);
3103 edit
->force
|= REDRAW_PAGE
;
3107 edit_move_block_to_left (WEdit
* edit
)
3109 long start_mark
, end_mark
;
3110 long cur_bol
, start_bol
;
3111 int i
, del_tab_width
;
3114 if (eval_marks (edit
, &start_mark
, &end_mark
))
3117 start_bol
= edit_bol (edit
, start_mark
);
3118 cur_bol
= edit_bol (edit
, end_mark
- 1);
3121 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3122 if (option_fake_half_tabs
)
3124 del_tab_width
= HALF_TAB_SIZE
;
3128 del_tab_width
= option_tab_spacing
;
3130 next_char
= edit_get_byte (edit
, edit
->curs1
);
3131 if (next_char
== '\t')
3133 edit_delete (edit
, 1);
3135 else if (next_char
== ' ')
3137 for (i
= 1; i
<= del_tab_width
; i
++)
3139 if (next_char
== ' ')
3141 edit_delete (edit
, 1);
3143 next_char
= edit_get_byte (edit
, edit
->curs1
);
3150 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3152 while (cur_bol
>= start_bol
);
3153 edit
->force
|= REDRAW_PAGE
;