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 <il.smind@gmail.com>
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Ilia Maslakov 2011-01-26 00:12:30 +00:00
parent 83177cfc16
commit d31116328a
10 changed files with 75 additions and 194 deletions

View File

@ -66,6 +66,7 @@
#define EDIT_DIR "mcedit" #define EDIT_DIR "mcedit"
/* file names */ /* 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_SYNTAX_FILE EDIT_DIR PATH_SEP_STR "Syntax"
#define EDIT_CLIP_FILE EDIT_DIR PATH_SEP_STR "mcedit.clip" #define EDIT_CLIP_FILE EDIT_DIR PATH_SEP_STR "mcedit.clip"
#define EDIT_BLOCK_FILE EDIT_DIR PATH_SEP_STR "mcedit.block" #define EDIT_BLOCK_FILE EDIT_DIR PATH_SEP_STR "mcedit.block"

View File

@ -187,7 +187,6 @@ static name_keymap_t command_names[] = {
{"EditSelectionHistory", CK_Selection_History}, {"EditSelectionHistory", CK_Selection_History},
{"EditShell", CK_Shell}, {"EditShell", CK_Shell},
{"EditInsertLiteral", CK_Insert_Literal}, {"EditInsertLiteral", CK_Insert_Literal},
{"EditExecuteMacro", CK_Execute_Macro},
{"EditBeginOrEndMacro", CK_Begin_End_Macro}, {"EditBeginOrEndMacro", CK_Begin_End_Macro},
{"EditExtMode", CK_Ext_Mode}, {"EditExtMode", CK_Ext_Mode},
{"EditToggleLineState", CK_Toggle_Line_State}, {"EditToggleLineState", CK_Toggle_Line_State},

View File

@ -200,7 +200,6 @@
#define CK_Ext_Mode 820 #define CK_Ext_Mode 820
#define CK_Insert_Literal 851 #define CK_Insert_Literal 851
#define CK_Execute_Macro 852
#define CK_Begin_End_Macro 853 #define CK_Begin_End_Macro 853
#define CK_Begin_End_Repeat 854 #define CK_Begin_End_Repeat 854
#define CK_Begin_Record_Repeat 855 #define CK_Begin_Record_Repeat 855
@ -501,17 +500,7 @@
#define CK_DiffContinueSearch 9037 #define CK_DiffContinueSearch 9037
#define CK_DiffOptions 9038 #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 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_Macro(i) (20000+(i))
#define CK_Last_Macro CK_Macro(0x7FFF) #define CK_Last_Macro CK_Macro(0x7FFF)

View File

@ -215,6 +215,7 @@ extern gboolean search_create_bookmark;
int edit_drop_hotkey_menu (WEdit * e, int key); int edit_drop_hotkey_menu (WEdit * e, int key);
void edit_menu_cmd (WEdit * e); 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 edit_init_menu (struct WMenuBar *menubar);
void menu_save_mode_cmd (void); void menu_save_mode_cmd (void);
int edit_translate_key (WEdit * edit, long x_key, int *cmd, int *ch); 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); long edit_insert_file (WEdit * edit, const char *filename);
int edit_load_back_cmd (WEdit * edit); int edit_load_back_cmd (WEdit * edit);
int edit_load_forward_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_refresh_cmd (WEdit * edit);
void edit_date_cmd (WEdit * edit); void edit_date_cmd (WEdit * edit);
void edit_goto_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_select_codepage_cmd (WEdit * edit);
void edit_insert_literal_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); gboolean edit_execute_macro (WEdit * edit, int hotkey);
void edit_begin_end_macro_cmd (WEdit * edit); void edit_begin_end_macro_cmd (WEdit * edit);
void edit_begin_end_repeat_cmd (WEdit * edit); void edit_begin_end_repeat_cmd (WEdit * edit);

View File

@ -132,8 +132,6 @@ static const struct edit_filters
static long last_bracket = -1; static long last_bracket = -1;
static const char *const shell_cmd[] = SHELL_COMMANDS_i;
/*** file scope functions ************************************************************************/ /*** 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); 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. */ /** User edit menu, like user menu (F2) but only in editor. */
static void void
user_menu (WEdit * edit) user_menu (WEdit * edit, const char *menu_file, int selected_entry)
{ {
char *block_file; char *block_file;
int nomark; int nomark;
@ -1678,7 +1678,9 @@ user_menu (WEdit * edit)
edit_save_block (edit, block_file, start_mark, end_mark); edit_save_block (edit, block_file, start_mark, end_mark);
/* run shell scripts from menu */ /* 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; int rc = 0;
FILE *fd; FILE *fd;
@ -1706,8 +1708,6 @@ user_menu (WEdit * edit)
g_free (block_file); g_free (block_file);
} }
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
int int
@ -4102,7 +4102,7 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
edit_goto_matching_bracket (edit); edit_goto_matching_bracket (edit);
break; break;
case CK_User_Menu: case CK_User_Menu:
user_menu (edit); user_menu (edit, NULL, -1);
break; break;
case CK_Sort: case CK_Sort:
edit_sort_cmd (edit); edit_sort_cmd (edit);
@ -4122,9 +4122,6 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
case CK_Insert_Literal: case CK_Insert_Literal:
edit_insert_literal_cmd (edit); edit_insert_literal_cmd (edit);
break; break;
case CK_Execute_Macro:
edit_execute_macro_cmd (edit);
break;
case CK_Begin_End_Macro: case CK_Begin_End_Macro:
edit_begin_end_macro_cmd (edit); edit_begin_end_macro_cmd (edit);
break; break;
@ -4139,8 +4136,8 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
} }
/* CK_Pipe_Block */ /* CK_Pipe_Block */
if ((command / 10000) == 1) /* a shell command */ if ((command / CK_Pipe_Block (0)) == 1)
edit_block_process_cmd (edit, shell_cmd[command - 10000], 1); edit_block_process_cmd (edit, command - CK_Pipe_Block (0));
/* keys which must set the col position, and the search vars */ /* keys which must set the col position, and the search vars */
switch (command) switch (command)

View File

@ -1446,7 +1446,7 @@ edit_delete_macro (WEdit * edit, int hotkey)
edit_macro_sort_by_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); macros_config = mc_config_init (macros_fname);
g_free (macros_fname); g_free (macros_fname);
@ -1540,7 +1540,7 @@ edit_store_macro_cmd (WEdit * edit)
edit_delete_macro (edit, hotkey); 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); macros_config = mc_config_init (macros_fname);
g_free (macros_fname); g_free (macros_fname);
@ -1643,7 +1643,7 @@ edit_load_macro_cmd (WEdit * edit)
(void) 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); macros_config = mc_config_init (macros_fname);
g_free (macros_fname); g_free (macros_fname);
@ -1673,19 +1673,19 @@ edit_load_macro_cmd (WEdit * edit)
if (macro_pair != NULL) if (macro_pair != NULL)
{ {
macro_action_t m_act; 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; m_act.action = 0;
else else
{ {
m_act.action = keybind_lookup_action (macro_pair [0]); m_act.action = keybind_lookup_action (macro_pair[0]);
g_free (macro_pair[0]); g_free (macro_pair[0]);
macro_pair[0] = NULL; 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; m_act.ch = -1;
else else
{ {
m_act.ch = strtol (macro_pair [1], NULL, 0); m_act.ch = strtol (macro_pair[1], NULL, 0);
g_free (macro_pair[1]); g_free (macro_pair[1]);
macro_pair[1] = NULL; macro_pair[1] = NULL;
} }
@ -2852,129 +2852,17 @@ edit_ext_cmd (WEdit * edit)
command, that just produces some output which is to be inserted */ command, that just produces some output which is to be inserted */
void 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 *fname;
char buf[BUFSIZ]; char *macros_fname = NULL;
FILE *script_home = NULL;
FILE *block_file = NULL;
gchar *o, *h, *b, *tmp;
char *quoted_name = NULL;
o = g_strconcat (mc_sysconfig_dir, shell_cmd, (char *) NULL); /* original source script */ fname = g_strdup_printf ("%s.%i.sh", MC_EXTMACRO_FILE, macro_number);
h = g_strconcat (mc_config_get_data_path (), PATH_SEP_STR EDIT_DIR, shell_cmd, (char *) NULL); /* home script */ macros_fname = g_build_filename (mc_config_get_data_path (), fname, (char *) NULL);
b = concat_dir_and_file (mc_config_get_cache_path (), EDIT_BLOCK_FILE); /* block file */ user_menu (edit, macros_fname, 0);
g_free (fname);
script_home = fopen (h, "r"); g_free (macros_fname);
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; 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);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -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 void
edit_begin_end_macro_cmd (WEdit * edit) edit_begin_end_macro_cmd (WEdit * edit)
{ {

View File

@ -1340,7 +1340,7 @@ help_cmd (void)
void void
user_file_menu_cmd (void) user_file_menu_cmd (void)
{ {
(void) user_menu_cmd (NULL); (void) user_menu_cmd (NULL, NULL, -1);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

View File

@ -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 */ /** FIXME: recode this routine on version 3.0, it could be cleaner */
static void 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; FILE *cmd_file;
int cmd_file_fd; 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 /* execute the command indirectly to allow execution even
* on no-exec filesystems. */ * on no-exec filesystems. */
char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL); char *cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL);
if (dont_show_prompt)
{
if (system (cmd) == -1)
message (D_ERROR, MSG_ERROR, "%s", _("Error calling program"));
}
else
{
shell_execute (cmd, EXECUTE_HIDE); shell_execute (cmd, EXECUTE_HIDE);
}
g_free (cmd); g_free (cmd);
} }
unlink (file_name); unlink (file_name);
@ -851,7 +859,7 @@ expand_format (struct WEdit *edit_widget, char c, gboolean do_quote)
*/ */
gboolean 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 *p;
char *data, **entries; 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")); message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute commands on non-local filesystems"));
return FALSE; return FALSE;
} }
if (menu_file != NULL)
menu = g_strdup (menu_file);
else
menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU); menu = g_strdup (edit_widget ? EDIT_LOCAL_MENU : MC_LOCAL_MENU);
if (!exist_file (menu) || !menu_file_own (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); g_free (menu);
if (edit_widget) if (edit_widget)
menu = concat_dir_and_file (mc_config_get_data_path (), EDIT_HOME_MENU); menu = concat_dir_and_file (mc_config_get_data_path (), EDIT_HOME_MENU);
@ -1005,6 +1023,10 @@ user_menu_cmd (struct WEdit *edit_widget)
res = FALSE; res = FALSE;
} }
else else
{
if (selected_entry >= 0)
selected = selected_entry;
else
{ {
max_cols = min (max (max_cols, col), MAX_ENTRY_LEN); max_cols = min (max (max_cols, col), MAX_ENTRY_LEN);
@ -1022,9 +1044,10 @@ user_menu_cmd (struct WEdit *edit_widget)
listbox_select_entry (listbox->list, selected); listbox_select_entry (listbox->list, selected);
selected = run_listbox (listbox); selected = run_listbox (listbox);
}
if (selected >= 0) if (selected >= 0)
{ {
execute_menu_command (edit_widget, entries[selected]); execute_menu_command (edit_widget, entries[selected], (selected_entry >= 0));
res = TRUE; res = TRUE;
} }

View File

@ -19,7 +19,7 @@ struct WEdit;
/*** declarations of public functions ************************************************************/ /*** 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); char *expand_format (struct WEdit *edit_widget, char c, gboolean do_quote);
int check_format_view (const char *); int check_format_view (const char *);
int check_format_var (const char *, char **); int check_format_var (const char *, char **);

View File

@ -293,7 +293,6 @@ const global_keymap_t default_editor_keymap[] = {
{XCTRL ('r'), CK_Begin_End_Macro, "C-r"}, {XCTRL ('r'), CK_Begin_End_Macro, "C-r"},
{XCTRL ('r'), CK_Begin_Record_Macro, "C-r"}, {XCTRL ('r'), CK_Begin_Record_Macro, "C-r"},
{XCTRL ('r'), CK_End_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"}, {XCTRL ('f'), CK_Save_Block, "C-f"},
/* Spell check */ /* Spell check */
{XCTRL ('p'), CK_Pipe_Block (1), "C-p"}, {XCTRL ('p'), CK_Pipe_Block (1), "C-p"},
@ -361,7 +360,6 @@ const global_keymap_t default_editor_keymap[] = {
/* emacs keyboard layout emulation */ /* emacs keyboard layout emulation */
const global_keymap_t default_editor_x_keymap[] = { const global_keymap_t default_editor_x_keymap[] = {
{'k', CK_New, "k"}, {'k', CK_New, "k"},
{'e', CK_Execute_Macro, "e"},
{0, CK_Ignore_Key, ""} {0, CK_Ignore_Key, ""}
}; };
#endif /* USE_INTERNAL_EDIT */ #endif /* USE_INTERNAL_EDIT */