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