From d31116328a7359396325de466124f0b9462190f1 Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Wed, 26 Jan 2011 00:12:30 +0000 Subject: [PATCH] Changed engine of external macros execution Now "EditPipeBlock (X)" action tries execute the ~/.local/share/mc/mcedit/macros.d/macro.X.sh script. To bind action EditPipeBlock (X) to the any hotkey you need add this binding into ~/.local/share/mc/mc.macros file like following: [editor] ctrl-Q=EditWordLeft:-1;EditWordRightHighlight:-1;EditPipeBlock:3; ctrl-W=EditPipeBlock:1; This means that "ctrl-W" hotkey initiates the EditPipeBlock (1) action, editor handler translates this into execution of ~/.local/share/mc/mcedit/macros.d/macro.1.sh shell script. Signed-off-by: Ilia Maslakov Signed-off-by: Andrew Borodin Signed-off-by: Slava Zanko --- lib/fileloc.h | 1 + lib/keybind.c | 1 - lib/keybind.h | 11 --- src/editor/edit-impl.h | 4 +- src/editor/edit.c | 25 +++--- src/editor/editcmd.c | 158 ++++--------------------------------- src/filemanager/cmd.c | 2 +- src/filemanager/usermenu.c | 63 ++++++++++----- src/filemanager/usermenu.h | 2 +- src/keybind-defaults.c | 2 - 10 files changed, 75 insertions(+), 194 deletions(-) diff --git a/lib/fileloc.h b/lib/fileloc.h index 12133aaef..6f80db82b 100644 --- a/lib/fileloc.h +++ b/lib/fileloc.h @@ -66,6 +66,7 @@ #define EDIT_DIR "mcedit" /* file names */ +#define MC_EXTMACRO_FILE EDIT_DIR PATH_SEP_STR "macros.d" PATH_SEP_STR "macro" #define EDIT_SYNTAX_FILE EDIT_DIR PATH_SEP_STR "Syntax" #define EDIT_CLIP_FILE EDIT_DIR PATH_SEP_STR "mcedit.clip" #define EDIT_BLOCK_FILE EDIT_DIR PATH_SEP_STR "mcedit.block" diff --git a/lib/keybind.c b/lib/keybind.c index 5b7c6a5b5..a4f409395 100644 --- a/lib/keybind.c +++ b/lib/keybind.c @@ -187,7 +187,6 @@ static name_keymap_t command_names[] = { {"EditSelectionHistory", CK_Selection_History}, {"EditShell", CK_Shell}, {"EditInsertLiteral", CK_Insert_Literal}, - {"EditExecuteMacro", CK_Execute_Macro}, {"EditBeginOrEndMacro", CK_Begin_End_Macro}, {"EditExtMode", CK_Ext_Mode}, {"EditToggleLineState", CK_Toggle_Line_State}, diff --git a/lib/keybind.h b/lib/keybind.h index 20bf4244a..7a7f1b80f 100644 --- a/lib/keybind.h +++ b/lib/keybind.h @@ -200,7 +200,6 @@ #define CK_Ext_Mode 820 #define CK_Insert_Literal 851 -#define CK_Execute_Macro 852 #define CK_Begin_End_Macro 853 #define CK_Begin_End_Repeat 854 #define CK_Begin_Record_Repeat 855 @@ -501,17 +500,7 @@ #define CK_DiffContinueSearch 9037 #define CK_DiffOptions 9038 -/* - Process a block through a shell command: CK_Pipe_Block(i) executes shell_cmd[i]. - shell_cmd[i] must process the file ~/cooledit.block and output ~/cooledit.block - which is then inserted into the text in place of the original block. shell_cmd[i] must - also produce a file homedir/cooledit.error . If this file is not empty an error will - have been assumed to have occured, and the block will not be replaced. - TODO: bring up a viewer to display the error message instead of inserting - it into the text, which is annoying. - */ #define CK_Pipe_Block(i) (10000+(i)) -#define SHELL_COMMANDS_i {"/edit.indent.rc", "/edit.spell.rc", /* and so on */ 0 } #define CK_Macro(i) (20000+(i)) #define CK_Last_Macro CK_Macro(0x7FFF) diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h index 5b49e316c..05019d208 100644 --- a/src/editor/edit-impl.h +++ b/src/editor/edit-impl.h @@ -215,6 +215,7 @@ extern gboolean search_create_bookmark; int edit_drop_hotkey_menu (WEdit * e, int key); void edit_menu_cmd (WEdit * e); +void user_menu (WEdit * edit, const char *menu_file, int selected_entry); void edit_init_menu (struct WMenuBar *menubar); void menu_save_mode_cmd (void); int edit_translate_key (WEdit * edit, long x_key, int *cmd, int *ch); @@ -289,7 +290,7 @@ int edit_insert_column_of_text_from_file (WEdit * edit, int file); long edit_insert_file (WEdit * edit, const char *filename); int edit_load_back_cmd (WEdit * edit); int edit_load_forward_cmd (WEdit * edit); -void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block); +void edit_block_process_cmd (WEdit * edit, int macro_number); void edit_refresh_cmd (WEdit * edit); void edit_date_cmd (WEdit * edit); void edit_goto_cmd (WEdit * edit); @@ -316,7 +317,6 @@ void edit_paste_from_X_buf_cmd (WEdit * edit); void edit_select_codepage_cmd (WEdit * edit); void edit_insert_literal_cmd (WEdit * edit); -void edit_execute_macro_cmd (WEdit * edit); gboolean edit_execute_macro (WEdit * edit, int hotkey); void edit_begin_end_macro_cmd (WEdit * edit); void edit_begin_end_repeat_cmd (WEdit * edit); diff --git a/src/editor/edit.c b/src/editor/edit.c index 84b1e3813..90dfa63cb 100644 --- a/src/editor/edit.c +++ b/src/editor/edit.c @@ -132,8 +132,6 @@ static const struct edit_filters static long last_bracket = -1; -static const char *const shell_cmd[] = SHELL_COMMANDS_i; - /*** file scope functions ************************************************************************/ /* --------------------------------------------------------------------------------------------- */ @@ -167,7 +165,6 @@ static const char *const shell_cmd[] = SHELL_COMMANDS_i; /* --------------------------------------------------------------------------------------------- */ -static void user_menu (WEdit * edit); static int left_of_four_spaces (WEdit * edit); /* --------------------------------------------------------------------------------------------- */ @@ -1661,10 +1658,13 @@ edit_goto_matching_bracket (WEdit * edit) } /* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + /** User edit menu, like user menu (F2) but only in editor. */ -static void -user_menu (WEdit * edit) +void +user_menu (WEdit * edit, const char *menu_file, int selected_entry) { char *block_file; int nomark; @@ -1678,7 +1678,9 @@ user_menu (WEdit * edit) edit_save_block (edit, block_file, start_mark, end_mark); /* run shell scripts from menu */ - if (user_menu_cmd (edit) && (mc_stat (block_file, &status) == 0) && (status.st_size != 0)) + if (user_menu_cmd (edit, menu_file, selected_entry) + && (mc_stat (block_file, &status) == 0) + && (status.st_size != 0)) { int rc = 0; FILE *fd; @@ -1706,8 +1708,6 @@ user_menu (WEdit * edit) g_free (block_file); } -/* --------------------------------------------------------------------------------------------- */ -/*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ int @@ -4102,7 +4102,7 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) edit_goto_matching_bracket (edit); break; case CK_User_Menu: - user_menu (edit); + user_menu (edit, NULL, -1); break; case CK_Sort: edit_sort_cmd (edit); @@ -4122,9 +4122,6 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) case CK_Insert_Literal: edit_insert_literal_cmd (edit); break; - case CK_Execute_Macro: - edit_execute_macro_cmd (edit); - break; case CK_Begin_End_Macro: edit_begin_end_macro_cmd (edit); break; @@ -4139,8 +4136,8 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion) } /* CK_Pipe_Block */ - if ((command / 10000) == 1) /* a shell command */ - edit_block_process_cmd (edit, shell_cmd[command - 10000], 1); + if ((command / CK_Pipe_Block (0)) == 1) + edit_block_process_cmd (edit, command - CK_Pipe_Block (0)); /* keys which must set the col position, and the search vars */ switch (command) diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c index e763b4b40..728683cd8 100644 --- a/src/editor/editcmd.c +++ b/src/editor/editcmd.c @@ -1446,7 +1446,7 @@ edit_delete_macro (WEdit * edit, int hotkey) edit_macro_sort_by_hotkey (); } - macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL); + macros_fname = g_build_filename (mc_config_get_data_path (), MC_MACRO_FILE, (char *) NULL); macros_config = mc_config_init (macros_fname); g_free (macros_fname); @@ -1540,7 +1540,7 @@ edit_store_macro_cmd (WEdit * edit) edit_delete_macro (edit, hotkey); - macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL); + macros_fname = g_build_filename (mc_config_get_data_path (), MC_MACRO_FILE, (char *) NULL); macros_config = mc_config_init (macros_fname); g_free (macros_fname); @@ -1643,7 +1643,7 @@ edit_load_macro_cmd (WEdit * edit) (void) edit; - macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL); + macros_fname = g_build_filename (mc_config_get_data_path (), MC_MACRO_FILE, (char *) NULL); macros_config = mc_config_init (macros_fname); g_free (macros_fname); @@ -1673,19 +1673,19 @@ edit_load_macro_cmd (WEdit * edit) if (macro_pair != NULL) { macro_action_t m_act; - if (macro_pair [0] == NULL || macro_pair [0][0] == '\0') + if (macro_pair[0] == NULL || macro_pair[0][0] == '\0') m_act.action = 0; else { - m_act.action = keybind_lookup_action (macro_pair [0]); + m_act.action = keybind_lookup_action (macro_pair[0]); g_free (macro_pair[0]); macro_pair[0] = NULL; } - if (macro_pair [1] == NULL || macro_pair [1][0] == '\0') + if (macro_pair[1] == NULL || macro_pair[1][0] == '\0') m_act.ch = -1; else { - m_act.ch = strtol (macro_pair [1], NULL, 0); + m_act.ch = strtol (macro_pair[1], NULL, 0); g_free (macro_pair[1]); macro_pair[1] = NULL; } @@ -2852,129 +2852,17 @@ edit_ext_cmd (WEdit * edit) command, that just produces some output which is to be inserted */ void -edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block) +edit_block_process_cmd (WEdit * edit, int macro_number) { - long start_mark, end_mark; - char buf[BUFSIZ]; - FILE *script_home = NULL; - FILE *block_file = NULL; - gchar *o, *h, *b, *tmp; - char *quoted_name = NULL; + char *fname; + char *macros_fname = NULL; - o = g_strconcat (mc_sysconfig_dir, shell_cmd, (char *) NULL); /* original source script */ - h = g_strconcat (mc_config_get_data_path (), PATH_SEP_STR EDIT_DIR, shell_cmd, (char *) NULL); /* home script */ - b = concat_dir_and_file (mc_config_get_cache_path (), EDIT_BLOCK_FILE); /* block file */ - - script_home = fopen (h, "r"); - if (script_home == NULL) - { - FILE *script_src = NULL; - - script_home = fopen (h, "w"); - if (script_home == NULL) - { - tmp = g_strconcat (_("Error creating script:"), h, (char *) NULL); - edit_error_dialog ("", get_sys_error (tmp)); - g_free (tmp); - goto edit_block_process_cmd__EXIT; - } - - script_src = fopen (o, "r"); - if (script_src == NULL) - { - o = g_strconcat (mc_share_data_dir, shell_cmd, (char *) NULL); - script_src = fopen (o, "r"); - if (script_src == NULL) - { - fclose (script_home); - unlink (h); - tmp = g_strconcat (_("Error reading script:"), o, (char *) NULL); - edit_error_dialog ("", get_sys_error (tmp)); - g_free (tmp); - goto edit_block_process_cmd__EXIT; - } - } - while (fgets (buf, sizeof (buf), script_src)) - fputs (buf, script_home); - fclose (script_src); - - if (fclose (script_home)) - { - tmp = g_strconcat (_("Error closing script:"), h, (char *) NULL); - edit_error_dialog ("", get_sys_error (tmp)); - g_free (tmp); - goto edit_block_process_cmd__EXIT; - } - chmod (h, 0700); - tmp = g_strconcat (_("Script created:"), h, (char *) NULL); - edit_error_dialog ("", get_sys_error (tmp)); - g_free (tmp); - } - - open_error_pipe (); - - if (block) - { /* for marked block run indent formatter */ - if (eval_marks (edit, &start_mark, &end_mark)) - { - edit_error_dialog (_("Process block"), _("You must first highlight a block of text")); - goto edit_block_process_cmd__EXIT; - } - edit_save_block (edit, b, start_mark, end_mark); - quoted_name = name_quote (edit->filename, 0); - /* - * Run script. - * Initial space is to avoid polluting bash history. - * Arguments: - * $1 - name of the edited file (to check its extension etc). - * $2 - file containing the current block. - * $3 - file where error messages should be put - * (for compatibility with old scripts). - */ - tmp = - g_strconcat (" ", mc_config_get_cache_path (), PATH_SEP_STR EDIT_DIR, shell_cmd, " ", - quoted_name, " ", mc_config_get_cache_path (), - PATH_SEP_STR EDIT_BLOCK_FILE " /dev/null", (char *) NULL); - } - else - { - /* - * No block selected, just execute the command for the file. - * Arguments: - * $1 - name of the edited file. - */ - tmp = g_strconcat (" ", mc_config_get_cache_path (), PATH_SEP_STR EDIT_DIR, shell_cmd, " ", - quoted_name, (char *) NULL); - } - - if (system (tmp) == -1) - { - edit_error_dialog (_("Process block"), _("Error calling program")); - } - else - { - - g_free (quoted_name); - close_error_pipe (D_NORMAL, NULL); - - edit_refresh_cmd (edit); - edit->force |= REDRAW_COMPLETELY; - - /* insert result block */ - if (block && !edit_block_delete_cmd (edit)) - { - edit_insert_file (edit, b); - block_file = fopen (b, "w"); - if (block_file != NULL) - fclose (block_file); - } - } - g_free (tmp); - - edit_block_process_cmd__EXIT: - g_free (b); - g_free (h); - g_free (o); + fname = g_strdup_printf ("%s.%i.sh", MC_EXTMACRO_FILE, macro_number); + macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL); + user_menu (edit, macros_fname, 0); + g_free (fname); + g_free (macros_fname); + edit->force |= REDRAW_COMPLETELY; } /* --------------------------------------------------------------------------------------------- */ @@ -3137,20 +3025,6 @@ edit_insert_literal_cmd (WEdit * edit) /* --------------------------------------------------------------------------------------------- */ -void -edit_execute_macro_cmd (WEdit * edit) -{ - int command = - CK_Macro (editcmd_dialog_raw_key_query (_("Execute macro"), _("Press macro hotkey:"), - 1)); - if (command == CK_Macro (0)) - command = CK_Insert_Char; - - edit_execute_key_command (edit, command, -1); -} - -/* --------------------------------------------------------------------------------------------- */ - void edit_begin_end_macro_cmd (WEdit * edit) { diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index a5d504e7f..42d58e910 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -1340,7 +1340,7 @@ help_cmd (void) void user_file_menu_cmd (void) { - (void) user_menu_cmd (NULL); + (void) user_menu_cmd (NULL, NULL, -1); } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/usermenu.c b/src/filemanager/usermenu.c index 67b89f444..36c404da6 100644 --- a/src/filemanager/usermenu.c +++ b/src/filemanager/usermenu.c @@ -404,7 +404,7 @@ test_line (WEdit * edit_widget, char *p, int *result) /** FIXME: recode this routine on version 3.0, it could be cleaner */ static void -execute_menu_command (WEdit * edit_widget, const char *commands) +execute_menu_command (WEdit * edit_widget, const char *commands, gboolean dont_show_prompt) { FILE *cmd_file; int cmd_file_fd; @@ -534,7 +534,15 @@ execute_menu_command (WEdit * edit_widget, const char *commands) /* execute the command indirectly to allow execution even * on no-exec filesystems. */ char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); - shell_execute (cmd, EXECUTE_HIDE); + if (dont_show_prompt) + { + if (system (cmd) == -1) + message (D_ERROR, MSG_ERROR, "%s", _("Error calling program")); + } + else + { + shell_execute (cmd, EXECUTE_HIDE); + } g_free (cmd); } unlink (file_name); @@ -851,7 +859,7 @@ expand_format (struct WEdit *edit_widget, char c, gboolean do_quote) */ gboolean -user_menu_cmd (struct WEdit *edit_widget) +user_menu_cmd (struct WEdit *edit_widget, const char *menu_file, int selected_entry) { char *p; char *data, **entries; @@ -866,10 +874,20 @@ user_menu_cmd (struct WEdit *edit_widget) message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute commands on non-local filesystems")); return FALSE; } - - menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU); + if (menu_file != NULL) + menu = g_strdup (menu_file); + else + menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU); if (!exist_file (menu) || !menu_file_own (menu)) { + if (menu_file != NULL) + { + message (D_ERROR, MSG_ERROR, _("Cannot open file%s\n%s"), menu, unix_error_string (errno)); + g_free (menu); + menu = NULL; + return FALSE; + } + g_free (menu); if (edit_widget) menu = concat_dir_and_file (mc_config_get_data_path (), EDIT_HOME_MENU); @@ -1006,25 +1024,30 @@ user_menu_cmd (struct WEdit *edit_widget) } else { - max_cols = min (max (max_cols, col), MAX_ENTRY_LEN); - - /* Create listbox */ - listbox = create_listbox_window (menu_lines, max_cols + 2, _("User menu"), - "[Menu File Edit]"); - /* insert all the items found */ - for (i = 0; i < menu_lines; i++) + if (selected_entry >= 0) + selected = selected_entry; + else { - p = entries[i]; - LISTBOX_APPEND_TEXT (listbox, (unsigned char) p[0], - extract_line (p, p + MAX_ENTRY_LEN), p); - } - /* Select the default entry */ - listbox_select_entry (listbox->list, selected); + max_cols = min (max (max_cols, col), MAX_ENTRY_LEN); - selected = run_listbox (listbox); + /* Create listbox */ + listbox = create_listbox_window (menu_lines, max_cols + 2, _("User menu"), + "[Menu File Edit]"); + /* insert all the items found */ + for (i = 0; i < menu_lines; i++) + { + p = entries[i]; + LISTBOX_APPEND_TEXT (listbox, (unsigned char) p[0], + extract_line (p, p + MAX_ENTRY_LEN), p); + } + /* Select the default entry */ + listbox_select_entry (listbox->list, selected); + + selected = run_listbox (listbox); + } if (selected >= 0) { - execute_menu_command (edit_widget, entries[selected]); + execute_menu_command (edit_widget, entries[selected], (selected_entry >= 0)); res = TRUE; } diff --git a/src/filemanager/usermenu.h b/src/filemanager/usermenu.h index 9cbefccb2..9596d788a 100644 --- a/src/filemanager/usermenu.h +++ b/src/filemanager/usermenu.h @@ -19,7 +19,7 @@ struct WEdit; /*** declarations of public functions ************************************************************/ -gboolean user_menu_cmd (struct WEdit *edit_widget); +gboolean user_menu_cmd (struct WEdit *edit_widget, const char * menu_file, int selected_entry); char *expand_format (struct WEdit *edit_widget, char c, gboolean do_quote); int check_format_view (const char *); int check_format_var (const char *, char **); diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c index 381e44e5b..2b2626261 100644 --- a/src/keybind-defaults.c +++ b/src/keybind-defaults.c @@ -293,7 +293,6 @@ const global_keymap_t default_editor_keymap[] = { {XCTRL ('r'), CK_Begin_End_Macro, "C-r"}, {XCTRL ('r'), CK_Begin_Record_Macro, "C-r"}, {XCTRL ('r'), CK_End_Record_Macro, "C-r"}, - {XCTRL ('a'), CK_Execute_Macro, "C-a"}, {XCTRL ('f'), CK_Save_Block, "C-f"}, /* Spell check */ {XCTRL ('p'), CK_Pipe_Block (1), "C-p"}, @@ -361,7 +360,6 @@ const global_keymap_t default_editor_keymap[] = { /* emacs keyboard layout emulation */ const global_keymap_t default_editor_x_keymap[] = { {'k', CK_New, "k"}, - {'e', CK_Execute_Macro, "e"}, {0, CK_Ignore_Key, ""} }; #endif /* USE_INTERNAL_EDIT */