mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
Merge branch '323_editor_macros'
* 323_editor_macros: (mc_config_init): don't drop file name if file is not exist. added examples added rules for misc/macros.d/*. in the process of installation, example scripts will be copied into share/mc/examples/macros.d added check for instruction "#interactive" in the script. if the external script contain #interactive then do show prompt. changed mcedit.1.in Fix cursor position after execution of external script. Changed engine of external macros execution added a new action "Record and Repeat commands", added menu entry (Record/Repeat actions) for this. Removed unneeded menu entries. Added lookup_key_by_code, now parameter is string. Ticket #323 (reimplimented editor macros)
This commit is contained in:
commit
0cfbe19d96
@ -529,6 +529,7 @@ contrib/dist/prototype
|
||||
|
||||
misc/Makefile
|
||||
misc/skins/Makefile
|
||||
misc/macros.d/Makefile
|
||||
misc/mc.ext
|
||||
|
||||
src/Makefile
|
||||
|
@ -97,38 +97,116 @@ or
|
||||
.BR "Escape Tab" )
|
||||
completes the word under the cursor using the words used earlier in the
|
||||
file.
|
||||
.SH MACRO
|
||||
.PP
|
||||
To define a macro, press
|
||||
.B Ctrl\-R
|
||||
and then type out the keys you want to be executed. Press
|
||||
.B Ctrl\-R
|
||||
again when finished. You can then assign the macro to any key you like
|
||||
by pressing that key. The macro is executed when you press
|
||||
.B Ctrl\-A
|
||||
and then the assigned key. The macro is also executed if you press
|
||||
Meta, Ctrl, or Esc and the assigned key, provided that the key is not
|
||||
used for any other function. The macro commands are stored in the file
|
||||
.BR ~/.local/share/mc/mcedit/mcedit.macros .
|
||||
Do NOT edit this file if you are going to use macros again in the same
|
||||
editing session, because
|
||||
.B mcedit
|
||||
caches macro key defines in memory.
|
||||
.B mcedit
|
||||
now overwrites a macro if a macro with the same key already exists,
|
||||
so you won't have to edit this file. You will also have to restart
|
||||
other running editors for macros to take effect.
|
||||
.P
|
||||
.B F19
|
||||
will format C, C++, Java or HTML code when it is highlighted. An executable
|
||||
file called
|
||||
.B ~/.local/share/mc/mcedit/edit.indent.rc
|
||||
will be created for you from the default template. Feel free to edit it
|
||||
if you need.
|
||||
again when finished. The macro can be assigned to any key by pressing that key.
|
||||
The macro is executed when you press the assigned key.
|
||||
.PP
|
||||
.B C\-p
|
||||
will run ispell on a block of text in a similar way. The script file
|
||||
will be called
|
||||
.BR ~/.local/share/mc/mcedit/edit.spell.rc .
|
||||
The macro commands are stored in section
|
||||
.B [editor]
|
||||
it the file
|
||||
.BR ~/.local/share/mc/mc.macros .
|
||||
.PP
|
||||
External scripts (filters) can be assigned into the any hotkey by edit
|
||||
.B mc.macros
|
||||
like following:
|
||||
.PP
|
||||
.nf
|
||||
[editor]
|
||||
ctrl\-W=EditPipeBlock:25;
|
||||
.fi
|
||||
.PP
|
||||
This means that ctrl\-W hotkey initiates the
|
||||
.I EditPipeBlock(25)
|
||||
action, next the editor handler translates this into execution of
|
||||
.B ~/.local/share/mc/mcedit/macros.d/macro.25.sh
|
||||
shell script.
|
||||
.PP
|
||||
External scripts stored into
|
||||
.B ~/.local/share/mc/mcedit/macros.d/
|
||||
directory and must named
|
||||
.B macro.XXXX.sh
|
||||
where
|
||||
.B XXXX
|
||||
is the number from 0 to 9999.
|
||||
See
|
||||
.B Menu File Edit
|
||||
for more detail about format of the script.
|
||||
.PP
|
||||
Following macro definition and directives can be used:
|
||||
.TP
|
||||
.I #interactive
|
||||
If this directive is set, then script starts in subshell.
|
||||
.TP
|
||||
.I %c
|
||||
The cursor column position number.
|
||||
.TP
|
||||
.I %i
|
||||
The indent of blank space, equal the cursor column.
|
||||
.TP
|
||||
.I %y
|
||||
The syntax type of current file.
|
||||
.TP
|
||||
.I %b
|
||||
The block file name.
|
||||
.TP
|
||||
.I %f
|
||||
The current file name.
|
||||
.TP
|
||||
.I %n
|
||||
Only the current file name without extension.
|
||||
.TP
|
||||
.I %x
|
||||
The extension of current file name.
|
||||
.TP
|
||||
.I %d
|
||||
The current directory name.
|
||||
.TP
|
||||
.I %F
|
||||
The current file in the unselected panel.
|
||||
.TP
|
||||
.I %D
|
||||
The directory name of the unselected panel.
|
||||
.TP
|
||||
.I %t
|
||||
The currently tagged files.
|
||||
.TP
|
||||
.I %T
|
||||
The tagged files in the unselected panel.
|
||||
.TP
|
||||
.I %u
|
||||
and
|
||||
.I %U
|
||||
Similar to the
|
||||
.I %t
|
||||
and
|
||||
.I %T
|
||||
macros, but in addition the files are untagged. You can use this macro
|
||||
only once per menu file entry or extension file entry, because next time
|
||||
there will be no tagged files.
|
||||
.TP
|
||||
.I %s
|
||||
and
|
||||
.I %S
|
||||
The selected files: The tagged files if there are any. Otherwise the
|
||||
current file.
|
||||
.PP
|
||||
Feel free to edit this files, if you need.
|
||||
Here is a sample external script:
|
||||
.PP
|
||||
.nf
|
||||
l comment selection
|
||||
TMPFILE=`mktemp ${MC_TMPDIR:\-/tmp}/up.XXXXXX` || exit 1
|
||||
echo #if 0 > $TMPFILE
|
||||
cat %b >> $TMPFILE
|
||||
echo #endif >> $TMPFILE
|
||||
cat $TMPFILE > %b
|
||||
rm \-f $TMPFILE
|
||||
.fi
|
||||
.PP
|
||||
If some keys don't work, you can use
|
||||
.B Learn Keys
|
||||
|
@ -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"
|
||||
|
||||
@ -65,9 +66,9 @@
|
||||
#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_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},
|
||||
@ -133,6 +134,7 @@ static name_keymap_t command_names[] = {
|
||||
{"EditUserMenu", CK_User_Menu},
|
||||
{"EditBeginRecordMacro", CK_Begin_Record_Macro},
|
||||
{"EditEndRecordMacro", CK_End_Record_Macro},
|
||||
{"EditBeginEndRepeat", CK_Begin_End_Repeat},
|
||||
{"EditDeleteMacro", CK_Delete_Macro},
|
||||
{"EditToggleBookmark", CK_Toggle_Bookmark},
|
||||
{"EditFlushBookmarks", CK_Flush_Bookmarks},
|
||||
@ -185,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},
|
||||
@ -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)
|
||||
{
|
||||
|
@ -189,19 +189,21 @@
|
||||
#define CK_Paragraph_Down_Alt_Highlight 671
|
||||
|
||||
/* X clipboard operations */
|
||||
#define CK_XStore 701
|
||||
#define CK_XCut 702
|
||||
#define CK_XPaste 703
|
||||
#define CK_Selection_History 704
|
||||
#define CK_XStore 701
|
||||
#define CK_XCut 702
|
||||
#define CK_XPaste 703
|
||||
#define CK_Selection_History 704
|
||||
|
||||
#define CK_Shell 801
|
||||
#define CK_Shell 801
|
||||
|
||||
/* C-x or similar */
|
||||
#define CK_Ext_Mode 820
|
||||
#define CK_Ext_Mode 820
|
||||
|
||||
#define CK_Insert_Literal 851
|
||||
#define CK_Execute_Macro 852
|
||||
#define CK_Begin_End_Macro 853
|
||||
#define CK_Insert_Literal 851
|
||||
#define CK_Begin_End_Macro 853
|
||||
#define CK_Begin_End_Repeat 854
|
||||
#define CK_Begin_Record_Repeat 855
|
||||
#define CK_End_Record_Repeat 856
|
||||
|
||||
/* help */
|
||||
#define CK_HelpHelp 1001
|
||||
@ -498,18 +500,8 @@
|
||||
#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) (1000+(i))
|
||||
#define SHELL_COMMANDS_i {"/edit.indent.rc", "/edit.spell.rc", /* and so on */ 0 }
|
||||
#define CK_Macro(i) (2000+(i))
|
||||
#define CK_Pipe_Block(i) (10000+(i))
|
||||
#define CK_Macro(i) (20000+(i))
|
||||
#define CK_Last_Macro CK_Macro(0x7FFF)
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
@ -544,6 +536,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);
|
||||
|
||||
|
@ -112,14 +112,12 @@ mc_config_init (const gchar * ini_path)
|
||||
g_free (mc_config);
|
||||
return NULL;
|
||||
}
|
||||
if (!ini_path || !exist_file (ini_path))
|
||||
{
|
||||
if (ini_path == NULL)
|
||||
return mc_config;
|
||||
}
|
||||
|
||||
if (!mc_stat (ini_path, &st) && st.st_size)
|
||||
if (exist_file (ini_path) && mc_stat (ini_path, &st) == 0 && st.st_size != 0)
|
||||
{
|
||||
/* file present and not empty */
|
||||
/* file exists and not empty */
|
||||
g_key_file_load_from_file (mc_config->handle, ini_path, G_KEY_FILE_KEEP_COMMENTS, NULL);
|
||||
}
|
||||
|
||||
|
@ -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"},
|
||||
|
181
lib/tty/key.c
181
lib/tty/key.c
@ -251,6 +251,13 @@ typedef struct SelectList
|
||||
struct SelectList *next;
|
||||
} SelectList;
|
||||
|
||||
typedef enum KeySortType
|
||||
{
|
||||
KEY_NOSORT = 0,
|
||||
KEY_SORTBYNAME,
|
||||
KEY_SORTBYCODE
|
||||
} KeySortType;
|
||||
|
||||
#ifdef __QNXNTO__
|
||||
typedef int (*ph_dv_f) (void *, void *);
|
||||
typedef int (*ph_ov_f) (void *);
|
||||
@ -524,11 +531,11 @@ static Display *x11_display;
|
||||
static Window x11_window;
|
||||
#endif /* HAVE_TEXTMODE_X11_SUPPORT */
|
||||
|
||||
static const size_t key_name_conv_tab_size = sizeof (key_name_conv_tab) /
|
||||
sizeof (key_name_conv_tab[0]) - 1;
|
||||
static KeySortType has_been_sorted = KEY_NOSORT;
|
||||
|
||||
static const key_code_name_t *key_name_conv_tab_sorted[sizeof (key_name_conv_tab) /
|
||||
sizeof (key_name_conv_tab[0]) - 1];
|
||||
static const size_t key_conv_tab_size = G_N_ELEMENTS (key_name_conv_tab) - 1;
|
||||
|
||||
static const key_code_name_t *key_conv_tab_sorted[G_N_ELEMENTS (key_name_conv_tab) - 1];
|
||||
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1144,7 +1151,7 @@ s_dispose (SelectList * sel)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
key_code_name_comparator (const void *p1, const void *p2)
|
||||
key_code_comparator_by_name (const void *p1, const void *p2)
|
||||
{
|
||||
const key_code_name_t *n1 = *(const key_code_name_t **) p1;
|
||||
const key_code_name_t *n2 = *(const key_code_name_t **) p2;
|
||||
@ -1154,21 +1161,37 @@ key_code_name_comparator (const void *p1, const void *p2)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static inline void
|
||||
sort_key_name_conv_tab (void)
|
||||
static int
|
||||
key_code_comparator_by_code (const void *p1, const void *p2)
|
||||
{
|
||||
static gboolean has_been_sorted = FALSE;
|
||||
const key_code_name_t *n1 = *(const key_code_name_t **) p1;
|
||||
const key_code_name_t *n2 = *(const key_code_name_t **) p2;
|
||||
|
||||
if (!has_been_sorted)
|
||||
return n1->code - n2->code;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static inline void
|
||||
sort_key_conv_tab (enum KeySortType type_sort)
|
||||
{
|
||||
if (has_been_sorted != type_sort)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < key_name_conv_tab_size; i++)
|
||||
key_name_conv_tab_sorted[i] = &key_name_conv_tab[i];
|
||||
for (i = 0; i < key_conv_tab_size; i++)
|
||||
key_conv_tab_sorted[i] = &key_name_conv_tab[i];
|
||||
|
||||
qsort (key_name_conv_tab_sorted,
|
||||
key_name_conv_tab_size, sizeof (key_name_conv_tab_sorted[0]),
|
||||
&key_code_name_comparator);
|
||||
has_been_sorted = TRUE;
|
||||
if (type_sort == KEY_SORTBYNAME)
|
||||
{
|
||||
qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
|
||||
&key_code_comparator_by_name);
|
||||
}
|
||||
else if (type_sort == KEY_SORTBYCODE)
|
||||
{
|
||||
qsort (key_conv_tab_sorted, key_conv_tab_size, sizeof (key_conv_tab_sorted[0]),
|
||||
&key_code_comparator_by_code);
|
||||
}
|
||||
has_been_sorted = type_sort;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1189,15 +1212,14 @@ lookup_keyname (const char *name, int *idx)
|
||||
return (int) name[0];
|
||||
}
|
||||
|
||||
sort_key_name_conv_tab ();
|
||||
sort_key_conv_tab (KEY_SORTBYNAME);
|
||||
|
||||
res = bsearch (&keyp, key_name_conv_tab_sorted,
|
||||
key_name_conv_tab_size,
|
||||
sizeof (key_name_conv_tab_sorted[0]), key_code_name_comparator);
|
||||
res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size,
|
||||
sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_name);
|
||||
|
||||
if (res != NULL)
|
||||
{
|
||||
*idx = (int) (res - (key_code_name_t **) key_name_conv_tab_sorted);
|
||||
*idx = (int) (res - (key_code_name_t **) key_conv_tab_sorted);
|
||||
return (*res)->code;
|
||||
}
|
||||
}
|
||||
@ -1206,6 +1228,33 @@ lookup_keyname (const char *name, int *idx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
lookup_keycode (const long code, int *idx)
|
||||
{
|
||||
if (code != 0)
|
||||
{
|
||||
const key_code_name_t key = { code, NULL, NULL, NULL };
|
||||
const key_code_name_t *keyp = &key;
|
||||
key_code_name_t **res;
|
||||
|
||||
sort_key_conv_tab (KEY_SORTBYCODE);
|
||||
|
||||
res = bsearch (&keyp, key_conv_tab_sorted, key_conv_tab_size,
|
||||
sizeof (key_conv_tab_sorted[0]), key_code_comparator_by_code);
|
||||
|
||||
if (res != NULL)
|
||||
{
|
||||
*idx = (int) (res - (key_code_name_t **) key_conv_tab_sorted);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
*idx = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1413,12 +1462,12 @@ lookup_key (const char *name, char **label)
|
||||
|
||||
if (use_meta != -1)
|
||||
{
|
||||
g_string_append (s, key_name_conv_tab_sorted[use_meta]->shortcut);
|
||||
g_string_append (s, key_conv_tab_sorted[use_meta]->shortcut);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
if (use_ctrl != -1)
|
||||
{
|
||||
g_string_append (s, key_name_conv_tab_sorted[use_ctrl]->shortcut);
|
||||
g_string_append (s, key_conv_tab_sorted[use_ctrl]->shortcut);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
if (use_shift != -1)
|
||||
@ -1427,21 +1476,21 @@ lookup_key (const char *name, char **label)
|
||||
g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k));
|
||||
else
|
||||
{
|
||||
g_string_append (s, key_name_conv_tab_sorted[use_shift]->shortcut);
|
||||
g_string_append (s, key_conv_tab_sorted[use_shift]->shortcut);
|
||||
g_string_append_c (s, '-');
|
||||
g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut);
|
||||
g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
|
||||
}
|
||||
}
|
||||
else if (k < 128)
|
||||
{
|
||||
if ((k >= 'A') || (lc_index < 0)
|
||||
|| (key_name_conv_tab_sorted[lc_index]->shortcut == NULL))
|
||||
|| (key_conv_tab_sorted[lc_index]->shortcut == NULL))
|
||||
g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) k));
|
||||
else
|
||||
g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut);
|
||||
g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
|
||||
}
|
||||
else if ((lc_index != -1) && (key_name_conv_tab_sorted[lc_index]->shortcut != NULL))
|
||||
g_string_append (s, key_name_conv_tab_sorted[lc_index]->shortcut);
|
||||
else if ((lc_index != -1) && (key_conv_tab_sorted[lc_index]->shortcut != NULL))
|
||||
g_string_append (s, key_conv_tab_sorted[lc_index]->shortcut);
|
||||
else
|
||||
g_string_append_c (s, (gchar) g_ascii_tolower ((gchar) key));
|
||||
|
||||
@ -1470,6 +1519,82 @@ lookup_key (const char *name, char **label)
|
||||
return (long) k;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
char *
|
||||
lookup_key_by_code (const int keycode)
|
||||
{
|
||||
/* code without modifier */
|
||||
unsigned int k = keycode & ~KEY_M_MASK;
|
||||
/* modifier */
|
||||
unsigned int mod = keycode & KEY_M_MASK;
|
||||
|
||||
int use_meta = -1;
|
||||
int use_ctrl = -1;
|
||||
int use_shift = -1;
|
||||
int key_idx = -1;
|
||||
|
||||
GString *s;
|
||||
int idx;
|
||||
|
||||
s = g_string_sized_new (8);
|
||||
|
||||
if (lookup_keycode (k, &key_idx) || (k > 0 && k < 256))
|
||||
{
|
||||
if (mod & KEY_M_ALT)
|
||||
{
|
||||
if (lookup_keycode (KEY_M_ALT, &idx))
|
||||
{
|
||||
use_meta = idx;
|
||||
g_string_append (s, key_conv_tab_sorted[use_meta]->name);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
}
|
||||
if (mod & KEY_M_CTRL)
|
||||
{
|
||||
/* non printeble chars like a CTRL-[A..Z] */
|
||||
if (k < 32)
|
||||
k += 64;
|
||||
|
||||
if (lookup_keycode (KEY_M_CTRL, &idx))
|
||||
{
|
||||
use_ctrl = idx;
|
||||
g_string_append (s, key_conv_tab_sorted[use_ctrl]->name);
|
||||
g_string_append_c (s, '-');
|
||||
}
|
||||
}
|
||||
if (mod & KEY_M_SHIFT)
|
||||
{
|
||||
if (lookup_keycode (KEY_M_ALT, &idx))
|
||||
{
|
||||
use_shift = idx;
|
||||
if (k < 127)
|
||||
g_string_append_c (s, (gchar) g_ascii_toupper ((gchar) k));
|
||||
else
|
||||
{
|
||||
g_string_append (s, key_conv_tab_sorted[use_shift]->name);
|
||||
g_string_append_c (s, '-');
|
||||
g_string_append (s, key_conv_tab_sorted[key_idx]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (k < 128)
|
||||
{
|
||||
if ((k >= 'A') || (key_idx < 0)
|
||||
|| (key_conv_tab_sorted[key_idx]->name == NULL))
|
||||
g_string_append_c (s, (gchar) k);
|
||||
else
|
||||
g_string_append (s, key_conv_tab_sorted[key_idx]->name);
|
||||
}
|
||||
else if ((key_idx != -1) && (key_conv_tab_sorted[key_idx]->name != NULL))
|
||||
g_string_append (s, key_conv_tab_sorted[key_idx]->name);
|
||||
else
|
||||
g_string_append_c (s, (gchar) keycode);
|
||||
}
|
||||
|
||||
return g_string_free (s, s->len == 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Return TRUE on success, FALSE on error.
|
||||
|
@ -68,7 +68,7 @@ void init_key_input_fd (void);
|
||||
void done_key (void);
|
||||
|
||||
long lookup_key (const char *name, char **label);
|
||||
|
||||
char *lookup_key_by_code (const int keycode);
|
||||
/* mouse support */
|
||||
int tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block);
|
||||
gboolean is_idle (void);
|
||||
|
@ -1,6 +1,6 @@
|
||||
## Process this file with automake to create Makefile.in.
|
||||
|
||||
SUBDIRS = skins syntax
|
||||
SUBDIRS = macros.d skins syntax
|
||||
|
||||
LIBFILES_OUT = mc.ext
|
||||
|
||||
@ -23,7 +23,6 @@ LIBFILES_CONST = \
|
||||
mc.menu \
|
||||
mc.menu.sr
|
||||
|
||||
|
||||
CLEANFILES = $(SCRIPTS_OUT)
|
||||
|
||||
cfgdir = $(sysconfdir)/@PACKAGE@
|
||||
|
11
misc/macros.d/Makefile.am
Normal file
11
misc/macros.d/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
macrodir = $(pkgdatadir)/examples/macros.d
|
||||
|
||||
macro_DATA = \
|
||||
macro.0.sh \
|
||||
macro.1.sh \
|
||||
macro.3.sh \
|
||||
macro.4.sh \
|
||||
macro.5.sh
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(macro_DATA)
|
6
misc/macros.d/macro.0.sh
Normal file
6
misc/macros.d/macro.0.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#interactive
|
||||
m make
|
||||
TMPFILE=`mktemp ${MC_TMPDIR:-/tmp}/up.XXXXXX` || exit 1
|
||||
make 2> $TMPFILE
|
||||
mcedit $TMPFILE
|
||||
rm $TMPFILE
|
5
misc/macros.d/macro.1.sh
Normal file
5
misc/macros.d/macro.1.sh
Normal file
@ -0,0 +1,5 @@
|
||||
u Upper case selection
|
||||
TMPFILE=`mktemp ${MC_TMPDIR:-/tmp}/up.XXXXXX` || exit 1
|
||||
cat %b > $TMPFILE
|
||||
cat $TMPFILE| sed 's/\(.*\)/\U\1/' >%b
|
||||
rm -f $TMPFILE
|
5
misc/macros.d/macro.2.sh
Normal file
5
misc/macros.d/macro.2.sh
Normal file
@ -0,0 +1,5 @@
|
||||
l Lower case selection
|
||||
TMPFILE=`mktemp ${MC_TMPDIR:-/tmp}/up.XXXXXX` || exit 1
|
||||
cat %b > $TMPFILE
|
||||
cat $TMPFILE| sed 's/\(.*\)/\L\1/' >%b
|
||||
rm -f $TMPFILE
|
5
misc/macros.d/macro.3.sh
Normal file
5
misc/macros.d/macro.3.sh
Normal file
@ -0,0 +1,5 @@
|
||||
S Sort selection
|
||||
TMPFILE=`mktemp ${MC_TMPDIR:-/tmp}/up.XXXXXX` || exit 1
|
||||
cat %b > $TMPFILE
|
||||
cat $TMPFILE| sort >%b
|
||||
rm -f $TMPFILE
|
2
misc/macros.d/macro.4.sh
Normal file
2
misc/macros.d/macro.4.sh
Normal file
@ -0,0 +1,2 @@
|
||||
t Indent `C' formatter
|
||||
indent -gnu -fc1 -i4 -bli0 -nut -bap -l100 %b 1>/dev/null 2> %e
|
41
misc/macros.d/macro.5.sh
Normal file
41
misc/macros.d/macro.5.sh
Normal file
@ -0,0 +1,41 @@
|
||||
s snippets
|
||||
a=`cat %b`
|
||||
if [ "$a" = "fori" ]; then
|
||||
echo "for (i = 0; i _; i++)" > %b
|
||||
fi
|
||||
if [ "$a" = "ife" ]; then
|
||||
cat <<EOF > %b
|
||||
if ( )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
if [ "$a" = "GPL" ]; then
|
||||
cat >>%b <<EOF
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
EOF
|
||||
fi
|
||||
if [ "$a" = "type" ]; then
|
||||
cat <<EOF > %b
|
||||
typedef struct {
|
||||
;
|
||||
} ?;
|
||||
EOF
|
||||
fi
|
@ -160,6 +160,8 @@ EditFindDefinition = alt-enter
|
||||
EditLoadPrevFile = alt-minus
|
||||
EditLoadNextFile = alt-plus
|
||||
|
||||
EditBeginEndRepeat =
|
||||
|
||||
SelectCodepage = alt-e
|
||||
|
||||
[viewer]
|
||||
|
@ -157,6 +157,8 @@ EditFindDefinition = alt-enter
|
||||
EditLoadPrevFile = alt-minus
|
||||
EditLoadNextFile = alt-plus
|
||||
|
||||
EditBeginEndRepeat =
|
||||
|
||||
SelectCodepage = alt-e
|
||||
|
||||
EditExtMode = ctrl-x
|
||||
|
9
misc/mc.macros
Normal file
9
misc/mc.macros
Normal file
@ -0,0 +1,9 @@
|
||||
#see ./macros.d/*
|
||||
[editor]
|
||||
#autocomplete "ife", "GPL", "fori"
|
||||
ctrl-space=EditWordLeftHighlight:-1;EditPipeBlock:5;EditUnmark:-1;
|
||||
#run make
|
||||
ctrl-f9=EditPipeBlock:0;
|
||||
#indent current selection
|
||||
meta-ctrl-F=EditPipeBlock:4;
|
||||
|
@ -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;
|
||||
|
||||
@ -221,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);
|
||||
@ -295,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);
|
||||
@ -311,9 +306,10 @@ 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);
|
||||
gboolean edit_repeat_macro_cmd (WEdit * edit);
|
||||
|
||||
int edit_copy_to_X_buf_cmd (WEdit * edit);
|
||||
int edit_cut_to_X_buf_cmd (WEdit * edit);
|
||||
@ -321,8 +317,9 @@ 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);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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,9 +165,7 @@ 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 +554,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 */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1663,46 +1658,30 @@ 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--;
|
||||
}
|
||||
|
||||
/*** 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;
|
||||
long curs;
|
||||
long start_mark, end_mark;
|
||||
struct stat status;
|
||||
|
||||
block_file = concat_dir_and_file (mc_config_get_cache_path (), EDIT_BLOCK_FILE);
|
||||
|
||||
curs = edit->curs1;
|
||||
nomark = eval_marks (edit, &start_mark, &end_mark);
|
||||
if (nomark == 0)
|
||||
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;
|
||||
@ -1724,14 +1703,13 @@ user_menu (WEdit * edit)
|
||||
if (fd != NULL)
|
||||
fclose (fd);
|
||||
}
|
||||
edit_cursor_move (edit, curs - edit->curs1);
|
||||
edit_refresh_cmd (edit);
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
|
||||
g_free (block_file);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
@ -2225,7 +2203,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 +2244,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 +3381,35 @@ 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_Record_Repeat
|
||||
|| (macro_index < 0 && (command == CK_Begin_End_Macro || command == CK_Begin_End_Repeat)))
|
||||
{
|
||||
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 (macro_index != -1)
|
||||
{
|
||||
edit->force |= REDRAW_COMPLETELY;
|
||||
edit_save_macro_cmd (edit, edit->macro, edit->macro_i);
|
||||
edit->macro_i = -1;
|
||||
return;
|
||||
if (command == CK_End_Record_Macro || command == CK_Begin_End_Macro)
|
||||
{
|
||||
edit_store_macro_cmd (edit);
|
||||
macro_index = -1;
|
||||
return;
|
||||
}
|
||||
else if (command == CK_End_Record_Repeat || command == CK_Begin_End_Repeat)
|
||||
{
|
||||
edit_repeat_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)
|
||||
@ -4115,7 +4104,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);
|
||||
@ -4135,12 +4124,12 @@ 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;
|
||||
case CK_Begin_End_Repeat:
|
||||
edit_begin_end_repeat_cmd (edit);
|
||||
break;
|
||||
case CK_Ext_Mode:
|
||||
edit->extmod = 1;
|
||||
break;
|
||||
@ -4149,15 +4138,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 / 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)
|
||||
|
@ -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,42 +1378,88 @@ 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 (void)
|
||||
{
|
||||
FILE *f;
|
||||
int s, i;
|
||||
if (macros_list != NULL && macros_list->len != 0)
|
||||
g_array_sort (macros_list, (GCompareFunc) edit_macro_comparator);
|
||||
}
|
||||
|
||||
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)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
|
||||
(void) edit;
|
||||
|
||||
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)
|
||||
{
|
||||
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")));
|
||||
*indx = (result - array_start);
|
||||
*macros = result;
|
||||
return TRUE;
|
||||
}
|
||||
return 0;
|
||||
*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;
|
||||
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 ();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (macros_config == NULL)
|
||||
return FALSE;
|
||||
|
||||
keyname = lookup_key_by_code (hotkey);
|
||||
while (mc_config_del_key (macros_config, section_name, keyname))
|
||||
;
|
||||
g_free (keyname);
|
||||
mc_config_save_file (macros_config, NULL);
|
||||
mc_config_deinit (macros_config);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -1541,74 +1467,260 @@ edit_save_macro_cmd (WEdit * edit, struct macro macro[], int n)
|
||||
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;
|
||||
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;
|
||||
char *keyname = NULL;
|
||||
|
||||
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_data_path (), MC_MACRO_FILE, (char *) NULL);
|
||||
macros_config = mc_config_init (macros_fname);
|
||||
g_free (macros_fname);
|
||||
|
||||
if (macros_config == NULL)
|
||||
return FALSE;
|
||||
|
||||
edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
|
||||
|
||||
marcros_string = g_string_sized_new (250);
|
||||
macros = g_array_new (TRUE, FALSE, sizeof (macro_action_t));
|
||||
|
||||
keyname = lookup_key_by_code (hotkey);
|
||||
|
||||
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);
|
||||
|
||||
g_free (keyname);
|
||||
edit_macro_sort_by_hotkey ();
|
||||
|
||||
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:"), MC_HISTORY_EDIT_REPEAT, NULL);
|
||||
if (f == NULL || *f == '\0')
|
||||
{
|
||||
g_free (f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
count_repeat = strtol (f, &error, 0);
|
||||
|
||||
if (*error != '\0')
|
||||
{
|
||||
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_data_path (), MC_MACRO_FILE, (char *) 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 = lookup_key (*profile_keys, NULL);
|
||||
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 ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* }}} Macro stuff starts here */
|
||||
/* }}} Macro stuff end here */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on success */
|
||||
@ -1634,7 +1746,6 @@ edit_save_confirm_cmd (WEdit * edit)
|
||||
return edit_save_cmd (edit);
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** returns 1 on success */
|
||||
|
||||
@ -2741,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;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -3026,27 +3025,26 @@ 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)
|
||||
{
|
||||
/* edit is a pointer to the widget */
|
||||
if (edit)
|
||||
if (edit != NULL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
edit_begin_end_repeat_cmd (WEdit * edit)
|
||||
{
|
||||
/* edit is a pointer to the widget */
|
||||
if (edit != NULL)
|
||||
{
|
||||
unsigned long command = macro_index < 0 ? CK_Begin_Record_Repeat : CK_End_Record_Repeat;
|
||||
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() */
|
||||
|
@ -168,12 +168,9 @@ create_command_menu (void)
|
||||
entries = g_list_append (entries, menu_separator_create ());
|
||||
entries =
|
||||
g_list_append (entries,
|
||||
menu_entry_create (_("&Start record macro"), CK_Begin_Record_Macro));
|
||||
entries =
|
||||
g_list_append (entries,
|
||||
menu_entry_create (_("Finis&h record macro..."), CK_End_Record_Macro));
|
||||
entries = g_list_append (entries, menu_entry_create (_("&Execute macro..."), CK_Execute_Macro));
|
||||
menu_entry_create (_("&Start/Stop record macro"), CK_Begin_End_Macro));
|
||||
entries = g_list_append (entries, menu_entry_create (_("Delete macr&o..."), CK_Delete_Macro));
|
||||
entries = g_list_append (entries, menu_entry_create (_("Record/Repeat &actions"), CK_Begin_End_Repeat));
|
||||
entries = g_list_append (entries, menu_separator_create ());
|
||||
entries =
|
||||
g_list_append (entries, menu_entry_create (_("'ispell' s&pell check"), CK_Pipe_Block (1)));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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 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 (!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;
|
||||
@ -860,16 +868,27 @@ user_menu_cmd (struct WEdit *edit_widget)
|
||||
int selected, old_patterns;
|
||||
Listbox *listbox;
|
||||
gboolean res = FALSE;
|
||||
gboolean interactive = FALSE;
|
||||
|
||||
if (!vfs_current_is_local ())
|
||||
{
|
||||
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);
|
||||
@ -936,6 +955,9 @@ user_menu_cmd (struct WEdit *edit_widget)
|
||||
{
|
||||
if (*p == '#')
|
||||
{
|
||||
/* show prompt if first line of external script is #interactive */
|
||||
if (selected_entry >= 0 && strncmp (p, "#interactive", 12) == 0)
|
||||
interactive = TRUE;
|
||||
/* A commented menu entry */
|
||||
accept_entry = 1;
|
||||
}
|
||||
@ -1006,25 +1028,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], interactive);
|
||||
res = TRUE;
|
||||
}
|
||||
|
||||
|
@ -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 **);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define MC_HISTORY_EDIT_GOTO_LINE "mc.edit.goto-line"
|
||||
#define MC_HISTORY_EDIT_SORT "mc.edit.sort"
|
||||
#define MC_HISTORY_EDIT_PASTE_EXTCMD "mc.edit.paste-extcmd"
|
||||
#define MC_HISTORY_EDIT_REPEAT "mc.edit.repeat-action"
|
||||
|
||||
#define MC_HISTORY_FM_VIEW_FILE "mc.fm.view-file"
|
||||
#define MC_HISTORY_FM_MKDIR "mc.fm.mkdir"
|
||||
|
@ -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 */
|
||||
|
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
|
||||
|
Loading…
Reference in New Issue
Block a user