This source file includes following definitions.
- edit_save_mode_callback
- edit_save_file
- edit_check_newline
- edit_get_save_file_as
- edit_save_cmd
- edit_delete_column_of_text
- edit_block_delete
- edit_get_block
- edit_save_block_to_clip_file
- pipe_mail
- edit_insert_column_of_text
- edit_syntax_onoff_cb
- editcmd_dialog_raw_key_query_cb
- edit_refresh_cmd
- edit_syntax_onoff_cmd
- edit_show_tabs_tws_cmd
- edit_show_margin_cmd
- edit_show_numbers_cmd
- edit_save_mode_cmd
- edit_set_filename
- edit_save_as_cmd
- edit_save_confirm_cmd
- edit_load_cmd
- edit_load_file_from_filename
- edit_load_file_from_history
- edit_load_syntax_file
- edit_load_menu_file
- edit_close_cmd
- eval_marks
- edit_block_copy_cmd
- edit_block_move_cmd
- edit_block_delete_cmd
- edit_ok_to_exit
- edit_save_block
- edit_paste_from_history
- edit_copy_to_X_buf_cmd
- edit_cut_to_X_buf_cmd
- edit_paste_from_X_buf_cmd
- edit_goto_cmd
- edit_save_block_cmd
- edit_insert_file_cmd
- edit_sort_cmd
- edit_ext_cmd
- edit_block_process_cmd
- edit_mail_dialog
- edit_select_codepage_cmd
- edit_insert_literal_cmd
- edit_load_forward_cmd
- edit_load_back_cmd
- editcmd_dialog_raw_key_query
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <config.h>
37
38 #include <ctype.h>
39 #include <stdio.h>
40 #include <stdarg.h>
41 #include <sys/types.h>
42 #include <unistd.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <sys/stat.h>
46 #include <stdlib.h>
47
48 #include "lib/global.h"
49 #include "lib/tty/tty.h"
50 #include "lib/tty/key.h"
51 #include "lib/strutil.h"
52 #include "lib/fileloc.h"
53 #include "lib/lock.h"
54 #include "lib/util.h"
55 #include "lib/vfs/vfs.h"
56 #include "lib/widget.h"
57 #include "lib/event.h"
58 #ifdef HAVE_CHARSET
59 #include "lib/charsets.h"
60 #endif
61
62 #include "src/history.h"
63 #include "src/file_history.h"
64 #include "src/setup.h"
65 #ifdef HAVE_CHARSET
66 #include "src/selcodepage.h"
67 #endif
68 #include "src/util.h"
69
70 #include "edit-impl.h"
71 #include "editwidget.h"
72 #include "editsearch.h"
73 #include "etags.h"
74
75
76
77
78 int search_create_bookmark = FALSE;
79
80
81 gboolean edit_confirm_save = TRUE;
82
83
84 gboolean option_drop_selection_on_copy = TRUE;
85
86
87
88 #define space_width 1
89
90 #define TEMP_BUF_LEN 1024
91
92
93
94
95
96 static unsigned long edit_save_mode_radio_id, edit_save_mode_input_id;
97
98
99
100
101
102 static cb_ret_t
103 edit_save_mode_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
104 {
105 switch (msg)
106 {
107 case MSG_CHANGED_FOCUS:
108 if (sender != NULL && sender->id == edit_save_mode_radio_id)
109 {
110 Widget *ww;
111
112 ww = widget_find_by_id (w, edit_save_mode_input_id);
113 widget_disable (ww, RADIO (sender)->sel != 2);
114 return MSG_HANDLED;
115 }
116 return MSG_NOT_HANDLED;
117
118 default:
119 return dlg_default_callback (w, sender, msg, parm, data);
120 }
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135 static int
136 edit_save_file (WEdit * edit, const vfs_path_t * filename_vpath)
137 {
138 char *p;
139 gchar *tmp;
140 off_t filelen = 0;
141 int this_save_mode, rv, fd = -1;
142 vfs_path_t *real_filename_vpath;
143 vfs_path_t *savename_vpath = NULL;
144 const char *start_filename;
145 const vfs_path_element_t *vpath_element;
146 struct stat sb;
147
148 vpath_element = vfs_path_get_by_index (filename_vpath, 0);
149 if (vpath_element == NULL)
150 return 0;
151
152 start_filename = vpath_element->path;
153 if (*start_filename == '\0')
154 return 0;
155
156 if (!IS_PATH_SEP (*start_filename) && edit->dir_vpath != NULL)
157 real_filename_vpath = vfs_path_append_vpath_new (edit->dir_vpath, filename_vpath, NULL);
158 else
159 real_filename_vpath = vfs_path_clone (filename_vpath);
160
161 this_save_mode = option_save_mode;
162 if (this_save_mode != EDIT_QUICK_SAVE)
163 {
164 if (!vfs_file_is_local (real_filename_vpath))
165
166 this_save_mode = EDIT_QUICK_SAVE;
167 else
168 {
169 fd = mc_open (real_filename_vpath, O_RDONLY | O_BINARY);
170 if (fd == -1)
171
172 this_save_mode = EDIT_QUICK_SAVE;
173 }
174
175 if (fd != -1)
176 mc_close (fd);
177 }
178
179 rv = mc_stat (real_filename_vpath, &sb);
180 if (rv == 0)
181 {
182 if (this_save_mode == EDIT_QUICK_SAVE && !edit->skip_detach_prompt && sb.st_nlink > 1)
183 {
184 rv = edit_query_dialog3 (_("Warning"),
185 _("File has hard-links. Detach before saving?"),
186 _("&Yes"), _("&No"), _("&Cancel"));
187 switch (rv)
188 {
189 case 0:
190 this_save_mode = EDIT_SAFE_SAVE;
191 MC_FALLTHROUGH;
192 case 1:
193 edit->skip_detach_prompt = 1;
194 break;
195 default:
196 vfs_path_free (real_filename_vpath, TRUE);
197 return -1;
198 }
199 }
200
201
202 if (edit->stat1.st_mtime != 0 && edit->stat1.st_mtime != sb.st_mtime)
203 {
204
205 query_set_sel (1);
206
207 rv = edit_query_dialog2 (_("Warning"),
208 _("The file has been modified in the meantime. Save anyway?"),
209 _("&Yes"), _("&Cancel"));
210 if (rv != 0)
211 {
212 vfs_path_free (real_filename_vpath, TRUE);
213 return -1;
214 }
215 }
216 }
217
218 if (this_save_mode == EDIT_QUICK_SAVE)
219 savename_vpath = vfs_path_clone (real_filename_vpath);
220 else
221 {
222 char *savedir, *saveprefix;
223
224 savedir = vfs_path_tokens_get (real_filename_vpath, 0, -1);
225 if (savedir == NULL)
226 savedir = g_strdup (".");
227
228
229 saveprefix = mc_build_filename (PATH_SEP_STR, savedir, "cooledit", (char *) NULL);
230 g_free (savedir);
231 fd = mc_mkstemps (&savename_vpath, saveprefix, NULL);
232 g_free (saveprefix);
233 if (savename_vpath == NULL)
234 {
235 vfs_path_free (real_filename_vpath, TRUE);
236 return 0;
237 }
238
239
240
241
242
243 close (fd);
244 }
245
246 (void) mc_chown (savename_vpath, edit->stat1.st_uid, edit->stat1.st_gid);
247 (void) mc_chmod (savename_vpath, edit->stat1.st_mode);
248
249 fd = mc_open (savename_vpath, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode);
250 if (fd == -1)
251 goto error_save;
252
253
254 p = edit_get_write_filter (savename_vpath, real_filename_vpath);
255 if (p != NULL)
256 {
257 FILE *file;
258
259 mc_close (fd);
260 file = (FILE *) popen (p, "w");
261
262 if (file != NULL)
263 {
264 filelen = edit_write_stream (edit, file);
265 #if 1
266 pclose (file);
267 #else
268 if (pclose (file) != 0)
269 {
270 tmp = g_strdup_printf (_("Error writing to pipe: %s"), p);
271 edit_error_dialog (_("Error"), tmp);
272 g_free (tmp);
273 g_free (p);
274 goto error_save;
275 }
276 #endif
277 }
278 else
279 {
280 tmp = g_strdup_printf (_("Cannot open pipe for writing: %s"), p);
281 edit_error_dialog (_("Error"), get_sys_error (tmp));
282 g_free (p);
283 g_free (tmp);
284 goto error_save;
285 }
286 g_free (p);
287 }
288 else if (edit->lb == LB_ASIS)
289 {
290 filelen = edit_buffer_write_file (&edit->buffer, fd);
291
292 if (filelen != edit->buffer.size)
293 {
294 mc_close (fd);
295 goto error_save;
296 }
297
298 if (mc_close (fd) != 0)
299 goto error_save;
300
301
302 if (mc_stat (savename_vpath, &edit->stat1) == -1)
303 goto error_save;
304 }
305 else
306 {
307 FILE *file;
308 const vfs_path_element_t *path_element;
309
310 mc_close (fd);
311
312 path_element = vfs_path_get_by_index (savename_vpath, -1);
313 file = (FILE *) fopen (path_element->path, "w");
314 if (file != NULL)
315 {
316 filelen = edit_write_stream (edit, file);
317 fclose (file);
318 }
319 else
320 {
321 char *msg;
322
323 msg = g_strdup_printf (_("Cannot open file for writing: %s"), path_element->path);
324 edit_error_dialog (_("Error"), msg);
325 g_free (msg);
326 goto error_save;
327 }
328 }
329
330 if (filelen != edit->buffer.size)
331 goto error_save;
332
333 if (this_save_mode == EDIT_DO_BACKUP)
334 {
335 char *tmp_store_filename;
336 vfs_path_element_t *last_vpath_element;
337 vfs_path_t *tmp_vpath;
338 gboolean ok;
339
340 g_assert (option_backup_ext != NULL);
341
342
343 tmp_vpath = vfs_path_clone (real_filename_vpath);
344 last_vpath_element = (vfs_path_element_t *) vfs_path_get_by_index (tmp_vpath, -1);
345 tmp_store_filename = last_vpath_element->path;
346 last_vpath_element->path = g_strdup_printf ("%s%s", tmp_store_filename, option_backup_ext);
347 g_free (tmp_store_filename);
348
349 ok = (mc_rename (real_filename_vpath, tmp_vpath) != -1);
350 vfs_path_free (tmp_vpath, TRUE);
351 if (!ok)
352 goto error_save;
353 }
354
355 if (this_save_mode != EDIT_QUICK_SAVE && mc_rename (savename_vpath, real_filename_vpath) == -1)
356 goto error_save;
357
358 vfs_path_free (real_filename_vpath, TRUE);
359 vfs_path_free (savename_vpath, TRUE);
360 return 1;
361 error_save:
362
363
364
365
366 vfs_path_free (real_filename_vpath, TRUE);
367 vfs_path_free (savename_vpath, TRUE);
368 return 0;
369 }
370
371
372
373 static gboolean
374 edit_check_newline (const edit_buffer_t * buf)
375 {
376 return !(option_check_nl_at_eof && buf->size > 0
377 && edit_buffer_get_byte (buf, buf->size - 1) != '\n'
378 && edit_query_dialog2 (_("Warning"),
379 _("The file you are saving does not end with a newline."),
380 _("C&ontinue"), _("&Cancel")) != 0);
381 }
382
383
384
385 static vfs_path_t *
386 edit_get_save_file_as (WEdit * edit)
387 {
388 static LineBreaks cur_lb = LB_ASIS;
389 char *filename_res;
390 vfs_path_t *ret_vpath = NULL;
391
392 const char *lb_names[LB_NAMES] = {
393 N_("&Do not change"),
394 N_("&Unix format (LF)"),
395 N_("&Windows/DOS format (CR LF)"),
396 N_("&Macintosh format (CR)")
397 };
398
399 quick_widget_t quick_widgets[] = {
400
401 QUICK_LABELED_INPUT (N_("Enter file name:"), input_label_above,
402 vfs_path_as_str (edit->filename_vpath), "save-as",
403 &filename_res, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
404 QUICK_SEPARATOR (TRUE),
405 QUICK_LABEL (N_("Change line breaks to:"), NULL),
406 QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL),
407 QUICK_BUTTONS_OK_CANCEL,
408 QUICK_END
409
410 };
411
412 WRect r = { -1, -1, 0, 64 };
413
414 quick_dialog_t qdlg = {
415 r, N_("Save As"), "[Save File As]",
416 quick_widgets, NULL, NULL
417 };
418
419 if (quick_dialog (&qdlg) != B_CANCEL)
420 {
421 char *fname;
422
423 edit->lb = cur_lb;
424 fname = tilde_expand (filename_res);
425 g_free (filename_res);
426 ret_vpath = vfs_path_from_str (fname);
427 g_free (fname);
428 }
429
430 return ret_vpath;
431 }
432
433
434
435
436
437 static gboolean
438 edit_save_cmd (WEdit * edit)
439 {
440 int res, save_lock = 0;
441
442 if (!edit->locked && !edit->delete_file)
443 save_lock = lock_file (edit->filename_vpath);
444 res = edit_save_file (edit, edit->filename_vpath);
445
446
447 if ((res > 0 && edit->locked) || save_lock)
448 edit->locked = unlock_file (edit->filename_vpath);
449
450
451 if (res == 0)
452 return edit_save_as_cmd (edit);
453
454 if (res > 0)
455 {
456 edit->delete_file = 0;
457 edit->modified = 0;
458 }
459
460 edit->force |= REDRAW_COMPLETELY;
461
462 return TRUE;
463 }
464
465
466
467 static void
468 edit_delete_column_of_text (WEdit * edit)
469 {
470 off_t m1, m2;
471 off_t n;
472 long b, c, d;
473
474 eval_marks (edit, &m1, &m2);
475 n = edit_buffer_get_forward_offset (&edit->buffer, m1, 0, m2) + 1;
476 c = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m1), 0, m1);
477 d = (long) edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, m2), 0, m2);
478 b = MAX (MIN (c, d), MIN (edit->column1, edit->column2));
479 c = MAX (c, MAX (edit->column1, edit->column2));
480
481 while (n-- != 0)
482 {
483 off_t r, p, q;
484
485 r = edit_buffer_get_current_bol (&edit->buffer);
486 p = edit_move_forward3 (edit, r, b, 0);
487 q = edit_move_forward3 (edit, r, c, 0);
488 p = MAX (p, m1);
489 q = MIN (q, m2);
490 edit_cursor_move (edit, p - edit->buffer.curs1);
491
492 for (; q > p; q--)
493 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
494 edit_delete (edit, TRUE);
495
496
497 if (n != 0)
498 edit_cursor_move (edit,
499 edit_buffer_get_forward_offset (&edit->buffer, edit->buffer.curs1, 1,
500 0) - edit->buffer.curs1);
501 }
502 }
503
504
505
506
507 static int
508 edit_block_delete (WEdit * edit)
509 {
510 off_t start_mark, end_mark;
511 off_t curs_pos;
512 long curs_line, c1, c2;
513
514 if (!eval_marks (edit, &start_mark, &end_mark))
515 return 0;
516
517 if (edit->column_highlight && edit->mark2 < 0)
518 edit_mark_cmd (edit, FALSE);
519
520
521 if ((end_mark - start_mark) > option_max_undo / 2 &&
522 edit_query_dialog2 (_("Warning"),
523 ("Block is large, you may not be able to undo this action"),
524 _("C&ontinue"), _("&Cancel")) != 0)
525 return 1;
526
527 c1 = MIN (edit->column1, edit->column2);
528 c2 = MAX (edit->column1, edit->column2);
529 edit->column1 = c1;
530 edit->column2 = c2;
531
532 edit_push_markers (edit);
533
534 curs_line = edit->buffer.curs_line;
535
536 curs_pos = edit->curs_col + edit->over_col;
537
538
539 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
540 edit_scroll_screen_over_cursor (edit);
541
542 if (start_mark < end_mark)
543 {
544 if (edit->column_highlight)
545 {
546 off_t line_width;
547
548 if (edit->mark2 < 0)
549 edit_mark_cmd (edit, FALSE);
550 edit_delete_column_of_text (edit);
551
552 edit_move_to_line (edit, curs_line);
553
554 line_width = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), 0,
555 edit_buffer_get_current_eol (&edit->buffer));
556 if (option_cursor_beyond_eol && curs_pos > line_width)
557 edit->over_col = curs_pos - line_width;
558 }
559 else
560 {
561 off_t count;
562
563 for (count = start_mark; count < end_mark; count++)
564 edit_delete (edit, TRUE);
565 }
566 }
567
568 edit_set_markers (edit, 0, 0, 0, 0);
569 edit->force |= REDRAW_PAGE;
570
571 return 0;
572 }
573
574
575
576
577 static unsigned char *
578 edit_get_block (WEdit * edit, off_t start, off_t finish, off_t * l)
579 {
580 unsigned char *s, *r;
581
582 r = s = g_malloc0 (finish - start + 1);
583
584 if (edit->column_highlight)
585 {
586 *l = 0;
587
588
589 for (; start < finish; start++)
590 {
591 int c;
592 off_t x;
593
594 x = edit_move_forward3 (edit, edit_buffer_get_bol (&edit->buffer, start), 0, start);
595 c = edit_buffer_get_byte (&edit->buffer, start);
596 if ((x >= edit->column1 && x < edit->column2)
597 || (x >= edit->column2 && x < edit->column1) || c == '\n')
598 {
599 *s++ = c;
600 (*l)++;
601 }
602 }
603 }
604 else
605 {
606 *l = finish - start;
607
608 for (; start < finish; start++)
609 *s++ = edit_buffer_get_byte (&edit->buffer, start);
610 }
611
612 *s = '\0';
613
614 return r;
615 }
616
617
618
619
620 static gboolean
621 edit_save_block_to_clip_file (WEdit * edit, off_t start, off_t finish)
622 {
623 gboolean ret;
624 gchar *tmp;
625
626 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
627 ret = edit_save_block (edit, tmp, start, finish);
628 g_free (tmp);
629
630 return ret;
631 }
632
633
634
635 static void
636 pipe_mail (const edit_buffer_t * buf, char *to, char *subject, char *cc)
637 {
638 FILE *p = 0;
639 char *s;
640
641 to = name_quote (to, FALSE);
642 subject = name_quote (subject, FALSE);
643 cc = name_quote (cc, FALSE);
644 s = g_strconcat ("mail -s ", subject, *cc ? " -c " : "", cc, " ", to, (char *) NULL);
645 g_free (to);
646 g_free (subject);
647 g_free (cc);
648
649 if (s != NULL)
650 {
651 p = popen (s, "w");
652 g_free (s);
653 }
654
655 if (p != NULL)
656 {
657 off_t i;
658
659 for (i = 0; i < buf->size; i++)
660 if (fputc (edit_buffer_get_byte (buf, i), p) < 0)
661 break;
662 pclose (p);
663 }
664 }
665
666
667
668 static void
669 edit_insert_column_of_text (WEdit * edit, unsigned char *data, off_t size, long width,
670 off_t * start_pos, off_t * end_pos, long *col1, long *col2)
671 {
672 off_t i, cursor;
673 long col;
674
675 cursor = edit->buffer.curs1;
676 col = edit_get_col (edit);
677
678 for (i = 0; i < size; i++)
679 {
680 if (data[i] != '\n')
681 edit_insert (edit, data[i]);
682 else
683 {
684 long l;
685 off_t p;
686
687 if (edit_buffer_get_current_byte (&edit->buffer) != '\n')
688 {
689 for (l = width - (edit_get_col (edit) - col); l > 0; l -= space_width)
690 edit_insert (edit, ' ');
691 }
692 for (p = edit->buffer.curs1;; p++)
693 {
694 if (p == edit->buffer.size)
695 {
696 edit_cursor_move (edit, edit->buffer.size - edit->buffer.curs1);
697 edit_insert_ahead (edit, '\n');
698 p++;
699 break;
700 }
701 if (edit_buffer_get_byte (&edit->buffer, p) == '\n')
702 {
703 p++;
704 break;
705 }
706 }
707 edit_cursor_move (edit, edit_move_forward3 (edit, p, col, 0) - edit->buffer.curs1);
708
709 for (l = col - edit_get_col (edit); l >= space_width; l -= space_width)
710 edit_insert (edit, ' ');
711 }
712 }
713
714 *col1 = col;
715 *col2 = col + width;
716 *start_pos = cursor;
717 *end_pos = edit->buffer.curs1;
718 edit_cursor_move (edit, cursor - edit->buffer.curs1);
719 }
720
721
722
723
724
725
726
727
728
729
730 static void
731 edit_syntax_onoff_cb (void *data, void *user_data)
732 {
733 (void) user_data;
734
735 if (edit_widget_is_editor (CONST_WIDGET (data)))
736 {
737 WEdit *edit = (WEdit *) data;
738
739 if (option_syntax_highlighting)
740 edit_load_syntax (edit, NULL, edit->syntax_type);
741 edit->force |= REDRAW_PAGE;
742 }
743 }
744
745
746
747 static cb_ret_t
748 editcmd_dialog_raw_key_query_cb (Widget * w, Widget * sender, widget_msg_t msg, int parm,
749 void *data)
750 {
751 WDialog *h = DIALOG (w);
752
753 switch (msg)
754 {
755 case MSG_KEY:
756 h->ret_value = parm;
757 dlg_stop (h);
758 return MSG_HANDLED;
759 default:
760 return dlg_default_callback (w, sender, msg, parm, data);
761 }
762 }
763
764
765
766
767
768 void
769 edit_refresh_cmd (void)
770 {
771 tty_clear_screen ();
772 repaint_screen ();
773 tty_keypad (TRUE);
774 }
775
776
777
778
779
780
781
782
783 void
784 edit_syntax_onoff_cmd (WDialog * h)
785 {
786 option_syntax_highlighting = !option_syntax_highlighting;
787 g_list_foreach (GROUP (h)->widgets, edit_syntax_onoff_cb, NULL);
788 widget_draw (WIDGET (h));
789 }
790
791
792
793
794
795
796
797
798 void
799 edit_show_tabs_tws_cmd (WDialog * h)
800 {
801 enable_show_tabs_tws = !enable_show_tabs_tws;
802 widget_draw (WIDGET (h));
803 }
804
805
806
807
808
809
810
811
812 void
813 edit_show_margin_cmd (WDialog * h)
814 {
815 show_right_margin = !show_right_margin;
816 widget_draw (WIDGET (h));
817 }
818
819
820
821
822
823
824
825
826 void
827 edit_show_numbers_cmd (WDialog * h)
828 {
829 option_line_state = !option_line_state;
830 option_line_state_width = option_line_state ? LINE_STATE_WIDTH : 0;
831 widget_draw (WIDGET (h));
832 }
833
834
835
836 void
837 edit_save_mode_cmd (void)
838 {
839 char *str_result = NULL;
840
841 const char *str[] = {
842 N_("&Quick save"),
843 N_("&Safe save"),
844 N_("&Do backups with following extension:")
845 };
846
847 #ifdef ENABLE_NLS
848 size_t i;
849
850 for (i = 0; i < 3; i++)
851 str[i] = _(str[i]);
852 #endif
853
854 g_assert (option_backup_ext != NULL);
855
856 {
857 quick_widget_t quick_widgets[] = {
858
859 QUICK_RADIO (3, str, &option_save_mode, &edit_save_mode_radio_id),
860 QUICK_INPUT (option_backup_ext, "edit-backup-ext", &str_result,
861 &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
862 QUICK_SEPARATOR (TRUE),
863 QUICK_CHECKBOX (N_("Check &POSIX new line"), &option_check_nl_at_eof, NULL),
864 QUICK_BUTTONS_OK_CANCEL,
865 QUICK_END
866
867 };
868
869 WRect r = { -1, -1, 0, 38 };
870
871 quick_dialog_t qdlg = {
872 r, N_("Edit Save Mode"), "[Edit Save Mode]",
873 quick_widgets, edit_save_mode_callback, NULL
874 };
875
876 if (quick_dialog (&qdlg) != B_CANCEL)
877 {
878 g_free (option_backup_ext);
879 option_backup_ext = str_result;
880 }
881 }
882 }
883
884
885
886 void
887 edit_set_filename (WEdit * edit, const vfs_path_t * name_vpath)
888 {
889 vfs_path_free (edit->filename_vpath, TRUE);
890 edit->filename_vpath = vfs_path_clone (name_vpath);
891
892 if (edit->dir_vpath == NULL)
893 edit->dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
894 }
895
896
897
898
899
900 gboolean
901 edit_save_as_cmd (WEdit * edit)
902 {
903
904 vfs_path_t *exp_vpath;
905 int save_lock = 0;
906 gboolean different_filename = FALSE;
907 gboolean ret = FALSE;
908
909 if (!edit_check_newline (&edit->buffer))
910 return FALSE;
911
912 exp_vpath = edit_get_save_file_as (edit);
913 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
914
915 if (exp_vpath != NULL && vfs_path_len (exp_vpath) != 0)
916 {
917 int rv;
918
919 if (!vfs_path_equal (edit->filename_vpath, exp_vpath))
920 {
921 int file;
922 struct stat sb;
923
924 if (mc_stat (exp_vpath, &sb) == 0 && !S_ISREG (sb.st_mode))
925 {
926 edit_error_dialog (_("Save as"),
927 get_sys_error (_
928 ("Cannot save: destination is not a regular file")));
929 goto ret;
930 }
931
932 different_filename = TRUE;
933 file = mc_open (exp_vpath, O_RDONLY | O_BINARY);
934
935 if (file == -1)
936 edit->stat1.st_mode |= S_IWUSR;
937 else
938 {
939
940 mc_close (file);
941
942 if (edit_query_dialog2
943 (_("Warning"),
944 _("A file already exists with this name"), _("&Overwrite"), _("&Cancel")))
945 goto ret;
946 }
947
948 save_lock = lock_file (exp_vpath);
949 }
950 else if (!edit->locked && !edit->delete_file)
951
952 save_lock = lock_file (exp_vpath);
953
954 if (different_filename)
955
956
957 edit->stat1.st_mode |= S_IWUSR;
958
959 rv = edit_save_file (edit, exp_vpath);
960 switch (rv)
961 {
962 case 1:
963
964 if (different_filename)
965 {
966 if (save_lock)
967 unlock_file (exp_vpath);
968 if (edit->locked)
969 edit->locked = unlock_file (edit->filename_vpath);
970 }
971 else if (edit->locked || save_lock)
972 edit->locked = unlock_file (edit->filename_vpath);
973
974 edit_set_filename (edit, exp_vpath);
975 if (edit->lb != LB_ASIS)
976 edit_reload (edit, exp_vpath);
977 edit->modified = 0;
978 edit->delete_file = 0;
979 if (different_filename)
980 edit_load_syntax (edit, NULL, edit->syntax_type);
981 ret = TRUE;
982 break;
983
984 default:
985 edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
986 MC_FALLTHROUGH;
987
988 case -1:
989
990 if (save_lock)
991 unlock_file (exp_vpath);
992 break;
993 }
994 }
995
996 ret:
997 vfs_path_free (exp_vpath, TRUE);
998 edit->force |= REDRAW_COMPLETELY;
999 return ret;
1000 }
1001
1002
1003
1004
1005 gboolean
1006 edit_save_confirm_cmd (WEdit * edit)
1007 {
1008 if (edit->filename_vpath == NULL)
1009 return edit_save_as_cmd (edit);
1010
1011 if (!edit_check_newline (&edit->buffer))
1012 return FALSE;
1013
1014 if (edit_confirm_save)
1015 {
1016 char *f;
1017 gboolean ok;
1018
1019 f = g_strdup_printf (_("Confirm save file: \"%s\""),
1020 vfs_path_as_str (edit->filename_vpath));
1021 ok = (edit_query_dialog2 (_("Save file"), f, _("&Save"), _("&Cancel")) == 0);
1022 g_free (f);
1023 if (!ok)
1024 return FALSE;
1025 }
1026
1027 return edit_save_cmd (edit);
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 gboolean
1038 edit_load_cmd (WDialog * h)
1039 {
1040 char *exp;
1041 gboolean ret = TRUE;
1042
1043 exp = input_expand_dialog (_("Load"), _("Enter file name:"),
1044 MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT,
1045 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
1046
1047 if (exp != NULL && *exp != '\0')
1048 {
1049 vfs_path_t *exp_vpath;
1050
1051 exp_vpath = vfs_path_from_str (exp);
1052 ret = edit_load_file_from_filename (h, exp_vpath, 0);
1053 vfs_path_free (exp_vpath, TRUE);
1054 }
1055
1056 g_free (exp);
1057
1058 return ret;
1059 }
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 gboolean
1073 edit_load_file_from_filename (WDialog * h, const vfs_path_t * vpath, long line)
1074 {
1075 WRect r = WIDGET (h)->rect;
1076
1077 rect_grow (&r, -1, 0);
1078
1079 return edit_add_window (h, &r, vpath, line);
1080 }
1081
1082
1083
1084
1085
1086
1087
1088
1089 gboolean
1090 edit_load_file_from_history (WDialog * h)
1091 {
1092 char *exp;
1093 int action;
1094 gboolean ret = TRUE;
1095
1096 exp = show_file_history (CONST_WIDGET (h), &action);
1097 if (exp != NULL && (action == CK_Edit || action == CK_Enter))
1098 {
1099 vfs_path_t *exp_vpath;
1100
1101 exp_vpath = vfs_path_from_str (exp);
1102 ret = edit_load_file_from_filename (h, exp_vpath, 0);
1103 vfs_path_free (exp_vpath, TRUE);
1104 }
1105
1106 g_free (exp);
1107
1108 return ret;
1109 }
1110
1111
1112
1113
1114
1115
1116
1117
1118 gboolean
1119 edit_load_syntax_file (WDialog * h)
1120 {
1121 vfs_path_t *extdir_vpath;
1122 int dir = 0;
1123 gboolean ret = FALSE;
1124
1125 if (geteuid () == 0)
1126 dir = query_dialog (_("Syntax file edit"),
1127 _("Which syntax file you want to edit?"), D_NORMAL, 2,
1128 _("&User"), _("&System wide"));
1129
1130 extdir_vpath =
1131 vfs_path_build_filename (mc_global.sysconfig_dir, "syntax", "Syntax", (char *) NULL);
1132 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
1133 {
1134 vfs_path_free (extdir_vpath, TRUE);
1135 extdir_vpath =
1136 vfs_path_build_filename (mc_global.share_data_dir, "syntax", "Syntax", (char *) NULL);
1137 }
1138
1139 if (dir == 0)
1140 {
1141 vfs_path_t *user_syntax_file_vpath;
1142
1143 user_syntax_file_vpath = mc_config_get_full_vpath (EDIT_HOME_SYNTAX_FILE);
1144 check_for_default (extdir_vpath, user_syntax_file_vpath);
1145 ret = edit_load_file_from_filename (h, user_syntax_file_vpath, 0);
1146 vfs_path_free (user_syntax_file_vpath, TRUE);
1147 }
1148 else if (dir == 1)
1149 ret = edit_load_file_from_filename (h, extdir_vpath, 0);
1150
1151 vfs_path_free (extdir_vpath, TRUE);
1152
1153 return ret;
1154 }
1155
1156
1157
1158
1159
1160
1161
1162
1163 gboolean
1164 edit_load_menu_file (WDialog * h)
1165 {
1166 vfs_path_t *buffer_vpath;
1167 vfs_path_t *menufile_vpath;
1168 int dir;
1169 gboolean ret;
1170
1171 query_set_sel (1);
1172 dir = query_dialog (_("Menu edit"),
1173 _("Which menu file do you want to edit?"), D_NORMAL,
1174 geteuid () != 0 ? 2 : 3, _("&Local"), _("&User"), _("&System wide"));
1175
1176 menufile_vpath =
1177 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1178 if (!exist_file (vfs_path_get_last_path_str (menufile_vpath)))
1179 {
1180 vfs_path_free (menufile_vpath, TRUE);
1181 menufile_vpath =
1182 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1183 }
1184
1185 switch (dir)
1186 {
1187 case 0:
1188 buffer_vpath = vfs_path_from_str (EDIT_LOCAL_MENU);
1189 check_for_default (menufile_vpath, buffer_vpath);
1190 chmod (vfs_path_get_last_path_str (buffer_vpath), 0600);
1191 break;
1192
1193 case 1:
1194 buffer_vpath = mc_config_get_full_vpath (EDIT_HOME_MENU);
1195 check_for_default (menufile_vpath, buffer_vpath);
1196 break;
1197
1198 case 2:
1199 buffer_vpath =
1200 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1201 if (!exist_file (vfs_path_get_last_path_str (buffer_vpath)))
1202 {
1203 vfs_path_free (buffer_vpath, TRUE);
1204 buffer_vpath =
1205 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1206 }
1207 break;
1208
1209 default:
1210 vfs_path_free (menufile_vpath, TRUE);
1211 return FALSE;
1212 }
1213
1214 ret = edit_load_file_from_filename (h, buffer_vpath, 0);
1215
1216 vfs_path_free (buffer_vpath, TRUE);
1217 vfs_path_free (menufile_vpath, TRUE);
1218
1219 return ret;
1220 }
1221
1222
1223
1224
1225
1226
1227
1228
1229 gboolean
1230 edit_close_cmd (WEdit * edit)
1231 {
1232 gboolean ret;
1233
1234 ret = (edit != NULL) && edit_ok_to_exit (edit);
1235
1236 if (ret)
1237 {
1238 Widget *w = WIDGET (edit);
1239 WGroup *g = w->owner;
1240
1241 if (edit->locked != 0)
1242 unlock_file (edit->filename_vpath);
1243
1244 group_remove_widget (w);
1245 widget_destroy (w);
1246
1247 if (edit_widget_is_editor (CONST_WIDGET (g->current->data)))
1248 edit = (WEdit *) (g->current->data);
1249 else
1250 {
1251 edit = find_editor (DIALOG (g));
1252 if (edit != NULL)
1253 widget_select (WIDGET (edit));
1254 }
1255 }
1256
1257 if (edit != NULL)
1258 edit->force |= REDRAW_COMPLETELY;
1259
1260 return ret;
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270 gboolean
1271 eval_marks (WEdit * edit, off_t * start_mark, off_t * end_mark)
1272 {
1273 long end_mark_curs;
1274
1275 if (edit->mark1 == edit->mark2)
1276 {
1277 *start_mark = *end_mark = 0;
1278 edit->column2 = edit->column1 = 0;
1279 return FALSE;
1280 }
1281
1282 if (edit->end_mark_curs < 0)
1283 end_mark_curs = edit->buffer.curs1;
1284 else
1285 end_mark_curs = edit->end_mark_curs;
1286
1287 if (edit->mark2 >= 0)
1288 {
1289 *start_mark = MIN (edit->mark1, edit->mark2);
1290 *end_mark = MAX (edit->mark1, edit->mark2);
1291 }
1292 else
1293 {
1294 *start_mark = MIN (edit->mark1, end_mark_curs);
1295 *end_mark = MAX (edit->mark1, end_mark_curs);
1296 edit->column2 = edit->curs_col + edit->over_col;
1297 }
1298
1299 if (edit->column_highlight
1300 && ((edit->mark1 > end_mark_curs && edit->column1 < edit->column2)
1301 || (edit->mark1 < end_mark_curs && edit->column1 > edit->column2)))
1302 {
1303 off_t start_bol, start_eol;
1304 off_t end_bol, end_eol;
1305 long col1, col2;
1306 off_t diff1, diff2;
1307
1308 start_bol = edit_buffer_get_bol (&edit->buffer, *start_mark);
1309 start_eol = edit_buffer_get_eol (&edit->buffer, start_bol - 1) + 1;
1310 end_bol = edit_buffer_get_bol (&edit->buffer, *end_mark);
1311 end_eol = edit_buffer_get_eol (&edit->buffer, *end_mark);
1312 col1 = MIN (edit->column1, edit->column2);
1313 col2 = MAX (edit->column1, edit->column2);
1314
1315 diff1 = edit_move_forward3 (edit, start_bol, col2, 0) -
1316 edit_move_forward3 (edit, start_bol, col1, 0);
1317 diff2 = edit_move_forward3 (edit, end_bol, col2, 0) -
1318 edit_move_forward3 (edit, end_bol, col1, 0);
1319
1320 *start_mark -= diff1;
1321 *end_mark += diff2;
1322 *start_mark = MAX (*start_mark, start_eol);
1323 *end_mark = MIN (*end_mark, end_eol);
1324 }
1325
1326 return TRUE;
1327 }
1328
1329
1330
1331 void
1332 edit_block_copy_cmd (WEdit * edit)
1333 {
1334 off_t start_mark, end_mark, current = edit->buffer.curs1;
1335 off_t mark1 = 0, mark2 = 0;
1336 long c1 = 0, c2 = 0;
1337 off_t size;
1338 unsigned char *copy_buf;
1339
1340 edit_update_curs_col (edit);
1341 if (!eval_marks (edit, &start_mark, &end_mark))
1342 return;
1343
1344 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1345
1346
1347
1348 edit_push_markers (edit);
1349
1350 if (edit->column_highlight)
1351 {
1352 long col_delta;
1353
1354 col_delta = labs (edit->column2 - edit->column1);
1355 edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2);
1356 }
1357 else
1358 {
1359 int size_orig = size;
1360
1361 while (size-- != 0)
1362 edit_insert_ahead (edit, copy_buf[size]);
1363
1364
1365 if (option_cursor_after_inserted_block)
1366 edit_cursor_move (edit, size_orig);
1367 }
1368
1369 g_free (copy_buf);
1370 edit_scroll_screen_over_cursor (edit);
1371
1372 if (edit->column_highlight)
1373 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
1374 else if (start_mark < current && end_mark > current)
1375 edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
1376
1377 edit->force |= REDRAW_PAGE;
1378 }
1379
1380
1381
1382
1383 void
1384 edit_block_move_cmd (WEdit * edit)
1385 {
1386 off_t current;
1387 unsigned char *copy_buf = NULL;
1388 off_t start_mark, end_mark;
1389
1390 if (!eval_marks (edit, &start_mark, &end_mark))
1391 return;
1392
1393 if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark)
1394 return;
1395
1396 if (edit->mark2 < 0)
1397 edit_mark_cmd (edit, FALSE);
1398 edit_push_markers (edit);
1399
1400 if (edit->column_highlight)
1401 {
1402 off_t mark1, mark2;
1403 off_t size;
1404 long c1, c2, b_width;
1405 long x, x2;
1406
1407 c1 = MIN (edit->column1, edit->column2);
1408 c2 = MAX (edit->column1, edit->column2);
1409 b_width = c2 - c1;
1410
1411 edit_update_curs_col (edit);
1412
1413 x = edit->curs_col;
1414 x2 = x + edit->over_col;
1415
1416
1417 if ((edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1) ==
1418 edit_buffer_get_eol (&edit->buffer, start_mark)) && x2 > c1 && x2 <= c2)
1419 return;
1420
1421 if (edit->buffer.curs1 > start_mark
1422 && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark))
1423 {
1424 if (x > c2)
1425 x -= b_width;
1426 else if (x > c1 && x <= c2)
1427 x = c1;
1428 }
1429
1430 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1431
1432
1433 edit_block_delete_cmd (edit);
1434
1435 edit->over_col = MAX (0, edit->over_col - b_width);
1436
1437 current = edit_move_forward3 (edit, edit_buffer_get_current_bol (&edit->buffer), x, 0);
1438 edit_cursor_move (edit, current - edit->buffer.curs1);
1439 edit_scroll_screen_over_cursor (edit);
1440
1441
1442 if (option_cursor_beyond_eol && edit->over_col > 0)
1443 edit_insert_over (edit);
1444
1445 edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2);
1446 edit_set_markers (edit, mark1, mark2, c1, c2);
1447 }
1448 else
1449 {
1450 off_t count, count_orig;
1451
1452 current = edit->buffer.curs1;
1453 copy_buf = g_malloc0 (end_mark - start_mark);
1454 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
1455 edit_scroll_screen_over_cursor (edit);
1456
1457 for (count = start_mark; count < end_mark; count++)
1458 copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE);
1459
1460 edit_scroll_screen_over_cursor (edit);
1461 edit_cursor_move (edit,
1462 current - edit->buffer.curs1 -
1463 (((current - edit->buffer.curs1) > 0) ? end_mark - start_mark : 0));
1464 edit_scroll_screen_over_cursor (edit);
1465 count_orig = count;
1466 while (count-- > start_mark)
1467 edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
1468
1469 edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0,
1470 0);
1471
1472
1473 if (option_cursor_after_inserted_block)
1474 edit_cursor_move (edit, count_orig - start_mark);
1475 }
1476
1477 edit_scroll_screen_over_cursor (edit);
1478 g_free (copy_buf);
1479 edit->force |= REDRAW_PAGE;
1480 }
1481
1482
1483
1484
1485 int
1486 edit_block_delete_cmd (WEdit * edit)
1487 {
1488 off_t start_mark, end_mark;
1489
1490 if (eval_marks (edit, &start_mark, &end_mark))
1491 return edit_block_delete (edit);
1492
1493 edit_delete_line (edit);
1494
1495 return 0;
1496 }
1497
1498
1499
1500
1501
1502
1503
1504
1505 gboolean
1506 edit_ok_to_exit (WEdit * edit)
1507 {
1508 const char *fname = N_("[NoName]");
1509 char *msg;
1510 int act;
1511
1512 if (!edit->modified)
1513 return TRUE;
1514
1515 if (edit->filename_vpath != NULL)
1516 fname = vfs_path_as_str (edit->filename_vpath);
1517 #ifdef ENABLE_NLS
1518 else
1519 fname = _(fname);
1520 #endif
1521
1522 if (!mc_global.midnight_shutdown)
1523 {
1524 query_set_sel (2);
1525
1526 msg = g_strdup_printf (_("File %s was modified.\nSave before close?"), fname);
1527 act = edit_query_dialog3 (_("Close file"), msg, _("&Yes"), _("&No"), _("&Cancel"));
1528 }
1529 else
1530 {
1531 msg = g_strdup_printf (_("Midnight Commander is being shut down.\nSave modified file %s?"),
1532 fname);
1533 act = edit_query_dialog2 (_("Quit"), msg, _("&Yes"), _("&No"));
1534
1535
1536 if (act == -1)
1537 act = 1;
1538 }
1539
1540 g_free (msg);
1541
1542 switch (act)
1543 {
1544 case 0:
1545 if (!mc_global.midnight_shutdown && !edit_check_newline (&edit->buffer))
1546 return FALSE;
1547 edit_push_markers (edit);
1548 edit_set_markers (edit, 0, 0, 0, 0);
1549 if (!edit_save_cmd (edit) || mc_global.midnight_shutdown)
1550 return mc_global.midnight_shutdown;
1551 break;
1552 case 1:
1553 default:
1554 break;
1555 case 2:
1556 case -1:
1557 return FALSE;
1558 }
1559
1560 return TRUE;
1561 }
1562
1563
1564
1565
1566 gboolean
1567 edit_save_block (WEdit * edit, const char *filename, off_t start, off_t finish)
1568 {
1569 int file;
1570 off_t len = 1;
1571 vfs_path_t *vpath;
1572
1573 vpath = vfs_path_from_str (filename);
1574 file = mc_open (vpath, O_CREAT | O_WRONLY | O_TRUNC,
1575 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY);
1576 vfs_path_free (vpath, TRUE);
1577 if (file == -1)
1578 return FALSE;
1579
1580 if (edit->column_highlight)
1581 {
1582 int r;
1583
1584 r = mc_write (file, VERTICAL_MAGIC, sizeof (VERTICAL_MAGIC));
1585 if (r > 0)
1586 {
1587 unsigned char *block, *p;
1588
1589 p = block = edit_get_block (edit, start, finish, &len);
1590 while (len != 0)
1591 {
1592 r = mc_write (file, p, len);
1593 if (r < 0)
1594 break;
1595 p += r;
1596 len -= r;
1597 }
1598 g_free (block);
1599 }
1600 }
1601 else
1602 {
1603 unsigned char *buf;
1604 off_t i = start;
1605
1606 len = finish - start;
1607 buf = g_malloc0 (TEMP_BUF_LEN);
1608 while (start != finish)
1609 {
1610 off_t end;
1611
1612 end = MIN (finish, start + TEMP_BUF_LEN);
1613 for (; i < end; i++)
1614 buf[i - start] = edit_buffer_get_byte (&edit->buffer, i);
1615 len -= mc_write (file, (char *) buf, end - start);
1616 start = end;
1617 }
1618 g_free (buf);
1619 }
1620 mc_close (file);
1621
1622 return (len == 0);
1623 }
1624
1625
1626
1627 void
1628 edit_paste_from_history (WEdit * edit)
1629 {
1630 (void) edit;
1631 edit_error_dialog (_("Error"), _("This function is not implemented"));
1632 }
1633
1634
1635
1636 gboolean
1637 edit_copy_to_X_buf_cmd (WEdit * edit)
1638 {
1639 off_t start_mark, end_mark;
1640
1641 if (!eval_marks (edit, &start_mark, &end_mark))
1642 return TRUE;
1643
1644 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1645 {
1646 edit_error_dialog (_("Copy to clipboard"), get_sys_error (_("Unable to save to file")));
1647 return FALSE;
1648 }
1649
1650 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1651
1652 if (option_drop_selection_on_copy)
1653 edit_mark_cmd (edit, TRUE);
1654
1655 return TRUE;
1656 }
1657
1658
1659
1660 gboolean
1661 edit_cut_to_X_buf_cmd (WEdit * edit)
1662 {
1663 off_t start_mark, end_mark;
1664
1665 if (!eval_marks (edit, &start_mark, &end_mark))
1666 return TRUE;
1667
1668 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1669 {
1670 edit_error_dialog (_("Cut to clipboard"), _("Unable to save to file"));
1671 return FALSE;
1672 }
1673
1674 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1675
1676 edit_block_delete_cmd (edit);
1677 edit_mark_cmd (edit, TRUE);
1678
1679 return TRUE;
1680 }
1681
1682
1683
1684 gboolean
1685 edit_paste_from_X_buf_cmd (WEdit * edit)
1686 {
1687 vfs_path_t *tmp;
1688 gboolean ret;
1689
1690
1691 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
1692 tmp = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
1693 ret = (edit_insert_file (edit, tmp) >= 0);
1694 vfs_path_free (tmp, TRUE);
1695
1696 return ret;
1697 }
1698
1699
1700
1701
1702
1703
1704
1705 void
1706 edit_goto_cmd (WEdit * edit)
1707 {
1708 static gboolean first_run = TRUE;
1709
1710 char *f;
1711 long l;
1712 char *error;
1713
1714 f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE,
1715 first_run ? NULL : INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1716 if (f == NULL || *f == '\0')
1717 {
1718 g_free (f);
1719 return;
1720 }
1721
1722 l = strtol (f, &error, 0);
1723 if (*error != '\0')
1724 {
1725 g_free (f);
1726 return;
1727 }
1728
1729 if (l < 0)
1730 l = edit->buffer.lines + l + 2;
1731
1732 edit_move_display (edit, l - WIDGET (edit)->rect.lines / 2 - 1);
1733 edit_move_to_line (edit, l - 1);
1734 edit->force |= REDRAW_COMPLETELY;
1735
1736 g_free (f);
1737 first_run = FALSE;
1738 }
1739
1740
1741
1742
1743 gboolean
1744 edit_save_block_cmd (WEdit * edit)
1745 {
1746 off_t start_mark, end_mark;
1747 char *exp, *tmp;
1748 gboolean ret = FALSE;
1749
1750 if (!eval_marks (edit, &start_mark, &end_mark))
1751 return TRUE;
1752
1753 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1754 exp =
1755 input_expand_dialog (_("Save block"), _("Enter file name:"),
1756 MC_HISTORY_EDIT_SAVE_BLOCK, tmp, INPUT_COMPLETE_FILENAMES);
1757 g_free (tmp);
1758 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1759
1760 if (exp != NULL && *exp != '\0')
1761 {
1762 if (edit_save_block (edit, exp, start_mark, end_mark))
1763 ret = TRUE;
1764 else
1765 edit_error_dialog (_("Save block"), get_sys_error (_("Cannot save file")));
1766
1767 edit->force |= REDRAW_COMPLETELY;
1768 }
1769
1770 g_free (exp);
1771
1772 return ret;
1773 }
1774
1775
1776
1777
1778 gboolean
1779 edit_insert_file_cmd (WEdit * edit)
1780 {
1781 char *tmp;
1782 char *exp;
1783 gboolean ret = FALSE;
1784
1785 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1786 exp = input_expand_dialog (_("Insert file"), _("Enter file name:"),
1787 MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES);
1788 g_free (tmp);
1789
1790 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1791
1792 if (exp != NULL && *exp != '\0')
1793 {
1794 vfs_path_t *exp_vpath;
1795
1796 exp_vpath = vfs_path_from_str (exp);
1797 ret = (edit_insert_file (edit, exp_vpath) >= 0);
1798 vfs_path_free (exp_vpath, TRUE);
1799
1800 if (!ret)
1801 edit_error_dialog (_("Insert file"), get_sys_error (_("Cannot insert file")));
1802 }
1803
1804 g_free (exp);
1805
1806 edit->force |= REDRAW_COMPLETELY;
1807 return ret;
1808 }
1809
1810
1811
1812
1813 int
1814 edit_sort_cmd (WEdit * edit)
1815 {
1816 char *exp, *tmp, *tmp_edit_block_name, *tmp_edit_temp_name;
1817 off_t start_mark, end_mark;
1818 int e;
1819
1820 if (!eval_marks (edit, &start_mark, &end_mark))
1821 {
1822 edit_error_dialog (_("Sort block"), _("You must first highlight a block of text"));
1823 return 0;
1824 }
1825
1826 tmp = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1827 edit_save_block (edit, tmp, start_mark, end_mark);
1828 g_free (tmp);
1829
1830 exp = input_dialog (_("Run sort"),
1831 _("Enter sort options (see sort(1) manpage) separated by whitespace:"),
1832 MC_HISTORY_EDIT_SORT, INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1833
1834 if (exp == NULL)
1835 return 1;
1836
1837 tmp_edit_block_name = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1838 tmp_edit_temp_name = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1839 tmp =
1840 g_strconcat (" sort ", exp, " ", tmp_edit_block_name,
1841 " > ", tmp_edit_temp_name, (char *) NULL);
1842 g_free (tmp_edit_temp_name);
1843 g_free (tmp_edit_block_name);
1844 g_free (exp);
1845
1846 e = system (tmp);
1847 g_free (tmp);
1848 if (e != 0)
1849 {
1850 if (e == -1 || e == 127)
1851 edit_error_dialog (_("Sort"), get_sys_error (_("Cannot execute sort command")));
1852 else
1853 {
1854 char q[8];
1855
1856 sprintf (q, "%d ", e);
1857 tmp = g_strdup_printf (_("Sort returned non-zero: %s"), q);
1858 edit_error_dialog (_("Sort"), tmp);
1859 g_free (tmp);
1860 }
1861
1862 return -1;
1863 }
1864
1865 edit->force |= REDRAW_COMPLETELY;
1866
1867 if (edit_block_delete_cmd (edit))
1868 return 1;
1869
1870 {
1871 vfs_path_t *tmp_vpath;
1872
1873 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1874 edit_insert_file (edit, tmp_vpath);
1875 vfs_path_free (tmp_vpath, TRUE);
1876 }
1877
1878 return 0;
1879 }
1880
1881
1882
1883
1884
1885
1886
1887 int
1888 edit_ext_cmd (WEdit * edit)
1889 {
1890 char *exp, *tmp, *tmp_edit_temp_file;
1891 int e;
1892
1893 exp =
1894 input_dialog (_("Paste output of external command"),
1895 _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD, INPUT_LAST_TEXT,
1896 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
1897 | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS |
1898 INPUT_COMPLETE_SHELL_ESC);
1899
1900 if (!exp)
1901 return 1;
1902
1903 tmp_edit_temp_file = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1904 tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL);
1905 g_free (tmp_edit_temp_file);
1906 e = system (tmp);
1907 g_free (tmp);
1908 g_free (exp);
1909
1910 if (e != 0)
1911 {
1912 edit_error_dialog (_("External command"), get_sys_error (_("Cannot execute command")));
1913 return -1;
1914 }
1915
1916 edit->force |= REDRAW_COMPLETELY;
1917
1918 {
1919 vfs_path_t *tmp_vpath;
1920
1921 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1922 edit_insert_file (edit, tmp_vpath);
1923 vfs_path_free (tmp_vpath, TRUE);
1924 }
1925
1926 return 0;
1927 }
1928
1929
1930
1931
1932
1933
1934 void
1935 edit_block_process_cmd (WEdit * edit, int macro_number)
1936 {
1937 char *fname;
1938 char *macros_fname = NULL;
1939
1940 fname = g_strdup_printf ("%s.%i.sh", EDIT_HOME_MACRO_FILE, macro_number);
1941 macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL);
1942 user_menu (edit, macros_fname, 0);
1943 g_free (fname);
1944 g_free (macros_fname);
1945 edit->force |= REDRAW_COMPLETELY;
1946 }
1947
1948
1949
1950 void
1951 edit_mail_dialog (WEdit * edit)
1952 {
1953 char *mail_to, *mail_subject, *mail_cc;
1954
1955 quick_widget_t quick_widgets[] = {
1956
1957 QUICK_LABEL (N_("mail -s <subject> -c <cc> <to>"), NULL),
1958 QUICK_LABELED_INPUT (N_("To"), input_label_above,
1959 INPUT_LAST_TEXT, "mail-dlg-input-3",
1960 &mail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1961 QUICK_LABELED_INPUT (N_("Subject"), input_label_above,
1962 INPUT_LAST_TEXT, "mail-dlg-input-2",
1963 &mail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
1964 QUICK_LABELED_INPUT (N_("Copies to"), input_label_above,
1965 INPUT_LAST_TEXT, "mail-dlg-input",
1966 &mail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1967 QUICK_BUTTONS_OK_CANCEL,
1968 QUICK_END
1969
1970 };
1971
1972 WRect r = { -1, -1, 0, 50 };
1973
1974 quick_dialog_t qdlg = {
1975 r, N_("Mail"), "[Input Line Keys]",
1976 quick_widgets, NULL, NULL
1977 };
1978
1979 if (quick_dialog (&qdlg) != B_CANCEL)
1980 {
1981 pipe_mail (&edit->buffer, mail_to, mail_subject, mail_cc);
1982 g_free (mail_to);
1983 g_free (mail_subject);
1984 g_free (mail_cc);
1985 }
1986 }
1987
1988
1989
1990 #ifdef HAVE_CHARSET
1991 void
1992 edit_select_codepage_cmd (WEdit * edit)
1993 {
1994 if (do_select_codepage ())
1995 edit_set_codeset (edit);
1996
1997 edit->force = REDRAW_PAGE;
1998 widget_draw (WIDGET (edit));
1999 }
2000 #endif
2001
2002
2003
2004 void
2005 edit_insert_literal_cmd (WEdit * edit)
2006 {
2007 int char_for_insertion;
2008
2009 char_for_insertion = editcmd_dialog_raw_key_query (_("Insert literal"),
2010 _("Press any key:"), FALSE);
2011 edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion));
2012 }
2013
2014
2015
2016 gboolean
2017 edit_load_forward_cmd (WEdit * edit)
2018 {
2019 if (edit->modified
2020 && edit_query_dialog2 (_("Warning"),
2021 _("Current text was modified without a file save.\n"
2022 "Continue discards these changes."), _("C&ontinue"),
2023 _("&Cancel")) == 1)
2024 {
2025 edit->force |= REDRAW_COMPLETELY;
2026 return TRUE;
2027 }
2028
2029 if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO)
2030 return FALSE;
2031
2032 if (edit_history_moveto[edit_stack_iterator + 1].line < 1)
2033 return FALSE;
2034
2035 edit_stack_iterator++;
2036 if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL)
2037 return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath,
2038 edit_history_moveto[edit_stack_iterator].line);
2039
2040 return FALSE;
2041 }
2042
2043
2044
2045 gboolean
2046 edit_load_back_cmd (WEdit * edit)
2047 {
2048 if (edit->modified
2049 && edit_query_dialog2 (_("Warning"),
2050 _("Current text was modified without a file save.\n"
2051 "Continue discards these changes."), _("C&ontinue"),
2052 _("&Cancel")) == 1)
2053 {
2054 edit->force |= REDRAW_COMPLETELY;
2055 return TRUE;
2056 }
2057
2058
2059 if (edit_stack_iterator == 0)
2060 return FALSE;
2061
2062 edit_stack_iterator--;
2063 if (edit_history_moveto[edit_stack_iterator].filename_vpath != NULL)
2064 return edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename_vpath,
2065 edit_history_moveto[edit_stack_iterator].line);
2066
2067 return FALSE;
2068 }
2069
2070
2071
2072
2073
2074
2075
2076
2077 int
2078 editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean cancel)
2079 {
2080 int w, wq;
2081 int y = 2;
2082 WDialog *raw_dlg;
2083 WGroup *g;
2084
2085 w = str_term_width1 (heading) + 6;
2086 wq = str_term_width1 (query);
2087 w = MAX (w, wq + 3 * 2 + 1 + 2);
2088
2089 raw_dlg =
2090 dlg_create (TRUE, 0, 0, cancel ? 7 : 5, w, WPOS_CENTER | WPOS_TRYUP, FALSE, dialog_colors,
2091 editcmd_dialog_raw_key_query_cb, NULL, NULL, heading);
2092 g = GROUP (raw_dlg);
2093 widget_want_tab (WIDGET (raw_dlg), TRUE);
2094
2095 group_add_widget (g, label_new (y, 3, query));
2096 group_add_widget (g,
2097 input_new (y++, 3 + wq + 1, input_colors, w - (6 + wq + 1), "", 0,
2098 INPUT_COMPLETE_NONE));
2099 if (cancel)
2100 {
2101 group_add_widget (g, hline_new (y++, -1, -1));
2102
2103 group_add_widget_autopos (g, button_new (y, 1, B_CANCEL, NORMAL_BUTTON, _("Cancel"), NULL),
2104 WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
2105 }
2106
2107 w = dlg_run (raw_dlg);
2108 widget_destroy (WIDGET (raw_dlg));
2109
2110 return (cancel && (w == ESC_CHAR || w == B_CANCEL)) ? 0 : w;
2111 }
2112
2113