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 _ ("&Do not change"),
380 _ ("&Unix format (LF)"),
381 _ ("&Windows/DOS format (CR LF)"),
382 _ ("&Macintosh format (CR)"),
383 };
384
385 quick_widget_t quick_widgets[] = {
386 QUICK_LABELED_INPUT (_ ("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 (_ ("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 = _ ("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 _ ("&Quick save"),
889 _ ("&Safe save"),
890 _ ("&Do backups with following extension:"),
891 };
892
893 g_assert (edit_options.backup_ext != NULL);
894
895 {
896 quick_widget_t quick_widgets[] = {
897 QUICK_RADIO (3, str, &edit_options.save_mode, &edit_save_mode_radio_id),
898 QUICK_INPUT (edit_options.backup_ext, "edit-backup-ext", &str_result,
899 &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
900 QUICK_SEPARATOR (TRUE),
901 QUICK_CHECKBOX (_ ("Check &POSIX new line"), &edit_options.check_nl_at_eof, NULL),
902 QUICK_BUTTONS_OK_CANCEL,
903 QUICK_END,
904 };
905
906 WRect r = { -1, -1, 0, 38 };
907
908 quick_dialog_t qdlg = {
909 .rect = r,
910 .title = _ ("Edit Save Mode"),
911 .help = "[Edit Save Mode]",
912 .widgets = quick_widgets,
913 .callback = edit_save_mode_callback,
914 .mouse_callback = NULL,
915 };
916
917 if (quick_dialog (&qdlg) != B_CANCEL)
918 {
919 g_free (edit_options.backup_ext);
920 edit_options.backup_ext = str_result;
921 }
922 }
923 }
924
925
926
927 void
928 edit_set_filename (WEdit *edit, const vfs_path_t *name_vpath)
929 {
930 vfs_path_free (edit->filename_vpath, TRUE);
931 edit->filename_vpath = vfs_path_clone (name_vpath);
932
933 if (edit->dir_vpath == NULL)
934 edit->dir_vpath = vfs_path_clone (vfs_get_raw_current_dir ());
935 }
936
937
938
939
940
941 gboolean
942 edit_save_as_cmd (WEdit *edit)
943 {
944
945 vfs_path_t *exp_vpath;
946 int save_lock = 0;
947 gboolean different_filename = FALSE;
948 gboolean ret = FALSE;
949
950 if (!edit_check_newline (&edit->buffer))
951 return FALSE;
952
953 exp_vpath = edit_get_save_file_as (edit);
954 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
955
956 if (exp_vpath != NULL && vfs_path_len (exp_vpath) != 0)
957 {
958 int rv;
959
960 if (!vfs_path_equal (edit->filename_vpath, exp_vpath))
961 {
962 int file;
963 struct stat sb;
964
965 if (mc_stat (exp_vpath, &sb) == 0 && !S_ISREG (sb.st_mode))
966 {
967 file_error_message (_ ("Cannot save\n%s:\nnot a regular file"),
968 vfs_path_as_str (exp_vpath));
969 goto ret;
970 }
971
972 different_filename = TRUE;
973 file = mc_open (exp_vpath, O_RDONLY | O_BINARY);
974
975 if (file == -1)
976 edit->stat1.st_mode |= S_IWUSR;
977 else
978 {
979
980 mc_close (file);
981
982 if (edit_query_dialog2 (_ ("Warning"), _ ("A file already exists with this name"),
983 _ ("&Overwrite"), _ ("&Cancel")))
984 goto ret;
985 }
986
987 save_lock = lock_file (exp_vpath);
988 }
989 else if (edit->locked == 0 && edit->delete_file == 0)
990
991 save_lock = lock_file (exp_vpath);
992
993 if (different_filename)
994
995
996 edit->stat1.st_mode |= S_IWUSR;
997
998 rv = edit_save_file (edit, exp_vpath);
999 switch (rv)
1000 {
1001 case 1:
1002
1003 if (different_filename)
1004 {
1005 if (save_lock != 0)
1006 unlock_file (exp_vpath);
1007 if (edit->locked != 0)
1008 edit->locked = unlock_file (edit->filename_vpath);
1009 }
1010 else if (edit->locked != 0 || save_lock != 0)
1011 edit->locked = unlock_file (edit->filename_vpath);
1012
1013 edit_set_filename (edit, exp_vpath);
1014 if (edit->lb != LB_ASIS)
1015 edit_reload (edit, exp_vpath);
1016 edit->modified = 0;
1017 edit->delete_file = 0;
1018 if (different_filename)
1019 edit_load_syntax (edit, NULL, edit->syntax_type);
1020 ret = TRUE;
1021 break;
1022
1023 default:
1024 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot save file"));
1025 MC_FALLTHROUGH;
1026
1027 case -1:
1028
1029 if (save_lock != 0)
1030 unlock_file (exp_vpath);
1031 break;
1032 }
1033 }
1034
1035 ret:
1036 vfs_path_free (exp_vpath, TRUE);
1037 edit->force |= REDRAW_COMPLETELY;
1038 return ret;
1039 }
1040
1041
1042
1043
1044 gboolean
1045 edit_save_confirm_cmd (WEdit *edit)
1046 {
1047 if (edit->filename_vpath == NULL)
1048 return edit_save_as_cmd (edit);
1049
1050 if (!edit_check_newline (&edit->buffer))
1051 return FALSE;
1052
1053 if (edit_options.confirm_save)
1054 {
1055 char *f;
1056 gboolean ok;
1057
1058 f = g_strdup_printf (_ ("Confirm save file: \"%s\""),
1059 vfs_path_as_str (edit->filename_vpath));
1060 ok = (edit_query_dialog2 (_ ("Save file"), f, _ ("&Save"), _ ("&Cancel")) == 0);
1061 g_free (f);
1062 if (!ok)
1063 return FALSE;
1064 }
1065
1066 return edit_save_cmd (edit);
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076 gboolean
1077 edit_load_cmd (WDialog *h)
1078 {
1079 char *exp;
1080 gboolean ret = TRUE;
1081
1082 exp = input_expand_dialog (_ ("Load"), _ ("Enter file name:"), MC_HISTORY_EDIT_LOAD,
1083 INPUT_LAST_TEXT, INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
1084
1085 if (exp != NULL && *exp != '\0')
1086 {
1087 vfs_path_t *exp_vpath;
1088 edit_arg_t arg;
1089
1090 exp_vpath = vfs_path_from_str (exp);
1091 edit_arg_init (&arg, exp_vpath, 0);
1092 ret = edit_load_file_from_filename (h, &arg);
1093 vfs_path_free (exp_vpath, TRUE);
1094 }
1095
1096 g_free (exp);
1097
1098 return ret;
1099 }
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112 gboolean
1113 edit_load_file_from_filename (WDialog *h, const edit_arg_t *arg)
1114 {
1115 WRect r = WIDGET (h)->rect;
1116
1117 rect_grow (&r, -1, 0);
1118
1119 return edit_add_window (h, &r, arg);
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129 gboolean
1130 edit_load_file_from_history (WDialog *h)
1131 {
1132 char *exp;
1133 int action;
1134 gboolean ret = TRUE;
1135
1136 exp = show_file_history (CONST_WIDGET (h), &action);
1137 if (exp != NULL && (action == CK_Edit || action == CK_Enter))
1138 {
1139 vfs_path_t *exp_vpath;
1140 edit_arg_t arg;
1141
1142 exp_vpath = vfs_path_from_str (exp);
1143 edit_arg_init (&arg, exp_vpath, 0);
1144 ret = edit_load_file_from_filename (h, &arg);
1145 vfs_path_free (exp_vpath, TRUE);
1146 }
1147
1148 g_free (exp);
1149
1150 return ret;
1151 }
1152
1153
1154
1155
1156
1157
1158
1159
1160 gboolean
1161 edit_load_syntax_file (WDialog *h)
1162 {
1163 vfs_path_t *extdir_vpath;
1164 int dir = 0;
1165 edit_arg_t arg;
1166 gboolean ret = FALSE;
1167
1168 if (geteuid () == 0)
1169 dir = query_dialog (_ ("Syntax file edit"), _ ("Which syntax file you want to edit?"),
1170 D_NORMAL, 2, _ ("&User"), _ ("&System wide"));
1171
1172 extdir_vpath =
1173 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1174 if (!exist_file (vfs_path_get_last_path_str (extdir_vpath)))
1175 {
1176 vfs_path_free (extdir_vpath, TRUE);
1177 extdir_vpath =
1178 vfs_path_build_filename (mc_global.share_data_dir, EDIT_SYNTAX_FILE, (char *) NULL);
1179 }
1180
1181 if (dir == 0)
1182 {
1183 vfs_path_t *user_syntax_file_vpath;
1184
1185 user_syntax_file_vpath = mc_config_get_full_vpath (EDIT_SYNTAX_FILE);
1186
1187 if (editcmd_check_and_create_user_syntax_directory (user_syntax_file_vpath))
1188 {
1189 check_for_default (extdir_vpath, user_syntax_file_vpath);
1190 edit_arg_init (&arg, user_syntax_file_vpath, 0);
1191 ret = edit_load_file_from_filename (h, &arg);
1192 }
1193
1194 vfs_path_free (user_syntax_file_vpath, TRUE);
1195 }
1196 else if (dir == 1)
1197 {
1198 edit_arg_init (&arg, extdir_vpath, 0);
1199 ret = edit_load_file_from_filename (h, &arg);
1200 }
1201
1202 vfs_path_free (extdir_vpath, TRUE);
1203
1204 return ret;
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214 gboolean
1215 edit_load_menu_file (WDialog *h)
1216 {
1217 vfs_path_t *buffer_vpath;
1218 vfs_path_t *menufile_vpath;
1219 int dir;
1220 edit_arg_t arg;
1221 gboolean ret;
1222
1223 query_set_sel (1);
1224 dir = query_dialog (_ ("Menu edit"), _ ("Which menu file do you want to edit?"), D_NORMAL,
1225 geteuid () != 0 ? 2 : 3, _ ("&Local"), _ ("&User"), _ ("&System wide"));
1226
1227 menufile_vpath =
1228 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1229 if (!exist_file (vfs_path_get_last_path_str (menufile_vpath)))
1230 {
1231 vfs_path_free (menufile_vpath, TRUE);
1232 menufile_vpath =
1233 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1234 }
1235
1236 switch (dir)
1237 {
1238 case 0:
1239 buffer_vpath = vfs_path_from_str (EDIT_LOCAL_MENU);
1240 check_for_default (menufile_vpath, buffer_vpath);
1241 chmod (vfs_path_get_last_path_str (buffer_vpath), 0600);
1242 break;
1243
1244 case 1:
1245 buffer_vpath = mc_config_get_full_vpath (EDIT_HOME_MENU);
1246 check_for_default (menufile_vpath, buffer_vpath);
1247 break;
1248
1249 case 2:
1250 buffer_vpath =
1251 vfs_path_build_filename (mc_global.sysconfig_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1252 if (!exist_file (vfs_path_get_last_path_str (buffer_vpath)))
1253 {
1254 vfs_path_free (buffer_vpath, TRUE);
1255 buffer_vpath =
1256 vfs_path_build_filename (mc_global.share_data_dir, EDIT_GLOBAL_MENU, (char *) NULL);
1257 }
1258 break;
1259
1260 default:
1261 vfs_path_free (menufile_vpath, TRUE);
1262 return FALSE;
1263 }
1264
1265 edit_arg_init (&arg, buffer_vpath, 0);
1266 ret = edit_load_file_from_filename (h, &arg);
1267
1268 vfs_path_free (buffer_vpath, TRUE);
1269 vfs_path_free (menufile_vpath, TRUE);
1270
1271 return ret;
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281 gboolean
1282 edit_close_cmd (WEdit *edit)
1283 {
1284 gboolean ret;
1285
1286 ret = (edit != NULL) && edit_ok_to_quit (edit);
1287
1288 if (ret)
1289 {
1290 Widget *w = WIDGET (edit);
1291 WGroup *g = w->owner;
1292
1293 if (edit->locked != 0)
1294 edit->locked = unlock_file (edit->filename_vpath);
1295
1296 group_remove_widget (w);
1297 widget_destroy (w);
1298
1299 if (edit_widget_is_editor (CONST_WIDGET (g->current->data)))
1300 edit = EDIT (g->current->data);
1301 else
1302 {
1303 edit = edit_find_editor (DIALOG (g));
1304 if (edit != NULL)
1305 widget_select (WIDGET (edit));
1306 }
1307 }
1308
1309 if (edit != NULL)
1310 edit->force |= REDRAW_COMPLETELY;
1311
1312 return ret;
1313 }
1314
1315
1316
1317 void
1318 edit_block_copy_cmd (WEdit *edit)
1319 {
1320 off_t start_mark, end_mark, current = edit->buffer.curs1;
1321 off_t mark1 = 0, mark2 = 0;
1322 long c1 = 0, c2 = 0;
1323 off_t size;
1324 unsigned char *copy_buf;
1325
1326 edit_update_curs_col (edit);
1327 if (!eval_marks (edit, &start_mark, &end_mark))
1328 return;
1329
1330 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1331
1332
1333
1334 edit_push_markers (edit);
1335
1336 if (edit->column_highlight)
1337 {
1338 long col_delta;
1339
1340 col_delta = labs (edit->column2 - edit->column1);
1341 edit_insert_column_of_text (edit, copy_buf, size, col_delta, &mark1, &mark2, &c1, &c2);
1342 }
1343 else
1344 {
1345 int size_orig = size;
1346
1347 while (size-- != 0)
1348 edit_insert_ahead (edit, copy_buf[size]);
1349
1350
1351 if (edit_options.cursor_after_inserted_block)
1352 edit_cursor_move (edit, size_orig);
1353 }
1354
1355 g_free (copy_buf);
1356 edit_scroll_screen_over_cursor (edit);
1357
1358 if (edit->column_highlight)
1359 edit_set_markers (edit, edit->buffer.curs1, mark2, c1, c2);
1360 else if (start_mark < current && end_mark > current)
1361 edit_set_markers (edit, start_mark, end_mark + end_mark - start_mark, 0, 0);
1362
1363 edit->force |= REDRAW_PAGE;
1364 }
1365
1366
1367
1368 void
1369 edit_block_move_cmd (WEdit *edit)
1370 {
1371 off_t current;
1372 unsigned char *copy_buf = NULL;
1373 off_t start_mark, end_mark;
1374
1375 if (!eval_marks (edit, &start_mark, &end_mark))
1376 return;
1377
1378 if (!edit->column_highlight && edit->buffer.curs1 > start_mark && edit->buffer.curs1 < end_mark)
1379 return;
1380
1381 if (edit->mark2 < 0)
1382 edit_mark_cmd (edit, FALSE);
1383 edit_push_markers (edit);
1384
1385 if (edit->column_highlight)
1386 {
1387 off_t mark1, mark2;
1388 off_t size;
1389 long c1, c2, b_width;
1390 long x, x2;
1391 off_t b1, b2;
1392
1393 c1 = MIN (edit->column1, edit->column2);
1394 c2 = MAX (edit->column1, edit->column2);
1395 b_width = c2 - c1;
1396
1397 edit_update_curs_col (edit);
1398
1399 x = edit->curs_col;
1400 x2 = x + edit->over_col;
1401
1402
1403 b1 = edit_buffer_get_eol (&edit->buffer, edit->buffer.curs1);
1404 b2 = edit_buffer_get_eol (&edit->buffer, start_mark);
1405 if (b1 == b2 && x2 > c1 && x2 <= c2)
1406 return;
1407
1408 if (edit->buffer.curs1 > start_mark
1409 && edit->buffer.curs1 < edit_buffer_get_eol (&edit->buffer, end_mark))
1410 {
1411 if (x > c2)
1412 x -= b_width;
1413 else if (x > c1 && x <= c2)
1414 x = c1;
1415 }
1416
1417 copy_buf = edit_get_block (edit, start_mark, end_mark, &size);
1418
1419
1420 edit_block_delete_cmd (edit);
1421
1422 edit->over_col = MAX (0, edit->over_col - b_width);
1423
1424 b1 = edit_buffer_get_current_bol (&edit->buffer);
1425 current = edit_move_forward3 (edit, b1, x, 0);
1426 edit_cursor_move (edit, current - edit->buffer.curs1);
1427 edit_scroll_screen_over_cursor (edit);
1428
1429
1430 if (edit_options.cursor_beyond_eol && edit->over_col > 0)
1431 edit_insert_over (edit);
1432
1433 edit_insert_column_of_text (edit, copy_buf, size, b_width, &mark1, &mark2, &c1, &c2);
1434 edit_set_markers (edit, mark1, mark2, c1, c2);
1435 }
1436 else
1437 {
1438 off_t count, count_orig;
1439 off_t x;
1440
1441 current = edit->buffer.curs1;
1442 copy_buf = g_malloc0 (end_mark - start_mark);
1443 edit_cursor_move (edit, start_mark - edit->buffer.curs1);
1444 edit_scroll_screen_over_cursor (edit);
1445
1446 for (count = start_mark; count < end_mark; count++)
1447 copy_buf[end_mark - count - 1] = edit_delete (edit, TRUE);
1448
1449 edit_scroll_screen_over_cursor (edit);
1450 x = current > edit->buffer.curs1 ? end_mark - start_mark : 0;
1451 edit_cursor_move (edit, current - edit->buffer.curs1 - x);
1452 edit_scroll_screen_over_cursor (edit);
1453 count_orig = count;
1454 while (count-- > start_mark)
1455 edit_insert_ahead (edit, copy_buf[end_mark - count - 1]);
1456
1457 edit_set_markers (edit, edit->buffer.curs1, edit->buffer.curs1 + end_mark - start_mark, 0,
1458 0);
1459
1460
1461 if (edit_options.cursor_after_inserted_block)
1462 edit_cursor_move (edit, count_orig - start_mark);
1463 }
1464
1465 edit_scroll_screen_over_cursor (edit);
1466 g_free (copy_buf);
1467 edit->force |= REDRAW_PAGE;
1468 }
1469
1470
1471
1472
1473 gboolean
1474 edit_block_delete_cmd (WEdit *edit)
1475 {
1476 off_t start_mark, end_mark;
1477
1478 if (eval_marks (edit, &start_mark, &end_mark))
1479 return edit_block_delete (edit, start_mark, end_mark);
1480
1481 edit_delete_line (edit);
1482
1483 return TRUE;
1484 }
1485
1486
1487
1488
1489
1490
1491
1492
1493 gboolean
1494 edit_ok_to_quit (WEdit *edit)
1495 {
1496 const char *fname;
1497 char *msg;
1498 int act;
1499
1500 if (edit->modified == 0)
1501 return TRUE;
1502
1503 if (edit->filename_vpath != NULL)
1504 fname = vfs_path_as_str (edit->filename_vpath);
1505 else
1506 fname = _ ("[NoName]");
1507
1508 if (!mc_global.midnight_shutdown)
1509 {
1510 query_set_sel (2);
1511
1512 msg = g_strdup_printf (_ ("File %s was modified.\nSave before close?"), fname);
1513 act = edit_query_dialog3 (_ ("Close file"), msg, _ ("&Yes"), _ ("&No"), _ ("&Cancel"));
1514 }
1515 else
1516 {
1517 msg = g_strdup_printf (_ ("%s is being shut down.\nSave modified file %s?"), PACKAGE_NAME,
1518 fname);
1519 act = edit_query_dialog2 (_ ("Quit"), msg, _ ("&Yes"), _ ("&No"));
1520
1521
1522 if (act == -1)
1523 act = 1;
1524 }
1525
1526 g_free (msg);
1527
1528 switch (act)
1529 {
1530 case 0:
1531 if (!mc_global.midnight_shutdown && !edit_check_newline (&edit->buffer))
1532 return FALSE;
1533 edit_push_markers (edit);
1534 edit_set_markers (edit, 0, 0, 0, 0);
1535 if (!edit_save_cmd (edit) || mc_global.midnight_shutdown)
1536 return mc_global.midnight_shutdown;
1537 break;
1538 case 1:
1539 default:
1540 break;
1541 case 2:
1542 case -1:
1543 return FALSE;
1544 }
1545
1546 return TRUE;
1547 }
1548
1549
1550
1551
1552 gboolean
1553 edit_save_block (WEdit *edit, const char *filename, off_t start, off_t finish)
1554 {
1555 int file;
1556 off_t len = 1;
1557 vfs_path_t *vpath;
1558
1559 vpath = vfs_path_from_str (filename);
1560 file = mc_open (vpath, O_CREAT | O_WRONLY | O_TRUNC,
1561 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | O_BINARY);
1562 vfs_path_free (vpath, TRUE);
1563 if (file == -1)
1564 return FALSE;
1565
1566 if (edit->column_highlight)
1567 {
1568 int r;
1569
1570 r = mc_write (file, VERTICAL_MAGIC, sizeof (VERTICAL_MAGIC));
1571 if (r > 0)
1572 {
1573 unsigned char *block, *p;
1574
1575 p = block = edit_get_block (edit, start, finish, &len);
1576 while (len != 0)
1577 {
1578 r = mc_write (file, p, len);
1579 if (r < 0)
1580 break;
1581 p += r;
1582 len -= r;
1583 }
1584 g_free (block);
1585 }
1586 }
1587 else
1588 {
1589 unsigned char *buf;
1590 off_t i = start;
1591
1592 len = finish - start;
1593 buf = g_malloc0 (TEMP_BUF_LEN);
1594 while (start != finish)
1595 {
1596 off_t end;
1597
1598 end = MIN (finish, start + TEMP_BUF_LEN);
1599 for (; i < end; i++)
1600 buf[i - start] = edit_buffer_get_byte (&edit->buffer, i);
1601 len -= mc_write (file, (char *) buf, end - start);
1602 start = end;
1603 }
1604 g_free (buf);
1605 }
1606 mc_close (file);
1607
1608 return (len == 0);
1609 }
1610
1611
1612
1613 void
1614 edit_paste_from_history (WEdit *edit)
1615 {
1616 (void) edit;
1617
1618 message (D_ERROR, MSG_ERROR, "%s", _ ("This function is not implemented"));
1619 }
1620
1621
1622
1623 gboolean
1624 edit_copy_to_X_buf_cmd (WEdit *edit)
1625 {
1626 off_t start_mark, end_mark;
1627
1628 if (!eval_marks (edit, &start_mark, &end_mark))
1629 return TRUE;
1630
1631 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1632 {
1633 message (D_ERROR, MSG_ERROR, "%s", _ ("Unable to save to file"));
1634 return FALSE;
1635 }
1636
1637 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1638
1639 if (edit_options.drop_selection_on_copy)
1640 edit_mark_cmd (edit, TRUE);
1641
1642 return TRUE;
1643 }
1644
1645
1646
1647 gboolean
1648 edit_cut_to_X_buf_cmd (WEdit *edit)
1649 {
1650 off_t start_mark, end_mark;
1651
1652 if (!eval_marks (edit, &start_mark, &end_mark))
1653 return TRUE;
1654
1655 if (!edit_save_block_to_clip_file (edit, start_mark, end_mark))
1656 {
1657 message (D_ERROR, MSG_ERROR, "%s", _ ("Unable to save to file"));
1658 return FALSE;
1659 }
1660
1661 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
1662
1663 edit_block_delete_cmd (edit);
1664 edit_mark_cmd (edit, TRUE);
1665
1666 return TRUE;
1667 }
1668
1669
1670
1671 gboolean
1672 edit_paste_from_X_buf_cmd (WEdit *edit)
1673 {
1674 vfs_path_t *tmp;
1675 gboolean ret;
1676
1677
1678 mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
1679 tmp = mc_config_get_full_vpath (EDIT_HOME_CLIP_FILE);
1680 ret = (edit_insert_file (edit, tmp) >= 0);
1681 vfs_path_free (tmp, TRUE);
1682
1683 return ret;
1684 }
1685
1686
1687
1688
1689
1690
1691
1692 void
1693 edit_goto_cmd (WEdit *edit)
1694 {
1695 static gboolean first_run = TRUE;
1696
1697 char *f;
1698 long l;
1699 char *error;
1700
1701 f = input_dialog (_ ("Goto line"), _ ("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE,
1702 first_run ? NULL : INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1703 if (f == NULL || *f == '\0')
1704 {
1705 g_free (f);
1706 return;
1707 }
1708
1709 l = strtol (f, &error, 0);
1710 if (*error != '\0')
1711 {
1712 g_free (f);
1713 return;
1714 }
1715
1716 if (l < 0)
1717 l = edit->buffer.lines + l + 2;
1718
1719 edit_move_display (edit, l - WIDGET (edit)->rect.lines / 2 - 1);
1720 edit_move_to_line (edit, l - 1);
1721 edit->force |= REDRAW_COMPLETELY;
1722
1723 g_free (f);
1724 first_run = FALSE;
1725 }
1726
1727
1728
1729
1730 gboolean
1731 edit_save_block_cmd (WEdit *edit)
1732 {
1733 off_t start_mark, end_mark;
1734 char *exp, *tmp;
1735 gboolean ret = FALSE;
1736
1737 if (!eval_marks (edit, &start_mark, &end_mark))
1738 return TRUE;
1739
1740 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1741 exp = input_expand_dialog (_ ("Save block"), _ ("Enter file name:"), MC_HISTORY_EDIT_SAVE_BLOCK,
1742 tmp, INPUT_COMPLETE_FILENAMES);
1743 g_free (tmp);
1744 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1745
1746 if (exp != NULL && *exp != '\0')
1747 {
1748 if (edit_save_block (edit, exp, start_mark, end_mark))
1749 ret = TRUE;
1750 else
1751 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot save block"));
1752
1753 edit->force |= REDRAW_COMPLETELY;
1754 }
1755
1756 g_free (exp);
1757
1758 return ret;
1759 }
1760
1761
1762
1763
1764 gboolean
1765 edit_insert_file_cmd (WEdit *edit)
1766 {
1767 char *tmp;
1768 char *exp;
1769 gboolean ret = FALSE;
1770
1771 tmp = mc_config_get_full_path (EDIT_HOME_CLIP_FILE);
1772 exp = input_expand_dialog (_ ("Insert file"), _ ("Enter file name:"),
1773 MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES);
1774 g_free (tmp);
1775
1776 edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
1777
1778 if (exp != NULL && *exp != '\0')
1779 {
1780 vfs_path_t *exp_vpath;
1781
1782 exp_vpath = vfs_path_from_str (exp);
1783 ret = (edit_insert_file (edit, exp_vpath) >= 0);
1784 vfs_path_free (exp_vpath, TRUE);
1785
1786 if (!ret)
1787 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot insert file"));
1788 }
1789
1790 g_free (exp);
1791
1792 edit->force |= REDRAW_COMPLETELY;
1793 return ret;
1794 }
1795
1796
1797
1798
1799 int
1800 edit_sort_cmd (WEdit *edit)
1801 {
1802 char *exp, *tmp, *tmp_edit_block_name, *tmp_edit_temp_name;
1803 off_t start_mark, end_mark;
1804 int e;
1805
1806 if (!eval_marks (edit, &start_mark, &end_mark))
1807 {
1808 message (D_ERROR, MSG_ERROR, "%s", _ ("You must first highlight a block of text"));
1809 return 0;
1810 }
1811
1812 tmp = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1813 edit_save_block (edit, tmp, start_mark, end_mark);
1814 g_free (tmp);
1815
1816 exp = input_dialog (_ ("Run sort"),
1817 _ ("Enter sort options (see sort(1) manpage) separated by whitespace:"),
1818 MC_HISTORY_EDIT_SORT, INPUT_LAST_TEXT, INPUT_COMPLETE_NONE);
1819
1820 if (exp == NULL)
1821 return 1;
1822
1823 tmp_edit_block_name = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
1824 tmp_edit_temp_name = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1825 tmp = g_strconcat (" sort ", exp, " ", tmp_edit_block_name, " > ", tmp_edit_temp_name,
1826 (char *) NULL);
1827 g_free (tmp_edit_temp_name);
1828 g_free (tmp_edit_block_name);
1829 g_free (exp);
1830
1831 e = system (tmp);
1832 g_free (tmp);
1833 if (e != 0)
1834 {
1835 if (e == -1 || e == 127)
1836 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot execute sort command"));
1837 else
1838 {
1839 char q[8];
1840
1841 sprintf (q, "%d ", e);
1842 message (D_ERROR, MSG_ERROR, _ ("Sort returned non-zero: %s"), q);
1843 }
1844
1845 return -1;
1846 }
1847
1848 edit->force |= REDRAW_COMPLETELY;
1849
1850 if (!edit_block_delete_cmd (edit))
1851 return 1;
1852
1853 {
1854 vfs_path_t *tmp_vpath;
1855
1856 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1857 edit_insert_file (edit, tmp_vpath);
1858 vfs_path_free (tmp_vpath, TRUE);
1859 }
1860
1861 return 0;
1862 }
1863
1864
1865
1866
1867
1868
1869
1870 int
1871 edit_ext_cmd (WEdit *edit)
1872 {
1873 char *exp, *tmp, *tmp_edit_temp_file;
1874 int e;
1875
1876 exp =
1877 input_dialog (_ ("Paste output of external command"), _ ("Enter shell command(s):"),
1878 MC_HISTORY_EDIT_PASTE_EXTCMD, INPUT_LAST_TEXT,
1879 INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
1880 | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS
1881 | INPUT_COMPLETE_SHELL_ESC);
1882
1883 if (!exp)
1884 return 1;
1885
1886 tmp_edit_temp_file = mc_config_get_full_path (EDIT_HOME_TEMP_FILE);
1887 tmp = g_strconcat (exp, " > ", tmp_edit_temp_file, (char *) NULL);
1888 g_free (tmp_edit_temp_file);
1889 e = system (tmp);
1890 g_free (tmp);
1891 g_free (exp);
1892
1893 if (e != 0)
1894 {
1895 message (D_ERROR, MSG_ERROR, "%s", _ ("Cannot execute external command"));
1896 return -1;
1897 }
1898
1899 edit->force |= REDRAW_COMPLETELY;
1900
1901 {
1902 vfs_path_t *tmp_vpath;
1903
1904 tmp_vpath = mc_config_get_full_vpath (EDIT_HOME_TEMP_FILE);
1905 edit_insert_file (edit, tmp_vpath);
1906 vfs_path_free (tmp_vpath, TRUE);
1907 }
1908
1909 return 0;
1910 }
1911
1912
1913
1914
1915
1916
1917 void
1918 edit_block_process_cmd (WEdit *edit, int macro_number)
1919 {
1920 char *fname;
1921 char *macros_fname = NULL;
1922
1923 fname = g_strdup_printf ("%s.%i.sh", EDIT_HOME_MACRO_FILE, macro_number);
1924 macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL);
1925 edit_user_menu (edit, macros_fname, 0);
1926 g_free (fname);
1927 g_free (macros_fname);
1928 edit->force |= REDRAW_COMPLETELY;
1929 }
1930
1931
1932
1933 void
1934 edit_mail_dialog (WEdit *edit)
1935 {
1936 char *mail_to = NULL;
1937 char *mail_subject = NULL;
1938 char *mail_cc = NULL;
1939
1940 quick_widget_t quick_widgets[] = {
1941 QUICK_LABEL (_ ("mail -s <subject> -c <cc> <to>"), NULL),
1942 QUICK_LABELED_INPUT (_ ("To"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input-3",
1943 &mail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1944 QUICK_LABELED_INPUT (_ ("Subject"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input-2",
1945 &mail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
1946 QUICK_LABELED_INPUT (_ ("Copies to"), input_label_above, INPUT_LAST_TEXT, "mail-dlg-input",
1947 &mail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
1948 QUICK_BUTTONS_OK_CANCEL,
1949 QUICK_END,
1950 };
1951
1952 WRect r = { -1, -1, 0, 50 };
1953
1954 quick_dialog_t qdlg = {
1955 .rect = r,
1956 .title = _ ("Mail"),
1957 .help = "[Input Line Keys]",
1958 .widgets = quick_widgets,
1959 .callback = NULL,
1960 .mouse_callback = NULL,
1961 };
1962
1963 if (quick_dialog (&qdlg) != B_CANCEL)
1964 {
1965 pipe_mail (&edit->buffer, mail_to, mail_subject, mail_cc);
1966 g_free (mail_to);
1967 g_free (mail_subject);
1968 g_free (mail_cc);
1969 }
1970 }
1971
1972
1973
1974 void
1975 edit_select_codepage_cmd (WEdit *edit)
1976 {
1977 if (do_select_codepage ())
1978 edit_set_codeset (edit);
1979
1980 edit->force = REDRAW_PAGE;
1981 widget_draw (WIDGET (edit));
1982 }
1983
1984
1985
1986 void
1987 edit_insert_literal_cmd (WEdit *edit)
1988 {
1989 int char_for_insertion;
1990
1991 char_for_insertion =
1992 editcmd_dialog_raw_key_query (_ ("Insert literal"), _ ("Press any key:"), FALSE);
1993 edit_execute_key_command (edit, -1, ascii_alpha_to_cntrl (char_for_insertion));
1994 }
1995
1996
1997
1998 gboolean
1999 edit_load_forward_cmd (WEdit *edit)
2000 {
2001 if (edit->modified != 0
2002 && edit_query_dialog2 (_ ("Warning"),
2003 _ ("Current text was modified without a file save.\n"
2004 "Continue discards these changes."),
2005 _ ("C&ontinue"), _ ("&Cancel"))
2006 == 1)
2007 {
2008 edit->force |= REDRAW_COMPLETELY;
2009 return TRUE;
2010 }
2011
2012 if (edit_stack_iterator + 1 >= MAX_HISTORY_MOVETO)
2013 return FALSE;
2014
2015 if (edit_history_moveto[edit_stack_iterator + 1].line_number < 1)
2016 return FALSE;
2017
2018 edit_stack_iterator++;
2019 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
2020 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
2021
2022 return FALSE;
2023 }
2024
2025
2026
2027 gboolean
2028 edit_load_back_cmd (WEdit *edit)
2029 {
2030 if (edit->modified != 0
2031 && edit_query_dialog2 (_ ("Warning"),
2032 _ ("Current text was modified without a file save.\n"
2033 "Continue discards these changes."),
2034 _ ("C&ontinue"), _ ("&Cancel"))
2035 == 1)
2036 {
2037 edit->force |= REDRAW_COMPLETELY;
2038 return TRUE;
2039 }
2040
2041
2042 if (edit_stack_iterator == 0)
2043 return FALSE;
2044
2045 edit_stack_iterator--;
2046 if (edit_history_moveto[edit_stack_iterator].file_vpath != NULL)
2047 return edit_reload_line (edit, &edit_history_moveto[edit_stack_iterator]);
2048
2049 return FALSE;
2050 }
2051
2052
2053
2054
2055
2056
2057
2058
2059 int
2060 editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean cancel)
2061 {
2062 int w, wq;
2063 int y = 2;
2064 WDialog *raw_dlg;
2065 WGroup *g;
2066
2067 w = str_term_width1 (heading) + 6;
2068 wq = str_term_width1 (query);
2069 w = MAX (w, wq + 3 * 2 + 1 + 2);
2070
2071 raw_dlg = dlg_create (TRUE, 0, 0, cancel ? 7 : 5, w, WPOS_CENTER | WPOS_TRYUP, FALSE,
2072 dialog_colors, editcmd_dialog_raw_key_query_cb, NULL, NULL, heading);
2073 g = GROUP (raw_dlg);
2074 widget_want_tab (WIDGET (raw_dlg), TRUE);
2075
2076 group_add_widget (g, label_new (y, 3, query));
2077 group_add_widget (
2078 g, input_new (y++, 3 + wq + 1, input_colors, w - (6 + wq + 1), "", 0, INPUT_COMPLETE_NONE));
2079 if (cancel)
2080 {
2081 group_add_widget (g, hline_new (y++, -1, -1));
2082
2083 group_add_widget_autopos (g, button_new (y, 1, B_CANCEL, NORMAL_BUTTON, _ ("Cancel"), NULL),
2084 WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
2085 }
2086
2087 w = dlg_run (raw_dlg);
2088 widget_destroy (WIDGET (raw_dlg));
2089
2090 return (cancel && (w == ESC_CHAR || w == B_CANCEL)) ? 0 : w;
2091 }
2092
2093