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"
/* 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"

View File

@ -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},

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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);
}
/* --------------------------------------------------------------------------------------------- */

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 */
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;
}

View File

@ -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 **);

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_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 */