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