1 /* editor high level editing commands
3 Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006,
4 2007 Free Software Foundation, Inc.
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 * \brief Source: editor high level editing commands
31 /* #define PIPE_BLOCKS_SO_READ_BYTE_BY_BYTE */
40 #include <sys/types.h>
48 #include "lib/global.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h" /* XCTRL */
51 #include "lib/mcconfig.h"
53 #include "lib/strutil.h" /* utf string functions */
55 #include "lib/util.h" /* tilde_expand() */
56 #include "lib/vfs/mc-vfs/vfs.h"
57 #include "lib/widget.h"
58 #include "lib/charsets.h"
60 #include "src/filemanager/layout.h" /* clr_scr() */
62 #include "src/history.h"
63 #include "src/main.h" /* mc_home, midnight_shutdown */
64 #include "src/setup.h" /* option_tab_spacing */
65 #include "src/help.h" /* interactive_display() */
66 #include "src/selcodepage.h"
67 #include "src/keybind-defaults.h"
68 #include "src/clipboard.h" /* copy_file_to_ext_clip, paste_to_file_from_ext_clip */
70 #include "edit-impl.h"
71 #include "edit-widget.h"
72 #include "editcmd_dialogs.h"
75 /*** global variables ****************************************************************************/
77 /* search and replace: */
78 int search_create_bookmark
= FALSE
;
80 /* queries on a save */
81 int edit_confirm_save
= 1;
83 static int edit_save_cmd (WEdit
* edit
);
84 static unsigned char *edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
);
86 /*** file scope macro definitions ****************************************************************/
90 #define TEMP_BUF_LEN 1024
94 /* thanks to Liviu Daia <daia@stoilow.imar.ro> for getting this
95 (and the above) routines to work properly - paul */
97 #define is_digit(x) ((x) >= '0' && (x) <= '9')
99 #define MAIL_DLG_HEIGHT 12
101 #define MAX_WORD_COMPLETIONS 100 /* in listbox */
103 /*** file scope type declarations ****************************************************************/
105 /*** file scope variables ************************************************************************/
107 /*** file scope functions ************************************************************************/
108 /* --------------------------------------------------------------------------------------------- */
110 /* If 0 (quick save) then a) create/truncate <filename> file,
111 b) save to <filename>;
112 if 1 (safe save) then a) save to <tempnam>,
113 b) rename <tempnam> to <filename>;
114 if 2 (do backups) then a) save to <tempnam>,
115 b) rename <filename> to <filename.backup_ext>,
116 c) rename <tempnam> to <filename>. */
118 /* returns 0 on error, -1 on abort */
121 edit_save_file (WEdit
* edit
, const char *filename
)
127 gchar
*real_filename
;
128 int this_save_mode
, fd
= -1;
135 if (*filename
!= PATH_SEP
&& edit
->dir
)
137 real_filename
= concat_dir_and_file (edit
->dir
, filename
);
141 real_filename
= g_strdup (filename
);
144 this_save_mode
= option_save_mode
;
145 if (this_save_mode
!= EDIT_QUICK_SAVE
)
147 if (!vfs_file_is_local (real_filename
) ||
148 (fd
= mc_open (real_filename
, O_RDONLY
| O_BINARY
)) == -1)
151 * The file does not exists yet, so no safe save or
152 * backup are necessary.
154 this_save_mode
= EDIT_QUICK_SAVE
;
160 if (this_save_mode
== EDIT_QUICK_SAVE
&& !edit
->skip_detach_prompt
)
165 rv
= mc_stat (real_filename
, &sb
);
166 if (rv
== 0 && sb
.st_nlink
> 1)
168 rv
= edit_query_dialog3 (_("Warning"),
169 _("File has hard-links. Detach before saving?"),
170 _("&Yes"), _("&No"), _("&Cancel"));
174 this_save_mode
= EDIT_SAFE_SAVE
;
177 edit
->skip_detach_prompt
= 1;
180 g_free (real_filename
);
185 /* Prevent overwriting changes from other editor sessions. */
186 if (rv
== 0 && edit
->stat1
.st_mtime
!= 0 && edit
->stat1
.st_mtime
!= sb
.st_mtime
)
189 /* The default action is "Cancel". */
192 rv
= edit_query_dialog2 (_("Warning"),
193 _("The file has been modified in the meantime. Save anyway?"),
194 _("&Yes"), _("&Cancel"));
197 g_free (real_filename
);
203 if (this_save_mode
!= EDIT_QUICK_SAVE
)
205 char *savedir
, *saveprefix
;
206 const char *slashpos
;
207 slashpos
= strrchr (real_filename
, PATH_SEP
);
210 savedir
= g_strdup (real_filename
);
211 savedir
[slashpos
- real_filename
+ 1] = '\0';
214 savedir
= g_strdup (".");
215 saveprefix
= concat_dir_and_file (savedir
, "cooledit");
217 fd
= mc_mkstemps (&savename
, saveprefix
, NULL
);
221 g_free (real_filename
);
225 * Close for now because mc_mkstemps use pure open system call
226 * to create temporary file and it needs to be reopened by
227 * VFS-aware mc_open().
232 savename
= g_strdup (real_filename
);
235 ret
= mc_chown (savename
, edit
->stat1
.st_uid
, edit
->stat1
.st_gid
);
236 ret
= mc_chmod (savename
, edit
->stat1
.st_mode
);
239 fd
= mc_open (savename
, O_CREAT
| O_WRONLY
| O_TRUNC
| O_BINARY
, edit
->stat1
.st_mode
);
244 p
= edit_get_write_filter (savename
, real_filename
);
250 file
= (FILE *) popen (p
, "w");
254 filelen
= edit_write_stream (edit
, file
);
258 if (pclose (file
) != 0)
260 tmp
= g_strdup_printf (_("Error writing to pipe: %s"), p
);
261 edit_error_dialog (_("Error"), tmp
);
270 tmp
= g_strdup_printf (_("Cannot open pipe for writing: %s"), p
);
271 edit_error_dialog (_("Error"), get_sys_error (tmp
));
278 else if (edit
->lb
== LB_ASIS
)
279 { /* do not change line breaks */
282 filelen
= edit
->last_byte
;
283 while (buf
<= (edit
->curs1
>> S_EDIT_BUF_SIZE
) - 1)
285 if (mc_write (fd
, (char *) edit
->buffers1
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
293 (fd
, (char *) edit
->buffers1
[buf
],
294 edit
->curs1
& M_EDIT_BUF_SIZE
) != (edit
->curs1
& M_EDIT_BUF_SIZE
))
298 else if (edit
->curs2
)
301 buf
= (edit
->curs2
>> S_EDIT_BUF_SIZE
);
304 (char *) edit
->buffers2
[buf
] + EDIT_BUF_SIZE
-
305 (edit
->curs2
& M_EDIT_BUF_SIZE
) - 1,
306 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
)) != 1 + (edit
->curs2
& M_EDIT_BUF_SIZE
))
314 if (mc_write (fd
, (char *) edit
->buffers2
[buf
], EDIT_BUF_SIZE
) != EDIT_BUF_SIZE
)
326 /* Update the file information, especially the mtime. */
327 if (mc_stat (savename
, &edit
->stat1
) == -1)
331 { /* change line breaks */
336 file
= (FILE *) fopen (savename
, "w");
340 filelen
= edit_write_stream (edit
, file
);
347 msg
= g_strdup_printf (_("Cannot open file for writing: %s"), savename
);
348 edit_error_dialog (_("Error"), msg
);
354 if (filelen
!= edit
->last_byte
)
357 if (this_save_mode
== EDIT_DO_BACKUP
)
359 assert (option_backup_ext
!= NULL
);
360 tmp
= g_strconcat (real_filename
, option_backup_ext
, (char *) NULL
);
361 if (mc_rename (real_filename
, tmp
) == -1)
368 if (this_save_mode
!= EDIT_QUICK_SAVE
)
369 if (mc_rename (savename
, real_filename
) == -1)
372 g_free (real_filename
);
375 /* FIXME: Is this safe ?
376 * if (this_save_mode != EDIT_QUICK_SAVE)
377 * mc_unlink (savename);
379 g_free (real_filename
);
384 /* --------------------------------------------------------------------------------------------- */
387 edit_check_newline (WEdit
* edit
)
389 return !(option_check_nl_at_eof
&& edit
->last_byte
> 0
390 && edit_get_byte (edit
, edit
->last_byte
- 1) != '\n'
391 && edit_query_dialog2 (_("Warning"),
392 _("The file you are saving is not finished with a newline"),
393 _("C&ontinue"), _("&Cancel")));
396 /* --------------------------------------------------------------------------------------------- */
399 edit_get_save_file_as (WEdit
* edit
)
402 #define DLG_HEIGHT 14
404 static LineBreaks cur_lb
= LB_ASIS
;
406 char *filename
= edit
->filename
;
408 const char *lb_names
[LB_NAMES
] = {
409 N_("&Do not change"),
410 N_("&Unix format (LF)"),
411 N_("&Windows/DOS format (CR LF)"),
412 N_("&Macintosh format (CR)")
415 QuickWidget quick_widgets
[] = {
416 QUICK_BUTTON (6, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
417 QUICK_BUTTON (2, 10, DLG_HEIGHT
- 3, DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
418 QUICK_RADIO (5, DLG_WIDTH
, DLG_HEIGHT
- 8, DLG_HEIGHT
, LB_NAMES
, lb_names
, (int *) &cur_lb
),
419 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 9, DLG_HEIGHT
, N_("Change line breaks to:")),
420 QUICK_INPUT (3, DLG_WIDTH
, DLG_HEIGHT
- 11, DLG_HEIGHT
, filename
, DLG_WIDTH
- 6, 0,
421 "save-as", &filename
),
422 QUICK_LABEL (3, DLG_WIDTH
, DLG_HEIGHT
- 12, DLG_HEIGHT
, N_("Enter file name:")),
426 QuickDialog Quick_options
= {
427 DLG_WIDTH
, DLG_HEIGHT
, -1, -1,
428 N_("Save As"), "[Save File As]",
429 quick_widgets
, NULL
, FALSE
432 if (quick_dialog (&Quick_options
) != B_CANCEL
)
437 fname
= tilde_expand (filename
);
448 /* {{{ Macro stuff starts here */
450 /* --------------------------------------------------------------------------------------------- */
451 /** creates a macro file if it doesn't exist */
454 edit_open_macro_file (const char *r
)
459 filename
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
460 file
= open (filename
, O_CREAT
| O_RDWR
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
467 fd
= fopen (filename
, r
);
472 #define MAX_MACROS 1024
473 static int saved_macro
[MAX_MACROS
+ 1];
474 static int saved_macros_loaded
= 0;
476 /* --------------------------------------------------------------------------------------------- */
478 This is just to stop the macro file be loaded over and over for keys
479 that aren't defined to anything. On slow systems this could be annoying.
486 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++)
487 if (saved_macro
[i
] == k
)
492 /* --------------------------------------------------------------------------------------------- */
493 /** returns 1 on error */
496 edit_delete_macro (WEdit
* edit
, int k
)
499 struct macro macro
[MAX_MACRO_LENGTH
];
505 if (saved_macros_loaded
)
507 j
= macro_exists (k
);
511 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
512 g
= fopen (tmp
, "w");
516 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open temp file")));
519 f
= edit_open_macro_file ("r");
522 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open macro file")));
528 n
= fscanf (f
, ("key '%d 0': "), &s
);
532 while (fscanf (f
, "%lu %d, ", ¯o
[n
].command
, ¯o
[n
].ch
))
536 ret
= fscanf (f
, ";\n");
540 fprintf (g
, ("key '%d 0': "), s
);
541 for (i
= 0; i
< n
; i
++)
542 fprintf (g
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
548 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
549 tmp2
= concat_dir_and_file (home_dir
, EDIT_MACRO_FILE
);
550 if (rename (tmp
, tmp2
) == -1)
552 edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot overwrite macro file")));
560 if (saved_macros_loaded
)
561 memmove (saved_macro
+ j
, saved_macro
+ j
+ 1, sizeof (int) * (MAX_MACROS
- j
- 1));
567 /* --------------------------------------------------------------------------------------------- */
568 /** returns 1 on success */
571 edit_save_cmd (WEdit
* edit
)
573 int res
, save_lock
= 0;
575 if (!edit
->locked
&& !edit
->delete_file
)
576 save_lock
= edit_lock_file (edit
);
577 res
= edit_save_file (edit
, edit
->filename
);
579 /* Maintain modify (not save) lock on failure */
580 if ((res
> 0 && edit
->locked
) || save_lock
)
581 edit
->locked
= edit_unlock_file (edit
);
583 /* On failure try 'save as', it does locking on its own */
585 return edit_save_as_cmd (edit
);
586 edit
->force
|= REDRAW_COMPLETELY
;
589 edit
->delete_file
= 0;
596 /* --------------------------------------------------------------------------------------------- */
597 /** returns 1 on error */
600 edit_load_file_from_filename (WEdit
* edit
, char *exp
)
602 int prev_locked
= edit
->locked
;
603 char *prev_filename
= g_strdup (edit
->filename
);
605 if (!edit_reload (edit
, exp
))
607 g_free (prev_filename
);
615 fullpath
= g_build_filename (edit
->dir
, prev_filename
, (char *) NULL
);
616 unlock_file (fullpath
);
619 g_free (prev_filename
);
623 /* --------------------------------------------------------------------------------------------- */
626 edit_load_syntax_file (WEdit
* edit
)
633 dir
= query_dialog (_("Syntax file edit"),
634 _("Which syntax file you want to edit?"), D_NORMAL
, 2,
635 _("&User"), _("&System Wide"));
638 extdir
= g_build_filename (mc_home
, "syntax", "Syntax", (char *) NULL
);
639 if (!exist_file (extdir
))
642 extdir
= g_build_filename (mc_home_alt
, "syntax", "Syntax", (char *) NULL
);
649 buffer
= concat_dir_and_file (home_dir
, EDIT_SYNTAX_FILE
);
650 check_for_default (extdir
, buffer
);
651 edit_load_file_from_filename (edit
, buffer
);
655 edit_load_file_from_filename (edit
, extdir
);
660 /* --------------------------------------------------------------------------------------------- */
663 edit_load_menu_file (WEdit
* edit
)
669 dir
= query_dialog (_("Menu edit"),
670 _("Which menu file do you want to edit?"), D_NORMAL
,
671 geteuid () != 0 ? 2 : 3, _("&Local"), _("&User"), _("&System Wide"));
673 menufile
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
675 if (!exist_file (menufile
))
678 menufile
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
684 buffer
= g_strdup (EDIT_LOCAL_MENU
);
685 check_for_default (menufile
, buffer
);
686 chmod (buffer
, 0600);
690 buffer
= concat_dir_and_file (home_dir
, EDIT_HOME_MENU
);
691 check_for_default (menufile
, buffer
);
695 buffer
= concat_dir_and_file (mc_home
, EDIT_GLOBAL_MENU
);
696 if (!exist_file (buffer
))
699 buffer
= concat_dir_and_file (mc_home_alt
, EDIT_GLOBAL_MENU
);
708 edit_load_file_from_filename (edit
, buffer
);
714 /* --------------------------------------------------------------------------------------------- */
717 edit_delete_column_of_text (WEdit
* edit
)
719 long p
, q
, r
, m1
, m2
;
722 eval_marks (edit
, &m1
, &m2
);
723 n
= edit_move_forward (edit
, m1
, 0, m2
) + 1;
724 c
= edit_move_forward3 (edit
, edit_bol (edit
, m1
), 0, m1
);
725 d
= edit_move_forward3 (edit
, edit_bol (edit
, m2
), 0, m2
);
726 b
= max (min (c
, d
), min (edit
->column1
, edit
->column2
));
727 c
= max (c
, max (edit
->column1
, edit
->column2
));
731 r
= edit_bol (edit
, edit
->curs1
);
732 p
= edit_move_forward3 (edit
, r
, b
, 0);
733 q
= edit_move_forward3 (edit
, r
, c
, 0);
738 edit_cursor_move (edit
, p
- edit
->curs1
);
741 /* delete line between margins */
742 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
743 edit_delete (edit
, 1);
747 /* move to next line except on the last delete */
748 edit_cursor_move (edit
, edit_move_forward (edit
, edit
->curs1
, 1, 0) - edit
->curs1
);
752 /* --------------------------------------------------------------------------------------------- */
753 /** if success return 0 */
756 edit_block_delete (WEdit
* edit
)
759 long start_mark
, end_mark
;
760 int curs_pos
, line_width
;
761 long curs_line
, c1
, c2
;
763 if (eval_marks (edit
, &start_mark
, &end_mark
))
765 if (edit
->column_highlight
&& edit
->mark2
< 0)
766 edit_mark_cmd (edit
, 0);
767 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
769 /* Warning message with a query to continue or cancel the operation */
770 if (edit_query_dialog2
773 ("Block is large, you may not be able to undo this action"),
774 _("C&ontinue"), _("&Cancel")))
779 c1
= min (edit
->column1
, edit
->column2
);
780 c2
= max (edit
->column1
, edit
->column2
);
784 edit_push_markers (edit
);
786 curs_line
= edit
->curs_line
;
788 /* calculate line width and cursor position before cut */
789 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
790 edit_eol (edit
, edit
->curs1
));
791 curs_pos
= edit
->curs_col
+ edit
->over_col
;
793 /* move cursor to start of selection */
794 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
795 edit_scroll_screen_over_cursor (edit
);
797 if (start_mark
< end_mark
)
799 if (edit
->column_highlight
)
802 edit_mark_cmd (edit
, 0);
803 edit_delete_column_of_text (edit
);
804 /* move cursor to the saved position */
805 edit_move_to_line (edit
, curs_line
);
806 /* calculate line width after cut */
807 line_width
= edit_move_forward3 (edit
, edit_bol (edit
, edit
->curs1
), 0,
808 edit_eol (edit
, edit
->curs1
));
809 if (option_cursor_beyond_eol
&& curs_pos
> line_width
)
810 edit
->over_col
= curs_pos
- line_width
;
814 while (count
< end_mark
)
816 edit_delete (edit
, 1);
821 edit_set_markers (edit
, 0, 0, 0, 0);
822 edit
->force
|= REDRAW_PAGE
;
826 /* --------------------------------------------------------------------------------------------- */
829 editcmd_find (WEdit
* edit
, gsize
* len
)
831 off_t search_start
= edit
->search_start
;
834 long end_mark
= edit
->last_byte
;
837 if (edit_search_options
.only_in_selection
)
839 mark_res
= eval_marks (edit
, &start_mark
, &end_mark
);
842 edit
->search
->error
= MC_SEARCH_E_NOTFOUND
;
843 edit
->search
->error_str
= g_strdup (_("Search string not found"));
846 if (edit_search_options
.backwards
)
848 if (search_start
> end_mark
|| search_start
<= start_mark
)
850 search_start
= end_mark
;
855 if (search_start
< start_mark
|| search_start
>= end_mark
)
857 search_start
= start_mark
;
863 if (edit_search_options
.backwards
)
864 end_mark
= max (1, edit
->curs1
) - 1;
866 if (edit_search_options
.backwards
)
868 search_end
= end_mark
;
869 while ((int) search_start
>= start_mark
)
871 if (search_end
> (off_t
) (search_start
+ edit
->search
->original_len
) &&
872 mc_search_is_fixed_search_str (edit
->search
))
874 search_end
= search_start
+ edit
->search
->original_len
;
876 if (mc_search_run (edit
->search
, (void *) edit
, search_start
, search_end
, len
)
877 && edit
->search
->normal_offset
== search_start
)
883 edit
->search
->error_str
= g_strdup (_("Search string not found"));
887 return mc_search_run (edit
->search
, (void *) edit
, search_start
, end_mark
, len
);
892 /* --------------------------------------------------------------------------------------------- */
895 edit_replace_cmd__conv_to_display (char *str
)
900 tmp
= str_convert_to_display (str
);
904 return g_string_free (tmp
, FALSE
);
905 g_string_free (tmp
, TRUE
);
908 return g_strdup (str
);
911 /* --------------------------------------------------------------------------------------------- */
914 edit_replace_cmd__conv_to_input (char *str
)
919 tmp
= str_convert_to_input (str
);
923 return g_string_free (tmp
, FALSE
);
924 g_string_free (tmp
, TRUE
);
927 return g_strdup (str
);
930 /* --------------------------------------------------------------------------------------------- */
933 edit_do_search (WEdit
* edit
)
937 if (edit
->search
== NULL
)
938 edit
->search_start
= edit
->curs1
;
940 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
942 if (search_create_bookmark
)
944 int found
= 0, books
= 0;
945 long l
= 0, l_last
= -1;
948 search_create_bookmark
= FALSE
;
949 book_mark_flush (edit
, -1);
953 if (!mc_search_run (edit
->search
, (void *) edit
, q
, edit
->last_byte
, &len
))
956 edit
->search_start
= edit
->search
->normal_offset
;
958 l
+= edit_count_lines (edit
, q
, edit
->search
->normal_offset
);
961 book_mark_insert (edit
, l
, BOOK_MARK_FOUND_COLOR
);
965 q
= edit
->search
->normal_offset
+ 1;
969 edit_error_dialog (_("Search"), _("Search string not found"));
971 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
975 if (edit
->found_len
!= 0 && edit
->search_start
== edit
->found_start
+ 1
976 && edit_search_options
.backwards
)
977 edit
->search_start
--;
979 if (edit
->found_len
!= 0 && edit
->search_start
== edit
->found_start
- 1
980 && !edit_search_options
.backwards
)
981 edit
->search_start
++;
983 if (editcmd_find (edit
, &len
))
985 edit
->found_start
= edit
->search_start
= edit
->search
->normal_offset
;
986 edit
->found_len
= len
;
988 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
989 edit_scroll_screen_over_cursor (edit
);
990 if (edit_search_options
.backwards
)
991 edit
->search_start
--;
993 edit
->search_start
++;
997 edit
->search_start
= edit
->curs1
;
998 if (edit
->search
->error_str
!= NULL
)
999 edit_error_dialog (_("Search"), edit
->search
->error_str
);
1003 edit
->force
|= REDRAW_COMPLETELY
;
1004 edit_scroll_screen_over_cursor (edit
);
1007 /* --------------------------------------------------------------------------------------------- */
1010 edit_search (WEdit
*edit
)
1012 if (editcmd_dialog_search_show (edit
))
1013 edit_do_search (edit
);
1016 /* --------------------------------------------------------------------------------------------- */
1017 /** Return a null terminated length of text. Result must be g_free'd */
1019 static unsigned char *
1020 edit_get_block (WEdit
* edit
, long start
, long finish
, int *l
)
1022 unsigned char *s
, *r
;
1023 r
= s
= g_malloc0 (finish
- start
+ 1);
1024 if (edit
->column_highlight
)
1027 /* copy from buffer, excluding chars that are out of the column 'margins' */
1028 while (start
< finish
)
1032 x
= edit_move_forward3 (edit
, edit_bol (edit
, start
), 0, start
);
1033 c
= edit_get_byte (edit
, start
);
1034 if ((x
>= edit
->column1
&& x
< edit
->column2
)
1035 || (x
>= edit
->column2
&& x
< edit
->column1
) || c
== '\n')
1045 *l
= finish
- start
;
1046 while (start
< finish
)
1047 *s
++ = edit_get_byte (edit
, start
++);
1053 /* --------------------------------------------------------------------------------------------- */
1054 /** copies a block to clipboard file */
1057 edit_save_block_to_clip_file (WEdit
* edit
, long start
, long finish
)
1061 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
1062 ret
= edit_save_block (edit
, tmp
, start
, finish
);
1067 /* --------------------------------------------------------------------------------------------- */
1070 pipe_mail (WEdit
* edit
, char *to
, char *subject
, char *cc
)
1075 to
= name_quote (to
, 0);
1076 subject
= name_quote (subject
, 0);
1077 cc
= name_quote (cc
, 0);
1078 s
= g_strconcat ("mail -s ", subject
, *cc
? " -c " : "", cc
, " ", to
, (char *) NULL
);
1092 for (i
= 0; i
< edit
->last_byte
; i
++)
1093 fputc (edit_get_byte (edit
, i
), p
);
1098 /* --------------------------------------------------------------------------------------------- */
1101 is_break_char (char c
)
1103 return (isspace (c
) || strchr ("{}[]()<>=|/\\!?~'\",.;:#$%^&*", c
));
1106 /* --------------------------------------------------------------------------------------------- */
1107 /** find first character of current word */
1110 edit_find_word_start (WEdit
* edit
, long *word_start
, gsize
* word_len
)
1115 /* return if at begin of file */
1116 if (edit
->curs1
<= 0)
1119 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- 1);
1120 /* return if not at end or in word */
1121 if (is_break_char (c
))
1124 /* search start of word to be completed */
1127 /* return if at begin of file */
1128 if ((gsize
) edit
->curs1
< i
)
1132 c
= (unsigned char) edit_get_byte (edit
, edit
->curs1
- i
);
1134 if (is_break_char (c
))
1136 /* return if word starts with digit */
1140 *word_start
= edit
->curs1
- (i
- 1); /* start found */
1149 /* --------------------------------------------------------------------------------------------- */
1150 /** collect the possible completions */
1152 edit_collect_completions (WEdit
* edit
, long start
, gsize word_len
,
1153 char *match_expr
, struct selection
*compl, gsize
* num
)
1164 srch
= mc_search_new (match_expr
, -1);
1168 if (mc_config_get_bool
1169 (mc_main_config
, CONFIG_APP_SECTION
, "editor_wordcompletion_collect_entire_file", 0))
1171 last_byte
= edit
->last_byte
;
1178 srch
->search_type
= MC_SEARCH_T_REGEX
;
1179 srch
->is_case_sensitive
= TRUE
;
1180 srch
->search_fn
= edit_search_cmd_callback
;
1182 /* collect max MAX_WORD_COMPLETIONS completions */
1186 /* get next match */
1187 if (mc_search_run (srch
, (void *) edit
, start
+ 1, last_byte
, &len
) == FALSE
)
1189 start
= srch
->normal_offset
;
1191 /* add matched completion if not yet added */
1192 temp
= g_string_new ("");
1193 for (i
= 0; i
< len
; i
++)
1195 skip
= edit_get_byte (edit
, start
+ i
);
1198 g_string_append_c (temp
, skip
);
1203 for (i
= 0; i
< (gsize
) * num
; i
++)
1206 ((char *) &compl[i
].text
[word_len
],
1207 (char *) &temp
->str
[word_len
], max (len
, compl[i
].len
) - (gsize
) word_len
) == 0)
1209 struct selection
this = compl[i
];
1210 for (++i
; i
< *num
; i
++)
1212 compl[i
- 1] = compl[i
];
1214 compl[*num
- 1] = this;
1216 break; /* skip it, already added */
1221 g_string_free (temp
, TRUE
);
1224 if (*num
== MAX_WORD_COMPLETIONS
&& MAX_WORD_COMPLETIONS
)
1226 g_free (compl[0].text
);
1227 for (i
= 1; i
< *num
; i
++)
1229 compl[i
- 1] = compl[i
];
1236 recoded
= str_convert_to_display (temp
->str
);
1238 if (recoded
&& recoded
->len
)
1240 g_string_free (temp
, TRUE
);
1244 g_string_free (recoded
, TRUE
);
1247 compl[*num
].text
= temp
->str
;
1248 compl[*num
].len
= temp
->len
;
1251 g_string_free (temp
, FALSE
);
1253 /* note the maximal length needed for the completion dialog */
1257 mc_search_free (srch
);
1262 /* --------------------------------------------------------------------------------------------- */
1263 /*** public functions ****************************************************************************/
1264 /* --------------------------------------------------------------------------------------------- */
1267 edit_help_cmd (WEdit
* edit
)
1269 interactive_display (NULL
, "[Internal File Editor]");
1270 edit
->force
|= REDRAW_COMPLETELY
;
1273 /* --------------------------------------------------------------------------------------------- */
1276 edit_refresh_cmd (WEdit
* edit
)
1281 edit_get_syntax_color (edit
, -1, &color
);
1282 tty_touch_screen ();
1289 #endif /* !HAVE_SLANG */
1293 /* --------------------------------------------------------------------------------------------- */
1296 menu_save_mode_cmd (void)
1299 const int DLG_X
= 38;
1300 const int DLG_Y
= 13;
1304 const char *str
[] = {
1307 N_("&Do backups with following extension:")
1310 QuickWidget widgets
[] = {
1312 QUICK_BUTTON (18, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&Cancel"), B_CANCEL
, NULL
),
1314 QUICK_BUTTON (6, DLG_X
, DLG_Y
- 3, DLG_Y
, N_("&OK"), B_ENTER
, NULL
),
1316 QUICK_CHECKBOX (4, DLG_X
, 8, DLG_Y
, N_("Check &POSIX new line"), &option_check_nl_at_eof
),
1318 QUICK_INPUT (8, DLG_X
, 6, DLG_Y
, option_backup_ext
, 9, 0, "edit-backup-ext", &str_result
),
1320 QUICK_RADIO (4, DLG_X
, 3, DLG_Y
, 3, str
, &option_save_mode
),
1324 QuickDialog dialog
= {
1325 DLG_X
, DLG_Y
, -1, -1, N_("Edit Save Mode"),
1326 "[Edit Save Mode]", widgets
, NULL
, FALSE
1331 size_t w0
, w1
, b_len
, w3
;
1333 assert (option_backup_ext
!= NULL
);
1335 /* OK/Cancel buttons */
1336 w0
= str_term_width1 (_(widgets
[0].u
.button
.text
)) + 3;
1337 w1
= str_term_width1 (_(widgets
[1].u
.button
.text
)) + 5; /* default button */
1338 b_len
= w0
+ w1
+ 3;
1340 maxlen
= max (b_len
, (size_t) str_term_width1 (_(dialog
.title
)) + 2);
1343 for (i
= 0; i
< 3; i
++)
1348 w3
= max (w3
, (size_t) str_term_width1 (str
[i
]));
1351 maxlen
= max (maxlen
, w3
+ 4);
1353 dialog
.xlen
= min ((size_t) COLS
, maxlen
+ 8);
1355 widgets
[3].u
.input
.len
= w3
;
1356 widgets
[1].relative_x
= (dialog
.xlen
- b_len
) / 2;
1357 widgets
[0].relative_x
= widgets
[1].relative_x
+ w0
+ 2;
1359 for (i
= 0; i
< sizeof (widgets
) / sizeof (widgets
[0]); i
++)
1360 widgets
[i
].x_divisions
= dialog
.xlen
;
1362 if (quick_dialog (&dialog
) != B_CANCEL
)
1364 g_free (option_backup_ext
);
1365 option_backup_ext
= str_result
;
1369 /* --------------------------------------------------------------------------------------------- */
1372 edit_set_filename (WEdit
* edit
, const char *name
)
1374 g_free (edit
->filename
);
1379 edit
->filename
= tilde_expand (name
);
1380 if (edit
->dir
== NULL
&& !g_path_is_absolute (name
))
1381 edit
->dir
= g_strdup (vfs_get_current_dir ());
1384 /* --------------------------------------------------------------------------------------------- */
1385 /* Here we want to warn the users of overwriting an existing file,
1386 but only if they have made a change to the filename */
1387 /* returns 1 on success */
1389 edit_save_as_cmd (WEdit
* edit
)
1391 /* This heads the 'Save As' dialog box */
1394 int different_filename
= 0;
1396 if (!edit_check_newline (edit
))
1399 exp
= edit_get_save_file_as (edit
);
1400 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1407 edit
->force
|= REDRAW_COMPLETELY
;
1413 if (strcmp (edit
->filename
, exp
))
1416 different_filename
= 1;
1417 file
= mc_open (exp
, O_RDONLY
| O_BINARY
);
1420 /* the file exists */
1422 /* Overwrite the current file or cancel the operation */
1423 if (edit_query_dialog2
1425 _("A file already exists with this name"), _("&Overwrite"), _("&Cancel")))
1427 edit
->force
|= REDRAW_COMPLETELY
;
1434 edit
->stat1
.st_mode
|= S_IWUSR
;
1436 save_lock
= lock_file (exp
);
1440 /* filenames equal, check if already locked */
1441 if (!edit
->locked
&& !edit
->delete_file
)
1442 save_lock
= lock_file (exp
);
1445 if (different_filename
)
1448 * Allow user to write into saved (under another name) file
1449 * even if original file had r/o user permissions.
1451 edit
->stat1
.st_mode
|= S_IWRITE
;
1454 rv
= edit_save_file (edit
, exp
);
1458 /* Succesful, so unlock both files */
1459 if (different_filename
)
1464 edit
->locked
= edit_unlock_file (edit
);
1468 if (edit
->locked
|| save_lock
)
1469 edit
->locked
= edit_unlock_file (edit
);
1472 edit_set_filename (edit
, exp
);
1473 if (edit
->lb
!= LB_ASIS
)
1474 edit_reload (edit
, exp
);
1477 edit
->delete_file
= 0;
1478 if (different_filename
)
1479 edit_load_syntax (edit
, NULL
, edit
->syntax_type
);
1480 edit
->force
|= REDRAW_COMPLETELY
;
1483 edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
1486 /* Failed, so maintain modify (not save) lock */
1490 edit
->force
|= REDRAW_COMPLETELY
;
1495 edit
->force
|= REDRAW_COMPLETELY
;
1499 /* {{{ Macro stuff starts here */
1502 /* --------------------------------------------------------------------------------------------- */
1503 /** returns 0 on error */
1506 edit_save_macro_cmd (WEdit
* edit
, struct macro macro
[], int n
)
1511 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
1512 s
= editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1);
1513 edit
->force
|= REDRAW_COMPLETELY
;
1516 if (edit_delete_macro (edit
, s
))
1518 f
= edit_open_macro_file ("a+");
1521 fprintf (f
, ("key '%d 0': "), s
);
1522 for (i
= 0; i
< n
; i
++)
1523 fprintf (f
, "%lu %d, ", macro
[i
].command
, macro
[i
].ch
);
1526 if (saved_macros_loaded
)
1528 for (i
= 0; i
< MAX_MACROS
&& saved_macro
[i
]; i
++);
1534 edit_error_dialog (_("Save macro"), get_sys_error (_("Cannot open macro file")));
1539 /* --------------------------------------------------------------------------------------------- */
1542 edit_delete_macro_cmd (WEdit
* edit
)
1546 command
= editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), 1);
1549 edit_delete_macro (edit
, command
);
1552 /* --------------------------------------------------------------------------------------------- */
1553 /** return 0 on error */
1556 edit_load_macro_cmd (WEdit
* edit
, struct macro macro
[], int *n
, int k
)
1559 int s
, i
= 0, found
= 0;
1563 if (saved_macros_loaded
)
1564 if (macro_exists (k
) < 0)
1567 f
= edit_open_macro_file ("r");
1574 u
= fscanf (f
, ("key '%d 0': "), &s
);
1577 if (!saved_macros_loaded
)
1578 saved_macro
[i
++] = s
;
1582 while (*n
< MAX_MACRO_LENGTH
1583 && 2 == fscanf (f
, "%lu %d, ", ¯o
[*n
].command
, ¯o
[*n
].ch
))
1588 while (2 == fscanf (f
, "%lu %d, ", &dummy
.command
, &dummy
.ch
));
1592 ret
= fscanf (f
, ";\n");
1597 while (!found
|| !saved_macros_loaded
);
1598 if (!saved_macros_loaded
)
1601 saved_macros_loaded
= 1;
1607 edit_error_dialog (_("Load macro"), get_sys_error (_("Cannot open macro file")));
1611 /* }}} Macro stuff starts here */
1613 /* --------------------------------------------------------------------------------------------- */
1614 /** returns 1 on success */
1617 edit_save_confirm_cmd (WEdit
* edit
)
1621 if (!edit_check_newline (edit
))
1624 if (edit_confirm_save
)
1626 f
= g_strdup_printf (_("Confirm save file: \"%s\""), edit
->filename
);
1627 if (edit_query_dialog2 (_("Save file"), f
, _("&Save"), _("&Cancel")))
1634 return edit_save_cmd (edit
);
1638 /* --------------------------------------------------------------------------------------------- */
1639 /** returns 1 on success */
1642 edit_new_cmd (WEdit
* edit
)
1646 if (edit_query_dialog2
1649 ("Current text was modified without a file save.\nContinue discards these changes"),
1650 _("C&ontinue"), _("&Cancel")))
1652 edit
->force
|= REDRAW_COMPLETELY
;
1656 edit
->force
|= REDRAW_COMPLETELY
;
1658 return edit_renew (edit
); /* if this gives an error, something has really screwed up */
1661 /* --------------------------------------------------------------------------------------------- */
1664 edit_load_cmd (WEdit
* edit
, edit_current_file_t what
)
1669 && (edit_query_dialog2
1671 _("Current text was modified without a file save.\n"
1672 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")) == 1))
1674 edit
->force
|= REDRAW_COMPLETELY
;
1680 case EDIT_FILE_COMMON
:
1681 exp
= input_expand_dialog (_("Load"), _("Enter file name:"),
1682 MC_HISTORY_EDIT_LOAD
, edit
->filename
);
1687 edit_load_file_from_filename (edit
, exp
);
1692 case EDIT_FILE_SYNTAX
:
1693 edit_load_syntax_file (edit
);
1696 case EDIT_FILE_MENU
:
1697 edit_load_menu_file (edit
);
1704 edit
->force
|= REDRAW_COMPLETELY
;
1708 /* --------------------------------------------------------------------------------------------- */
1710 if mark2 is -1 then marking is from mark1 to the cursor.
1711 Otherwise its between the markers. This handles this.
1712 Returns 1 if no text is marked.
1716 eval_marks (WEdit
* edit
, long *start_mark
, long *end_mark
)
1718 if (edit
->mark1
!= edit
->mark2
)
1720 long start_bol
, start_eol
;
1721 long end_bol
, end_eol
;
1724 if (edit
->mark2
>= 0)
1726 *start_mark
= min (edit
->mark1
, edit
->mark2
);
1727 *end_mark
= max (edit
->mark1
, edit
->mark2
);
1731 *start_mark
= min (edit
->mark1
, edit
->curs1
);
1732 *end_mark
= max (edit
->mark1
, edit
->curs1
);
1733 edit
->column2
= edit
->curs_col
+ edit
->over_col
;
1735 if (edit
->column_highlight
1736 && (((edit
->mark1
> edit
->curs1
) && (edit
->column1
< edit
->column2
))
1737 || ((edit
->mark1
< edit
->curs1
) && (edit
->column1
> edit
->column2
))))
1740 start_bol
= edit_bol (edit
, *start_mark
);
1741 start_eol
= edit_eol (edit
, start_bol
- 1) + 1;
1742 end_bol
= edit_bol (edit
, *end_mark
);
1743 end_eol
= edit_eol (edit
, *end_mark
);
1744 col1
= min (edit
->column1
, edit
->column2
);
1745 col2
= max (edit
->column1
, edit
->column2
);
1748 edit_move_forward3 (edit
, start_bol
, col2
, 0) - edit_move_forward3 (edit
, start_bol
,
1751 edit_move_forward3 (edit
, end_bol
, col2
, 0) - edit_move_forward3 (edit
, end_bol
,
1754 *start_mark
-= diff1
;
1756 *start_mark
= max (*start_mark
, start_eol
);
1757 *end_mark
= min (*end_mark
, end_eol
);
1763 *start_mark
= *end_mark
= 0;
1764 edit
->column2
= edit
->column1
= 0;
1769 /* --------------------------------------------------------------------------------------------- */
1772 edit_insert_column_of_text (WEdit
* edit
, unsigned char *data
, int size
, int width
)
1776 cursor
= edit
->curs1
;
1777 col
= edit_get_col (edit
);
1778 for (i
= 0; i
< size
; i
++)
1780 if (data
[i
] == '\n')
1781 { /* fill in and move to next line */
1784 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1786 l
= width
- (edit_get_col (edit
) - col
);
1789 edit_insert (edit
, ' ');
1793 for (p
= edit
->curs1
;; p
++)
1795 if (p
== edit
->last_byte
)
1797 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1798 edit_insert_ahead (edit
, '\n');
1802 if (edit_get_byte (edit
, p
) == '\n')
1808 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1809 l
= col
- edit_get_col (edit
);
1810 while (l
>= space_width
)
1812 edit_insert (edit
, ' ');
1817 edit_insert (edit
, data
[i
]);
1819 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1822 /* --------------------------------------------------------------------------------------------- */
1825 edit_insert_column_of_text_from_file (WEdit
* edit
, int file
)
1829 int blocklen
= -1, width
;
1830 unsigned char *data
;
1831 cursor
= edit
->curs1
;
1832 col
= edit_get_col (edit
);
1833 data
= g_malloc0 (TEMP_BUF_LEN
);
1834 while ((blocklen
= mc_read (file
, (char *) data
, TEMP_BUF_LEN
)) > 0)
1836 for (width
= 0; width
< blocklen
; width
++)
1838 if (data
[width
] == '\n')
1841 for (i
= 0; i
< blocklen
; i
++)
1843 if (data
[i
] == '\n')
1844 { /* fill in and move to next line */
1847 if (edit_get_byte (edit
, edit
->curs1
) != '\n')
1849 l
= width
- (edit_get_col (edit
) - col
);
1852 edit_insert (edit
, ' ');
1856 for (p
= edit
->curs1
;; p
++)
1858 if (p
== edit
->last_byte
)
1860 edit_cursor_move (edit
, edit
->last_byte
- edit
->curs1
);
1861 edit_insert_ahead (edit
, '\n');
1865 if (edit_get_byte (edit
, p
) == '\n')
1871 edit_cursor_move (edit
, edit_move_forward3 (edit
, p
, col
, 0) - edit
->curs1
);
1872 l
= col
- edit_get_col (edit
);
1873 while (l
>= space_width
)
1875 edit_insert (edit
, ' ');
1880 edit_insert (edit
, data
[i
]);
1883 edit_cursor_move (edit
, cursor
- edit
->curs1
);
1885 edit
->force
|= REDRAW_PAGE
;
1889 /* --------------------------------------------------------------------------------------------- */
1892 edit_block_copy_cmd (WEdit
* edit
)
1894 long start_mark
, end_mark
, current
= edit
->curs1
;
1896 unsigned char *copy_buf
;
1898 edit_update_curs_col (edit
);
1899 if (eval_marks (edit
, &start_mark
, &end_mark
))
1902 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1904 /* all that gets pushed are deletes hence little space is used on the stack */
1906 edit_push_markers (edit
);
1908 if (edit
->column_highlight
)
1910 edit_insert_column_of_text (edit
, copy_buf
, size
, abs (edit
->column2
- edit
->column1
));
1915 edit_insert_ahead (edit
, copy_buf
[size
]);
1919 edit_scroll_screen_over_cursor (edit
);
1921 if (edit
->column_highlight
)
1923 edit_set_markers (edit
, 0, 0, 0, 0);
1924 edit_push_action (edit
, COLUMN_ON
);
1925 edit
->column_highlight
= 0;
1927 else if (start_mark
< current
&& end_mark
> current
)
1928 edit_set_markers (edit
, start_mark
, end_mark
+ end_mark
- start_mark
, 0, 0);
1930 edit
->force
|= REDRAW_PAGE
;
1934 /* --------------------------------------------------------------------------------------------- */
1937 edit_block_move_cmd (WEdit
* edit
)
1941 unsigned char *copy_buf
;
1942 long start_mark
, end_mark
;
1946 if (eval_marks (edit
, &start_mark
, &end_mark
))
1948 if (edit
->column_highlight
)
1950 edit_update_curs_col (edit
);
1952 if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1953 if ((x
> edit
->column1
&& x
< edit
->column2
)
1954 || (x
> edit
->column2
&& x
< edit
->column1
))
1957 else if (start_mark
<= edit
->curs1
&& end_mark
>= edit
->curs1
)
1960 if ((end_mark
- start_mark
) > option_max_undo
/ 2)
1961 if (edit_query_dialog2
1964 ("Block is large, you may not be able to undo this action"),
1965 _("C&ontinue"), _("&Cancel")))
1968 edit_push_markers (edit
);
1969 current
= edit
->curs1
;
1970 if (edit
->column_highlight
)
1974 line
= edit
->curs_line
;
1975 if (edit
->mark2
< 0)
1976 edit_mark_cmd (edit
, 0);
1977 c1
= min (edit
->column1
, edit
->column2
);
1978 c2
= max (edit
->column1
, edit
->column2
);
1979 copy_buf
= edit_get_block (edit
, start_mark
, end_mark
, &size
);
1982 edit_block_delete_cmd (edit
);
1985 edit_move_to_line (edit
, line
);
1986 edit_cursor_move (edit
,
1987 edit_move_forward3 (edit
,
1988 edit_bol (edit
, edit
->curs1
), x
, 0) - edit
->curs1
);
1989 edit_insert_column_of_text (edit
, copy_buf
, size
, c2
- c1
);
1992 line
= edit
->curs_line
;
1993 edit_update_curs_col (edit
);
1995 edit_block_delete_cmd (edit
);
1996 edit_move_to_line (edit
, line
);
1997 edit_cursor_move (edit
,
1998 edit_move_forward3 (edit
,
2000 edit
->curs1
), x
, 0) - edit
->curs1
);
2002 edit_set_markers (edit
, 0, 0, 0, 0);
2003 edit_push_action (edit
, COLUMN_ON
);
2004 edit
->column_highlight
= 0;
2008 copy_buf
= g_malloc0 (end_mark
- start_mark
);
2009 edit_cursor_move (edit
, start_mark
- edit
->curs1
);
2010 edit_scroll_screen_over_cursor (edit
);
2012 while (count
< end_mark
)
2014 copy_buf
[end_mark
- count
- 1] = edit_delete (edit
, 1);
2017 edit_scroll_screen_over_cursor (edit
);
2018 edit_cursor_move (edit
,
2019 current
- edit
->curs1
-
2020 (((current
- edit
->curs1
) > 0) ? end_mark
- start_mark
: 0));
2021 edit_scroll_screen_over_cursor (edit
);
2022 while (count
-- > start_mark
)
2023 edit_insert_ahead (edit
, copy_buf
[end_mark
- count
- 1]);
2024 edit_set_markers (edit
, edit
->curs1
, edit
->curs1
+ end_mark
- start_mark
, 0, 0);
2026 edit_scroll_screen_over_cursor (edit
);
2028 edit
->force
|= REDRAW_PAGE
;
2031 /* --------------------------------------------------------------------------------------------- */
2032 /** returns 1 if canceelled by user */
2035 edit_block_delete_cmd (WEdit
* edit
)
2037 long start_mark
, end_mark
;
2038 if (eval_marks (edit
, &start_mark
, &end_mark
))
2040 edit_delete_line (edit
);
2043 return edit_block_delete (edit
);
2046 /* --------------------------------------------------------------------------------------------- */
2047 /** call with edit = 0 before shutdown to close memory leaks */
2050 edit_replace_cmd (WEdit
* edit
, int again
)
2052 /* 1 = search string, 2 = replace with */
2053 static char *saved1
= NULL
; /* saved default[123] */
2054 static char *saved2
= NULL
;
2055 char *input1
= NULL
; /* user input from the dialog */
2056 char *input2
= NULL
;
2059 long times_replaced
= 0;
2060 gboolean once_found
= FALSE
;
2064 g_free (saved1
), saved1
= NULL
;
2065 g_free (saved2
), saved2
= NULL
;
2069 edit
->force
|= REDRAW_COMPLETELY
;
2071 if (again
&& !saved1
&& !saved2
)
2076 input1
= g_strdup (saved1
? saved1
: "");
2077 input2
= g_strdup (saved2
? saved2
: "");
2081 char *tmp_inp1
, *tmp_inp2
;
2082 disp1
= edit_replace_cmd__conv_to_display (saved1
? saved1
: (char *) "");
2083 disp2
= edit_replace_cmd__conv_to_display (saved2
? saved2
: (char *) "");
2085 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2087 editcmd_dialog_replace_show (edit
, disp1
, disp2
, &input1
, &input2
);
2092 if (input1
== NULL
|| *input1
== '\0')
2094 edit
->force
= REDRAW_COMPLETELY
;
2100 input1
= edit_replace_cmd__conv_to_input (input1
);
2101 input2
= edit_replace_cmd__conv_to_input (input2
);
2105 g_free (saved1
), saved1
= g_strdup (input1
);
2106 g_free (saved2
), saved2
= g_strdup (input2
);
2108 mc_search_free (edit
->search
);
2109 edit
->search
= NULL
;
2114 edit
->search
= mc_search_new (input1
, -1);
2115 if (edit
->search
== NULL
)
2117 edit
->search_start
= edit
->curs1
;
2120 edit
->search
->search_type
= edit_search_options
.type
;
2121 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
2122 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
2123 edit
->search
->whole_words
= edit_search_options
.whole_words
;
2124 edit
->search
->search_fn
= edit_search_cmd_callback
;
2127 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
+ 1
2128 && edit_search_options
.backwards
)
2129 edit
->search_start
--;
2131 if (edit
->found_len
&& edit
->search_start
== edit
->found_start
- 1
2132 && !edit_search_options
.backwards
)
2133 edit
->search_start
++;
2139 if (!editcmd_find (edit
, &len
))
2141 if (!(edit
->search
->error
== MC_SEARCH_E_OK
||
2142 (once_found
&& edit
->search
->error
== MC_SEARCH_E_NOTFOUND
)))
2144 edit_error_dialog (_("Search"), edit
->search
->error_str
);
2150 edit
->search_start
= edit
->search
->normal_offset
;
2151 /*returns negative on not found or error in pattern */
2153 if ((edit
->search_start
>= 0) && (edit
->search_start
< edit
->last_byte
))
2156 GString
*tmp_str
, *repl_str
;
2158 edit
->found_start
= edit
->search_start
;
2159 i
= edit
->found_len
= len
;
2161 edit_cursor_move (edit
, edit
->search_start
- edit
->curs1
);
2162 edit_scroll_screen_over_cursor (edit
);
2164 if (edit
->replace_mode
== 0)
2169 l
= edit
->curs_row
- edit
->num_widget_lines
/ 3;
2171 edit_scroll_downward (edit
, l
);
2173 edit_scroll_upward (edit
, -l
);
2175 edit_scroll_screen_over_cursor (edit
);
2176 edit
->force
|= REDRAW_PAGE
;
2177 edit_render_keypress (edit
);
2179 /*so that undo stops at each query */
2180 edit_push_key_press (edit
);
2181 /* and prompt 2/3 down */
2182 disp1
= edit_replace_cmd__conv_to_display (saved1
);
2183 disp2
= edit_replace_cmd__conv_to_display (saved2
);
2184 prompt
= editcmd_dialog_replace_prompt_show (edit
, disp1
, disp2
, -1, -1);
2188 if (prompt
== B_REPLACE_ALL
)
2189 edit
->replace_mode
= 1;
2190 else if (prompt
== B_SKIP_REPLACE
)
2192 if (edit_search_options
.backwards
)
2193 edit
->search_start
--;
2195 edit
->search_start
++;
2196 continue; /* loop */
2198 else if (prompt
== B_CANCEL
)
2200 edit
->replace_mode
= -1;
2205 /* don't process string each time */
2206 tmp_str
= g_string_new (input2
);
2207 repl_str
= mc_search_prepare_replace_str (edit
->search
, tmp_str
);
2208 g_string_free (tmp_str
, TRUE
);
2210 if (edit
->search
->error
!= MC_SEARCH_E_OK
)
2212 edit_error_dialog (_("Replace"), edit
->search
->error_str
);
2213 g_string_free (repl_str
, TRUE
);
2217 /* delete then insert new */
2218 for (i
= 0; i
< len
; i
++)
2219 edit_delete (edit
, 1);
2221 for (i
= 0; i
< repl_str
->len
; i
++)
2222 edit_insert (edit
, repl_str
->str
[i
]);
2224 edit
->found_len
= repl_str
->len
;
2225 g_string_free (repl_str
, TRUE
);
2228 /* so that we don't find the same string again */
2229 if (edit_search_options
.backwards
)
2230 edit
->search_start
--;
2233 edit
->search_start
+= edit
->found_len
;
2235 if (edit
->search_start
>= edit
->last_byte
)
2239 edit_scroll_screen_over_cursor (edit
);
2243 /* try and find from right here for next search */
2244 edit
->search_start
= edit
->curs1
;
2245 edit_update_curs_col (edit
);
2247 edit
->force
|= REDRAW_PAGE
;
2248 edit_render_keypress (edit
);
2250 if (times_replaced
== 0)
2251 query_dialog (_("Replace"), _("Search string not found"), D_NORMAL
, 1, _("&OK"));
2255 while (edit
->replace_mode
>= 0);
2257 edit_scroll_screen_over_cursor (edit
);
2258 edit
->force
|= REDRAW_COMPLETELY
;
2259 edit_render_keypress (edit
);
2261 if ((edit
->replace_mode
== 1) && (times_replaced
!= 0))
2262 message (D_NORMAL
, _("Replace"), _("%ld replacements made"), times_replaced
);
2269 /* --------------------------------------------------------------------------------------------- */
2272 edit_search_cmd_callback (const void *user_data
, gsize char_offset
)
2274 return edit_get_byte ((WEdit
*) user_data
, (long) char_offset
);
2277 /* --------------------------------------------------------------------------------------------- */
2280 edit_search_cmd (WEdit
* edit
, gboolean again
)
2287 else if (edit
->last_search_string
!= NULL
)
2288 edit_do_search (edit
);
2291 /* find last search string in history */
2294 history
= history_get (MC_HISTORY_SHARED_SEARCH
);
2295 if (history
!= NULL
&& history
->data
!= NULL
)
2297 edit
->last_search_string
= (char *) history
->data
;
2298 history
->data
= NULL
;
2299 history
= g_list_first (history
);
2300 g_list_foreach (history
, (GFunc
) g_free
, NULL
);
2301 g_list_free (history
);
2303 edit
->search
= mc_search_new (edit
->last_search_string
, -1);
2304 if (edit
->search
== NULL
)
2306 /* if not... then ask for an expression */
2307 g_free (edit
->last_search_string
);
2308 edit
->last_search_string
= NULL
;
2313 edit
->search
->search_type
= edit_search_options
.type
;
2314 edit
->search
->is_all_charsets
= edit_search_options
.all_codepages
;
2315 edit
->search
->is_case_sensitive
= edit_search_options
.case_sens
;
2316 edit
->search
->whole_words
= edit_search_options
.whole_words
;
2317 edit
->search
->search_fn
= edit_search_cmd_callback
;
2318 edit_do_search (edit
);
2323 /* if not... then ask for an expression */
2324 g_free (edit
->last_search_string
);
2325 edit
->last_search_string
= NULL
;
2332 /* --------------------------------------------------------------------------------------------- */
2334 * Check if it's OK to close the editor. If there are unsaved changes,
2335 * ask user. Return 1 if it's OK to exit, 0 to continue editing.
2339 edit_ok_to_exit (WEdit
* edit
)
2343 if (!edit
->modified
)
2346 if (!midnight_shutdown
)
2348 if (!edit_check_newline (edit
))
2352 act
= edit_query_dialog3 (_("Quit"), _("File was modified. Save with exit?"),
2353 _("&Yes"), _("&No"), _("&Cancel quit"));
2358 edit_query_dialog2 (_("Quit"),
2359 _("Midnight Commander is being shut down.\nSave modified file?"),
2360 _("&Yes"), _("&No"));
2370 edit_push_markers (edit
);
2371 edit_set_markers (edit
, 0, 0, 0, 0);
2372 if (!edit_save_cmd (edit
) || midnight_shutdown
)
2373 return (gboolean
) midnight_shutdown
;
2377 case 2: /* Cancel quit */
2385 /* --------------------------------------------------------------------------------------------- */
2386 /** save block, returns 1 on success */
2389 edit_save_block (WEdit
* edit
, const char *filename
, long start
, long finish
)
2393 file
= mc_open (filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
2394 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
| O_BINARY
);
2398 if (edit
->column_highlight
)
2401 r
= mc_write (file
, VERTICAL_MAGIC
, sizeof (VERTICAL_MAGIC
));
2404 unsigned char *block
, *p
;
2405 p
= block
= edit_get_block (edit
, start
, finish
, &len
);
2408 r
= mc_write (file
, p
, len
);
2421 len
= finish
- start
;
2422 buf
= g_malloc0 (TEMP_BUF_LEN
);
2423 while (start
!= finish
)
2425 end
= min (finish
, start
+ TEMP_BUF_LEN
);
2426 for (; i
< end
; i
++)
2427 buf
[i
- start
] = edit_get_byte (edit
, i
);
2428 len
-= mc_write (file
, (char *) buf
, end
- start
);
2439 /* --------------------------------------------------------------------------------------------- */
2442 edit_paste_from_history (WEdit
* edit
)
2445 edit_error_dialog (_("Error"), _("This function is not implemented"));
2448 /* --------------------------------------------------------------------------------------------- */
2451 edit_copy_to_X_buf_cmd (WEdit
* edit
)
2453 long start_mark
, end_mark
;
2454 if (eval_marks (edit
, &start_mark
, &end_mark
))
2456 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2458 edit_error_dialog (_("Copy to clipboard"), get_sys_error (_("Unable to save to file")));
2461 /* try use external clipboard utility */
2462 copy_file_to_ext_clip ();
2467 /* --------------------------------------------------------------------------------------------- */
2470 edit_cut_to_X_buf_cmd (WEdit
* edit
)
2472 long start_mark
, end_mark
;
2473 if (eval_marks (edit
, &start_mark
, &end_mark
))
2475 if (!edit_save_block_to_clip_file (edit
, start_mark
, end_mark
))
2477 edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file"));
2480 /* try use external clipboard utility */
2481 copy_file_to_ext_clip ();
2483 edit_block_delete_cmd (edit
);
2484 edit_mark_cmd (edit
, 1);
2488 /* --------------------------------------------------------------------------------------------- */
2491 edit_paste_from_X_buf_cmd (WEdit
* edit
)
2494 /* try use external clipboard utility */
2495 paste_to_file_from_ext_clip ();
2496 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2497 edit_insert_file (edit
, tmp
);
2502 /* --------------------------------------------------------------------------------------------- */
2504 * Ask user for the line and go to that line.
2505 * Negative numbers mean line from the end (i.e. -1 is the last line).
2509 edit_goto_cmd (WEdit
* edit
)
2512 static long line
= 0; /* line as typed, saved as default */
2517 g_snprintf (s
, sizeof (s
), "%ld", line
);
2518 f
= input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE
, line
? s
: "");
2528 l
= strtol (f
, &error
, 0);
2537 l
= edit
->total_lines
+ l
+ 2;
2538 edit_move_display (edit
, l
- edit
->num_widget_lines
/ 2 - 1);
2539 edit_move_to_line (edit
, l
- 1);
2540 edit
->force
|= REDRAW_COMPLETELY
;
2545 /* --------------------------------------------------------------------------------------------- */
2546 /** Return 1 on success */
2549 edit_save_block_cmd (WEdit
* edit
)
2551 long start_mark
, end_mark
;
2554 if (eval_marks (edit
, &start_mark
, &end_mark
))
2557 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2559 input_expand_dialog (_("Save block"), _("Enter file name:"),
2560 MC_HISTORY_EDIT_SAVE_BLOCK
, tmp
);
2562 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2572 if (edit_save_block (edit
, exp
, start_mark
, end_mark
))
2575 edit
->force
|= REDRAW_COMPLETELY
;
2581 edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file")));
2585 edit
->force
|= REDRAW_COMPLETELY
;
2590 /* --------------------------------------------------------------------------------------------- */
2591 /** returns 1 on success */
2594 edit_insert_file_cmd (WEdit
* edit
)
2599 tmp
= concat_dir_and_file (home_dir
, EDIT_CLIP_FILE
);
2600 exp
= input_expand_dialog (_("Insert file"), _("Enter file name:"),
2601 MC_HISTORY_EDIT_INSERT_FILE
, tmp
);
2603 edit_push_action (edit
, KEY_PRESS
+ edit
->start_display
);
2613 if (edit_insert_file (edit
, exp
))
2616 edit
->force
|= REDRAW_COMPLETELY
;
2622 edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file")));
2626 edit
->force
|= REDRAW_COMPLETELY
;
2630 /* --------------------------------------------------------------------------------------------- */
2631 /** sorts a block, returns -1 on system fail, 1 on cancel and 0 on success */
2634 edit_sort_cmd (WEdit
* edit
)
2636 static char *old
= 0;
2638 long start_mark
, end_mark
;
2641 if (eval_marks (edit
, &start_mark
, &end_mark
))
2643 edit_error_dialog (_("Sort block"), _("You must first highlight a block of text"));
2647 tmp
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
);
2648 edit_save_block (edit
, tmp
, start_mark
, end_mark
);
2651 exp
= input_dialog (_("Run sort"),
2652 _("Enter sort options (see manpage) separated by whitespace:"),
2653 MC_HISTORY_EDIT_SORT
, (old
!= NULL
) ? old
: "");
2659 tmp
= g_strconcat (" sort ", exp
, " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
, " > ",
2660 home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2665 if (e
== -1 || e
== 127)
2667 edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command")));
2672 sprintf (q
, "%d ", e
);
2673 tmp
= g_strdup_printf (_("Sort returned non-zero: %s"), q
);
2674 edit_error_dialog (_("Sort"), tmp
);
2680 edit
->force
|= REDRAW_COMPLETELY
;
2682 if (edit_block_delete_cmd (edit
))
2684 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2685 edit_insert_file (edit
, tmp
);
2690 /* --------------------------------------------------------------------------------------------- */
2692 * Ask user for a command, execute it and paste its output back to the
2697 edit_ext_cmd (WEdit
* edit
)
2703 input_dialog (_("Paste output of external command"),
2704 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD
, NULL
);
2709 tmp
= g_strconcat (exp
, " > ", home_dir
, PATH_SEP_STR EDIT_TEMP_FILE
, (char *) NULL
);
2716 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
2720 edit
->force
|= REDRAW_COMPLETELY
;
2721 tmp
= concat_dir_and_file (home_dir
, EDIT_TEMP_FILE
);
2722 edit_insert_file (edit
, tmp
);
2727 /* --------------------------------------------------------------------------------------------- */
2728 /** if block is 1, a block must be highlighted and the shell command
2729 processes it. If block is 0 the shell command is a straight system
2730 command, that just produces some output which is to be inserted */
2733 edit_block_process_cmd (WEdit
* edit
, const char *shell_cmd
, int block
)
2735 long start_mark
, end_mark
;
2737 FILE *script_home
= NULL
;
2738 FILE *block_file
= NULL
;
2739 gchar
*o
, *h
, *b
, *tmp
;
2740 char *quoted_name
= NULL
;
2742 o
= g_strconcat (mc_home
, shell_cmd
, (char *) NULL
); /* original source script */
2743 h
= g_strconcat (home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, (char *) NULL
); /* home script */
2744 b
= concat_dir_and_file (home_dir
, EDIT_BLOCK_FILE
); /* block file */
2746 script_home
= fopen (h
, "r");
2747 if (script_home
== NULL
)
2749 FILE *script_src
= NULL
;
2751 script_home
= fopen (h
, "w");
2752 if (script_home
== NULL
)
2754 tmp
= g_strconcat (_("Error creating script:"), h
, (char *) NULL
);
2755 edit_error_dialog ("", get_sys_error (tmp
));
2757 goto edit_block_process_cmd__EXIT
;
2760 script_src
= fopen (o
, "r");
2761 if (script_src
== NULL
)
2763 o
= g_strconcat (mc_home_alt
, shell_cmd
, (char *) NULL
);
2764 script_src
= fopen (o
, "r");
2765 if (script_src
== NULL
)
2767 fclose (script_home
);
2769 tmp
= g_strconcat (_("Error reading script:"), o
, (char *) NULL
);
2770 edit_error_dialog ("", get_sys_error (tmp
));
2772 goto edit_block_process_cmd__EXIT
;
2775 while (fgets (buf
, sizeof (buf
), script_src
))
2776 fputs (buf
, script_home
);
2777 fclose (script_src
);
2779 if (fclose (script_home
))
2781 tmp
= g_strconcat (_("Error closing script:"), h
, (char *) NULL
);
2782 edit_error_dialog ("", get_sys_error (tmp
));
2784 goto edit_block_process_cmd__EXIT
;
2787 tmp
= g_strconcat (_("Script created:"), h
, (char *) NULL
);
2788 edit_error_dialog ("", get_sys_error (tmp
));
2795 { /* for marked block run indent formatter */
2796 if (eval_marks (edit
, &start_mark
, &end_mark
))
2798 edit_error_dialog (_("Process block"), _("You must first highlight a block of text"));
2799 goto edit_block_process_cmd__EXIT
;
2801 edit_save_block (edit
, b
, start_mark
, end_mark
);
2802 quoted_name
= name_quote (edit
->filename
, 0);
2805 * Initial space is to avoid polluting bash history.
2807 * $1 - name of the edited file (to check its extension etc).
2808 * $2 - file containing the current block.
2809 * $3 - file where error messages should be put
2810 * (for compatibility with old scripts).
2812 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ", quoted_name
,
2813 " ", home_dir
, PATH_SEP_STR EDIT_BLOCK_FILE
" /dev/null", (char *) NULL
);
2818 * No block selected, just execute the command for the file.
2820 * $1 - name of the edited file.
2822 tmp
= g_strconcat (" ", home_dir
, PATH_SEP_STR EDIT_DIR
, shell_cmd
, " ",
2823 quoted_name
, (char *) NULL
);
2826 if (system (tmp
) == -1)
2828 edit_error_dialog (_("Process block"), _("Error calling program"));
2833 g_free (quoted_name
);
2834 close_error_pipe (D_NORMAL
, NULL
);
2836 edit_refresh_cmd (edit
);
2837 edit
->force
|= REDRAW_COMPLETELY
;
2839 /* insert result block */
2840 if (block
&& !edit_block_delete_cmd (edit
))
2842 edit_insert_file (edit
, b
);
2843 block_file
= fopen (b
, "w");
2844 if (block_file
!= NULL
)
2845 fclose (block_file
);
2850 edit_block_process_cmd__EXIT
:
2856 /* --------------------------------------------------------------------------------------------- */
2858 * prints at the cursor
2859 * @returns the number of chars printed
2863 edit_print_string (WEdit
* e
, const char *s
)
2866 while (s
[i
] != '\0')
2867 edit_execute_cmd (e
, CK_Insert_Char
, (unsigned char) s
[i
++]);
2868 e
->force
|= REDRAW_COMPLETELY
;
2869 edit_update_screen (e
);
2873 /* --------------------------------------------------------------------------------------------- */
2876 edit_mail_dialog (WEdit
* edit
)
2879 char *tmail_subject
;
2882 static char *mail_cc_last
= 0;
2883 static char *mail_subject_last
= 0;
2884 static char *mail_to_last
= 0;
2886 QuickWidget quick_widgets
[] = {
2887 /* 0 */ QUICK_BUTTON (6, 10, 9, MAIL_DLG_HEIGHT
, N_("&Cancel"), B_CANCEL
, NULL
),
2888 /* 1 */ QUICK_BUTTON (2, 10, 9, MAIL_DLG_HEIGHT
, N_("&OK"), B_ENTER
, NULL
),
2889 /* 2 */ QUICK_INPUT (3, 50, 8, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input", &tmail_cc
),
2890 /* 3 */ QUICK_LABEL (3, 50, 7, MAIL_DLG_HEIGHT
, N_("Copies to")),
2891 /* 4 */ QUICK_INPUT (3, 50, 6, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-2",
2893 /* 5 */ QUICK_LABEL (3, 50, 5, MAIL_DLG_HEIGHT
, N_("Subject")),
2894 /* 6 */ QUICK_INPUT (3, 50, 4, MAIL_DLG_HEIGHT
, "", 44, 0, "mail-dlg-input-3", &tmail_to
),
2895 /* 7 */ QUICK_LABEL (3, 50, 3, MAIL_DLG_HEIGHT
, N_("To")),
2896 /* 8 */ QUICK_LABEL (3, 50, 2, MAIL_DLG_HEIGHT
, N_("mail -s <subject> -c <cc> <to>")),
2900 QuickDialog Quick_input
= {
2901 50, MAIL_DLG_HEIGHT
, -1, -1, N_("Mail"),
2902 "[Input Line Keys]", quick_widgets
, NULL
, FALSE
2905 quick_widgets
[2].u
.input
.text
= mail_cc_last
? mail_cc_last
: "";
2906 quick_widgets
[4].u
.input
.text
= mail_subject_last
? mail_subject_last
: "";
2907 quick_widgets
[6].u
.input
.text
= mail_to_last
? mail_to_last
: "";
2909 if (quick_dialog (&Quick_input
) != B_CANCEL
)
2911 g_free (mail_cc_last
);
2912 g_free (mail_subject_last
);
2913 g_free (mail_to_last
);
2914 mail_cc_last
= tmail_cc
;
2915 mail_subject_last
= tmail_subject
;
2916 mail_to_last
= tmail_to
;
2917 pipe_mail (edit
, mail_to_last
, mail_subject_last
, mail_cc_last
);
2922 /*******************/
2923 /* Word Completion */
2924 /*******************/
2926 /* --------------------------------------------------------------------------------------------- */
2928 * Complete current word using regular expression search
2929 * backwards beginning at the current cursor position.
2933 edit_complete_word_cmd (WEdit
* edit
)
2935 gsize i
, max_len
, word_len
= 0, num_compl
= 0;
2936 long word_start
= 0;
2937 unsigned char *bufpos
;
2939 struct selection
compl[MAX_WORD_COMPLETIONS
]; /* completions */
2941 /* search start of word to be completed */
2942 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
2945 /* prepare match expression */
2946 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
2948 /* match_expr = g_strdup_printf ("\\b%.*s[a-zA-Z_0-9]+", word_len, bufpos); */
2951 ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+",
2952 (int) word_len
, bufpos
);
2954 /* collect the possible completions */
2955 /* start search from begin to end of file */
2957 edit_collect_completions (edit
, word_start
, word_len
, match_expr
,
2958 (struct selection
*) &compl, &num_compl
);
2962 /* insert completed word if there is only one match */
2965 for (i
= word_len
; i
< compl[0].len
; i
++)
2966 edit_insert (edit
, *(compl[0].text
+ i
));
2968 /* more than one possible completion => ask the user */
2971 /* !!! usually only a beep is expected and when <ALT-TAB> is !!! */
2972 /* !!! pressed again the selection dialog pops up, but that !!! */
2973 /* !!! seems to require a further internal state !!! */
2976 /* let the user select the preferred completion */
2977 editcmd_dialog_completion_show (edit
, max_len
, word_len
,
2978 (struct selection
*) &compl, num_compl
);
2982 g_free (match_expr
);
2983 /* release memory before return */
2984 for (i
= 0; i
< num_compl
; i
++)
2985 g_free (compl[i
].text
);
2988 /* --------------------------------------------------------------------------------------------- */
2991 edit_select_codepage_cmd (WEdit
* edit
)
2994 if (do_select_codepage ())
2995 edit_set_codeset (edit
);
2997 edit
->force
= REDRAW_COMPLETELY
;
2998 edit_refresh_cmd (edit
);
3004 /* --------------------------------------------------------------------------------------------- */
3007 edit_insert_literal_cmd (WEdit
* edit
)
3009 int char_for_insertion
= editcmd_dialog_raw_key_query (_("Insert literal"),
3010 _("Press any key:"), 0);
3011 edit_execute_key_command (edit
, -1, ascii_alpha_to_cntrl (char_for_insertion
));
3014 /* --------------------------------------------------------------------------------------------- */
3017 edit_execute_macro_cmd (WEdit
* edit
)
3020 CK_Macro (editcmd_dialog_raw_key_query (_("Execute macro"), _("Press macro hotkey:"),
3022 if (command
== CK_Macro (0))
3023 command
= CK_Insert_Char
;
3025 edit_execute_key_command (edit
, command
, -1);
3028 /* --------------------------------------------------------------------------------------------- */
3031 edit_begin_end_macro_cmd (WEdit
* edit
)
3033 /* edit is a pointer to the widget */
3036 unsigned long command
= edit
->macro_i
< 0 ? CK_Begin_Record_Macro
: CK_End_Record_Macro
;
3037 edit_execute_key_command (edit
, command
, -1);
3041 /* --------------------------------------------------------------------------------------------- */
3044 edit_load_forward_cmd (WEdit
* edit
)
3048 if (edit_query_dialog2
3050 _("Current text was modified without a file save\n"
3051 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")))
3053 edit
->force
|= REDRAW_COMPLETELY
;
3057 if (edit_stack_iterator
+ 1 < MAX_HISTORY_MOVETO
)
3059 if (edit_history_moveto
[edit_stack_iterator
+ 1].line
< 1)
3063 edit_stack_iterator
++;
3064 if (edit_history_moveto
[edit_stack_iterator
].filename
)
3066 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
3067 edit_history_moveto
[edit_stack_iterator
].line
);
3081 /* --------------------------------------------------------------------------------------------- */
3084 edit_load_back_cmd (WEdit
* edit
)
3088 if (edit_query_dialog2
3090 _("Current text was modified without a file save\n"
3091 "Continue discards these changes"), _("C&ontinue"), _("&Cancel")))
3093 edit
->force
|= REDRAW_COMPLETELY
;
3097 if (edit_stack_iterator
> 0)
3099 edit_stack_iterator
--;
3100 if (edit_history_moveto
[edit_stack_iterator
].filename
)
3102 edit_reload_line (edit
, edit_history_moveto
[edit_stack_iterator
].filename
,
3103 edit_history_moveto
[edit_stack_iterator
].line
);
3117 /* --------------------------------------------------------------------------------------------- */
3120 edit_get_match_keyword_cmd (WEdit
* edit
)
3122 gsize word_len
= 0, max_len
= 0;
3125 long word_start
= 0;
3126 unsigned char *bufpos
;
3130 char *tagfile
= NULL
;
3132 etags_hash_t def_hash
[MAX_DEFINITIONS
];
3134 for (i
= 0; i
< MAX_DEFINITIONS
; i
++)
3136 def_hash
[i
].filename
= NULL
;
3139 /* search start of word to be completed */
3140 if (!edit_find_word_start (edit
, &word_start
, &word_len
))
3143 /* prepare match expression */
3144 bufpos
= &edit
->buffers1
[word_start
>> S_EDIT_BUF_SIZE
][word_start
& M_EDIT_BUF_SIZE
];
3145 match_expr
= g_strdup_printf ("%.*s", (int) word_len
, bufpos
);
3147 ptr
= g_get_current_dir ();
3148 path
= g_strconcat (ptr
, G_DIR_SEPARATOR_S
, (char *) NULL
);
3151 /* Recursive search file 'TAGS' in parent dirs */
3154 ptr
= g_path_get_dirname (path
);
3158 tagfile
= g_build_filename (path
, TAGS_NAME
, (char *) NULL
);
3159 if (exist_file (tagfile
))
3162 while (strcmp (path
, G_DIR_SEPARATOR_S
) != 0);
3167 etags_set_definition_hash (tagfile
, path
, match_expr
, (etags_hash_t
*) & def_hash
);
3172 max_len
= MAX_WIDTH_DEF_DIALOG
;
3176 editcmd_dialog_select_definition_show (edit
, match_expr
, max_len
, word_len
,
3177 (etags_hash_t
*) & def_hash
, num_def
);
3179 g_free (match_expr
);
3182 /* --------------------------------------------------------------------------------------------- */
3185 edit_move_block_to_right (WEdit
* edit
)
3187 long start_mark
, end_mark
;
3188 long cur_bol
, start_bol
;
3190 if (eval_marks (edit
, &start_mark
, &end_mark
))
3193 start_bol
= edit_bol (edit
, start_mark
);
3194 cur_bol
= edit_bol (edit
, end_mark
- 1);
3197 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3198 if (option_fill_tabs_with_spaces
)
3200 if (option_fake_half_tabs
)
3202 insert_spaces_tab (edit
, 1);
3206 insert_spaces_tab (edit
, 0);
3211 edit_insert (edit
, '\t');
3213 edit_cursor_move (edit
, edit_bol (edit
, cur_bol
) - edit
->curs1
);
3218 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3220 while (cur_bol
>= start_bol
);
3221 edit
->force
|= REDRAW_PAGE
;
3224 /* --------------------------------------------------------------------------------------------- */
3227 edit_move_block_to_left (WEdit
* edit
)
3229 long start_mark
, end_mark
;
3230 long cur_bol
, start_bol
;
3231 int i
, del_tab_width
;
3234 if (eval_marks (edit
, &start_mark
, &end_mark
))
3237 start_bol
= edit_bol (edit
, start_mark
);
3238 cur_bol
= edit_bol (edit
, end_mark
- 1);
3241 edit_cursor_move (edit
, cur_bol
- edit
->curs1
);
3242 if (option_fake_half_tabs
)
3244 del_tab_width
= HALF_TAB_SIZE
;
3248 del_tab_width
= option_tab_spacing
;
3250 next_char
= edit_get_byte (edit
, edit
->curs1
);
3251 if (next_char
== '\t')
3253 edit_delete (edit
, 1);
3255 else if (next_char
== ' ')
3257 for (i
= 1; i
<= del_tab_width
; i
++)
3259 if (next_char
== ' ')
3261 edit_delete (edit
, 1);
3263 next_char
= edit_get_byte (edit
, edit
->curs1
);
3270 cur_bol
= edit_bol (edit
, cur_bol
- 1);
3272 while (cur_bol
>= start_bol
);
3273 edit
->force
|= REDRAW_PAGE
;
3276 /* --------------------------------------------------------------------------------------------- */