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