Ticket #323 (reimplimented editor macros)
Reimplemented editor macro engine: * added string binding "InsertChar" for action - "CK_Insert_Char" * added keybind_lookup_actionname - found action name by numeric constant * replaced struct macro to struct macro_action_t * added struct macros_t for describe editor scripts * rewritten edit_load_macro_cmd, edit_execute_macro * renamed edit_save_macro_cmd into edit_store_macro_cmd (WEdit * edit); * dropped Wedit properties: macro_i, macro_depth, macro[MAX_MACRO_LENGTH] * added GArray *macros_list to the store macroses of mcedit * added edit_get_macro Signed-off-by: Ilia Maslakov <il.smind@gmail.com> Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
родитель
1636f8e956
Коммит
8509b74f73
@ -29,6 +29,7 @@
|
||||
#define GLOBAL_KEYMAP_FILE "mc.keymap"
|
||||
#define CHARSETS_LIST "mc.charsets"
|
||||
#define MC_LIB_EXT "mc.ext"
|
||||
#define MC_MACRO_FILE "mc.macros"
|
||||
|
||||
#define FISH_PREFIX "fish"
|
||||
|
||||
@ -67,7 +68,6 @@
|
||||
/* file names */
|
||||
#define EDIT_SYNTAX_FILE EDIT_DIR PATH_SEP_STR "Syntax"
|
||||
#define EDIT_CLIP_FILE EDIT_DIR PATH_SEP_STR "mcedit.clip"
|
||||
#define EDIT_MACRO_FILE EDIT_DIR PATH_SEP_STR "mcedit.macros"
|
||||
#define EDIT_BLOCK_FILE EDIT_DIR PATH_SEP_STR "mcedit.block"
|
||||
#define EDIT_TEMP_FILE EDIT_DIR PATH_SEP_STR "mcedit.temp"
|
||||
|
||||
|
@ -43,6 +43,7 @@
|
||||
/*** file scope variables ************************************************************************/
|
||||
|
||||
static name_keymap_t command_names[] = {
|
||||
{"InsertChar", CK_Insert_Char},
|
||||
#ifdef USE_INTERNAL_EDIT
|
||||
{"EditNoCommand", CK_Ignore_Key},
|
||||
{"EditIgnoreKey", CK_Ignore_Key},
|
||||
@ -199,6 +200,7 @@ static name_keymap_t command_names[] = {
|
||||
{"EditSaveMode", CK_Edit_Save_Mode},
|
||||
{"EditChooseSyntax", CK_Choose_Syntax},
|
||||
{"EditAbout", CK_About},
|
||||
{"EditPipeBlock", CK_Pipe_Block (0)},
|
||||
|
||||
#if 0
|
||||
{"EditFocusNext", CK_Focus_Next},
|
||||
@ -617,6 +619,20 @@ keybind_lookup_action (const char *name)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
const char *
|
||||
keybind_lookup_actionname (unsigned long action)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; command_names[i].name != NULL; i++)
|
||||
if (command_names[i].val == action)
|
||||
return command_names[i].name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
const char *
|
||||
keybind_lookup_keymap_shortcut (const global_keymap_t * keymap, unsigned long action)
|
||||
{
|
||||
|
@ -507,9 +507,9 @@
|
||||
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) (1000+(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) (2000+(i))
|
||||
#define CK_Macro(i) (20000+(i))
|
||||
#define CK_Last_Macro CK_Macro(0x7FFF)
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
@ -544,6 +544,7 @@ typedef struct global_keymap_t
|
||||
|
||||
void keybind_cmd_bind (GArray * keymap, const char *keybind, unsigned long action);
|
||||
unsigned long keybind_lookup_action (const char *name);
|
||||
const char *keybind_lookup_actionname (unsigned long action);
|
||||
const char *keybind_lookup_keymap_shortcut (const global_keymap_t * keymap, unsigned long action);
|
||||
unsigned long keybind_lookup_keymap_command (const global_keymap_t * keymap, long key);
|
||||
|
||||
|
@ -66,7 +66,6 @@ static const struct
|
||||
{ "hotlist", &xdg_config, MC_HOTLIST_FILE},
|
||||
{ "mc.keymap", &xdg_config, GLOBAL_KEYMAP_FILE},
|
||||
|
||||
|
||||
/* data */
|
||||
{ "skins", &xdg_data, MC_SKINS_SUBDIR},
|
||||
{ "fish", &xdg_data, FISH_PREFIX},
|
||||
@ -75,7 +74,6 @@ static const struct
|
||||
{ "bashrc", &xdg_data, "bashrc"},
|
||||
{ "inputrc", &xdg_data, "inputrc"},
|
||||
{ "extfs.d", &xdg_data, MC_EXTFS_DIR},
|
||||
{ "cedit" PATH_SEP_STR "cooledit.macros", &xdg_data, EDIT_MACRO_FILE},
|
||||
{ "cedit" PATH_SEP_STR "Syntax", &xdg_data, EDIT_SYNTAX_FILE},
|
||||
{ "cedit" PATH_SEP_STR "menu", &xdg_data, EDIT_HOME_MENU},
|
||||
{ "cedit" PATH_SEP_STR "edit.indent.rc", &xdg_data, EDIT_DIR PATH_SEP_STR "edit.indent.rc"},
|
||||
|
@ -184,12 +184,6 @@ typedef struct edit_stack_type
|
||||
char *filename;
|
||||
} edit_stack_type;
|
||||
|
||||
struct macro
|
||||
{
|
||||
unsigned long command;
|
||||
int ch;
|
||||
};
|
||||
|
||||
struct Widget;
|
||||
struct WMenuBar;
|
||||
|
||||
@ -311,8 +305,8 @@ int edit_sort_cmd (WEdit * edit);
|
||||
int edit_ext_cmd (WEdit * edit);
|
||||
void edit_help_cmd (WEdit * edit);
|
||||
|
||||
int edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n);
|
||||
int edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k);
|
||||
int edit_store_macro_cmd (WEdit * edit);
|
||||
gboolean edit_load_macro_cmd (WEdit * edit);
|
||||
void edit_delete_macro_cmd (WEdit * edit);
|
||||
|
||||
int edit_copy_to_X_buf_cmd (WEdit * edit);
|
||||
@ -322,6 +316,7 @@ 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_paste_from_history (WEdit * edit);
|
||||
|
@ -12,7 +12,6 @@
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
#define MAX_MACRO_LENGTH 1024
|
||||
#define N_LINE_CACHES 32
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
@ -132,11 +131,6 @@ struct WEdit
|
||||
GTree *defines; /* List of defines */
|
||||
gboolean is_case_insensitive; /* selects language case sensitivity */
|
||||
|
||||
/* macro stuff */
|
||||
int macro_i; /* index to macro[], -1 if not recording a macro */
|
||||
int macro_depth; /* depth of the macro recursion */
|
||||
struct macro macro[MAX_MACRO_LENGTH];
|
||||
|
||||
/* user map stuff */
|
||||
GIConv converter;
|
||||
|
||||
|
@ -169,7 +169,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 inline void edit_execute_macro (WEdit * edit, struct macro macro[], int n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@ -558,7 +557,6 @@ edit_purge_widget (WEdit * edit)
|
||||
size_t len = sizeof (WEdit) - sizeof (Widget);
|
||||
char *start = (char *) edit + sizeof (Widget);
|
||||
memset (start, 0, len);
|
||||
edit->macro_i = -1; /* not recording a macro */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1662,28 +1660,6 @@ edit_goto_matching_bracket (WEdit * edit)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
edit_execute_macro (WEdit * edit, struct macro macro[], int n)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (edit->macro_depth++ > 256)
|
||||
{
|
||||
edit_error_dialog (_("Error"), _("Macro recursion is too deep"));
|
||||
edit->macro_depth--;
|
||||
return;
|
||||
}
|
||||
edit->force |= REDRAW_PAGE;
|
||||
for (; i < n; i++)
|
||||
{
|
||||
edit_execute_cmd (edit, macro[i].command, macro[i].ch);
|
||||
}
|
||||
edit_update_screen (edit);
|
||||
edit->macro_depth--;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** User edit menu, like user menu (F2) but only in editor. */
|
||||
|
||||
@ -2225,7 +2201,7 @@ edit_init (WEdit * edit, int lines, int columns, const char *filename, long line
|
||||
}
|
||||
|
||||
edit_set_keymap ();
|
||||
|
||||
edit_load_macro_cmd (edit);
|
||||
return edit;
|
||||
}
|
||||
|
||||
@ -2266,7 +2242,6 @@ edit_clean (WEdit * edit)
|
||||
g_free (edit->redo_stack);
|
||||
g_free (edit->filename);
|
||||
g_free (edit->dir);
|
||||
|
||||
mc_search_free (edit->search);
|
||||
edit->search = NULL;
|
||||
|
||||
@ -3404,23 +3379,24 @@ edit_find_bracket (WEdit * edit)
|
||||
void
|
||||
edit_execute_key_command (WEdit * edit, unsigned long command, int char_for_insertion)
|
||||
{
|
||||
if (command == CK_Begin_Record_Macro)
|
||||
if (command == CK_Begin_Record_Macro || (command == CK_Begin_End_Macro && macro_index < 0))
|
||||
{
|
||||
edit->macro_i = 0;
|
||||
macro_index = 0;
|
||||
edit->force |= REDRAW_CHAR_ONLY | REDRAW_LINE;
|
||||
return;
|
||||
}
|
||||
if (command == CK_End_Record_Macro && edit->macro_i != -1)
|
||||
if ((command == CK_End_Record_Macro || command == CK_Begin_End_Macro) && macro_index != -1)
|
||||
{
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
edit_save_macro_cmd (edit, edit->macro, edit->macro_i);
|
||||
edit->macro_i = -1;
|
||||
edit_store_macro_cmd (edit);
|
||||
macro_index = -1;
|
||||
return;
|
||||
}
|
||||
if (edit->macro_i >= 0 && edit->macro_i < MAX_MACRO_LENGTH - 1)
|
||||
|
||||
if (macro_index >= 0 && macro_index < MAX_MACRO_LENGTH - 1)
|
||||
{
|
||||
edit->macro[edit->macro_i].command = command;
|
||||
edit->macro[edit->macro_i++].ch = char_for_insertion;
|
||||
record_macro_buf[macro_index].action = command;
|
||||
record_macro_buf[macro_index++].ch = char_for_insertion;
|
||||
}
|
||||
/* record the beginning of a set of editing actions initiated by a key press */
|
||||
if (command != CK_Undo && command != CK_Ext_Mode)
|
||||
@ -4149,15 +4125,8 @@ edit_execute_cmd (WEdit * edit, unsigned long command, int char_for_insertion)
|
||||
}
|
||||
|
||||
/* CK_Pipe_Block */
|
||||
if ((command / 1000) == 1) /* a shell command */
|
||||
edit_block_process_cmd (edit, shell_cmd[command - 1000], 1);
|
||||
if (command > CK_Macro (0) && command <= CK_Last_Macro)
|
||||
{ /* a macro command */
|
||||
struct macro m[MAX_MACRO_LENGTH];
|
||||
int nm;
|
||||
if (edit_load_macro_cmd (edit, m, &nm, command - 2000))
|
||||
edit_execute_macro (edit, m, nm);
|
||||
}
|
||||
if ((command / 10000) == 1) /* a shell command */
|
||||
edit_block_process_cmd (edit, shell_cmd[command - 10000], 1);
|
||||
|
||||
/* keys which must set the col position, and the search vars */
|
||||
switch (command)
|
||||
|
@ -445,126 +445,6 @@ edit_get_save_file_as (WEdit * edit)
|
||||
#undef DLG_HEIGHT
|
||||
}
|
||||
|
||||
/* {{{ Macro stuff starts here */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** creates a macro file if it doesn't exist */
|
||||
|
||||
static FILE *
|
||||
edit_open_macro_file (const char *r)
|
||||
{
|
||||
gchar *filename;
|
||||
FILE *fd;
|
||||
int file;
|
||||
filename = concat_dir_and_file (mc_config_get_data_path (), EDIT_MACRO_FILE);
|
||||
file = open (filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (file == -1)
|
||||
{
|
||||
g_free (filename);
|
||||
return 0;
|
||||
}
|
||||
close (file);
|
||||
fd = fopen (filename, r);
|
||||
g_free (filename);
|
||||
return fd;
|
||||
}
|
||||
|
||||
#define MAX_MACROS 1024
|
||||
static int saved_macro[MAX_MACROS + 1];
|
||||
static int saved_macros_loaded = 0;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
This is just to stop the macro file be loaded over and over for keys
|
||||
that aren't defined to anything. On slow systems this could be annoying.
|
||||
*/
|
||||
|
||||
static int
|
||||
macro_exists (int k)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_MACROS && saved_macro[i]; i++)
|
||||
if (saved_macro[i] == k)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on error */
|
||||
|
||||
static int
|
||||
edit_delete_macro (WEdit * edit, int k)
|
||||
{
|
||||
gchar *tmp, *tmp2;
|
||||
struct macro macro[MAX_MACRO_LENGTH];
|
||||
FILE *f, *g;
|
||||
int s, i, n, j = 0;
|
||||
|
||||
(void) edit;
|
||||
|
||||
if (saved_macros_loaded)
|
||||
{
|
||||
j = macro_exists (k);
|
||||
if (j < 0)
|
||||
return 0;
|
||||
}
|
||||
tmp = concat_dir_and_file (mc_config_get_cache_path (), EDIT_TEMP_FILE);
|
||||
g = fopen (tmp, "w");
|
||||
g_free (tmp);
|
||||
if (!g)
|
||||
{
|
||||
edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open temp file")));
|
||||
return 1;
|
||||
}
|
||||
f = edit_open_macro_file ("r");
|
||||
if (!f)
|
||||
{
|
||||
edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot open macro file")));
|
||||
fclose (g);
|
||||
return 1;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
n = fscanf (f, ("key '%d 0': "), &s);
|
||||
if (!n || n == EOF)
|
||||
break;
|
||||
n = 0;
|
||||
while (fscanf (f, "%lu %d, ", ¯o[n].command, ¯o[n].ch))
|
||||
n++;
|
||||
{
|
||||
int ret;
|
||||
ret = fscanf (f, ";\n");
|
||||
}
|
||||
if (s != k)
|
||||
{
|
||||
fprintf (g, ("key '%d 0': "), s);
|
||||
for (i = 0; i < n; i++)
|
||||
fprintf (g, "%lu %d, ", macro[i].command, macro[i].ch);
|
||||
fprintf (g, ";\n");
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
fclose (g);
|
||||
tmp = concat_dir_and_file (mc_config_get_cache_path (), EDIT_TEMP_FILE);
|
||||
tmp2 = concat_dir_and_file (mc_config_get_data_path (), EDIT_MACRO_FILE);
|
||||
if (rename (tmp, tmp2) == -1)
|
||||
{
|
||||
edit_error_dialog (_("Delete macro"), get_sys_error (_("Cannot overwrite macro file")));
|
||||
g_free (tmp);
|
||||
g_free (tmp2);
|
||||
return 1;
|
||||
}
|
||||
g_free (tmp);
|
||||
g_free (tmp2);
|
||||
|
||||
if (saved_macros_loaded)
|
||||
memmove (saved_macro + j, saved_macro + j + 1, sizeof (int) * (MAX_MACROS - j - 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on success */
|
||||
|
||||
static int
|
||||
@ -1498,117 +1378,345 @@ edit_save_as_cmd (WEdit * edit)
|
||||
|
||||
/* {{{ Macro stuff starts here */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
edit_macro_comparator (gconstpointer *macro1, gconstpointer *macro2)
|
||||
{
|
||||
const macros_t *m1 = (const macros_t *) macro1;
|
||||
const macros_t *m2 = (const macros_t *) macro2;
|
||||
|
||||
return m1->hotkey - m2->hotkey;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 0 on error */
|
||||
|
||||
int
|
||||
edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n)
|
||||
static void
|
||||
edit_macro_sort_by_hotkey (WEdit *edit)
|
||||
{
|
||||
FILE *f;
|
||||
int s, i;
|
||||
|
||||
edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
|
||||
s = editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1);
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
if (s)
|
||||
{
|
||||
if (edit_delete_macro (edit, s))
|
||||
return 0;
|
||||
f = edit_open_macro_file ("a+");
|
||||
if (f)
|
||||
{
|
||||
fprintf (f, ("key '%d 0': "), s);
|
||||
for (i = 0; i < n; i++)
|
||||
fprintf (f, "%lu %d, ", macro[i].command, macro[i].ch);
|
||||
fprintf (f, ";\n");
|
||||
fclose (f);
|
||||
if (saved_macros_loaded)
|
||||
{
|
||||
for (i = 0; i < MAX_MACROS && saved_macro[i]; i++);
|
||||
saved_macro[i] = s;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
edit_error_dialog (_("Save macro"), get_sys_error (_("Cannot open macro file")));
|
||||
}
|
||||
return 0;
|
||||
if (macros_list == NULL || macros_list->len == 0)
|
||||
return;
|
||||
g_array_sort (macros_list, (GCompareFunc) edit_macro_comparator);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
edit_get_macro (WEdit * edit, int hotkey, const macros_t **macros, guint *indx)
|
||||
{
|
||||
const macros_t *array_start = &g_array_index (macros_list, struct macros_t, 0);
|
||||
macros_t *result;
|
||||
macros_t search_macro;
|
||||
search_macro.hotkey = hotkey;
|
||||
result = bsearch (&search_macro, macros_list->data, macros_list->len,
|
||||
sizeof (macros_t), (GCompareFunc) edit_macro_comparator);
|
||||
|
||||
if (result != NULL && result->macro != NULL)
|
||||
{
|
||||
*indx = (result - array_start);
|
||||
*macros = result;
|
||||
return TRUE;
|
||||
}
|
||||
*indx = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns FALSE on error */
|
||||
|
||||
static gboolean
|
||||
edit_delete_macro (WEdit * edit, int hotkey)
|
||||
{
|
||||
mc_config_t *macros_config = NULL;
|
||||
const char *section_name = "editor";
|
||||
gchar *macros_fname;
|
||||
guint indx;
|
||||
char keyname[8];
|
||||
|
||||
const macros_t *macros = NULL;
|
||||
|
||||
/* clear array of actions for current hotkey */
|
||||
while (edit_get_macro (edit, hotkey, ¯os, &indx))
|
||||
{
|
||||
if (macros->macro != NULL)
|
||||
g_array_free (macros->macro, TRUE);
|
||||
macros = NULL;
|
||||
g_array_remove_index (macros_list, indx);
|
||||
edit_macro_sort_by_hotkey (edit);
|
||||
}
|
||||
|
||||
macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL);
|
||||
macros_config = mc_config_init (macros_fname);
|
||||
g_free (macros_fname);
|
||||
|
||||
if (macros_config == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_snprintf (keyname, sizeof (keyname), "%i", hotkey);
|
||||
while (mc_config_del_key (macros_config, section_name, keyname));
|
||||
mc_config_save_file (macros_config, NULL);
|
||||
mc_config_deinit (macros_config);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
edit_delete_macro_cmd (WEdit * edit)
|
||||
{
|
||||
int command;
|
||||
int hotkey;
|
||||
|
||||
command = editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), 1);
|
||||
hotkey = editcmd_dialog_raw_key_query (_("Delete macro"), _("Press macro hotkey:"), 1);
|
||||
|
||||
if (command != 0)
|
||||
edit_delete_macro (edit, command);
|
||||
if (hotkey != 0 && !edit_delete_macro (edit, hotkey))
|
||||
message (D_ERROR, _("Delete macro"), _("Macro not deleted"));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** return 0 on error */
|
||||
|
||||
int
|
||||
edit_load_macro_cmd (WEdit * edit, struct macro macro[], int *n, int k)
|
||||
/** returns FALSE on error */
|
||||
gboolean
|
||||
edit_execute_macro (WEdit * edit, int hotkey)
|
||||
{
|
||||
FILE *f;
|
||||
int s, i = 0, found = 0;
|
||||
gboolean res = FALSE;
|
||||
|
||||
if (hotkey != 0)
|
||||
{
|
||||
const macros_t *macros;
|
||||
guint indx;
|
||||
|
||||
if (edit_get_macro (edit, hotkey, ¯os, &indx) &&
|
||||
macros->macro != NULL && macros->macro->len != 0)
|
||||
{
|
||||
guint i;
|
||||
|
||||
edit->force |= REDRAW_PAGE;
|
||||
|
||||
for (i = 0; i < macros->macro->len; i++)
|
||||
{
|
||||
const macro_action_t *m_act;
|
||||
|
||||
m_act = &g_array_index (macros->macro, struct macro_action_t, i);
|
||||
edit_execute_cmd (edit, m_act->action, m_act->ch);
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
edit_update_screen (edit);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** returns FALSE on error */
|
||||
gboolean
|
||||
edit_store_macro_cmd (WEdit * edit)
|
||||
{
|
||||
int i;
|
||||
int hotkey;
|
||||
char keyname[8];
|
||||
GString *marcros_string;
|
||||
mc_config_t *macros_config = NULL;
|
||||
const char *section_name = "editor";
|
||||
gchar *macros_fname;
|
||||
GArray *macros; /* current macro */
|
||||
int tmp_act;
|
||||
gboolean have_macro = FALSE;
|
||||
|
||||
hotkey = editcmd_dialog_raw_key_query (_("Save macro"), _("Press the macro's new hotkey:"), 1);
|
||||
if (hotkey == ESC_CHAR)
|
||||
return FALSE;
|
||||
|
||||
tmp_act = keybind_lookup_keymap_command (editor_map, hotkey);
|
||||
|
||||
/* return FALSE if try assign macro into restricted hotkeys */
|
||||
if (tmp_act == CK_Begin_Record_Macro
|
||||
|| tmp_act == CK_End_Record_Macro
|
||||
|| tmp_act == CK_Begin_End_Macro)
|
||||
return FALSE;
|
||||
|
||||
edit_delete_macro (edit, hotkey);
|
||||
|
||||
macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL);
|
||||
macros_config = mc_config_init (macros_fname);
|
||||
g_free (macros_fname);
|
||||
|
||||
if (macros_config == NULL)
|
||||
return FALSE;
|
||||
|
||||
g_snprintf (keyname, sizeof (keyname), "%i", hotkey);
|
||||
|
||||
marcros_string = g_string_sized_new (250);
|
||||
|
||||
edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
|
||||
|
||||
macros = g_array_new (TRUE, FALSE, sizeof (macro_action_t));
|
||||
for (i = 0; i < macro_index; i++)
|
||||
{
|
||||
macro_action_t m_act;
|
||||
const char *action_name;
|
||||
|
||||
action_name = keybind_lookup_actionname (record_macro_buf[i].action);
|
||||
|
||||
if (action_name == NULL)
|
||||
break;
|
||||
|
||||
m_act.action = record_macro_buf[i].action;
|
||||
m_act.ch = record_macro_buf[i].ch;
|
||||
g_array_append_val (macros, m_act);
|
||||
have_macro = TRUE;
|
||||
g_string_append_printf (marcros_string, "%s:%i;", action_name, (int) record_macro_buf[i].ch);
|
||||
}
|
||||
if (have_macro)
|
||||
{
|
||||
macros_t macro;
|
||||
macro.hotkey = hotkey;
|
||||
macro.macro = macros;
|
||||
g_array_append_val (macros_list, macro);
|
||||
mc_config_set_string (macros_config, section_name, keyname, marcros_string->str);
|
||||
}
|
||||
else
|
||||
mc_config_del_key (macros_config, section_name, keyname);
|
||||
|
||||
edit_macro_sort_by_hotkey (edit);
|
||||
|
||||
g_string_free (marcros_string, TRUE);
|
||||
mc_config_save_file (macros_config, NULL);
|
||||
mc_config_deinit (macros_config);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
gboolean
|
||||
edit_repeat_macro_cmd (WEdit * edit)
|
||||
{
|
||||
int i, j;
|
||||
char *f;
|
||||
long count_repeat;
|
||||
char *error = NULL;
|
||||
|
||||
f = input_dialog (_("Repeat last commands"), _("Repeat times:"), NULL, "1");
|
||||
if (f == NULL || *f == '\0')
|
||||
{
|
||||
g_free (f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
count_repeat = strtol (f, &error, 0);
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
g_free (f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (f);
|
||||
|
||||
edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
|
||||
|
||||
edit->force |= REDRAW_PAGE;
|
||||
for (j = 0; j < count_repeat; j++)
|
||||
for (i = 0; i < macro_index; i++)
|
||||
edit_execute_cmd (edit, record_macro_buf[i].action, record_macro_buf[i].ch);
|
||||
edit_update_screen (edit);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** return FALSE on error */
|
||||
|
||||
gboolean
|
||||
edit_load_macro_cmd (WEdit * edit)
|
||||
{
|
||||
mc_config_t *macros_config = NULL;
|
||||
gchar **profile_keys, **keys;
|
||||
gchar **values, **curr_values;
|
||||
gsize len, values_len;
|
||||
const char *section_name = "editor";
|
||||
gchar *macros_fname;
|
||||
int hotkey;
|
||||
|
||||
(void) edit;
|
||||
|
||||
if (saved_macros_loaded)
|
||||
if (macro_exists (k) < 0)
|
||||
return 0;
|
||||
macros_fname = g_build_filename (mc_config_get_path (), MC_MACRO_FILE, NULL);
|
||||
macros_config = mc_config_init (macros_fname);
|
||||
g_free (macros_fname);
|
||||
|
||||
f = edit_open_macro_file ("r");
|
||||
if (f != NULL)
|
||||
if (macros_config == NULL)
|
||||
return FALSE;
|
||||
|
||||
profile_keys = keys = mc_config_get_keys (macros_config, section_name, &len);
|
||||
while (*profile_keys != NULL)
|
||||
{
|
||||
struct macro dummy;
|
||||
do
|
||||
gboolean have_macro;
|
||||
GArray *macros;
|
||||
macros_t macro;
|
||||
|
||||
macros = g_array_new (TRUE, FALSE, sizeof (macro_action_t));
|
||||
|
||||
curr_values = values = mc_config_get_string_list (macros_config, section_name,
|
||||
*profile_keys, &values_len);
|
||||
hotkey = strtol (*profile_keys, NULL, 0);
|
||||
have_macro = FALSE;
|
||||
while (*curr_values != NULL && *curr_values[0] != '\0')
|
||||
{
|
||||
int u;
|
||||
u = fscanf (f, ("key '%d 0': "), &s);
|
||||
if (!u || u == EOF)
|
||||
break;
|
||||
if (!saved_macros_loaded)
|
||||
saved_macro[i++] = s;
|
||||
if (!found)
|
||||
char **macro_pair = NULL;
|
||||
|
||||
macro_pair = g_strsplit (*curr_values, ":", 2);
|
||||
|
||||
if (macro_pair != NULL)
|
||||
{
|
||||
*n = 0;
|
||||
while (*n < MAX_MACRO_LENGTH
|
||||
&& 2 == fscanf (f, "%lu %d, ", ¯o[*n].command, ¯o[*n].ch))
|
||||
(*n)++;
|
||||
macro_action_t m_act;
|
||||
if (macro_pair [0] == NULL || macro_pair [0][0] == '\0')
|
||||
m_act.action = 0;
|
||||
else
|
||||
{
|
||||
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')
|
||||
m_act.ch = -1;
|
||||
else
|
||||
{
|
||||
m_act.ch = strtol (macro_pair [1], NULL, 0);
|
||||
g_free (macro_pair[1]);
|
||||
macro_pair[1] = NULL;
|
||||
}
|
||||
if (m_act.action != 0)
|
||||
{
|
||||
/* a shell command */
|
||||
if ((m_act.action / CK_Pipe_Block (0)) == 1)
|
||||
{
|
||||
m_act.action = CK_Pipe_Block (0) + (m_act.ch > 0 ? m_act.ch : 0);
|
||||
m_act.ch = -1;
|
||||
}
|
||||
g_array_append_val (macros, m_act);
|
||||
have_macro = TRUE;
|
||||
}
|
||||
g_strfreev (macro_pair);
|
||||
macro_pair = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (2 == fscanf (f, "%lu %d, ", &dummy.command, &dummy.ch));
|
||||
}
|
||||
{
|
||||
int ret;
|
||||
ret = fscanf (f, ";\n");
|
||||
}
|
||||
if (s == k)
|
||||
found = 1;
|
||||
curr_values++;
|
||||
}
|
||||
while (!found || !saved_macros_loaded);
|
||||
if (!saved_macros_loaded)
|
||||
if (have_macro)
|
||||
{
|
||||
saved_macro[i] = 0;
|
||||
saved_macros_loaded = 1;
|
||||
macro.hotkey = hotkey;
|
||||
macro.macro = macros;
|
||||
g_array_append_val (macros_list, macro);
|
||||
}
|
||||
fclose (f);
|
||||
return found;
|
||||
profile_keys++;
|
||||
g_strfreev (values);
|
||||
}
|
||||
else
|
||||
edit_error_dialog (_("Load macro"), get_sys_error (_("Cannot open macro file")));
|
||||
return 0;
|
||||
g_strfreev (keys);
|
||||
mc_config_deinit (macros_config);
|
||||
edit_macro_sort_by_hotkey (edit);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* }}} Macro stuff starts here */
|
||||
/* }}} Macro stuff end here */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on success */
|
||||
@ -1634,7 +1742,6 @@ edit_save_confirm_cmd (WEdit * edit)
|
||||
return edit_save_cmd (edit);
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on success */
|
||||
|
||||
@ -3046,7 +3153,7 @@ edit_begin_end_macro_cmd (WEdit * edit)
|
||||
/* edit is a pointer to the widget */
|
||||
if (edit)
|
||||
{
|
||||
unsigned long command = edit->macro_i < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro;
|
||||
unsigned long command = macro_index < 0 ? CK_Begin_Record_Macro : CK_End_Record_Macro;
|
||||
edit_execute_key_command (edit, command, -1);
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ status_string (WEdit * edit, char *s, int w)
|
||||
"%c%c%c%c %3ld %5ld/%ld %6ld/%ld %s %s",
|
||||
edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-',
|
||||
edit->modified ? 'M' : '-',
|
||||
edit->macro_i < 0 ? '-' : 'R',
|
||||
macro_index < 0 ? '-' : 'R',
|
||||
edit->overwrite == 0 ? '-' : 'O',
|
||||
edit->curs_col + edit->over_col,
|
||||
edit->curs_line + 1,
|
||||
@ -161,7 +161,7 @@ status_string (WEdit * edit, char *s, int w)
|
||||
"[%c%c%c%c] %2ld L:[%3ld+%2ld %3ld/%3ld] *(%-4ld/%4ldb) %s %s",
|
||||
edit->mark1 != edit->mark2 ? (edit->column_highlight ? 'C' : 'B') : '-',
|
||||
edit->modified ? 'M' : '-',
|
||||
edit->macro_i < 0 ? '-' : 'R',
|
||||
macro_index < 0 ? '-' : 'R',
|
||||
edit->overwrite == 0 ? '-' : 'O',
|
||||
edit->curs_col + edit->over_col,
|
||||
edit->start_line + 1,
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "lib/charsets.h" /* convert_from_input_c() */
|
||||
|
||||
#include "edit-impl.h"
|
||||
#include "edit-widget.h" /* edit->macro_i */
|
||||
#include "edit-widget.h" /* WEdit */
|
||||
#include "editcmd_dialogs.h"
|
||||
|
||||
#include "src/keybind-defaults.h" /* keybind_lookup_keymap_command() */
|
||||
|
@ -315,7 +315,9 @@ edit_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
cb_ret_t ret = MSG_NOT_HANDLED;
|
||||
|
||||
/* The user may override the access-keys for the menu bar. */
|
||||
if (edit_translate_key (e, parm, &cmd, &ch))
|
||||
if (macro_index == -1 && edit_execute_macro (e, parm))
|
||||
ret = MSG_HANDLED;
|
||||
else if (edit_translate_key (e, parm, &cmd, &ch))
|
||||
{
|
||||
edit_execute_key_command (e, cmd, ch);
|
||||
edit_update_screen (e);
|
||||
|
18
src/main.c
18
src/main.c
@ -133,6 +133,9 @@ int print_last_revert = FALSE;
|
||||
/* If set, then print to the given file the last directory we were at */
|
||||
char *last_wd_string = NULL;
|
||||
|
||||
/* index to record_macro_buf[], -1 if not recording a macro */
|
||||
int macro_index = -1;
|
||||
|
||||
/*** file scope macro definitions ****************************************************************/
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
@ -482,6 +485,8 @@ main (int argc, char *argv[])
|
||||
|
||||
load_keymap_defs ();
|
||||
|
||||
macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t));
|
||||
|
||||
tty_init_colors (mc_args__disable_colors, mc_args__force_colors);
|
||||
|
||||
{
|
||||
@ -587,6 +592,19 @@ main (int argc, char *argv[])
|
||||
|
||||
done_key ();
|
||||
|
||||
if (macros_list != NULL)
|
||||
{
|
||||
guint i;
|
||||
macros_t *macros;
|
||||
for (i = 0; i < macros_list->len; i++)
|
||||
{
|
||||
macros = &g_array_index (macros_list, struct macros_t, i);
|
||||
if (macros != NULL && macros->macro != NULL)
|
||||
g_array_free (macros->macro, FALSE);
|
||||
}
|
||||
g_array_free (macros_list, TRUE);
|
||||
}
|
||||
|
||||
str_uninit_strings ();
|
||||
|
||||
g_free (mc_run_param0);
|
||||
|
22
src/main.h
22
src/main.h
@ -9,6 +9,8 @@
|
||||
|
||||
/*** typedefs(not structures) and defined constants **********************************************/
|
||||
|
||||
#define MAX_MACRO_LENGTH 1024
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/* run mode and params */
|
||||
@ -26,9 +28,23 @@ enum cd_enum
|
||||
cd_exact
|
||||
};
|
||||
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct macro_action_t
|
||||
{
|
||||
unsigned long action;
|
||||
int ch;
|
||||
} macro_action_t;
|
||||
|
||||
typedef struct macros_t
|
||||
{
|
||||
int hotkey;
|
||||
GArray *macro;
|
||||
} macros_t;
|
||||
|
||||
/* macro stuff */
|
||||
struct macro_action_t record_macro_buf[MAX_MACRO_LENGTH];
|
||||
|
||||
struct mc_fhl_struct;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
@ -81,6 +97,10 @@ extern const char *mc_prompt;
|
||||
extern char *mc_sysconfig_dir;
|
||||
extern char *mc_share_data_dir;
|
||||
|
||||
GArray *macros_list;
|
||||
/* index to record_macro_buf[], -1 if not recording a macro */
|
||||
extern int macro_index;
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
#ifdef HAVE_SUBSHELL_SUPPORT
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user