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 "../src/global.h"
50 #include "../src/tty/tty.h"
51 #include "../src/tty/key.h" /* XCTRL */
53 #include "../src/history.h"
54 #include "../src/widget.h" /* listbox_new() */
55 #include "../src/layout.h" /* clr_scr() */
56 #include "../src/main.h" /* mc_home source_codepage */
57 #include "../src/help.h" /* interactive_display() */
58 #include "../src/wtools.h" /* message() */
59 #include "../src/charsets.h"
60 #include "../src/selcodepage.h"
61 #include "../src/strutil.h" /* utf string functions */
63 #include "../edit/edit-impl.h"
64 #include "../edit/edit.h"
65 #include "../edit/editlock.h"
66 #include "../edit/editcmddef.h"
67 #include "../edit/edit-widget.h"
68 #include "../edit/editcmd_dialogs.h"
69 #include "../edit/etags.h"
73 /* search and replace: */
74 static int search_create_bookmark
= 0;
75 /* static int search_in_all_charsets = 0; */
77 /* queries on a save */
78 int edit_confirm_save
= 1;
80 static int edit_save_cmd (WEdit
*edit
);
81 static unsigned char *edit_get_block (WEdit
*edit
, long start
,
85 edit_search_cmd_search_create_bookmark(WEdit
* edit
)
87 int found
= 0, books
= 0;
88 int l
= 0, l_last
= -1;
93 if (!mc_search_run(edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
97 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
99 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
103 q
= edit
->search
->normal_offset
+ 1;
107 /* in response to number of bookmarks added because of string being found %d times */
108 message (D_NORMAL
, _("Search"), _(" %d items found, %d bookmarks added "), found
, books
);
110 edit_error_dialog (_ ("Search"), _ (" Search string not found "));
115 edit_search_cmd_callback(const void *user_data
, gsize char_offset
)
117 return edit_get_byte ((WEdit
* )user_data
, (long) char_offset
);
120 void edit_help_cmd (WEdit
* edit
)
122 interactive_display (NULL
, "[Internal File Editor]");
123 edit
->force
|= REDRAW_COMPLETELY
;
127 edit_refresh_cmd (WEdit
* edit
)
132 edit_get_syntax_color (edit
, -1, &color
);
138 #endif /* !HAVE_SLANG */
142 /* If 0 (quick save) then a) create/truncate <filename> file,
143 b) save to <filename>;
144 if 1 (safe save) then a) save to <tempnam>,
145 b) rename <tempnam> to <filename>;
146 if 2 (do backups) then a) save to <tempnam>,
147 b) rename <filename> to <filename.backup_ext>,
148 c) rename <tempnam> to <filename>. */
150 /* returns 0 on error, -1 on abort */
152 edit_save_file (WEdit
*edit
, const char *filename
)
158 gchar
*real_filename
;
159 int this_save_mode
, fd
= -1;
166 if (*filename
!= PATH_SEP
&& edit
->dir
) {
167 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
169 real_filename
= g_strdup(filename
);
172 this_save_mode
= option_save_mode
;
173 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
174 if (!vfs_file_is_local (real_filename
) ||
175 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1) {
177 * The file does not exists yet, so no safe save or
178 * backup are necessary.
180 this_save_mode
= EDIT_QUICK_SAVE
;
186 if (this_save_mode
== EDIT_QUICK_SAVE
&&
187 !edit
->skip_detach_prompt
) {
191 rv
= mc_stat (real_filename
, &sb
);
192 if (rv
== 0 && sb
.st_nlink
> 1) {
193 rv
= edit_query_dialog3 (_("Warning"),
194 _(" File has hard-links. Detach before saving? "),
195 _("&Yes"), _("&No"), _("&Cancel"));
198 this_save_mode
= EDIT_SAFE_SAVE
;
201 edit
->skip_detach_prompt
= 1;
204 g_free(real_filename
);
209 /* Prevent overwriting changes from other editor sessions. */
210 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
) {
212 /* The default action is "Cancel". */
215 rv
= edit_query_dialog2 (
217 _("The file has been modified in the meantime. Save anyway?"),
221 g_free(real_filename
);
227 if (this_save_mode
!= EDIT_QUICK_SAVE
) {
228 char *savedir
, *saveprefix
;
229 const char *slashpos
;
230 slashpos
= strrchr (real_filename
, PATH_SEP
);
232 savedir
= g_strdup (real_filename
);
233 savedir
[slashpos
- real_filename
+ 1] = '\0';
235 savedir
= g_strdup (".");
236 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
238 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
241 g_free(real_filename
);
245 * Close for now because mc_mkstemps use pure open system call
246 * to create temporary file and it needs to be reopened by
247 * VFS-aware mc_open().
251 savename
= g_strdup (real_filename
);
253 mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
254 mc_chmod (savename
, edit
->stat1
.st_mode
);
257 mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
,
258 edit
->stat1
.st_mode
)) == -1)
262 if ((p
= edit_get_write_filter (savename
, real_filename
))) {
266 file
= (FILE *) popen (p
, "w");
269 filelen
= edit_write_stream (edit
, file
);
273 if (pclose (file
) != 0) {
274 tmp
= g_strconcat (_(" Error writing to pipe: "),
275 p
, " ", (char *) NULL
);
276 edit_error_dialog (_("Error"), tmp
);
283 tmp
= g_strconcat (_(" Cannot open pipe for writing: "),
284 p
, " ", (char *) NULL
);
286 edit_error_dialog (_("Error"),
287 get_sys_error (tmp
));
293 } else if (edit
->lb
== LB_ASIS
) { /* do not change line breaks */
296 filelen
= edit
->last_byte
;
297 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1) {
298 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
)
306 (fd
, (char *) edit
->buffers1
[buf
],
307 edit
->curs1
& M_EDIT_BUF_SIZE
) !=
308 (edit
->curs1
& M_EDIT_BUF_SIZE
)) {
310 } else if (edit
->curs2
) {
312 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
315 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
316 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
317 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) !=
318 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) {
323 (fd
, (char *) edit
->buffers2
[buf
],
324 EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
) {
335 /* Update the file information, especially the mtime. */
336 if (mc_stat (savename
, &edit
->stat1
) == -1)
338 } else { /* change line breaks */
343 file
= (FILE *) fopen (savename
, "w");
346 filelen
= edit_write_stream (edit
, file
);
351 msg
= g_strdup_printf (_(" Cannot open file for writing: %s "), savename
);
352 edit_error_dialog (_("Error"), msg
);
358 if (filelen
!= edit
->last_byte
)
361 if (this_save_mode
== EDIT_DO_BACKUP
) {
362 assert (option_backup_ext
!= NULL
);
363 tmp
= g_strconcat (real_filename
, option_backup_ext
,(char *) NULL
);
364 if (mc_rename (real_filename
, tmp
) == -1){
370 if (this_save_mode
!= EDIT_QUICK_SAVE
)
371 if (mc_rename (savename
, real_filename
) == -1)
374 g_free(real_filename
);
377 /* FIXME: Is this safe ?
378 * if (this_save_mode != EDIT_QUICK_SAVE)
379 * mc_unlink (savename);
381 g_free(real_filename
);
386 void menu_save_mode_cmd (void)
390 static char *str_result
;
391 static int save_mode_new
;
392 static const char *str
[] =
396 N_("Do backups -->")};
398 static QuickWidget widgets
[] =
400 {quick_button
, 18, DLG_X
, 7, DLG_Y
, N_("&Cancel"), 0,
401 B_CANCEL
, 0, 0, NULL
, NULL
, NULL
},
402 {quick_button
, 6, DLG_X
, 7, DLG_Y
, N_("&OK"), 0,
403 B_ENTER
, 0, 0, NULL
, NULL
, NULL
},
404 {quick_input
, 23, DLG_X
, 5, DLG_Y
, 0, 9,
405 0, 0, &str_result
, "edit-backup-ext", NULL
, NULL
},
406 {quick_label
, 22, DLG_X
, 4, DLG_Y
, N_("Extension:"), 0,
407 0, 0, 0, NULL
, NULL
, NULL
},
408 {quick_radio
, 4, DLG_X
, 3, DLG_Y
, "", 3,
409 0, &save_mode_new
, (char **) str
, NULL
, NULL
, NULL
},
411 static QuickDialog dialog
=
412 {DLG_X
, DLG_Y
, -1, -1, N_(" Edit Save Mode "), "[Edit Save Mode]",
414 static int i18n_flag
= 0;
422 /* OK/Cancel buttons */
423 l1
= str_term_width1 (_(widgets
[0].text
)) + str_term_width1 (_(widgets
[1].text
)) + 5;
424 maxlen
= max (maxlen
, l1
);
426 for (i
= 0; i
< 3; i
++ ) {
428 maxlen
= max (maxlen
, (size_t) str_term_width1 (str
[i
]) + 7);
432 dlg_x
= maxlen
+ str_term_width1 (_(widgets
[3].text
)) + 5 + 1;
433 widgets
[2].hotkey_pos
= str_term_width1 (_(widgets
[3].text
)); /* input field length */
434 dlg_x
= min (COLS
, dlg_x
);
438 widgets
[1].relative_x
= i
;
439 widgets
[0].relative_x
= i
+ str_term_width1 (_(widgets
[1].text
)) + i
+ 4;
441 widgets
[2].relative_x
= widgets
[3].relative_x
= maxlen
+ 2;
443 for (i
= 0; i
< sizeof (widgets
)/sizeof (widgets
[0]); i
++)
444 widgets
[i
].x_divisions
= dlg_x
;
447 assert (option_backup_ext
!= NULL
);
448 widgets
[2].text
= option_backup_ext
;
449 widgets
[4].value
= option_save_mode
;
450 if (quick_dialog (&dialog
) != B_ENTER
)
452 option_save_mode
= save_mode_new
;
454 g_free (option_backup_ext
);
455 option_backup_ext
= str_result
;
460 edit_set_filename (WEdit
*edit
, const char *f
)
462 g_free (edit
->filename
);
465 edit
->filename
= g_strdup (f
);
466 if (edit
->dir
== NULL
&& *f
!= PATH_SEP
)
468 edit
->dir
= g_strdup (vfs_get_current_dir ());
470 edit
->dir
= g_get_current_dir ();
475 edit_get_save_file_as (WEdit
*edit
)
478 #define DLG_HEIGHT 14
480 char *filename
= edit
->filename
;
482 const char *lb_names
[LB_NAMES
] =
484 N_("&Do not change"),
485 N_("&Unix format (LF)"),
486 N_("&Windows/DOS format (CR LF)"),
487 N_("&Macintosh format (LF)")
490 static LineBreaks cur_lb
= LB_ASIS
;
492 QuickWidget quick_widgets
[] =
494 {quick_button
, 6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
,
495 N_("&Cancel"), 0, B_CANCEL
, NULL
, NULL
, NULL
, NULL
, NULL
},
496 {quick_button
, 2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
,
497 N_("&OK"), 0, B_ENTER
, NULL
, NULL
, NULL
, NULL
, NULL
},
498 {quick_radio
, 5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, "",
499 LB_NAMES
, cur_lb
, (int *) &cur_lb
, (char **) lb_names
, NULL
, NULL
, NULL
},
500 {quick_label
, 3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
,
501 N_("Change line breaks to:"), 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
},
502 {quick_input
, 3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
,
503 filename
, 58, 0, 0, &filename
, "save-file-as", NULL
, NULL
},
504 {quick_label
, 2, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
,
505 N_(" Enter file name: "), 0, 0, NULL
, NULL
, NULL
, NULL
, NULL
},
509 QuickDialog Quick_options
=
511 DLG_WIDTH
, DLG_HEIGHT
, -1, -1, N_(" Save As "), "", quick_widgets
, 0
514 if (quick_dialog (&Quick_options
) != B_CANCEL
)
526 /* Here we want to warn the users of overwriting an existing file,
527 but only if they have made a change to the filename */
528 /* returns 1 on success */
530 edit_save_as_cmd (WEdit
*edit
)
532 /* This heads the 'Save As' dialog box */
535 int different_filename
= 0;
537 exp
= edit_get_save_file_as (edit
);
538 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
543 edit
->force
|= REDRAW_COMPLETELY
;
547 if (strcmp (edit
->filename
, exp
)) {
549 different_filename
= 1;
550 if ((file
= mc_open (exp
, O_RDONLY
| O_BINARY
)) != -1) {
551 /* the file exists */
553 /* Overwrite the current file or cancel the operation */
554 if (edit_query_dialog2
556 _(" A file already exists with this name. "),
557 _("&Overwrite"), _("&Cancel"))) {
558 edit
->force
|= REDRAW_COMPLETELY
;
563 edit
->stat1
.st_mode
|= S_IWUSR
;
565 save_lock
= edit_lock_file (exp
);
567 /* filenames equal, check if already locked */
568 if (!edit
->locked
&& !edit
->delete_file
)
569 save_lock
= edit_lock_file (exp
);
572 if (different_filename
)
575 * Allow user to write into saved (under another name) file
576 * even if original file had r/o user permissions.
578 edit
->stat1
.st_mode
|= S_IWRITE
;
581 rv
= edit_save_file (edit
, exp
);
584 /* Succesful, so unlock both files */
585 if (different_filename
) {
587 edit_unlock_file (exp
);
589 edit
->locked
= edit_unlock_file (edit
->filename
);
591 if (edit
->locked
|| save_lock
)
592 edit
->locked
= edit_unlock_file (edit
->filename
);
595 edit_set_filename (edit
, exp
);
596 if (edit
->lb
!= LB_ASIS
)
597 edit_reload(edit
, exp
);
600 edit
->delete_file
= 0;
601 if (different_filename
)
602 edit_load_syntax (edit
, NULL
, option_syntax_type
);
603 edit
->force
|= REDRAW_COMPLETELY
;
606 edit_error_dialog (_(" Save As "),
608 (" Cannot save file. ")));
611 /* Failed, so maintain modify (not save) lock */
613 edit_unlock_file (exp
);
615 edit
->force
|= REDRAW_COMPLETELY
;
620 edit
->force
|= REDRAW_COMPLETELY
;
624 /* {{{ Macro stuff starts here */
626 /* creates a macro file if it doesn't exist */
627 static FILE *edit_open_macro_file (const char *r
)
632 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
633 if ((file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
)) == -1){
638 fd
= fopen (filename
, r
);
643 #define MAX_MACROS 1024
644 static int saved_macro
[MAX_MACROS
+ 1];
645 static int saved_macros_loaded
= 0;
648 This is just to stop the macro file be loaded over and over for keys
649 that aren't defined to anything. On slow systems this could be annoying.
655 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
656 if (saved_macro
[i
] == k
)
661 /* returns 1 on error */
663 edit_delete_macro (WEdit
* edit
, int k
)
666 struct macro macro
[MAX_MACRO_LENGTH
];
672 if (saved_macros_loaded
)
673 if ((j
= macro_exists (k
)) < 0)
675 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
676 g
= fopen (tmp
, "w");
679 edit_error_dialog (_(" Delete macro "),
680 get_sys_error (_(" Cannot open temp file ")));
683 f
= edit_open_macro_file ("r");
685 edit_error_dialog (_(" Delete macro "),
686 get_sys_error (_(" Cannot open macro file ")));
691 n
= fscanf (f
, ("key '%d 0': "), &s
);
695 while (fscanf (f
, "%hd %hd, ", ¯o
[n
].command
, ¯o
[n
].ch
))
699 fprintf (g
, ("key '%d 0': "), s
);
700 for (i
= 0; i
< n
; i
++)
701 fprintf (g
, "%hd %hd, ", macro
[i
].command
, macro
[i
].ch
);
707 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
708 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
709 if (rename ( tmp
, tmp2
) == -1) {
710 edit_error_dialog (_(" Delete macro "),
711 get_sys_error (_(" Cannot overwrite macro file ")));
719 if (saved_macros_loaded
)
720 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
724 /* returns 0 on error */
725 int edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
730 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
731 s
= editcmd_dialog_raw_key_query (_(" Save macro "),
732 _(" Press the macro's new hotkey: "), 1);
733 edit
->force
|= REDRAW_COMPLETELY
;
735 if (edit_delete_macro (edit
, s
))
737 f
= edit_open_macro_file ("a+");
739 fprintf (f
, ("key '%d 0': "), s
);
740 for (i
= 0; i
< n
; i
++)
741 fprintf (f
, "%hd %hd, ", macro
[i
].command
, macro
[i
].ch
);
744 if (saved_macros_loaded
) {
745 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
750 edit_error_dialog (_(" Save macro "), get_sys_error (_(" Cannot open macro file ")));
755 void edit_delete_macro_cmd (WEdit
* edit
)
759 command
= editcmd_dialog_raw_key_query (_ (" Delete macro "),
760 _ (" Press macro hotkey: "), 1);
765 edit_delete_macro (edit
, command
);
768 /* return 0 on error */
769 int edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
772 int s
, i
= 0, found
= 0;
776 if (saved_macros_loaded
)
777 if (macro_exists (k
) < 0)
780 if ((f
= edit_open_macro_file ("r"))) {
784 u
= fscanf (f
, ("key '%d 0': "), &s
);
787 if (!saved_macros_loaded
)
788 saved_macro
[i
++] = s
;
791 while (*n
< MAX_MACRO_LENGTH
&& 2 == fscanf (f
, "%hd %hd, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
794 while (2 == fscanf (f
, "%hd %hd, ", &dummy
.command
, &dummy
.ch
));
799 } while (!found
|| !saved_macros_loaded
);
800 if (!saved_macros_loaded
) {
802 saved_macros_loaded
= 1;
807 edit_error_dialog (_(" Load macro "),
808 get_sys_error (_(" Cannot open macro file ")));
812 /* }}} Macro stuff starts here */
814 /* returns 1 on success */
815 int edit_save_confirm_cmd (WEdit
* edit
)
819 if (edit_confirm_save
) {
820 f
= g_strconcat (_(" Confirm save file? : "), edit
->filename
, " ", NULL
);
821 if (edit_query_dialog2 (_(" Save file "), f
, _("&Save"), _("&Cancel"))){
827 return edit_save_cmd (edit
);
831 /* returns 1 on success */
833 edit_save_cmd (WEdit
*edit
)
835 int res
, save_lock
= 0;
837 if (!edit
->locked
&& !edit
->delete_file
)
838 save_lock
= edit_lock_file (edit
->filename
);
839 res
= edit_save_file (edit
, edit
->filename
);
841 /* Maintain modify (not save) lock on failure */
842 if ((res
> 0 && edit
->locked
) || save_lock
)
843 edit
->locked
= edit_unlock_file (edit
->filename
);
845 /* On failure try 'save as', it does locking on its own */
847 return edit_save_as_cmd (edit
);
848 edit
->force
|= REDRAW_COMPLETELY
;
850 edit
->delete_file
= 0;
858 /* returns 1 on success */
859 int edit_new_cmd (WEdit
* edit
)
861 if (edit
->modified
) {
862 if (edit_query_dialog2 (_ ("Warning"), _ (" Current text was modified without a file save. \n Continue discards these changes. "), _ ("C&ontinue"), _ ("&Cancel"))) {
863 edit
->force
|= REDRAW_COMPLETELY
;
867 edit
->force
|= REDRAW_COMPLETELY
;
869 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
872 /* returns 1 on error */
874 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
876 int prev_locked
= edit
->locked
;
877 char *prev_filename
= g_strdup (edit
->filename
);
879 if (!edit_reload (edit
, exp
)) {
880 g_free (prev_filename
);
885 edit_unlock_file (prev_filename
);
886 g_free (prev_filename
);
891 edit_load_syntax_file (WEdit
* edit
)
896 if (geteuid () == 0) {
897 dir
= query_dialog (_("Syntax file edit"),
898 _(" Which syntax file you want to edit? "), D_NORMAL
, 2,
899 _("&User"), _("&System Wide"));
902 extdir
= concat_dir_and_file (mc_home
, "syntax" PATH_SEP_STR
"Syntax");
903 if (!exist_file(extdir
)) {
905 extdir
= concat_dir_and_file (mc_home_alt
, "syntax" PATH_SEP_STR
"Syntax");
911 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
912 check_for_default (extdir
, buffer
);
913 edit_load_file_from_filename (edit
, buffer
);
916 edit_load_file_from_filename (edit
, extdir
);
922 edit_load_menu_file (WEdit
* edit
)
930 _(" Which menu file do you want to edit? "), D_NORMAL
,
931 geteuid() ? 2 : 3, _("&Local"), _("&User"), _("&System Wide")
934 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
936 if (!exist_file (menufile
)) {
938 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
943 buffer
= g_strdup (EDIT_LOCAL_MENU
);
944 check_for_default (menufile
, buffer
);
945 chmod (buffer
, 0600);
949 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
950 check_for_default (menufile
, buffer
);
954 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
955 if (!exist_file (buffer
)) {
957 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
966 edit_load_file_from_filename (edit
, buffer
);
973 edit_load_cmd (WEdit
*edit
, edit_current_file_t what
)
978 && (edit_query_dialog2
980 _(" Current text was modified without a file save. \n"
981 " Continue discards these changes. "),
982 _("C&ontinue"), _("&Cancel")) == 1)) {
983 edit
->force
|= REDRAW_COMPLETELY
;
988 case EDIT_FILE_COMMON
:
989 exp
= input_expand_dialog (_(" Load "), _(" Enter file name: "),
990 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
994 edit_load_file_from_filename (edit
, exp
);
999 case EDIT_FILE_SYNTAX
:
1000 edit_load_syntax_file (edit
);
1003 case EDIT_FILE_MENU
:
1004 edit_load_menu_file (edit
);
1011 edit
->force
|= REDRAW_COMPLETELY
;
1016 if mark2 is -1 then marking is from mark1 to the cursor.
1017 Otherwise its between the markers. This handles this.
1018 Returns 1 if no text is marked.
1020 int eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1022 if (edit
->mark1
!= edit
->mark2
) {
1023 if (edit
->mark2
>= 0) {
1024 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1025 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1027 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1028 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1029 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1033 *start_mark
= *end_mark
= 0;
1034 edit
->column2
= edit
->column1
= 0;
1039 #define space_width 1
1042 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1046 cursor
= edit
->curs1
;
1047 col
= edit_get_col (edit
);
1048 for (i
= 0; i
< size
; i
++) {
1049 if (data
[i
] == '\n') { /* fill in and move to next line */
1052 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1053 l
= width
- (edit_get_col (edit
) - col
);
1055 edit_insert (edit
, ' ');
1059 for (p
= edit
->curs1
;; p
++) {
1060 if (p
== edit
->last_byte
) {
1061 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1062 edit_insert_ahead (edit
, '\n');
1066 if (edit_get_byte (edit
, p
) == '\n') {
1071 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1072 l
= col
- edit_get_col (edit
);
1073 while (l
>= space_width
) {
1074 edit_insert (edit
, ' ');
1079 edit_insert (edit
, data
[i
]);
1081 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1084 #define TEMP_BUF_LEN 1024
1087 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1091 int blocklen
= -1, width
;
1092 unsigned char *data
;
1093 cursor
= edit
->curs1
;
1094 col
= edit_get_col (edit
);
1095 data
= g_malloc (TEMP_BUF_LEN
);
1096 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0) {
1097 for (width
= 0; width
< blocklen
; width
++) {
1098 if (data
[width
] == '\n')
1101 for (i
= 0; i
< blocklen
; i
++) {
1102 if (data
[i
] == '\n') { /* fill in and move to next line */
1105 if (edit_get_byte (edit
, edit
->curs1
) != '\n') {
1106 l
= width
- (edit_get_col (edit
) - col
);
1108 edit_insert (edit
, ' ');
1112 for (p
= edit
->curs1
;; p
++) {
1113 if (p
== edit
->last_byte
) {
1114 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1115 edit_insert_ahead (edit
, '\n');
1119 if (edit_get_byte (edit
, p
) == '\n') {
1124 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1125 l
= col
- edit_get_col (edit
);
1126 while (l
>= space_width
) {
1127 edit_insert (edit
, ' ');
1132 edit_insert (edit
, data
[i
]);
1135 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1137 edit
->force
|= REDRAW_PAGE
;
1142 edit_block_copy_cmd (WEdit
*edit
)
1144 long start_mark
, end_mark
, current
= edit
->curs1
;
1146 unsigned char *copy_buf
;
1148 edit_update_curs_col (edit
);
1149 if (eval_marks (edit
, &start_mark
, &end_mark
))
1152 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1154 /* all that gets pushed are deletes hence little space is used on the stack */
1156 edit_push_markers (edit
);
1158 if (column_highlighting
) {
1159 edit_insert_column_of_text (edit
, copy_buf
, size
,
1160 abs (edit
->column2
- edit
->column1
));
1163 edit_insert_ahead (edit
, copy_buf
[size
]);
1167 edit_scroll_screen_over_cursor (edit
);
1169 if (column_highlighting
) {
1170 edit_set_markers (edit
, 0, 0, 0, 0);
1171 edit_push_action (edit
, COLUMN_ON
);
1172 column_highlighting
= 0;
1173 } else if (start_mark
< current
&& end_mark
> current
)
1174 edit_set_markers (edit
, start_mark
,
1175 end_mark
+ end_mark
- start_mark
, 0, 0);
1177 edit
->force
|= REDRAW_PAGE
;
1182 edit_block_move_cmd (WEdit
*edit
)
1186 unsigned char *copy_buf
;
1187 long start_mark
, end_mark
;
1191 if (eval_marks (edit
, &start_mark
, &end_mark
))
1193 if (column_highlighting
) {
1194 edit_update_curs_col (edit
);
1196 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1197 if ((x
> edit
->column1
&& x
< edit
->column2
)
1198 || (x
> edit
->column2
&& x
< edit
->column1
))
1200 } else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1203 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1204 if (edit_query_dialog2
1207 (" Block is large, you may not be able to undo this action. "),
1208 _("C&ontinue"), _("&Cancel")))
1211 edit_push_markers (edit
);
1212 current
= edit
->curs1
;
1213 if (column_highlighting
) {
1214 int size
, c1
, c2
, line
;
1215 line
= edit
->curs_line
;
1216 if (edit
->mark2
< 0)
1217 edit_mark_cmd (edit
, 0);
1218 c1
= min (edit
->column1
, edit
->column2
);
1219 c2
= max (edit
->column1
, edit
->column2
);
1220 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1222 edit_block_delete_cmd (edit
);
1225 edit_move_to_line (edit
, line
);
1226 edit_cursor_move (edit
,
1227 edit_move_forward3 (edit
,
1228 edit_bol (edit
, edit
->curs1
),
1229 x
, 0) - edit
->curs1
);
1230 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1232 line
= edit
->curs_line
;
1233 edit_update_curs_col (edit
);
1235 edit_block_delete_cmd (edit
);
1236 edit_move_to_line (edit
, line
);
1237 edit_cursor_move (edit
,
1238 edit_move_forward3 (edit
,
1241 x
, 0) - edit
->curs1
);
1243 edit_set_markers (edit
, 0, 0, 0, 0);
1244 edit_push_action (edit
, COLUMN_ON
);
1245 column_highlighting
= 0;
1247 copy_buf
= g_malloc (end_mark
- start_mark
);
1248 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1249 edit_scroll_screen_over_cursor (edit
);
1251 while (count
< end_mark
) {
1252 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
1255 edit_scroll_screen_over_cursor (edit
);
1256 edit_cursor_move (edit
,
1257 current
- edit
->curs1
-
1258 (((current
- edit
->curs1
) >
1259 0) ? end_mark
- start_mark
: 0));
1260 edit_scroll_screen_over_cursor (edit
);
1261 while (count
-- > start_mark
)
1262 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
1263 edit_set_markers (edit
, edit
->curs1
,
1264 edit
->curs1
+ end_mark
- start_mark
, 0, 0);
1266 edit_scroll_screen_over_cursor (edit
);
1268 edit
->force
|= REDRAW_PAGE
;
1272 edit_delete_column_of_text (WEdit
* edit
)
1274 long p
, q
, r
, m1
, m2
;
1278 eval_marks (edit
, &m1
, &m2
);
1279 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
1280 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
1281 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
1283 b
= max(min (c
, d
), min (edit
->column1
, edit
->column2
));
1284 c
= max (c
, d
+ edit
->over_col
);
1287 r
= edit_bol (edit
, edit
->curs1
);
1288 p
= edit_move_forward3 (edit
, r
, b
, 0);
1289 q
= edit_move_forward3 (edit
, r
, c
, 0);
1294 edit_cursor_move (edit
, p
- edit
->curs1
);
1295 while (q
> p
) { /* delete line between margins */
1296 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1297 edit_delete (edit
, 1);
1300 if (n
) /* move to next line except on the last delete */
1301 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
1305 /* if success return 0 */
1307 edit_block_delete (WEdit
*edit
)
1310 long start_mark
, end_mark
;
1311 if (eval_marks (edit
, &start_mark
, &end_mark
))
1313 if (column_highlighting
&& edit
->mark2
< 0)
1314 edit_mark_cmd (edit
, 0);
1315 if ((end_mark
- start_mark
) > option_max_undo
/ 2) {
1316 /* Warning message with a query to continue or cancel the operation */
1317 if (edit_query_dialog2
1320 (" Block is large, you may not be able to undo this action. "),
1321 _("C&ontinue"), _("&Cancel"))) {
1325 edit_push_markers (edit
);
1326 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
1327 edit_scroll_screen_over_cursor (edit
);
1329 if (start_mark
< end_mark
) {
1330 if (column_highlighting
) {
1331 if (edit
->mark2
< 0)
1332 edit_mark_cmd (edit
, 0);
1333 edit_delete_column_of_text (edit
);
1335 while (count
< end_mark
) {
1336 edit_delete (edit
, 1);
1341 edit_set_markers (edit
, 0, 0, 0, 0);
1342 edit
->force
|= REDRAW_PAGE
;
1346 /* returns 1 if canceelled by user */
1347 int edit_block_delete_cmd (WEdit
* edit
)
1349 long start_mark
, end_mark
;
1350 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
1351 edit_delete_line (edit
);
1354 return edit_block_delete (edit
);
1357 #define INPUT_INDEX 9
1360 editcmd_find (WEdit
*edit
, gsize
*len
)
1362 off_t search_start
= edit
->search_start
;
1364 long start_mark
= 0;
1365 long end_mark
= edit
->last_byte
;
1368 if (edit
->only_in_selection
) {
1369 mark_res
= eval_marks(edit
, &start_mark
, &end_mark
);
1370 if (mark_res
!= 0) {
1371 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
1372 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1375 if (edit
->replace_backwards
) {
1376 if (search_start
> end_mark
|| search_start
<= start_mark
) {
1377 search_start
= end_mark
;
1380 if (search_start
< start_mark
|| search_start
>= end_mark
) {
1381 search_start
= start_mark
;
1385 if (edit
->replace_backwards
)
1386 end_mark
= max(1, edit
->curs1
) - 1;
1388 if (edit
->replace_backwards
) {
1389 search_end
= end_mark
;
1390 while ((int) search_start
>= start_mark
) {
1391 if (search_end
> search_start
+ edit
->search
->original_len
1392 && mc_search_is_fixed_search_str(edit
->search
)) {
1393 search_end
= search_start
+ edit
->search
->original_len
;
1395 if (mc_search_run(edit
->search
, (void *) edit
, search_start
, search_end
, len
)
1396 && edit
->search
->normal_offset
== search_start
) {
1401 edit
->search
->error_str
= g_strdup(_(" Search string not found "));
1403 return mc_search_run(edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
1409 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
1410 (and the above) routines to work properly - paul */
1412 #define is_digit(x) ((x) >= '0' && (x) <= '9')
1415 edit_replace_cmd__conv_to_display(char *str
)
1419 tmp
= str_convert_to_display (str
);
1421 if (tmp
&& tmp
->len
){
1425 g_string_free (tmp
, FALSE
);
1428 return g_strdup(str
);
1433 edit_replace_cmd__conv_to_input(char *str
)
1437 tmp
= str_convert_to_input (str
);
1439 if (tmp
&& tmp
->len
){
1443 g_string_free (tmp
, FALSE
);
1446 return g_strdup(str
);
1449 /* call with edit = 0 before shutdown to close memory leaks */
1451 edit_replace_cmd (WEdit
*edit
, int again
)
1453 /* 1 = search string, 2 = replace with */
1454 static char *saved1
= NULL
; /* saved default[123] */
1455 static char *saved2
= NULL
;
1456 char *input1
= NULL
; /* user input from the dialog */
1457 char *input2
= NULL
;
1459 long times_replaced
= 0, last_search
;
1460 gboolean once_found
= FALSE
;
1463 g_free (saved1
), saved1
= NULL
;
1464 g_free (saved2
), saved2
= NULL
;
1468 last_search
= edit
->last_byte
;
1470 edit
->force
|= REDRAW_COMPLETELY
;
1472 if (again
&& !saved1
&& !saved2
)
1476 input1
= g_strdup (saved1
? saved1
: "");
1477 input2
= g_strdup (saved2
? saved2
: "");
1479 char *disp1
= edit_replace_cmd__conv_to_display(g_strdup (saved1
? saved1
: ""));
1480 char *disp2
= edit_replace_cmd__conv_to_display(g_strdup (saved2
? saved2
: ""));
1482 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1484 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
1489 if (input1
== NULL
|| *input1
== '\0') {
1490 edit
->force
= REDRAW_COMPLETELY
;
1494 input1
= edit_replace_cmd__conv_to_input(input1
);
1495 input2
= edit_replace_cmd__conv_to_input(input2
);
1497 g_free (saved1
), saved1
= g_strdup (input1
);
1498 g_free (saved2
), saved2
= g_strdup (input2
);
1501 mc_search_free(edit
->search
);
1502 edit
->search
= NULL
;
1506 if (!edit
->search
) {
1507 edit
->search
= mc_search_new(input1
, -1);
1508 if (edit
->search
== NULL
) {
1509 edit
->search_start
= edit
->curs1
;
1512 edit
->search
->search_type
= edit
->search_type
;
1513 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1514 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1515 edit
->search
->whole_words
= edit
->whole_words
;
1516 edit
->search
->search_fn
= edit_search_cmd_callback
;
1519 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
1520 && edit
->replace_backwards
)
1521 edit
->search_start
--;
1523 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
1524 && !edit
->replace_backwards
)
1525 edit
->search_start
++;
1531 if (! editcmd_find(edit
, &len
)) {
1532 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
1533 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
))) {
1534 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1539 new_start
= edit
->search
->normal_offset
;
1541 edit
->search_start
= new_start
= edit
->search
->normal_offset
;
1542 /*returns negative on not found or error in pattern */
1544 if (edit
->search_start
>= 0) {
1547 edit
->found_start
= edit
->search_start
;
1548 i
= edit
->found_len
= len
;
1550 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1551 edit_scroll_screen_over_cursor (edit
);
1555 if (edit
->replace_mode
== 0) {
1557 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
1559 edit_scroll_downward (edit
, l
);
1561 edit_scroll_upward (edit
, -l
);
1563 edit_scroll_screen_over_cursor (edit
);
1564 edit
->force
|= REDRAW_PAGE
;
1565 edit_render_keypress (edit
);
1567 /*so that undo stops at each query */
1568 edit_push_key_press (edit
);
1569 /* and prompt 2/3 down */
1570 switch (editcmd_dialog_replace_prompt_show (edit
, input1
, input2
, -1, -1)) {
1574 case B_SKIP_REPLACE
:
1578 edit
->replace_mode
=1;
1582 edit
->replace_mode
= -1;
1586 if (replace_yes
) { /* delete then insert new */
1587 GString
*repl_str
, *tmp_str
;
1588 tmp_str
= g_string_new(input2
);
1590 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
1591 g_string_free(tmp_str
, TRUE
);
1592 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
1594 edit_error_dialog (_ ("Replace"), edit
->search
->error_str
);
1599 edit_delete (edit
, 1);
1601 while (++i
< repl_str
->len
)
1602 edit_insert (edit
, repl_str
->str
[i
]);
1604 g_string_free(repl_str
, TRUE
);
1605 edit
->found_len
= i
;
1607 /* so that we don't find the same string again */
1608 if (edit
->replace_backwards
) {
1609 last_search
= edit
->search_start
;
1610 edit
->search_start
--;
1612 edit
->search_start
+= i
;
1613 last_search
= edit
->last_byte
;
1615 edit_scroll_screen_over_cursor (edit
);
1617 const char *msg
= _(" Replace ");
1618 /* try and find from right here for next search */
1619 edit
->search_start
= edit
->curs1
;
1620 edit_update_curs_col (edit
);
1622 edit
->force
|= REDRAW_PAGE
;
1623 edit_render_keypress (edit
);
1624 if (times_replaced
) {
1625 message (D_NORMAL
, msg
, _(" %ld replacements made. "),
1628 query_dialog (msg
, _(" Search string not found "),
1629 D_NORMAL
, 1, _("&OK"));
1630 edit
->replace_mode
= -1;
1632 } while (edit
->replace_mode
>= 0);
1634 edit
->force
= REDRAW_COMPLETELY
;
1635 edit_scroll_screen_over_cursor (edit
);
1642 void edit_search_cmd (WEdit
* edit
, int again
)
1644 char *search_string
= NULL
, *search_string_dup
= NULL
;
1651 if (edit
->search
!= NULL
) {
1652 search_string
= g_strndup(edit
->search
->original
, edit
->search
->original_len
);
1653 search_string_dup
= search_string
;
1656 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
1657 if (history
!= NULL
&& history
->data
!= NULL
) {
1658 search_string_dup
= search_string
= (char *) g_strdup(history
->data
);
1659 history
= g_list_first (history
);
1660 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
1661 g_list_free (history
);
1663 edit
->search_start
= edit
->curs1
;
1669 if (search_string
&& *search_string
) {
1670 tmp
= str_convert_to_display (search_string
);
1672 g_free(search_string_dup
);
1673 search_string_dup
= NULL
;
1675 if (tmp
&& tmp
->len
)
1676 search_string
= search_string_dup
= tmp
->str
;
1677 g_string_free (tmp
, FALSE
);
1679 #endif /* HAVE_CHARSET */
1680 editcmd_dialog_search_show (edit
, &search_string
);
1682 if (search_string
&& *search_string
) {
1683 tmp
= str_convert_to_input (search_string
);
1684 if (tmp
&& tmp
->len
)
1685 search_string
= tmp
->str
;
1687 g_string_free (tmp
, FALSE
);
1689 if (search_string_dup
)
1690 g_free(search_string_dup
);
1692 #endif /* HAVE_CHARSET */
1694 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1696 if (!search_string
) {
1697 edit
->force
|= REDRAW_COMPLETELY
;
1698 edit_scroll_screen_over_cursor (edit
);
1703 mc_search_free(edit
->search
);
1704 edit
->search
= NULL
;
1708 if (!edit
->search
) {
1709 edit
->search
= mc_search_new(search_string
, -1);
1710 if (edit
->search
== NULL
) {
1711 edit
->search_start
= edit
->curs1
;
1714 edit
->search
->search_type
= edit
->search_type
;
1715 edit
->search
->is_all_charsets
= edit
->all_codepages
;
1716 edit
->search
->is_case_sentitive
= edit
->replace_case
;
1717 edit
->search
->whole_words
= edit
->whole_words
;
1718 edit
->search
->search_fn
= edit_search_cmd_callback
;
1721 if (search_create_bookmark
) {
1722 edit_search_cmd_search_create_bookmark(edit
);
1724 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1 && edit
->replace_backwards
)
1725 edit
->search_start
--;
1727 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1 && !edit
->replace_backwards
)
1728 edit
->search_start
++;
1731 if (editcmd_find(edit
, &len
)) {
1732 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
1733 edit
->found_len
= len
;
1735 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
1736 edit_scroll_screen_over_cursor (edit
);
1737 if (edit
->replace_backwards
)
1738 edit
->search_start
--;
1740 edit
->search_start
++;
1742 edit
->search_start
= edit
->curs1
;
1743 if (edit
->search
->error_str
)
1744 edit_error_dialog (_ ("Search"), edit
->search
->error_str
);
1748 edit
->force
|= REDRAW_COMPLETELY
;
1749 edit_scroll_screen_over_cursor (edit
);
1754 * Check if it's OK to close the editor. If there are unsaved changes,
1755 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
1758 edit_ok_to_exit (WEdit
*edit
)
1760 if (!edit
->modified
)
1763 switch (edit_query_dialog3
1764 (_("Quit"), _(" File was modified, Save with exit? "),
1765 _("&Cancel quit"), _("&Yes"), _("&No"))) {
1767 edit_push_markers (edit
);
1768 edit_set_markers (edit
, 0, 0, 0, 0);
1769 if (!edit_save_cmd (edit
))
1782 /* Return a null terminated length of text. Result must be g_free'd */
1783 static unsigned char *
1784 edit_get_block (WEdit
*edit
, long start
, long finish
, int *l
)
1786 unsigned char *s
, *r
;
1787 r
= s
= g_malloc (finish
- start
+ 1);
1788 if (column_highlighting
) {
1790 /* copy from buffer, excluding chars that are out of the column 'margins' */
1791 while (start
< finish
) {
1793 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0,
1795 c
= edit_get_byte (edit
, start
);
1796 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1797 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n') {
1804 *l
= finish
- start
;
1805 while (start
< finish
)
1806 *s
++ = edit_get_byte (edit
, start
++);
1812 /* save block, returns 1 on success */
1814 edit_save_block (WEdit
* edit
, const char *filename
, long start
,
1820 mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1821 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
)) == -1)
1824 if (column_highlighting
) {
1826 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof(VERTICAL_MAGIC
));
1828 unsigned char *block
, *p
;
1829 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
1831 r
= mc_write (file
, p
, len
);
1842 len
= finish
- start
;
1843 buf
= g_malloc (TEMP_BUF_LEN
);
1844 while (start
!= finish
) {
1845 end
= min (finish
, start
+ TEMP_BUF_LEN
);
1846 for (; i
< end
; i
++)
1847 buf
[i
- start
] = edit_get_byte (edit
, i
);
1848 len
-= mc_write (file
, (char *) buf
, end
- start
);
1859 /* copies a block to clipboard file */
1860 static int edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1864 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1865 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1871 void edit_paste_from_history (WEdit
*edit
)
1874 edit_error_dialog (_(" Error "), _(" This function is not implemented. "));
1877 int edit_copy_to_X_buf_cmd (WEdit
* edit
)
1879 long start_mark
, end_mark
;
1880 if (eval_marks (edit
, &start_mark
, &end_mark
))
1882 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1883 edit_error_dialog (_(" Copy to clipboard "), get_sys_error (_(" Unable to save to file. ")));
1886 edit_mark_cmd (edit
, 1);
1890 int edit_cut_to_X_buf_cmd (WEdit
* edit
)
1892 long start_mark
, end_mark
;
1893 if (eval_marks (edit
, &start_mark
, &end_mark
))
1895 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
)) {
1896 edit_error_dialog (_(" Cut to clipboard "), _(" Unable to save to file. "));
1899 edit_block_delete_cmd (edit
);
1900 edit_mark_cmd (edit
, 1);
1904 void edit_paste_from_X_buf_cmd (WEdit
* edit
)
1907 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1908 edit_insert_file (edit
, tmp
);
1914 * Ask user for the line and go to that line.
1915 * Negative numbers mean line from the end (i.e. -1 is the last line).
1918 edit_goto_cmd (WEdit
*edit
)
1921 static long line
= 0; /* line as typed, saved as default */
1926 g_snprintf (s
, sizeof (s
), "%ld", line
);
1927 f
= input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE
,
1937 l
= strtol (f
, &error
, 0);
1945 l
= edit
->total_lines
+ l
+ 2;
1946 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
1947 edit_move_to_line (edit
, l
- 1);
1948 edit
->force
|= REDRAW_COMPLETELY
;
1953 /* Return 1 on success */
1955 edit_save_block_cmd (WEdit
*edit
)
1957 long start_mark
, end_mark
;
1960 if (eval_marks (edit
, &start_mark
, &end_mark
))
1963 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1965 input_expand_dialog (_(" Save Block "), _(" Enter file name: "),
1966 MC_HISTORY_EDIT_SAVE_BLOCK
,
1969 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1975 if (edit_save_block (edit
, exp
, start_mark
, end_mark
)) {
1977 edit
->force
|= REDRAW_COMPLETELY
;
1981 edit_error_dialog (_(" Save Block "),
1983 (" Cannot save file. ")));
1987 edit
->force
|= REDRAW_COMPLETELY
;
1992 /* returns 1 on success */
1994 edit_insert_file_cmd (WEdit
*edit
)
1999 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2000 exp
= input_expand_dialog (_(" Insert File "), _(" Enter file name: "),
2001 MC_HISTORY_EDIT_INSERT_FILE
,
2004 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2010 if (edit_insert_file (edit
, exp
)) {
2012 edit
->force
|= REDRAW_COMPLETELY
;
2016 edit_error_dialog (_(" Insert File "),
2018 (" Cannot insert file. ")));
2022 edit
->force
|= REDRAW_COMPLETELY
;
2026 /* sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2027 int edit_sort_cmd (WEdit
* edit
)
2029 static char *old
= 0;
2031 long start_mark
, end_mark
;
2034 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2035 edit_error_dialog (_(" Sort block "), _(" You must first highlight a block of text. "));
2039 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2040 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2043 exp
= input_dialog (_(" Run Sort "),
2044 _(" Enter sort options (see manpage) separated by whitespace: "),
2045 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2051 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2052 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2056 if (e
== -1 || e
== 127) {
2057 edit_error_dialog (_(" Sort "),
2058 get_sys_error (_(" Cannot execute sort command ")));
2061 sprintf (q
, "%d ", e
);
2062 tmp
= g_strconcat (_(" Sort returned non-zero: "), q
, (char *) NULL
);
2063 edit_error_dialog (_(" Sort "), tmp
);
2069 edit
->force
|= REDRAW_COMPLETELY
;
2071 if (edit_block_delete_cmd (edit
))
2073 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2074 edit_insert_file (edit
, tmp
);
2080 * Ask user for a command, execute it and paste its output back to the
2084 edit_ext_cmd (WEdit
*edit
)
2090 input_dialog (_("Paste output of external command"),
2091 _("Enter shell command(s):"),
2092 MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2097 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2103 edit_error_dialog (_("External command"),
2104 get_sys_error (_("Cannot execute command")));
2108 edit
->force
|= REDRAW_COMPLETELY
;
2109 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2110 edit_insert_file (edit
, tmp
);
2115 /* if block is 1, a block must be highlighted and the shell command
2116 processes it. If block is 0 the shell command is a straight system
2117 command, that just produces some output which is to be inserted */
2119 edit_block_process_cmd (WEdit
*edit
, const char *shell_cmd
, int block
)
2121 long start_mark
, end_mark
;
2123 FILE *script_home
= NULL
;
2124 FILE *script_src
= NULL
;
2125 FILE *block_file
= NULL
;
2126 gchar
*o
, *h
, *b
, *tmp
;
2127 char *quoted_name
= NULL
;
2129 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2130 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2131 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2133 if (!(script_home
= fopen (h
, "r"))) {
2134 if (!(script_home
= fopen (h
, "w"))) {
2135 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2136 edit_error_dialog ("", get_sys_error (tmp
));
2138 goto edit_block_process_cmd__EXIT
;
2140 if (!(script_src
= fopen (o
, "r"))) {
2141 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2142 if (!(script_src
= fopen (o
, "r"))) {
2143 fclose (script_home
);
2145 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2146 edit_error_dialog ("", get_sys_error (tmp
));
2148 goto edit_block_process_cmd__EXIT
;
2151 while (fgets (buf
, sizeof (buf
), script_src
))
2152 fputs (buf
, script_home
);
2153 if (fclose (script_home
)) {
2154 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2155 edit_error_dialog ("", get_sys_error (tmp
));
2157 goto edit_block_process_cmd__EXIT
;
2160 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2161 edit_error_dialog ("", get_sys_error (tmp
));
2167 if (block
) { /* for marked block run indent formatter */
2168 if (eval_marks (edit
, &start_mark
, &end_mark
)) {
2169 edit_error_dialog (_("Process block"),
2171 (" You must first highlight a block of text. "));
2172 goto edit_block_process_cmd__EXIT
;
2174 edit_save_block (edit
, b
, start_mark
, end_mark
);
2175 quoted_name
= name_quote (edit
->filename
, 0);
2178 * Initial space is to avoid polluting bash history.
2180 * $1 - name of the edited file (to check its extension etc).
2181 * $2 - file containing the current block.
2182 * $3 - file where error messages should be put
2183 * (for compatibility with old scripts).
2185 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2186 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2191 * No block selected, just execute the command for the file.
2193 * $1 - name of the edited file.
2195 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2196 quoted_name
, (char *) NULL
);
2200 g_free (quoted_name
);
2201 close_error_pipe (D_NORMAL
, NULL
);
2203 edit_refresh_cmd (edit
);
2204 edit
->force
|= REDRAW_COMPLETELY
;
2206 /* insert result block */
2208 if (edit_block_delete_cmd (edit
))
2209 goto edit_block_process_cmd__EXIT
;
2210 edit_insert_file (edit
, b
);
2211 if ((block_file
= fopen (b
, "w")))
2212 fclose (block_file
);
2213 goto edit_block_process_cmd__EXIT
;
2215 edit_block_process_cmd__EXIT
:
2222 /* prints at the cursor */
2223 /* returns the number of chars printed */
2224 int edit_print_string (WEdit
* e
, const char *s
)
2228 edit_execute_cmd (e
, -1, (unsigned char) s
[i
++]);
2229 e
->force
|= REDRAW_COMPLETELY
;
2230 edit_update_screen (e
);
2235 static void pipe_mail (WEdit
*edit
, char *to
, char *subject
, char *cc
)
2240 to
= name_quote (to
, 0);
2241 subject
= name_quote (subject
, 0);
2242 cc
= name_quote (cc
, 0);
2243 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "" , cc
, " ", to
, (char *) NULL
);
2255 for (i
= 0; i
< edit
->last_byte
; i
++)
2256 fputc (edit_get_byte (edit
, i
), p
);
2261 #define MAIL_DLG_HEIGHT 12
2263 void edit_mail_dialog (WEdit
* edit
)
2266 char *tmail_subject
;
2269 static char *mail_cc_last
= 0;
2270 static char *mail_subject_last
= 0;
2271 static char *mail_to_last
= 0;
2273 QuickDialog Quick_input
=
2274 {50, MAIL_DLG_HEIGHT
, -1, 0, N_(" Mail "),
2275 "[Input Line Keys]", 0, 0};
2277 QuickWidget quick_widgets
[] =
2279 {quick_button
, 6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), 0, B_CANCEL
, 0,
2280 0, NULL
, NULL
, NULL
},
2281 {quick_button
, 2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), 0, B_ENTER
, 0,
2282 0, NULL
, NULL
, NULL
},
2283 {quick_input
, 3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, 0,
2284 0, "mail-dlg-input", NULL
, NULL
},
2285 {quick_label
, 2, 50, 7, MAIL_DLG_HEIGHT
, N_(" Copies to"), 0, 0, 0,
2287 {quick_input
, 3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, 0,
2288 0, "mail-dlg-input-2", NULL
, NULL
},
2289 {quick_label
, 2, 50, 5, MAIL_DLG_HEIGHT
, N_(" Subject"), 0, 0, 0,
2291 {quick_input
, 3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, 0,
2292 0, "mail-dlg-input-3", NULL
, NULL
},
2293 {quick_label
, 2, 50, 3, MAIL_DLG_HEIGHT
, N_(" To"), 0, 0, 0,
2295 {quick_label
, 2, 50, 2, MAIL_DLG_HEIGHT
, N_(" mail -s <subject> -c <cc> <to>"), 0, 0, 0,
2299 quick_widgets
[2].str_result
= &tmail_cc
;
2300 quick_widgets
[2].text
= mail_cc_last
? mail_cc_last
: "";
2301 quick_widgets
[4].str_result
= &tmail_subject
;
2302 quick_widgets
[4].text
= mail_subject_last
? mail_subject_last
: "";
2303 quick_widgets
[6].str_result
= &tmail_to
;
2304 quick_widgets
[6].text
= mail_to_last
? mail_to_last
: "";
2306 Quick_input
.widgets
= quick_widgets
;
2308 if (quick_dialog (&Quick_input
) != B_CANCEL
) {
2309 g_free (mail_cc_last
);
2310 g_free (mail_subject_last
);
2311 g_free (mail_to_last
);
2312 mail_cc_last
= tmail_cc
;
2313 mail_subject_last
= tmail_subject
;
2314 mail_to_last
= tmail_to
;
2315 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2320 /*******************/
2321 /* Word Completion */
2322 /*******************/
2324 static gboolean
is_break_char(char c
)
2326 return (isspace(c
) || strchr("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
2329 /* find first character of current word */
2330 static int edit_find_word_start (WEdit
*edit
, long *word_start
, int *word_len
)
2334 /* return if at begin of file */
2335 if (edit
->curs1
<= 0)
2338 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
2339 /* return if not at end or in word */
2340 if (is_break_char(c
))
2343 /* search start of word to be completed */
2345 /* return if at begin of file */
2346 if (edit
->curs1
- i
< 0)
2350 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
2352 if (is_break_char(c
)) {
2353 /* return if word starts with digit */
2357 *word_start
= edit
->curs1
- (i
- 1); /* start found */
2366 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
2368 /* collect the possible completions */
2370 edit_collect_completions (WEdit
*edit
, long start
, int word_len
,
2371 char *match_expr
, struct selection
*compl,
2381 srch
= mc_search_new(match_expr
, -1);
2385 srch
->search_type
= MC_SEARCH_T_REGEX
;
2386 srch
->is_case_sentitive
= TRUE
;
2387 srch
->search_fn
= edit_search_cmd_callback
;
2389 /* collect max MAX_WORD_COMPLETIONS completions */
2391 while (*num
< MAX_WORD_COMPLETIONS
) {
2392 /* get next match */
2393 if (mc_search_run (srch
, (void *) edit
, start
+1, edit
->last_byte
, &len
) == FALSE
)
2395 start
= srch
->normal_offset
;
2397 /* add matched completion if not yet added */
2398 temp
= g_string_new("");
2399 for (i
= 0; i
< len
; i
++){
2400 skip
= edit_get_byte(edit
, start
+i
);
2403 g_string_append_c (temp
, skip
);
2408 for (i
= 0; i
< (gsize
) *num
; i
++) {
2411 (char *) &compl[i
].text
[word_len
],
2412 (char *) &temp
->str
[word_len
],
2413 max (len
, compl[i
].len
) - (gsize
)word_len
2416 break; /* skip it, already added */
2420 g_string_free(temp
, TRUE
);
2424 compl[*num
].text
= temp
->str
;
2425 compl[*num
].len
= temp
->len
;
2427 g_string_free(temp
, FALSE
);
2429 /* note the maximal length needed for the completion dialog */
2433 mc_search_free(srch
);
2438 * Complete current word using regular expression search
2439 * backwards beginning at the current cursor position.
2442 edit_complete_word_cmd (WEdit
*edit
)
2444 int word_len
= 0, num_compl
= 0;
2446 long word_start
= 0;
2447 unsigned char *bufpos
;
2449 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2451 /* search start of word to be completed */
2452 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2455 /* prepare match expression */
2456 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2457 [word_start
& M_EDIT_BUF_SIZE
];
2459 match_expr
= g_strdup_printf ("(^|\\s)%.*s[^\\s\\.=\\+\\{\\}\\[\\]\\(\\)\\\\\\!\\,<>\\?\\/@#\\$%%\\^&\\*\\~\\|\\\"'\\:\\;]+", word_len
, bufpos
);
2461 /* collect the possible completions */
2462 /* start search from begin to end of file */
2464 edit_collect_completions (edit
, 0, word_len
, match_expr
,
2465 (struct selection
*) &compl, &num_compl
);
2467 if (num_compl
> 0) {
2468 /* insert completed word if there is only one match */
2469 if (num_compl
== 1) {
2470 for (i
= word_len
; i
< compl[0].len
; i
++)
2471 edit_insert (edit
, *(compl[0].text
+ i
));
2473 /* more than one possible completion => ask the user */
2475 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2476 /* !!! pressed again the selection dialog pops up, but that !!! */
2477 /* !!! seems to require a further internal state !!! */
2480 /* let the user select the preferred completion */
2481 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2482 (struct selection
*) &compl,
2487 g_free (match_expr
);
2488 /* release memory before return */
2489 for (i
= 0; i
< (gsize
) num_compl
; i
++)
2490 g_free (compl[i
].text
);
2495 edit_select_codepage_cmd (WEdit
*edit
)
2498 const char *cp_id
= NULL
;
2499 if (do_select_codepage ()) {
2500 cp_id
= get_codepage_id (source_codepage
>= 0 ?
2501 source_codepage
: display_codepage
);
2503 if (cp_id
!= NULL
) {
2505 conv
= str_crt_conv_from (cp_id
);
2506 if (conv
!= INVALID_CONV
) {
2507 if (edit
->converter
!= str_cnv_from_term
)
2508 str_close_conv (edit
->converter
);
2509 edit
->converter
= conv
;
2515 edit
->utf8
= str_isutf8 (cp_id
);
2518 edit
->force
= REDRAW_COMPLETELY
;
2519 edit_refresh_cmd (edit
);
2524 edit_insert_literal_cmd (WEdit
*edit
)
2526 int char_for_insertion
=
2527 editcmd_dialog_raw_key_query (_(" Insert Literal "),
2528 _(" Press any key: "), 0);
2529 edit_execute_key_command (edit
, -1,
2530 ascii_alpha_to_cntrl (char_for_insertion
));
2534 edit_execute_macro_cmd (WEdit
*edit
)
2537 CK_Macro (editcmd_dialog_raw_key_query
2538 (_(" Execute Macro "), _(" Press macro hotkey: "),
2540 if (command
== CK_Macro (0))
2541 command
= CK_Insert_Char
;
2543 edit_execute_key_command (edit
, command
, -1);
2547 edit_begin_end_macro_cmd(WEdit
*edit
)
2551 /* edit is a pointer to the widget */
2555 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
2556 edit_execute_key_command (edit
, command
, -1);
2561 edit_load_forward_cmd (WEdit
*edit
)
2563 if (edit
->modified
) {
2564 if (edit_query_dialog2
2566 _(" Current text was modified without a file save. \n"
2567 " Continue discards these changes. "), _("C&ontinue"),
2569 edit
->force
|= REDRAW_COMPLETELY
;
2573 if ( edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
) {
2574 if ( edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1 ) {
2577 edit_stack_iterator
++;
2578 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2579 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2580 edit_history_moveto
[edit_stack_iterator
].line
);
2591 edit_load_back_cmd (WEdit
*edit
)
2593 if (edit
->modified
) {
2594 if (edit_query_dialog2
2596 _(" Current text was modified without a file save. \n"
2597 " Continue discards these changes. "), _("C&ontinue"),
2599 edit
->force
|= REDRAW_COMPLETELY
;
2603 if ( edit_stack_iterator
> 0 ) {
2604 edit_stack_iterator
--;
2605 if ( edit_history_moveto
[edit_stack_iterator
].filename
) {
2606 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
2607 edit_history_moveto
[edit_stack_iterator
].line
);
2618 edit_get_match_keyword_cmd (WEdit
*edit
)
2624 long word_start
= 0;
2625 unsigned char *bufpos
;
2629 char *tagfile
= NULL
;
2631 etags_hash_t def_hash
[MAX_DEFINITIONS
];
2633 for ( i
= 0; i
< MAX_DEFINITIONS
; i
++) {
2634 def_hash
[i
].filename
= NULL
;
2637 /* search start of word to be completed */
2638 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2641 /* prepare match expression */
2642 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
]
2643 [word_start
& M_EDIT_BUF_SIZE
];
2644 match_expr
= g_strdup_printf ("%.*s", word_len
, bufpos
);
2646 ptr
= g_get_current_dir ();
2647 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
2650 /* Recursive search file 'TAGS' in parent dirs */
2652 ptr
= g_path_get_dirname (path
);
2653 g_free(path
); path
= ptr
;
2655 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
2656 if ( exist_file (tagfile
) )
2658 } while (strcmp( path
, G_DIR_SEPARATOR_S
) != 0);
2661 num_def
= etags_set_definition_hash(tagfile
, path
, match_expr
, (etags_hash_t
*) &def_hash
);
2666 max_len
= MAX_WIDTH_DEF_DIALOG
;
2668 if ( num_def
> 0 ) {
2669 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
2670 (etags_hash_t
*) &def_hash
,
2673 g_free (match_expr
);
2677 edit_move_block_to_right (WEdit
* edit
)
2679 long start_mark
, end_mark
;
2680 long cur_bol
, start_bol
;
2682 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2685 start_bol
= edit_bol (edit
, start_mark
);
2686 cur_bol
= edit_bol (edit
, end_mark
- 1);
2688 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2689 if ( option_fill_tabs_with_spaces
) {
2690 if ( option_fake_half_tabs
) {
2691 insert_spaces_tab (edit
, 1);
2693 insert_spaces_tab (edit
, 0);
2696 edit_insert (edit
, '\t');
2698 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
2699 if ( cur_bol
== 0 ) {
2702 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2703 } while (cur_bol
>= start_bol
) ;
2704 edit
->force
|= REDRAW_PAGE
;
2708 edit_move_block_to_left (WEdit
* edit
)
2710 long start_mark
, end_mark
;
2711 long cur_bol
, start_bol
;
2712 int i
, del_tab_width
;
2715 if ( eval_marks (edit
, &start_mark
, &end_mark
) )
2718 start_bol
= edit_bol (edit
, start_mark
);
2719 cur_bol
= edit_bol (edit
, end_mark
- 1);
2721 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
2722 if (option_fake_half_tabs
) {
2723 del_tab_width
= HALF_TAB_SIZE
;
2725 del_tab_width
= option_tab_spacing
;
2727 next_char
= edit_get_byte (edit
, edit
->curs1
);
2728 if ( next_char
== '\t' ) {
2729 edit_delete (edit
, 1);
2730 } else if ( next_char
== ' ' ) {
2731 for (i
= 1; i
<= del_tab_width
; i
++) {
2732 if ( next_char
== ' ' ) {
2733 edit_delete (edit
, 1);
2735 next_char
= edit_get_byte (edit
, edit
->curs1
);
2738 if ( cur_bol
== 0 ) {
2741 cur_bol
= edit_bol (edit
, cur_bol
- 1);
2742 } while (cur_bol
>= start_bol
) ;
2743 edit
->force
|= REDRAW_PAGE
;