1 /* editor high level editing commands
3 Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * \brief Source: editor high level editing commands
31 /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */
40 #include <sys/types.h>
48 #include "lib/global.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h" /* XCTRL */
51 #include "lib/mcconfig.h"
53 #include "lib/strutil.h" /* utf string functions */
54 #include "lib/vfs/mc-vfs/vfs.h"
56 #include "src/history.h"
57 #include "src/widget.h" /* listbox_new() */
58 #include "src/layout.h" /* clr_scr() */
59 #include "src/main.h" /* mc_home source_codepage */
60 #include "src/help.h" /* interactive_display() */
61 #include "src/wtools.h" /* message() */
62 #include "src/charsets.h"
63 #include "src/selcodepage.h"
64 #include "src/cmddef.h"
66 #include "src/editor/edit-impl.h"
67 #include "src/editor/editlock.h"
68 #include "src/editor/edit-widget.h"
69 #include "src/editor/editcmd_dialogs.h"
70 #include "src/editor/etags.h"
74 /* search and replace: */
75 int search_create_bookmark
= 0;
76 /* static int search_in_all_charsets = 0; */
78 /* queries on a save */
79 int edit_confirm_save
= 1;
81 static int edit_save_cmd (WEdit
* edit
);
82 static unsigned char *edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
);
85 edit_search_cmd_search_create_bookmark (WEdit
* edit
)
87 int found
= 0, books
= 0;
88 long l
= 0, l_last
= -1;
92 search_create_bookmark
= 0;
93 book_mark_flush (edit
, -1);
97 if (!mc_search_run (edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
100 edit
->search_start
= edit
->search
->normal_offset
;
102 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
105 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
109 q
= edit
->search
->normal_offset
+ 1;
114 edit_error_dialog (_("Search"), _(" Search string not found "));
118 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
119 edit_scroll_screen_over_cursor (edit
);
124 edit_search_cmd_callback (const void *user_data
, gsize char_offset
)
126 return edit_get_byte ((WEdit
*) user_data
, (long) char_offset
);
130 edit_help_cmd (WEdit
* edit
)
132 interactive_display (NULL
, "[Internal File Editor]");
133 edit
->force
|= REDRAW_COMPLETELY
;
137 edit_refresh_cmd (WEdit
* edit
)
142 edit_get_syntax_color (edit
, -1, &color
);
150 #endif /* !HAVE_SLANG */
154 /* If 0 (quick save) then a) create/truncate <filename> file,
155 b) save to <filename>;
156 if 1 (safe save) then a) save to <tempnam>,
157 b) rename <tempnam> to <filename>;
158 if 2 (do backups) then a) save to <tempnam>,
159 b) rename <filename> to <filename.backup_ext>,
160 c) rename <tempnam> to <filename>. */
162 /* returns 0 on error, -1 on abort */
164 edit_save_file (WEdit
* edit
, const char *filename
)
170 gchar
*real_filename
;
171 int this_save_mode
, fd
= -1;
178 if (*filename
!= PATH_SEP
&& edit
->dir
)
180 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
184 real_filename
= g_strdup (filename
);
187 this_save_mode
= option_save_mode
;
188 if (this_save_mode
!= EDIT_QUICK_SAVE
)
190 if (!vfs_file_is_local (real_filename
) ||
191 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1)
194 * The file does not exists yet, so no safe save or
195 * backup are necessary.
197 this_save_mode
= EDIT_QUICK_SAVE
;
203 if (this_save_mode
== EDIT_QUICK_SAVE
&& !edit
->skip_detach_prompt
)
208 rv
= mc_stat (real_filename
, &sb
);
209 if (rv
== 0 && sb
.st_nlink
> 1)
211 rv
= edit_query_dialog3 (_("Warning"),
212 _(" File has hard-links. Detach before saving? "),
213 _("&Yes"), _("&No"), _("&Cancel"));
217 this_save_mode
= EDIT_SAFE_SAVE
;
220 edit
->skip_detach_prompt
= 1;
223 g_free (real_filename
);
228 /* Prevent overwriting changes from other editor sessions. */
229 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
)
232 /* The default action is "Cancel". */
235 rv
= edit_query_dialog2 (_("Warning"),
236 _("The file has been modified in the meantime. Save anyway?"),
237 _("&Yes"), _("&Cancel"));
240 g_free (real_filename
);
246 if (this_save_mode
!= EDIT_QUICK_SAVE
)
248 char *savedir
, *saveprefix
;
249 const char *slashpos
;
250 slashpos
= strrchr (real_filename
, PATH_SEP
);
253 savedir
= g_strdup (real_filename
);
254 savedir
[slashpos
- real_filename
+ 1] = '\0';
257 savedir
= g_strdup (".");
258 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
260 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
264 g_free (real_filename
);
268 * Close for now because mc_mkstemps use pure open system call
269 * to create temporary file and it needs to be reopened by
270 * VFS-aware mc_open().
275 savename
= g_strdup (real_filename
);
278 ret
= mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
279 ret
= mc_chmod (savename
, edit
->stat1
.st_mode
);
282 fd
= mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
, edit
->stat1
.st_mode
);
287 p
= edit_get_write_filter (savename
, real_filename
);
293 file
= (FILE *) popen (p
, "w");
297 filelen
= edit_write_stream (edit
, file
);
301 if (pclose (file
) != 0)
303 tmp
= g_strconcat (_(" Error writing to pipe: "), p
, " ", (char *) NULL
);
304 edit_error_dialog (_("Error"), tmp
);
313 tmp
= g_strconcat (_(" Cannot open pipe for writing: "), p
, " ", (char *) NULL
);
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 (2, 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_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", (char *) NULL
);
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. \n Continue 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 ()? 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_sentitive
= 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_sentitive
= 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
);
2171 edit_paste_from_history (WEdit
* edit
)
2174 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
2178 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2180 long start_mark
, end_mark
;
2181 if (eval_marks (edit
, &start_mark
, &end_mark
))
2183 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2185 edit_error_dialog (_(" Copy to clipboard "),
2186 get_sys_error (_(" Unable to save to file. ")));
2189 edit_mark_cmd (edit
, 1);
2194 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2196 long start_mark
, end_mark
;
2197 if (eval_marks (edit
, &start_mark
, &end_mark
))
2199 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2201 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
2204 edit_block_delete_cmd (edit
);
2205 edit_mark_cmd (edit
, 1);
2210 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2213 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2214 edit_insert_file (edit
, tmp
);
2220 * Ask user for the line and go to that line.
2221 * Negative numbers mean line from the end (i.e. -1 is the last line).
2224 edit_goto_cmd (WEdit
* edit
)
2227 static long line
= 0; /* line as typed, saved as default */
2232 g_snprintf (s
, sizeof (s
), "%ld", line
);
2233 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
2244 l
= strtol (f
, &error
, 0);
2253 l
= edit
->total_lines
+ l
+ 2;
2254 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2255 edit_move_to_line (edit
, l
- 1);
2256 edit
->force
|= REDRAW_COMPLETELY
;
2261 /* Return 1 on success */
2263 edit_save_block_cmd (WEdit
* edit
)
2265 long start_mark
, end_mark
;
2268 if (eval_marks (edit
, &start_mark
, &end_mark
))
2271 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2273 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
2274 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2276 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2286 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2289 edit
->force
|= REDRAW_COMPLETELY
;
2295 edit_error_dialog (_(" Save Block "), get_sys_error (_(" Cannot save file. ")));
2299 edit
->force
|= REDRAW_COMPLETELY
;
2304 /* returns 1 on success */
2306 edit_insert_file_cmd (WEdit
* edit
)
2311 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2312 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2313 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2315 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2325 if (edit_insert_file (edit
, exp
))
2328 edit
->force
|= REDRAW_COMPLETELY
;
2334 edit_error_dialog (_(" Insert File "), get_sys_error (_(" Cannot insert file. ")));
2338 edit
->force
|= REDRAW_COMPLETELY
;
2342 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2344 edit_sort_cmd (WEdit
* edit
)
2346 static char *old
= 0;
2348 long start_mark
, end_mark
;
2351 if (eval_marks (edit
, &start_mark
, &end_mark
))
2353 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2357 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2358 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2361 exp
= input_dialog (_(" Run Sort "),
2362 _(" Enter sort options (see manpage) separated by whitespace: "),
2363 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2369 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2370 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2375 if (e
== -1 || e
== 127)
2377 edit_error_dialog (_(" Sort "), get_sys_error (_(" Cannot execute sort command ")));
2382 sprintf (q
, "%d ", e
);
2383 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2384 edit_error_dialog (_(" Sort "), tmp
);
2390 edit
->force
|= REDRAW_COMPLETELY
;
2392 if (edit_block_delete_cmd (edit
))
2394 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2395 edit_insert_file (edit
, tmp
);
2401 * Ask user for a command, execute it and paste its output back to the
2405 edit_ext_cmd (WEdit
* edit
)
2411 input_dialog (_("Paste output of external command"),
2412 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2417 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2424 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2428 edit
->force
|= REDRAW_COMPLETELY
;
2429 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2430 edit_insert_file (edit
, tmp
);
2435 /* if block is 1, a block must be highlighted and the shell command
2436 processes it. If block is 0 the shell command is a straight system
2437 command, that just produces some output which is to be inserted */
2439 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2441 long start_mark
, end_mark
;
2443 FILE *script_home
= NULL
;
2444 FILE *block_file
= NULL
;
2445 gchar
*o
, *h
, *b
, *tmp
;
2446 char *quoted_name
= NULL
;
2448 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2449 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2450 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2452 script_home
= fopen (h
, "r");
2453 if (script_home
== NULL
)
2455 FILE *script_src
= NULL
;
2457 script_home
= fopen (h
, "w");
2458 if (script_home
== NULL
)
2460 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2461 edit_error_dialog ("", get_sys_error (tmp
));
2463 goto edit_block_process_cmd__EXIT
;
2466 script_src
= fopen (o
, "r");
2467 if (script_src
== NULL
)
2469 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2470 script_src
= fopen (o
, "r");
2471 if (script_src
== NULL
)
2473 fclose (script_home
);
2475 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2476 edit_error_dialog ("", get_sys_error (tmp
));
2478 goto edit_block_process_cmd__EXIT
;
2481 while (fgets (buf
, sizeof (buf
), script_src
))
2482 fputs (buf
, script_home
);
2483 fclose (script_src
);
2485 if (fclose (script_home
))
2487 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2488 edit_error_dialog ("", get_sys_error (tmp
));
2490 goto edit_block_process_cmd__EXIT
;
2493 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2494 edit_error_dialog ("", get_sys_error (tmp
));
2501 { /* for marked block run indent formatter */
2502 if (eval_marks (edit
, &start_mark
, &end_mark
))
2504 edit_error_dialog (_("Process block"),
2505 _(" You must first highlight a block of text. "));
2506 goto edit_block_process_cmd__EXIT
;
2508 edit_save_block (edit
, b
, start_mark
, end_mark
);
2509 quoted_name
= name_quote (edit
->filename
, 0);
2512 * Initial space is to avoid polluting bash history.
2514 * $1 - name of the edited file (to check its extension etc).
2515 * $2 - file containing the current block.
2516 * $3 - file where error messages should be put
2517 * (for compatibility with old scripts).
2519 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2520 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2525 * No block selected, just execute the command for the file.
2527 * $1 - name of the edited file.
2529 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2530 quoted_name
, (char *) NULL
);
2533 if (system (tmp
) == -1)
2535 edit_error_dialog (_("Process block"), _("Error calling program"));
2540 g_free (quoted_name
);
2541 close_error_pipe (D_NORMAL
, NULL
);
2543 edit_refresh_cmd (edit
);
2544 edit
->force
|= REDRAW_COMPLETELY
;
2546 /* insert result block */
2547 if (block
&& !edit_block_delete_cmd (edit
))
2549 edit_insert_file (edit
, b
);
2550 block_file
= fopen (b
, "w");
2551 if (block_file
!= NULL
)
2552 fclose (block_file
);
2557 edit_block_process_cmd__EXIT
:
2563 /* prints at the cursor */
2564 /* returns the number of chars printed */
2566 edit_print_string (WEdit
* e
, const char *s
)
2569 while (s
[i
] != '\0')
2570 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2571 e
->force
|= REDRAW_COMPLETELY
;
2572 edit_update_screen (e
);
2578 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
2583 to
= name_quote (to
, 0);
2584 subject
= name_quote (subject
, 0);
2585 cc
= name_quote (cc
, 0);
2586 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
2600 for (i
= 0; i
< edit
->last_byte
; i
++)
2601 fputc (edit_get_byte (edit
, i
), p
);
2606 #define MAIL_DLG_HEIGHT 12
2609 edit_mail_dialog (WEdit
* edit
)
2612 char *tmail_subject
;
2615 static char *mail_cc_last
= 0;
2616 static char *mail_subject_last
= 0;
2617 static char *mail_to_last
= 0;
2619 QuickWidget quick_widgets
[] = {
2620 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2621 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2622 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2623 /* 3 */ QUICK_LABEL (2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to")),
2624 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2626 /* 5 */ QUICK_LABEL (2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject")),
2627 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2628 /* 7 */ QUICK_LABEL (2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To")),
2629 /* 8 */ QUICK_LABEL (2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>")),
2633 QuickDialog Quick_input
= {
2634 50, MAIL_DLG_HEIGHT
, -1, -1, N_(" Mail "),
2635 "[Input Line Keys]", quick_widgets
, FALSE
2638 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2639 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2640 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2642 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2644 g_free (mail_cc_last
);
2645 g_free (mail_subject_last
);
2646 g_free (mail_to_last
);
2647 mail_cc_last
= tmail_cc
;
2648 mail_subject_last
= tmail_subject
;
2649 mail_to_last
= tmail_to
;
2650 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2655 /*******************/
2656 /* Word Completion */
2657 /*******************/
2660 is_break_char (char c
)
2662 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2665 /* find first character of current word */
2667 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
2672 /* return if at begin of file */
2673 if (edit
->curs1
<= 0)
2676 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2677 /* return if not at end or in word */
2678 if (is_break_char (c
))
2681 /* search start of word to be completed */
2684 /* return if at begin of file */
2685 if ((gsize
) edit
->curs1
< i
)
2689 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2691 if (is_break_char (c
))
2693 /* return if word starts with digit */
2697 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2706 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2708 /* collect the possible completions */
2710 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
2711 char *match_expr
, struct selection
*compl, gsize
* num
)
2722 srch
= mc_search_new (match_expr
, -1);
2726 if (mc_config_get_bool
2727 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
2729 last_byte
= edit
->last_byte
;
2736 srch
->search_type
= MC_SEARCH_T_REGEX
;
2737 srch
->is_case_sentitive
= TRUE
;
2738 srch
->search_fn
= edit_search_cmd_callback
;
2740 /* collect max MAX_WORD_COMPLETIONS completions */
2744 /* get next match */
2745 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
2747 start
= srch
->normal_offset
;
2749 /* add matched completion if not yet added */
2750 temp
= g_string_new ("");
2751 for (i
= 0; i
< len
; i
++)
2753 skip
= edit_get_byte (edit
, start
+ i
);
2756 g_string_append_c (temp
, skip
);
2761 for (i
= 0; i
< (gsize
) * num
; i
++)
2764 ((char *) &compl[i
].text
[word_len
],
2765 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
2767 struct selection
this = compl[i
];
2768 for (++i
; i
< *num
; i
++)
2770 compl[i
- 1] = compl[i
];
2772 compl[*num
- 1] = this;
2774 break; /* skip it, already added */
2779 g_string_free (temp
, TRUE
);
2782 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
2784 g_free (compl[0].text
);
2785 for (i
= 1; i
< *num
; i
++)
2787 compl[i
- 1] = compl[i
];
2794 recoded
= str_convert_to_display (temp
->str
);
2796 if (recoded
&& recoded
->len
)
2798 g_string_free (temp
, TRUE
);
2802 g_string_free (recoded
, TRUE
);
2805 compl[*num
].text
= temp
->str
;
2806 compl[*num
].len
= temp
->len
;
2809 g_string_free (temp
, FALSE
);
2811 /* note the maximal length needed for the completion dialog */
2815 mc_search_free (srch
);
2820 * Complete current word using regular expression search
2821 * backwards beginning at the current cursor position.
2824 edit_complete_word_cmd (WEdit
* edit
)
2826 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2827 long word_start
= 0;
2828 unsigned char *bufpos
;
2830 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2832 /* search start of word to be completed */
2833 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2836 /* prepare match expression */
2837 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2839 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2842 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2843 (int) word_len
, bufpos
);
2845 /* collect the possible completions */
2846 /* start search from begin to end of file */
2848 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2849 (struct selection
*) &compl, &num_compl
);
2853 /* insert completed word if there is only one match */
2856 for (i
= word_len
; i
< compl[0].len
; i
++)
2857 edit_insert (edit
, *(compl[0].text
+ i
));
2859 /* more than one possible completion => ask the user */
2862 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2863 /* !!! pressed again the selection dialog pops up, but that !!! */
2864 /* !!! seems to require a further internal state !!! */
2867 /* let the user select the preferred completion */
2868 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2869 (struct selection
*) &compl, num_compl
);
2873 g_free (match_expr
);
2874 /* release memory before return */
2875 for (i
= 0; i
< num_compl
; i
++)
2876 g_free (compl[i
].text
);
2880 edit_select_codepage_cmd (WEdit
* edit
)
2883 const char *cp_id
= NULL
;
2884 if (do_select_codepage ())
2886 cp_id
= get_codepage_id (source_codepage
>= 0 ? source_codepage
: display_codepage
);
2891 conv
= str_crt_conv_from (cp_id
);
2892 if (conv
!= INVALID_CONV
)
2894 if (edit
->converter
!= str_cnv_from_term
)
2895 str_close_conv (edit
->converter
);
2896 edit
->converter
= conv
;
2901 edit
->utf8
= str_isutf8 (cp_id
);
2904 edit
->force
= REDRAW_COMPLETELY
;
2905 edit_refresh_cmd (edit
);
2912 edit_insert_literal_cmd (WEdit
* edit
)
2914 int char_for_insertion
= editcmd_dialog_raw_key_query (_(" Insert Literal "),
2915 _(" Press any key: "), 0);
2916 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
2920 edit_execute_macro_cmd (WEdit
* edit
)
2923 CK_Macro (editcmd_dialog_raw_key_query (_(" Execute Macro "), _(" Press macro hotkey: "),
2925 if (command
== CK_Macro (0))
2926 command
= CK_Insert_Char
;
2928 edit_execute_key_command (edit
, command
, -1);
2932 edit_begin_end_macro_cmd (WEdit
* edit
)
2934 /* edit is a pointer to the widget */
2937 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2938 edit_execute_key_command (edit
, command
, -1);
2943 edit_load_forward_cmd (WEdit
* edit
)
2947 if (edit_query_dialog2
2949 _(" Current text was modified without a file save. \n"
2950 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2952 edit
->force
|= REDRAW_COMPLETELY
;
2956 if (edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
)
2958 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
2962 edit_stack_iterator
++;
2963 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2965 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2966 edit_history_moveto
[edit_stack_iterator
].line
);
2981 edit_load_back_cmd (WEdit
* edit
)
2985 if (edit_query_dialog2
2987 _(" Current text was modified without a file save. \n"
2988 " Continue discards these changes. "), _("C&ontinue"), _("&Cancel")))
2990 edit
->force
|= REDRAW_COMPLETELY
;
2994 if (edit_stack_iterator
> 0)
2996 edit_stack_iterator
--;
2997 if (edit_history_moveto
[edit_stack_iterator
].filename
)
2999 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
3000 edit_history_moveto
[edit_stack_iterator
].line
);
3015 edit_get_match_keyword_cmd (WEdit
* edit
)
3017 gsize word_len
= 0, max_len
= 0;
3020 long word_start
= 0;
3021 unsigned char *bufpos
;
3025 char *tagfile
= NULL
;
3027 etags_hash_t def_hash
[MAX_DEFINITIONS
];
3029 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
3031 def_hash
[i
].filename
= NULL
;
3034 /* search start of word to be completed */
3035 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3038 /* prepare match expression */
3039 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3040 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3042 ptr
= g_get_current_dir ();
3043 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3046 /* Recursive search file 'TAGS' in parent dirs */
3049 ptr
= g_path_get_dirname (path
);
3053 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3054 if (exist_file (tagfile
))
3057 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3062 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3067 max_len
= MAX_WIDTH_DEF_DIALOG
;
3071 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3072 (etags_hash_t
*) & def_hash
, num_def
);
3074 g_free (match_expr
);
3078 edit_move_block_to_right (WEdit
* edit
)
3080 long start_mark
, end_mark
;
3081 long cur_bol
, start_bol
;
3083 if (eval_marks (edit
, &start_mark
, &end_mark
))
3086 start_bol
= edit_bol (edit
, start_mark
);
3087 cur_bol
= edit_bol (edit
, end_mark
- 1);
3090 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3091 if (option_fill_tabs_with_spaces
)
3093 if (option_fake_half_tabs
)
3095 insert_spaces_tab (edit
, 1);
3099 insert_spaces_tab (edit
, 0);
3104 edit_insert (edit
, '\t');
3106 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3111 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3113 while (cur_bol
>= start_bol
);
3114 edit
->force
|= REDRAW_PAGE
;
3118 edit_move_block_to_left (WEdit
* edit
)
3120 long start_mark
, end_mark
;
3121 long cur_bol
, start_bol
;
3122 int i
, del_tab_width
;
3125 if (eval_marks (edit
, &start_mark
, &end_mark
))
3128 start_bol
= edit_bol (edit
, start_mark
);
3129 cur_bol
= edit_bol (edit
, end_mark
- 1);
3132 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3133 if (option_fake_half_tabs
)
3135 del_tab_width
= HALF_TAB_SIZE
;
3139 del_tab_width
= option_tab_spacing
;
3141 next_char
= edit_get_byte (edit
, edit
->curs1
);
3142 if (next_char
== '\t')
3144 edit_delete (edit
, 1);
3146 else if (next_char
== ' ')
3148 for (i
= 1; i
<= del_tab_width
; i
++)
3150 if (next_char
== ' ')
3152 edit_delete (edit
, 1);
3154 next_char
= edit_get_byte (edit
, edit
->curs1
);
3161 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3163 while (cur_bol
>= start_bol
);
3164 edit
->force
|= REDRAW_PAGE
;