Ticket #212 (User defined hotkeys)

created structs:
    struct name_key_map_t
    struct key_config_t
    global_key_map_t
    add lookup_action
    replace editor key map struct to global_key_map_t
    add main_map screen_map
    replace command CK_* to src/cmddef.h
    add mc.keymap
    fix misc/Makefile.am
    add x_keymap
    add more commands

Signed-off-by: Ilia Maslakov <il.smind@google.com>
This commit is contained in:
Ilia Maslakov 2009-07-05 15:04:42 +00:00 committed by Ilia Maslakov
parent 13dd762089
commit 10fd8660c1
17 changed files with 1223 additions and 178 deletions

View File

@ -10,6 +10,8 @@
#include "../src/search/search.h" /* mc_search_t */
#include "edit-impl.h"
#include "../src/keybind.h"
#define MAX_MACRO_LENGTH 1024
#define N_LINE_CACHES 32
@ -32,11 +34,6 @@ struct syntax_rule {
unsigned char border;
};
typedef struct edit_key_map_type {
long key;
long command;
} edit_key_map_type;
struct WEdit {
Widget widget;
@ -132,9 +129,9 @@ struct WEdit {
struct macro macro[MAX_MACRO_LENGTH];
/* user map stuff */
const edit_key_map_type *user_map;
const edit_key_map_type *ext_map;
GIConv converter;
const global_key_map_t *user_map;
const global_key_map_t *ext_map;
/* line break */
LineBreaks lb;

View File

@ -44,7 +44,7 @@
#include "edit-impl.h"
#include "editlock.h"
#include "edit-widget.h"
#include "editcmddef.h"
#include "../src/cmddef.h"
#include "usermap.h"
#include "../src/tty/color.h" /* EDITOR_NORMAL_COLOR */
@ -720,6 +720,13 @@ edit_purge_widget (WEdit *edit)
edit->macro_i = -1; /* not recording a macro */
}
static void
edit_set_keymap (WEdit *edit)
{
edit->user_map = (global_key_map_t *) editor_keymap->data;
}
#define space_width 1
/*
@ -829,7 +836,7 @@ edit_init (WEdit *edit, int lines, int columns, const char *filename,
edit_move_to_line (edit, line - 1);
}
edit_load_user_map(edit);
edit_set_keymap (edit);
return edit;
}

View File

@ -64,7 +64,7 @@
#include "../edit/edit-impl.h"
#include "../edit/edit.h"
#include "../edit/editlock.h"
#include "../edit/editcmddef.h"
#include "../src/cmddef.h"
#include "../edit/edit-widget.h"
#include "../edit/editcmd_dialogs.h"
#include "../edit/etags.h"

View File

@ -44,10 +44,10 @@
#include "edit-impl.h"
#include "edit-widget.h" /* edit->macro_i */
#include "editcmd_dialogs.h"
#include "editcmddef.h" /* list of commands */
#include "../src/tty/tty.h" /* keys */
#include "../src/tty/key.h" /* KEY_M_SHIFT */
#include "../src/cmddef.h" /* list of commands */
#include "../src/charsets.h" /* convert_from_input_c() */
#include "../src/main.h" /* display_codepage */
@ -57,7 +57,7 @@
* Ordinary translations. Note that the keys listed first take priority
* when the key is assigned to more than one command.
*/
static const edit_key_map_type cooledit_key_map[] = {
static const global_key_map_t cooledit_key_map[] = {
{ ALT ('b'), CK_Match_Bracket },
{ ALT ('m'), CK_Mail },
{ XCTRL ('f'), CK_Save_Block },
@ -69,7 +69,7 @@ static const edit_key_map_type cooledit_key_map[] = {
{ 0, 0 }
};
static const edit_key_map_type emacs_key_map[] = {
static const global_key_map_t emacs_key_map[] = {
{ ALT ('$'), CK_Pipe_Block (1) }, /* spell check */
{ ALT ('b'), CK_Word_Left },
{ ALT ('f'), CK_Word_Right },
@ -90,7 +90,7 @@ static const edit_key_map_type emacs_key_map[] = {
{ 0, 0 }
};
static const edit_key_map_type common_key_map[] = {
static const global_key_map_t common_key_map[] = {
{ '\n', CK_Enter },
{ '\t', CK_Tab },
@ -207,7 +207,7 @@ static const edit_key_map_type common_key_map[] = {
/*
* Translate the keycode into either 'command' or 'char_for_insertion'.
* 'command' is one of the editor commands from editcmddef.h.
* 'command' is one of the editor commands from cmddef.h.
*/
int
edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
@ -218,7 +218,7 @@ edit_translate_key (WEdit *edit, long x_key, int *cmd, int *ch)
int extmod = 0;
int c;
const edit_key_map_type *key_map = NULL;
const global_key_map_t *key_map = NULL;
switch (edit_key_emulation) {
case EDIT_KEY_EMULATION_NORMAL:
key_map = cooledit_key_map;

View File

@ -54,6 +54,9 @@
#include "../src/main.h" /* drop_menus */
#include "../src/learn.h" /* learn_keys */
#include "edit-widget.h"
#include "../src/cmddef.h"
static void
menu_cmd (int command)
{

View File

@ -43,7 +43,7 @@
#include "edit-impl.h"
#include "edit-widget.h"
#include "editcmddef.h" /* list of commands */
#include "../src/cmddef.h" /* list of commands */
#include "usermap.h"
#include "../src/wtools.h"
@ -333,10 +333,10 @@ split_line(char *str)
static void
keymap_add(GArray *keymap, int key, int cmd)
{
edit_key_map_type new_one, *map;
global_key_map_t new_one, *map;
guint i;
map = &(g_array_index(keymap, edit_key_map_type, 0));
map = &(g_array_index(keymap, global_key_map_t, 0));
for (i = 0; i < keymap->len; i++) {
if (map[i].key == key) {
map[i].command = cmd;
@ -583,8 +583,8 @@ load_user_keymap(config_t *cfg, const char *file)
{0, 0}
};
cfg->keymap = g_array_new(TRUE, FALSE, sizeof(edit_key_map_type));
cfg->ext_keymap = g_array_new(TRUE, FALSE, sizeof(edit_key_map_type));
cfg->keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
cfg->ext_keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
if (!parse_file(cfg, file, cmd)) {
return FALSE;
@ -629,8 +629,8 @@ edit_load_user_map(WEdit *edit)
}
}
edit->user_map = (edit_key_map_type *) cfg.keymap->data;
edit->ext_map = (edit_key_map_type *) cfg.ext_keymap->data;
edit->user_map = (global_key_map_t *) cfg.keymap->data;
edit->ext_map = (global_key_map_t *) cfg.ext_keymap->data;
memcpy(edit->labels, cfg.labels, sizeof(edit->labels));
g_free(file);

View File

@ -14,6 +14,7 @@ LIBFILES_CONST = \
edit.spell.rc \
mc.lib \
filehighlight.ini \
mc.keymap \
mc.menu

44
misc/mc.keymap Normal file
View File

@ -0,0 +1,44 @@
[editor]
XStore = ctrl g
XPaste = ctrl v
XCut = ctrl x
Delete-Line = ctrl y
[main]
FindCmd = alt f7
ViewOtherCmd = ctrl o
[panel:xmap]
[panel]
PanelStartSearch = ctrl s
PanelMarkFile = ins
PanelMoveDown = down
PanelMoveUp = up
PanelMoveLeft = left
PanelMoveRight = right
PanelPrevPage = pgup
PanelNextPage = pgdn
PanelDoEnter = enter
PanelChdirOtherPanel = alt o
PanelChdirToReadlink = alt l
PanelViewSimple = shift F3
PanelEditNew = F14
PanelCopyLocal = F15
PanelRenameLocal = F16
PanelDeleteLocal = F18
PanelReverseSelection = alt *
PanelSelect = plus
PanelUnselect = minus
PanelCtrlNextPage = ctrl pgdn
PanelCtrlPrevPage = ctrl pgup
PanelDirectoryHistoryList = alt h
PanelDirectoryHistoryNext = alt u
PanelDirectoryHistoryPrev = alt y
PanelGotoBottomFile = alt j
PanelGotoMiddleFile = alt r
PanelSyncOtherPanel = alt i
PanelGotoTopFile = alt g
PanelSetPanelEncoding = ctrl t

View File

@ -71,6 +71,7 @@ SRCS = args.c args.h achown.c achown.h background.c background.h \
user.h util.c util.h utilunix.c vfsdummy.h \
widget.c widget.h wtools.c wtools.h unixcompat.h \
ecs.h ecs.c \
keybind.c keybind.h cmddef.h \
strutil.h strutil.c strutilascii.c strutil8bit.c strutilutf8.c \
search/search.h strescape.c strescape.h

313
src/cmddef.h Normal file
View File

@ -0,0 +1,313 @@
/** \file
* \brief Header: editor constants
*/
#ifndef MC_CMD_DEF_H
#define MC_CMD_DEF_H
/** \todo In the distant future, keyboards will be invented with a
* separate key for each one of these commands *sigh*
*/
/* special commands */
#define CK_Insert_Char -1
#define CK_Ignore_Key 0
/* cursor movements */
#define CK_BackSpace 1
#define CK_Delete 2
#define CK_Enter 3
#define CK_Page_Up 4
#define CK_Page_Down 5
#define CK_Left 6
#define CK_Right 7
#define CK_Word_Left 8
#define CK_Word_Right 9
#define CK_Up 10
#define CK_Down 11
#define CK_Home 12
#define CK_End 13
#define CK_Tab 14
#define CK_Undo 15
#define CK_Beginning_Of_Text 16
#define CK_End_Of_Text 17
#define CK_Scroll_Up 18
#define CK_Scroll_Down 19
#define CK_Return 20
#define CK_Begin_Page 21
#define CK_End_Page 22
#define CK_Delete_Word_Left 23
#define CK_Delete_Word_Right 24
#define CK_Paragraph_Up 25
#define CK_Paragraph_Down 26
/* file commands */
#define CK_Save 101
#define CK_Load 102
#define CK_New 103
#define CK_Save_As 104
#define CK_Load_Prev_File 111
#define CK_Load_Next_File 112
#define CK_Load_Syntax_File 121
#define CK_Load_Menu_File 122
/* block commands */
#define CK_Mark 201
#define CK_Copy 202
#define CK_Move 203
#define CK_Remove 204
#define CK_Unmark 206
#define CK_Save_Block 207
#define CK_Column_Mark 208
/* search and replace */
#define CK_Find 301
#define CK_Find_Again 302
#define CK_Replace 303
#define CK_Replace_Again 304
#define CK_Complete_Word 305
/* debugger commands */
#define CK_Debug_Start 350
#define CK_Debug_Stop 351
#define CK_Debug_Toggle_Break 352
#define CK_Debug_Clear 353
#define CK_Debug_Next 354
#define CK_Debug_Step 355
#define CK_Debug_Back_Trace 356
#define CK_Debug_Continue 357
#define CK_Debug_Enter_Command 358
#define CK_Debug_Until_Curser 359
/* misc */
#define CK_Insert_File 401
#define CK_Exit 402
#define CK_Toggle_Insert 403
#define CK_Help 404
#define CK_Date 405
#define CK_Refresh 406
#define CK_Goto 407
#define CK_Delete_Line 408
#define CK_Delete_To_Line_End 409
#define CK_Delete_To_Line_Begin 410
#define CK_Man_Page 411
#define CK_Sort 412
#define CK_Mail 413
#define CK_Cancel 414
#define CK_Complete 415
#define CK_Paragraph_Format 416
#define CK_Util 417
#define CK_Type_Load_Python 418
#define CK_Find_File 419
#define CK_Ctags 420
#define CK_Match_Bracket 421
#define CK_Terminal 422
#define CK_Terminal_App 423
#define CK_ExtCmd 424
#define CK_User_Menu 425
#define CK_Find_Definition 426
/* application control */
#define CK_Save_Desktop 451
#define CK_New_Window 452
#define CK_Cycle 453
#define CK_Menu 454
#define CK_Save_And_Quit 455
#define CK_Run_Another 456
#define CK_Check_Save_And_Quit 457
#define CK_Maximize 458
#define CK_Toggle_Tab_TWS 470
#define CK_Toggle_Syntax 480
#define CK_Toggle_Line_State 490
/* macro */
#define CK_Begin_Record_Macro 501
#define CK_End_Record_Macro 502
#define CK_Delete_Macro 503
/* book mark */
#define CK_Toggle_Bookmark 550
#define CK_Flush_Bookmarks 551
#define CK_Next_Bookmark 552
#define CK_Prev_Bookmark 553
/* highlight commands */
#define CK_Page_Up_Highlight 604
#define CK_Page_Down_Highlight 605
#define CK_Left_Highlight 606
#define CK_Right_Highlight 607
#define CK_Word_Left_Highlight 608
#define CK_Word_Right_Highlight 609
#define CK_Up_Highlight 610
#define CK_Down_Highlight 611
#define CK_Home_Highlight 612
#define CK_End_Highlight 613
#define CK_Beginning_Of_Text_Highlight 614
#define CK_End_Of_Text_Highlight 615
#define CK_Begin_Page_Highlight 616
#define CK_End_Page_Highlight 617
#define CK_Scroll_Up_Highlight 618
#define CK_Scroll_Down_Highlight 619
#define CK_Paragraph_Up_Highlight 620
#define CK_Paragraph_Down_Highlight 621
/* alt highlight commands */
#define CK_Page_Up_Alt_Highlight 654
#define CK_Page_Down_Alt_Highlight 655
#define CK_Left_Alt_Highlight 656
#define CK_Right_Alt_Highlight 657
#define CK_Word_Left_Alt_Highlight 658
#define CK_Word_Right_Alt_Highlight 659
#define CK_Up_Alt_Highlight 660
#define CK_Down_Alt_Highlight 661
#define CK_Home_Alt_Highlight 662
#define CK_End_Alt_Highlight 663
#define CK_Beginning_Of_Text_Alt_Highlight 664
#define CK_End_Of_Text_Alt_Highlight 665
#define CK_Begin_Page_Alt_Highlight 666
#define CK_End_Page_Alt_Highlight 667
#define CK_Scroll_Up_Alt_Highlight 668
#define CK_Scroll_Down_Alt_Highlight 669
#define CK_Paragraph_Up_Alt_Highlight 670
#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_Shell 801
/* C-x or similar */
#define CK_Ext_Mode 820
#define CK_Select_Codepage 850
#define CK_Insert_Literal 851
#define CK_Execute_Macro 852
#define CK_Begin_End_Macro 853
#define CK_ChmodCmd 7001
#define CK_ChownAdvancedCmd 7002
#define CK_ChownCmd 7003
#define CK_CompareDirsCmd 7004
#define CK_ConfigureBox 7005
#define CK_ConfigureVfs 7006
#define CK_ConfirmBox 7007
#define CK_CopyCmd 7008
#define CK_CopyCurrentPathname 7009
#define CK_CopyOtherPathname 7010
#define CK_DeleteCmd 7011
#define CK_DirsizesCmd 7012
#define CK_DisplayBitsBox 7013
#define CK_EditCmd 7014
#define CK_EditMcMenuCmd 7015
#define CK_EditSymlinkCmd 7016
#define CK_EditSyntaxCmd 7017
#define CK_EditUserMenuCmd 7018
#define CK_ExternalPanelize 7020
#define CK_FilterCmd 7021
#define CK_FilteredViewCmd 7022
#define CK_FindCmd 7023
#define CK_FishlinkCmd 7024
#define CK_FtplinkCmd 7025
#define CK_HistoryCmd 7026
#define CK_InfoCmd 7027
#define CK_JobsCmd 7028
#define CK_LayoutCmd 7029
#define CK_LearnKeys 7030
#define CK_LinkCmd 7031
#define CK_ListingCmd 7033
#define CK_MenuLastSelectedCmd 7034
#define CK_MkdirCmd 7035
#define CK_QuickCdCmd 7036
#define CK_QuickChdirCmd 7037
#define CK_QuickViewCmd 7038
#define CK_RenCmd 7039
#define CK_RereadCmd 7040
#define CK_ReselectVfs 7041
#define CK_ReverseSelectionCmd 7043
#define CK_SaveSetupCmd 7044
#define CK_SelectCmd 7045
#define CK_SingleDirsizeCmd 7046
#define CK_SuspendCmd 7047
#define CK_SwapCmd 7048
#define CK_SymlinkCmd 7049
#define CK_ToggleListingCmd 7050
#define CK_TreeCmd 7051
#define CK_UndeleteCmd 7052
#define CK_UnselectCmd 7053
#define CK_UserFileMenuCmd 7054
#define CK_ViewCmd 7055
#define CK_ViewFileCmd 7056
#define CK_ViewOtherCmd 7057
#define CK_QuietQuitCmd 7058
#define CK_CopyCurrentTagged 7059
#define CK_CopyCurrentReadlink 7060
#define CK_CopyOtherReadlink 7061
#define CK_AddHotlist 7062
#define CK_StartExtCmd 7063
#define CK_QuitCmd 7064
#define CK_CopyOtherTarget 7065
#define CK_CopyOthertReadlink 7066
#define CK_PanelChdirOtherPanel 8001
#define CK_PanelChdirToReadlink 8002
#define CK_PanelCmdCopyLocal 8003
#define CK_PanelCmdDeleteLocal 8004
#define CK_PanelCmdDoEnter 8005
#define CK_PanelCmdEditNew 8006
#define CK_PanelCmdRenameLocal 8007
#define CK_PanelCmdReverseSelection 8008
#define CK_PanelCmdSelect 8009
#define CK_PanelCmdUnselect 8010
#define CK_PanelCmdViewSimple 8011
#define CK_PanelCtrlNextPage 8012
#define CK_PanelCtrlPrevPage 8013
#define CK_PanelDirectoryHistoryList 8014
#define CK_PanelDirectoryHistoryNext 8015
#define CK_PanelDirectoryHistoryPrev 8016
#define CK_PanelGotoBottomFile 8017
#define CK_PanelGotoMiddleFile 8018
#define CK_PanelGotoTopFile 8019
#define CK_PanelMarkFile 8020
#define CK_PanelMoveDown 8021
#define CK_PanelMoveEnd 8022
#define CK_PanelMoveHome 8023
#define CK_PanelMoveUp 8024
#define CK_PanelMoveLeft 8025
#define CK_PanelMoveRight 8026
#define CK_PanelNextPage 8027
#define CK_PanelPrevPage 8028
#define CK_PanelSetPanelEncoding 8029
#define CK_PanelStartSearch 8030
#define CK_PanelSyncOtherPanel 8031
/*
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_Last_Macro CK_Macro(0x7FFF)
#else
#define CK_User_Command(i) ((i) | (1 << 16))
#define IS_USER_COMMAND(i) ((i) & (1 << 16))
#define CK_Macro(i) ((i) | (1 << 17))
#define IS_MACRO_COMMAND(i) ((i) & (1 << 17))
#endif /* MC_CMD_DEF_H */

318
src/keybind.c Normal file
View File

@ -0,0 +1,318 @@
/* File management GUI for the text mode edition
*
* Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
* 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
*
* Written by: 2005 Vitja Makarov
* 2009 Ilia Maslakov
*
* The copy code was based in GNU's cp, and was written by:
* Torbjorn Granlund, David MacKenzie, and Jim Meyering.
*
* The move code was based in GNU's mv, and was written by:
* Mike Parker and David MacKenzie.
*
* Janne Kukonlehto added much error recovery to them for being used
* in an interactive program.
*
* 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.
*/
#include <config.h>
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "global.h"
#include "cmddef.h" /* list of commands */
#include "tty/win.h"
#include "tty/key.h" /* KEY_M_ */
#include "tty/tty.h" /* keys */
#include "wtools.h"
#include "keybind.h"
static const name_key_map_t command_names[] = {
{"No-Command", CK_Ignore_Key},
{"Ignore-Key", CK_Ignore_Key},
{"BackSpace", CK_BackSpace},
{"Delete", CK_Delete},
{"Enter", CK_Enter},
{"Page-Up", CK_Page_Up},
{"Page-Down", CK_Page_Down},
{"Left", CK_Left},
{"Right", CK_Right},
{"Word-Left", CK_Word_Left},
{"Word-Right", CK_Word_Right},
{"Up", CK_Up},
{"Down", CK_Down},
{"Home", CK_Home},
{"End", CK_End},
{"Tab", CK_Tab},
{"Undo", CK_Undo},
{"Beginning-Of-Text", CK_Beginning_Of_Text},
{"End-Of-Text", CK_End_Of_Text},
{"Scroll-Up", CK_Scroll_Up},
{"Scroll-Down", CK_Scroll_Down},
{"Return", CK_Return},
{"Begin-Page", CK_Begin_Page},
{"End-Page", CK_End_Page},
{"Delete-Word-Left", CK_Delete_Word_Left},
{"Delete-Word-Right", CK_Delete_Word_Right},
{"Paragraph-Up", CK_Paragraph_Up},
{"Paragraph-Down", CK_Paragraph_Down},
{"Save", CK_Save},
{"Load", CK_Load},
{"New", CK_New},
{"Save-as", CK_Save_As},
{"Mark", CK_Mark},
{"Copy", CK_Copy},
{"Move", CK_Move},
{"Remove", CK_Remove},
{"Unmark", CK_Unmark},
{"Save-Block", CK_Save_Block},
{"Column-Mark", CK_Column_Mark},
{"Find", CK_Find},
{"Find-Again", CK_Find_Again},
{"Replace", CK_Replace},
{"Replace-Again", CK_Replace_Again},
{"Complete-Word", CK_Complete_Word},
{"Debug-Start", CK_Debug_Start},
{"Debug-Stop", CK_Debug_Stop},
{"Debug-Toggle-Break", CK_Debug_Toggle_Break},
{"Debug-Clear", CK_Debug_Clear},
{"Debug-Next", CK_Debug_Next},
{"Debug-Step", CK_Debug_Step},
{"Debug-Back-Trace", CK_Debug_Back_Trace},
{"Debug-Continue", CK_Debug_Continue},
{"Debug-Enter-Command", CK_Debug_Enter_Command},
{"Debug-Until-Curser", CK_Debug_Until_Curser},
{"Insert-File", CK_Insert_File},
{"Exit", CK_Exit},
{"Toggle-Insert", CK_Toggle_Insert},
{"Help", CK_Help},
{"Date", CK_Date},
{"Refresh", CK_Refresh},
{"Goto", CK_Goto},
{"Delete-Line", CK_Delete_Line},
{"Delete-To-Line-End", CK_Delete_To_Line_End},
{"Delete-To-Line-Begin", CK_Delete_To_Line_Begin},
{"Man-Page", CK_Man_Page},
{"Sort", CK_Sort},
{"Mail", CK_Mail},
{"Cancel", CK_Cancel},
{"Complete", CK_Complete},
{"Paragraph-Format", CK_Paragraph_Format},
{"Util", CK_Util},
{"Type-Load-Python", CK_Type_Load_Python},
{"Find-File", CK_Find_File},
{"Ctags", CK_Ctags},
{"Match-Bracket", CK_Match_Bracket},
{"Terminal", CK_Terminal},
{"Terminal-App", CK_Terminal_App},
{"ExtCmd", CK_ExtCmd},
{"User-Menu", CK_User_Menu},
{"Save-Desktop", CK_Save_Desktop},
{"New-Window", CK_New_Window},
{"Cycle", CK_Cycle},
{"Menu", CK_Menu},
{"Save-And-Quit", CK_Save_And_Quit},
{"Run-Another", CK_Run_Another},
{"Check-Save-And-Quit", CK_Check_Save_And_Quit},
{"Maximize", CK_Maximize},
{"Begin-Record-Macro", CK_Begin_Record_Macro},
{"End-Record-Macro", CK_End_Record_Macro},
{"Delete-Macro", CK_Delete_Macro},
{"Toggle-Bookmark", CK_Toggle_Bookmark},
{"Flush-Bookmarks", CK_Flush_Bookmarks},
{"Next-Bookmark", CK_Next_Bookmark},
{"Prev-Bookmark", CK_Prev_Bookmark},
{"Page-Up-Highlight", CK_Page_Up_Highlight},
{"Page-Down-Highlight", CK_Page_Down_Highlight},
{"Left-Highlight", CK_Left_Highlight},
{"Right-Highlight", CK_Right_Highlight},
{"Word-Left-Highlight", CK_Word_Left_Highlight},
{"Word-Right-Highlight", CK_Word_Right_Highlight},
{"Up-Highlight", CK_Up_Highlight},
{"Down-Highlight", CK_Down_Highlight},
{"Home-Highlight", CK_Home_Highlight},
{"End-Highlight", CK_End_Highlight},
{"Beginning-Of-Text-Highlight", CK_Beginning_Of_Text_Highlight},
{"End-Of-Text_Highlight", CK_End_Of_Text_Highlight},
{"Begin-Page-Highlight", CK_Begin_Page_Highlight},
{"End-Page-Highlight", CK_End_Page_Highlight},
{"Scroll-Up-Highlight", CK_Scroll_Up_Highlight},
{"Scroll-Down-Highlight", CK_Scroll_Down_Highlight},
{"Paragraph-Up-Highlight", CK_Paragraph_Up_Highlight},
{"Paragraph-Down-Highlight", CK_Paragraph_Down_Highlight},
{"XStore", CK_XStore},
{"XCut", CK_XCut},
{"XPaste", CK_XPaste},
{"Selection-History", CK_Selection_History},
{"Shell", CK_Shell},
{"Select-Codepage", CK_Select_Codepage},
{"Insert-Literal", CK_Insert_Literal},
{"Execute-Macro", CK_Execute_Macro},
{"Begin-or-End-Macro", CK_Begin_End_Macro},
{"Ext-mode", CK_Ext_Mode},
{"Toggle-Line-State", CK_Toggle_Line_State},
#if 0
{"Focus-Next", CK_Focus_Next},
{"Focus-Prev", CK_Focus_Prev},
{"Height-Inc", CK_Height_Inc},
{"Height-Dec", CK_Height_Dec},
{"Make", CK_Make},
{"Error-Next", CK_Error_Next},
{"Error-Prev", CK_Error_Prev},
#endif
{"ChmodCmd", CK_ChmodCmd},
{"ChownAdvancedCmd", CK_ChownAdvancedCmd},
{"ChownCmd", CK_ChownCmd},
{"CompareDirsCmd", CK_CompareDirsCmd},
{"ConfigureBox", CK_ConfigureBox},
{"ConfigureVfs", CK_ConfigureVfs},
{"ConfirmBox", CK_ConfirmBox},
{"CopyCmd", CK_CopyCmd},
{"DeleteCmd", CK_DeleteCmd},
{"DirsizesCmd", CK_DirsizesCmd},
{"DisplayBitsBox", CK_DisplayBitsBox},
{"EditCmd", CK_EditCmd},
{"EditMcMenuCmd", CK_EditMcMenuCmd},
{"EditSymlinkCmd", CK_EditSymlinkCmd},
{"EditSyntaxCmd", CK_EditSyntaxCmd},
{"EditUserMenuCmd", CK_EditUserMenuCmd},
{"ExtCmd", CK_ExtCmd},
{"ExternalPanelize", CK_ExternalPanelize},
{"FilterCmd", CK_FilterCmd},
{"FilteredViewCmd", CK_FilteredViewCmd},
{"FindCmd", CK_FindCmd},
{"FishlinkCmd", CK_FishlinkCmd},
{"FtplinkCmd", CK_FtplinkCmd},
{"HistoryCmd", CK_HistoryCmd},
{"InfoCmd", CK_InfoCmd},
{"JobsCmd", CK_JobsCmd},
{"LayoutCmd", CK_LayoutCmd},
{"LearnKeys", CK_LearnKeys},
{"LinkCmd", CK_LinkCmd},
{"ListingCmd", CK_ListingCmd},
{"MkdirCmd", CK_MkdirCmd},
{"QuickCdCmd", CK_QuickCdCmd},
{"QuickChdirCmd", CK_QuickChdirCmd},
{"QuickViewCmd", CK_QuickViewCmd},
{"QuietQuitCmd", CK_QuietQuitCmd},
{"RenCmd", CK_RenCmd},
{"RereadCmd", CK_RereadCmd},
{"ReselectVfs", CK_ReselectVfs},
{"ReverseSelectionCmd", CK_ReverseSelectionCmd},
{"SaveSetupCmd", CK_SaveSetupCmd},
{"SelectCmd", CK_SelectCmd},
{"SwapCmd", CK_SwapCmd},
{"SymlinkCmd", CK_SymlinkCmd},
{"TreeCmd", CK_TreeCmd},
{"UndeleteCmd", CK_UndeleteCmd},
{"UnselectCmd", CK_UnselectCmd},
{"UserFileMenuCmd", CK_UserFileMenuCmd},
{"ViewCmd", CK_ViewCmd},
{"ViewFileCmd", CK_ViewFileCmd},
{"ViewOtherCmd", CK_ViewOtherCmd},
{"CopyCurrentReadlink", CK_CopyCurrentReadlink },
{"CopyOtherReadlink", CK_CopyOtherReadlink },
{"AddHotlist", CK_AddHotlist },
{"StartExtCmd", CK_StartExtCmd },
{"QuitCmd", CK_QuitCmd },
{"CopyOtherTarget", CK_CopyOtherTarget },
{"CopyOthertReadlink", CK_CopyOthertReadlink },
/* panel */
{ "PanelChdirOtherPanel", CK_PanelChdirOtherPanel },
{ "PanelChdirToReadlink", CK_PanelChdirToReadlink },
{ "PanelCopyLocal", CK_PanelCmdCopyLocal },
{ "PanelDeleteLocal", CK_PanelCmdDeleteLocal },
{ "PanelDoEnter", CK_PanelCmdDoEnter },
{ "PanelEditNew", CK_PanelCmdEditNew },
{ "PanelRenameLocal", CK_PanelCmdRenameLocal },
{ "PanelReverseSelection", CK_PanelCmdReverseSelection },
{ "PanelSelect", CK_PanelCmdSelect },
{ "PanelUnselect", CK_PanelCmdUnselect },
{ "PanelViewSimple", CK_PanelCmdViewSimple },
{ "PanelCtrlNextPage", CK_PanelCtrlNextPage },
{ "PanelCtrlPrevPage", CK_PanelCtrlPrevPage },
{ "PanelDirectoryHistoryList", CK_PanelDirectoryHistoryList },
{ "PanelDirectoryHistoryNext", CK_PanelDirectoryHistoryNext },
{ "PanelDirectoryHistoryPrev", CK_PanelDirectoryHistoryPrev },
{ "PanelGotoBottomFile", CK_PanelGotoBottomFile },
{ "PanelGotoMiddleFile", CK_PanelGotoMiddleFile },
{ "PanelGotoTopFile", CK_PanelGotoTopFile },
{ "PanelMarkFile", CK_PanelMarkFile },
{ "PanelMoveUp", CK_PanelMoveUp },
{ "PanelMoveDown", CK_PanelMoveDown },
{ "PanelMoveLeft", CK_PanelMoveLeft },
{ "PanelMoveRight", CK_PanelMoveRight },
{ "PanelMoveEnd", CK_PanelMoveEnd },
{ "PanelMoveHome", CK_PanelMoveHome },
{ "PanelNextPage", CK_PanelNextPage },
{ "PanelPrevPage", CK_PanelPrevPage },
{ "PanelSetPanelEncoding", CK_PanelSetPanelEncoding },
{ "PanelStartSearch", CK_PanelStartSearch },
{ "PanelSyncOtherPanel", CK_PanelSyncOtherPanel },
{NULL, 0}
};
int lookup_action (char *keyname)
{
int i;
for (i = 0; command_names [i].name; i++){
if (!str_casecmp (command_names [i].name, keyname))
return command_names [i].val;
}
return 0;
}
void
keymap_add(GArray *keymap, int key, int cmd)
{
global_key_map_t new_one, *map;
guint i;
map = &(g_array_index(keymap, global_key_map_t, 0));
for (i = 0; i < keymap->len; i++) {
if (map[i].key == key) {
map[i].command = cmd;
return;
}
}
new_one.key = key;
new_one.command = cmd;
g_array_append_val(keymap, new_one);
}
void
keybind_cmd_bind(GArray *keymap, char *keybind, int action)
{
keymap_add(keymap, lookup_key(keybind), action);
}

30
src/keybind.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef MC_KEYBIND_H
#define MC_KEYBIND_H
#include "global.h"
#define GLOBAL_KEYMAP_FILE "mc.keymap"
typedef struct name_key_map_t {
const char *name;
int val;
} name_key_map_t;
typedef struct key_config_t {
time_t mtime; /* mtime at the moment we read config file */
GArray *keymap;
GArray *ext_keymap;
gchar *labels[10];
} key_config_t;
/* The global keymaps are of this type */
typedef struct global_key_map_t {
long key;
long command;
} global_key_map_t;
int lookup_action (char *keyname);
void keybind_cmd_bind(GArray *keymap, char *keybind, int action);
#endif /* MC_KEYBIND_H */

View File

@ -77,6 +77,7 @@
#include "widget.h"
#include "command.h"
#include "wtools.h"
#include "cmddef.h"
#include "../vfs/vfs.h" /* vfs_translate_url() */
@ -100,6 +101,8 @@
#include "../vfs/gc.h"
#endif
#include "keybind.h" /* type global_key_map_t */
/* When the modes are active, left_panel, right_panel and tree_panel */
/* Point to a proper data structure. You should check with the functions */
/* get_current_type and get_other_type the types of the panels before using */
@ -301,6 +304,151 @@ mc_main_error_quark (void)
return g_quark_from_static_string (PACKAGE);
}
GArray *editor_keymap = NULL;
GArray *main_keymap = NULL;
GArray *main_x_keymap = NULL;
GArray *screen_keymap = NULL;
const global_key_map_t *main_map;
const global_key_map_t *main_x_map;
static const global_key_map_t default_main_map[] = {
{KEY_F (19), CK_MenuLastSelectedCmd},
{KEY_F (20), CK_QuietQuitCmd},
{XCTRL ('@'), CK_SingleDirsizeCmd},
/* Copy useful information to the command line */
{ALT ('a'), CK_CopyCurrentPathname},
{ALT ('A'), CK_CopyOtherPathname},
{ALT ('c'), CK_QuickCdCmd},
/* To access the directory hotlist */
{XCTRL ('\\'), CK_QuickChdirCmd},
/* Suspend */
{XCTRL ('z'), CK_SuspendCmd},
/* The filtered view command */
{ALT ('!'), CK_FilteredViewCmd},
/* Find file */
{ALT ('?'), CK_FindCmd},
/* Panel refresh */
{XCTRL ('r'), CK_RereadCmd},
/* Toggle listing between long, user defined and full formats */
{ALT ('t'), CK_ToggleListingCmd},
/* Swap panels */
{XCTRL ('u'), CK_SwapCmd},
/* View output */
{XCTRL ('o'), CK_ViewOtherCmd},
{XCTRL ('x'), CK_StartExtCmd},
{ 0, 0 }
};
static const global_key_map_t default_main_x_map[] = {
{XCTRL ('c'), CK_QuitCmd},
{'d', CK_CompareDirsCmd},
#ifdef USE_VFS
{'a', CK_ReselectVfs},
#endif /* USE_VFS */
{'p', CK_CopyCurrentPathname},
{XCTRL ('p'), CK_CopyOtherPathname},
{'t', CK_CopyCurrentTagged},
{XCTRL ('t'), CK_CopyCurrentReadlink},
{'c', CK_ChmodCmd},
{'o', CK_ChownCmd},
{'r', CK_CopyCurrentReadlink},
{XCTRL ('r'), CK_CopyOtherReadlink},
{'l', CK_LinkCmd},
{'s', CK_SymlinkCmd},
{XCTRL ('s'), CK_EditSymlinkCmd},
{'i', CK_InfoCmd},
{'q', CK_QuickViewCmd},
{'h', CK_AddHotlist},
{'!', CK_ExternalPanelize},
#ifdef WITH_BACKGROUND
{'j', CK_JobsCmd},
#endif /* WITH_BACKGROUND */
{0, 0}
};
static void
reload_panelized (WPanel *panel)
{
int i, j;
dir_list *list = &panel->dir;
if (panel != current_panel)
mc_chdir (panel->cwd);
for (i = 0, j = 0; i < panel->count; i++) {
if (list->list[i].f.marked) {
/* Unmark the file in advance. In case the following mc_lstat
* fails we are done, else we have to mark the file again
* (Note: do_file_mark depends on a valid "list->list [i].buf").
* IMO that's the best way to update the panel's summary status
* -- Norbert
*/
do_file_mark (panel, i, 0);
}
if (mc_lstat (list->list[i].fname, &list->list[i].st)) {
g_free (list->list[i].fname);
continue;
}
if (list->list[i].f.marked)
do_file_mark (panel, i, 1);
if (j != i)
list->list[j] = list->list[i];
j++;
}
if (j == 0)
panel->count = set_zero_dir (list);
else
panel->count = j;
if (panel != current_panel)
mc_chdir (current_panel->cwd);
}
static void
update_one_panel_widget (WPanel *panel, int force_update,
const char *current_file)
{
int free_pointer;
char *my_current_file = NULL;
if (force_update & UP_RELOAD) {
panel->is_panelized = 0;
mc_setctl (panel->cwd, VFS_SETCTL_FLUSH, 0);
memset (&(panel->dir_stat), 0, sizeof (panel->dir_stat));
}
/* If current_file == -1 (an invalid pointer) then preserve selection */
if (current_file == UP_KEEPSEL) {
free_pointer = 1;
my_current_file = g_strdup (panel->dir.list[panel->selected].fname);
current_file = my_current_file;
} else
free_pointer = 0;
if (panel->is_panelized)
reload_panelized (panel);
else
panel_reload (panel);
try_to_select (panel, current_file);
panel->dirty = 1;
if (free_pointer)
g_free (my_current_file);
}
static void
update_one_panel (int which, int force_update, const char *current_file)
{
WPanel *panel;
if (get_display_type (which) != view_listing)
return;
panel = (WPanel *) get_panel_widget (which);
update_one_panel_widget (panel, force_update, current_file);
}
/* Save current stat of directories to avoid reloading the panels */
/* when no modifications have taken place */
@ -1093,33 +1241,6 @@ init_labels (void)
buttonbar_set_label (midnight_dlg, 10, _("Quit"), quit_cmd);
}
static const key_map ctl_x_map[] = {
{XCTRL ('c'), quit_cmd},
{'d', compare_dirs_cmd},
#ifdef USE_VFS
{'a', reselect_vfs},
#endif /* USE_VFS */
{'p', copy_current_pathname},
{XCTRL ('p'), copy_other_pathname},
{'t', copy_current_tagged},
{XCTRL ('t'), copy_other_tagged},
{'c', chmod_cmd},
{'o', chown_cmd},
{'r', copy_current_readlink},
{XCTRL ('r'), copy_other_readlink},
{'l', link_cmd},
{'s', symlink_cmd},
{XCTRL ('s'), edit_symlink_cmd},
{'i', info_cmd_no_menu},
{'q', quick_cmd_no_menu},
{'h', add2hotlist_cmd},
{'!', external_panelize},
#ifdef WITH_BACKGROUND
{'j', jobs_cmd},
#endif /* WITH_BACKGROUND */
{0, 0}
};
static int ctl_x_map_enabled = 0;
static void
@ -1133,54 +1254,95 @@ nothing (void)
{
}
static const key_map default_map[] = {
{KEY_F (19), menu_last_selected_cmd},
{KEY_F (20), quiet_quit_cmd},
{XCTRL ('@'), smart_dirsize_cmd},
/* Copy useful information to the command line */
{ALT ('a'), copy_current_pathname},
{ALT ('A'), copy_other_pathname},
{ALT ('c'), quick_cd_cmd},
/* To access the directory hotlist */
{XCTRL ('\\'), quick_chdir_cmd},
/* Suspend */
{XCTRL ('z'), suspend_cmd},
/* The filtered view command */
{ALT ('!'), filtered_view_cmd},
/* Find file */
{ALT ('?'), find_cmd},
/* Panel refresh */
{XCTRL ('r'), reread_cmd},
/* Toggle listing between long, user defined and full formats */
{ALT ('t'), toggle_listing_cmd},
/* Swap panels */
{XCTRL ('u'), swap_cmd},
/* View output */
{XCTRL ('o'), view_other_cmd},
/* Control-X keybindings */
{XCTRL ('x'), ctl_x_cmd},
/* Show/hide hidden files */
{ALT ('.'), toggle_show_hidden},
/* Trap dlg's exit commands */
{ESC_CHAR, nothing},
{XCTRL ('c'), nothing},
{XCTRL ('g'), nothing},
{0, 0},
};
void
execute_cmd(int command)
{
switch (command) {
case CK_MenuLastSelectedCmd:
menu_last_selected_cmd ();
break;
case CK_QuietQuitCmd:
quiet_quit_cmd ();
break;
case CK_SingleDirsizeCmd:
single_dirsize_cmd ();
break;
case CK_CopyCurrentPathname:
copy_current_pathname ();
break;
case CK_CopyOtherPathname:
copy_other_pathname ();
break;
case CK_QuickCdCmd:
quick_cd_cmd ();
break;
case CK_QuickChdirCmd:
quick_chdir_cmd ();
break;
case CK_SuspendCmd:
suspend_cmd ();
break;
case CK_FilteredViewCmd:
filtered_view_cmd ();
break;
case CK_FindCmd:
find_cmd ();
break;
case CK_RereadCmd:
reread_cmd ();
break;
case CK_ToggleListingCmd:
toggle_listing_cmd ();
break;
case CK_SwapCmd:
swap_cmd ();
break;
case CK_ViewOtherCmd:
view_other_cmd ();
break;
case CK_QuitCmd:
break;
case CK_CompareDirsCmd:
break;
case CK_ReselectVfs:
break;
case CK_CopyCurrentTagged:
copy_current_tagged ();
break;
case CK_CopyOtherTarget:
copy_other_tagged ();
break;
case CK_CopyCurrentReadlink:
copy_current_readlink ();
break;
case CK_CopyOthertReadlink:
copy_other_readlink ();
break;
case CK_ChmodCmd:
break;
case CK_ChownCmd:
break;
case CK_LinkCmd:
break;
case CK_SymlinkCmd:
break;
case CK_EditSymlinkCmd:
break;
case CK_InfoCmd:
break;
case CK_QuickViewCmd:
break;
case CK_AddHotlist:
break;
case CK_ExternalPanelize:
break;
case CK_JobsCmd:
break;
case CK_StartExtCmd:
ctl_x_cmd ();
break;
}
}
static void
setup_pre (void)
@ -1400,9 +1562,9 @@ midnight_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
case DLG_KEY:
if (ctl_x_map_enabled) {
ctl_x_map_enabled = 0;
for (i = 0; ctl_x_map[i].key_code; i++)
if (parm == ctl_x_map[i].key_code) {
(*ctl_x_map[i].fn) ();
for (i = 0; main_x_map[i].key; i++)
if (parm == main_x_map[i].key) {
execute_cmd (main_x_map[i].command);
return MSG_HANDLED;
}
}
@ -1502,15 +1664,15 @@ midnight_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
}
if (ctl_x_map_enabled) {
ctl_x_map_enabled = 0;
for (i = 0; ctl_x_map[i].key_code; i++)
if (parm == ctl_x_map[i].key_code) {
(*ctl_x_map[i].fn) ();
for (i = 0; main_x_map[i].key; i++)
if (parm == main_x_map[i].key) {
execute_cmd (main_x_map[i].command);
return MSG_HANDLED;
}
} else {
for (i = 0; default_map[i].key_code; i++) {
if (parm == default_map[i].key_code) {
(*default_map[i].fn) ();
for (i = 0; main_map[i].key; i++) {
if (parm == main_map[i].key) {
execute_cmd (main_map[i].command);
return MSG_HANDLED;
}
}
@ -1689,6 +1851,15 @@ do_nc (void)
/* start check display_codepage and source_codepage */
check_codeset();
main_map = default_main_map;
if (main_keymap && main_keymap->len > 0)
main_map = (global_key_map_t *) main_keymap->data;
main_x_map = default_main_x_map;
if (main_x_keymap && main_x_keymap->len > 0)
main_x_map = (global_key_map_t *) main_x_keymap->data;
/* Check if we were invoked as an editor or file viewer */
if (!mc_maybe_editor_or_viewer ()) {
@ -2004,6 +2175,8 @@ main (int argc, char *argv[])
/* Removing this from the X code let's us type C-c */
load_key_defs ();
load_keymap_defs ();
/* Also done after init_subshell, to save any shell init file messages */
if (console_flag)
handle_console (CONSOLE_SAVE);

View File

@ -6,6 +6,8 @@
#ifndef MC_MAIN_H
#define MC_MAIN_H
//#include "global.h"
/* Toggling functions */
void toggle_fast_reload (void);
void toggle_mix_all_files (void);
@ -72,13 +74,10 @@ extern int is_right; /* If the selected menu was the right */
#define MENU_PANEL_IDX (is_right ? 1 : 0)
#define SELECTED_IS_PANEL (get_display_type (is_right ? 1 : 0) == view_listing)
typedef void (*key_callback) (void);
/* The keymaps are of this type */
typedef struct {
int key_code;
key_callback fn;
} key_map;
extern GArray *editor_keymap;
extern GArray *main_keymap;
extern GArray *main_x_keymap;
extern GArray *screen_keymap;
void do_update_prompt (void);

View File

@ -60,6 +60,8 @@
#include "selcodepage.h" /* select_charset () */
#include "charsets.h" /* get_codepage_id () */
#include "strutil.h"
#include "cmddef.h" /* cmd name const */
#include "keybind.h" /* global_key_map_t */
#define ELEMENTS(arr) ( sizeof(arr) / sizeof((arr)[0]) )
@ -105,6 +107,43 @@ int filetype_mode = 1;
/* The hook list for the select file function */
Hook *select_file_hook = 0;
const global_key_map_t *panel_keymap;
const global_key_map_t default_panel_keymap[] = {
{ ALT('o'), CK_PanelChdirOtherPanel },
{ ALT('l'), CK_PanelChdirToReadlink },
{ KEY_F(15), CK_PanelCmdCopyLocal },
{ KEY_F(18), CK_PanelCmdDeleteLocal },
{ KEY_ENTER, CK_PanelCmdDoEnter },
{ '\n', CK_PanelCmdDoEnter },
{ KEY_F(14), CK_PanelCmdEditNew },
{ KEY_F(16), CK_PanelCmdRenameLocal },
{ ALT('*'), CK_PanelCmdReverseSelection },
{ KEY_KP_ADD, CK_PanelCmdSelect },
{ KEY_KP_SUBTRACT, CK_PanelCmdUnselect },
{ KEY_F(13), CK_PanelCmdViewSimple },
{ KEY_M_CTRL | KEY_NPAGE, CK_PanelCtrlNextPage },
{ KEY_M_CTRL | KEY_PPAGE, CK_PanelCtrlPrevPage },
{ ALT('H'), CK_PanelDirectoryHistoryList },
{ ALT('u'), CK_PanelDirectoryHistoryNext },
{ ALT('y'), CK_PanelDirectoryHistoryPrev },
{ ALT('j'), CK_PanelGotoBottomFile },
{ ALT('r'), CK_PanelGotoMiddleFile },
{ ALT('g'), CK_PanelGotoTopFile },
{ KEY_IC, CK_PanelMarkFile },
{ KEY_UP, CK_PanelMoveUp },
{ KEY_DOWN, CK_PanelMoveDown },
{ KEY_END, CK_PanelMoveEnd },
{ KEY_HOME, CK_PanelMoveHome },
{ KEY_NPAGE, CK_PanelNextPage },
{ KEY_PPAGE, CK_PanelPrevPage },
{ XCTRL('t'), CK_PanelSetPanelEncoding },
{ XCTRL('s'), CK_PanelStartSearch },
{ ALT('i'), CK_PanelSyncOtherPanel },
{ 0, 0 }
};
static cb_ret_t panel_callback (Widget *, widget_msg_t msg, int parm);
static int panel_event (Gpm_Event *event, void *);
static void paint_frame (WPanel *panel);
@ -1103,6 +1142,7 @@ panel_new_with_dir (const char *panel_name, const char *wpath)
} else
mc_get_current_wd (panel->cwd, sizeof (panel->cwd) - 2);
panel_keymap = default_panel_keymap;
strcpy (panel->lwd, ".");
panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL);
@ -2273,10 +2313,6 @@ chdir_to_readlink (WPanel *panel)
}
typedef void (*panel_key_callback) (WPanel *);
typedef struct {
int key_code;
panel_key_callback fn;
} panel_key_map;
static void cmd_do_enter(WPanel *wp) { (void) do_enter(wp); }
static void cmd_view_simple(WPanel *wp) { (void) wp; view_simple_cmd(); }
@ -2288,74 +2324,119 @@ static void cmd_select(WPanel *wp) { (void) wp;select_cmd(); }
static void cmd_unselect(WPanel *wp) { (void) wp;unselect_cmd(); }
static void cmd_reverse_selection(WPanel *wp) { (void) wp;reverse_selection_cmd(); }
static const panel_key_map panel_keymap [] = {
{ KEY_DOWN, move_down },
{ KEY_UP, move_up },
/* The action button :-) */
{ '\n', cmd_do_enter },
{ KEY_ENTER, cmd_do_enter },
{ KEY_IC, mark_file },
{ KEY_HOME, move_home },
{ KEY_A1, move_home },
{ ALT ('<'), move_home },
{ KEY_C1, move_end },
{ KEY_END, move_end },
{ ALT ('>'), move_end },
{ KEY_NPAGE, next_page },
{ KEY_PPAGE, prev_page },
{ KEY_NPAGE | KEY_M_CTRL, ctrl_next_page },
{ KEY_PPAGE | KEY_M_CTRL, ctrl_prev_page },
/* To quickly move in the panel */
{ ALT('g'), goto_top_file },
{ ALT('r'), goto_middle_file }, /* M-r like emacs */
{ ALT('j'), goto_bottom_file },
/* Emacs-like bindings */
{ XCTRL('v'), next_page }, /* C-v like emacs */
{ ALT('v'), prev_page }, /* M-v like emacs */
{ XCTRL('p'), move_up }, /* C-p like emacs */
{ XCTRL('n'), move_down }, /* C-n like emacs */
{ XCTRL('s'), start_search }, /* C-s like emacs */
{ ALT('s'), start_search }, /* M-s not like emacs */
/* { XCTRL('t'), mark_file },*/
{ XCTRL('t'), set_panel_encoding },
{ ALT('o'), chdir_other_panel },
{ ALT('i'), sync_other_panel },
{ ALT('l'), chdir_to_readlink },
{ ALT('H'), directory_history_list },
{ KEY_F(13), cmd_view_simple },
{ KEY_F(14), cmd_edit_new },
{ KEY_F(15), cmd_copy_local },
{ KEY_F(16), cmd_rename_local },
{ KEY_F(18), cmd_delete_local },
{ ALT('y'), directory_history_prev },
{ ALT('u'), directory_history_next },
{ ALT('+'), cmd_select },
{ KEY_KP_ADD, cmd_select },
{ ALT('\\'), cmd_unselect },
{ ALT('-'), cmd_unselect },
{ KEY_KP_SUBTRACT, cmd_unselect },
{ ALT('*'), cmd_reverse_selection },
{ KEY_KP_MULTIPLY, cmd_reverse_selection },
{ 0, 0 }
};
void
screen_execute_cmd (WPanel *panel, int command, int key)
{
switch (command) {
case CK_PanelChdirOtherPanel:
chdir_other_panel (panel);
break;
case CK_PanelChdirToReadlink:
chdir_to_readlink (panel);
break;
case CK_PanelCmdCopyLocal:
cmd_copy_local (panel);
break;
case CK_PanelCmdDeleteLocal:
cmd_delete_local (panel);
break;
case CK_PanelCmdDoEnter:
cmd_do_enter (panel);
break;
case CK_PanelCmdViewSimple:
cmd_view_simple (panel);
break;
case CK_PanelCmdEditNew:
cmd_edit_new (panel);
break;
case CK_PanelCmdRenameLocal:
cmd_rename_local (panel);
break;
case CK_PanelCmdReverseSelection:
cmd_reverse_selection (panel);
break;
case CK_PanelCmdSelect:
cmd_select (panel);
break;
case CK_PanelCmdUnselect:
cmd_unselect (panel);
break;
case CK_PanelNextPage:
next_page (panel);
break;
case CK_PanelPrevPage:
prev_page (panel);
break;
case CK_PanelCtrlNextPage:
ctrl_next_page (panel);
break;
case CK_PanelCtrlPrevPage:
ctrl_prev_page (panel);
break;
case CK_PanelDirectoryHistoryList:
directory_history_list (panel);
break;
case CK_PanelDirectoryHistoryNext:
directory_history_next (panel);
break;
case CK_PanelDirectoryHistoryPrev:
directory_history_prev (panel);
break;
case CK_PanelGotoBottomFile:
goto_bottom_file (panel);
break;
case CK_PanelGotoMiddleFile:
goto_middle_file (panel);
break;
case CK_PanelGotoTopFile:
goto_top_file (panel);
break;
case CK_PanelMarkFile:
mark_file (panel);
break;
case CK_PanelMoveUp:
move_up (panel);
break;
case CK_PanelMoveDown:
move_down (panel);
break;
case CK_PanelMoveLeft:
move_left (panel, key);
break;
case CK_PanelMoveRight:
move_right (panel, key);
break;
case CK_PanelMoveEnd:
move_end (panel);
break;
case CK_PanelMoveHome:
move_home (panel);
break;
case CK_PanelSetPanelEncoding:
set_panel_encoding (panel);
break;
case CK_PanelStartSearch:
start_search (panel);
break;
case CK_PanelSyncOtherPanel:
sync_other_panel (panel);
break;
}
}
static cb_ret_t
panel_key (WPanel *panel, int key)
{
int i;
for (i = 0; panel_keymap[i].key_code; i++) {
if (key == panel_keymap[i].key_code) {
for (i = 0; panel_keymap[i].key; i++) {
if (key == panel_keymap[i].key) {
int old_searching = panel->searching;
if (panel_keymap[i].fn != start_search)
if (panel_keymap[i].command != CK_PanelStartSearch)
panel->searching = 0;
(*panel_keymap[i].fn) (panel);
screen_execute_cmd (panel, panel_keymap[i].command, key);
if (panel->searching != old_searching)
display_mini_info (panel);
@ -2369,12 +2450,13 @@ panel_key (WPanel *panel, int key)
/* We do not want to take a key press if nothing can be done with it */
/* The command line widget may do something more useful */
/*
if (key == KEY_LEFT)
return move_left (panel, key);
if (key == KEY_RIGHT)
return move_right (panel, key);
*/
if (is_abort_char (key)) {
panel->searching = 0;
display_mini_info (panel);

View File

@ -48,6 +48,7 @@
#include "menu.h" /* menubar_visible declaration */
#include "cmd.h"
#include "file.h" /* safe_delete */
#include "keybind.h" /* lookup_action */
#ifdef USE_VFS
#include "../vfs/gc.h"
@ -76,6 +77,7 @@ extern int num_history_items_recorded;
char *profile_name; /* .mc/ini */
char *global_profile_name; /* mc.lib */
char *panels_profile_name; /* .mc/panels.ini */
char *global_keymap_name; /* GLOBAL_KEYMAP_FILE */
char *setup_color_string;
char *term_color_string;
@ -595,11 +597,16 @@ load_setup (void)
/* mc.lib is common for all users, but has priority lower than
~/.mc/ini. FIXME: it's only used for keys and treestore now */
global_profile_name = concat_dir_and_file (mc_home, "mc.lib");
if (!exist_file(global_profile_name)) {
g_free (global_profile_name);
global_profile_name = concat_dir_and_file (mc_home_alt, "mc.lib");
}
global_keymap_name = concat_dir_and_file (mc_home, GLOBAL_KEYMAP_FILE);
if (!exist_file(global_keymap_name)) {
g_free (global_keymap_name);
global_keymap_name = concat_dir_and_file (mc_home_alt, GLOBAL_KEYMAP_FILE);
}
panels_profile_name = concat_dir_and_file (home_dir, PANELS_PROFILE_NAME);
mc_main_config = mc_config_init(profile);
@ -701,6 +708,7 @@ load_anon_passwd ()
void done_setup (void)
{
g_free (global_keymap_name);
g_free (profile_name);
g_free (global_profile_name);
g_free(color_terminal_string);
@ -785,3 +793,71 @@ void load_key_defs (void)
load_keys_from_section (getenv ("TERM"), mc_main_config);
}
static void
load_keymap_from_section (const char *section_name, GArray *keymap, mc_config_t *cfg)
{
gchar **profile_keys, **keys;
gchar **values, **curr_values;
char *valcopy, *value;
int action;
gsize len, values_len;
if (!section_name)
return;
profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
while (*profile_keys) {
curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
action = lookup_action (*profile_keys);
if (action>0) {
if (curr_values){
while (*curr_values){
valcopy = convert_controls (*curr_values);
keybind_cmd_bind (keymap, valcopy, action);
g_free (valcopy);
curr_values++;
}
} else {
value = mc_config_get_string (cfg, section_name, *profile_keys, "");
valcopy = convert_controls (value);
//define_sequence (key_code, valcopy, MCKEY_NOACTION);
g_free (valcopy);
g_free(value);
}
}
profile_keys++;
if (values)
g_strfreev(values);
}
g_strfreev(keys);
}
void
load_keymap_defs (void)
{
/*
* Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
* definitions override global settings.
*/
mc_config_t *mc_global_keymap;
mc_global_keymap = mc_config_init(global_keymap_name);
if (mc_global_keymap != NULL)
{
editor_keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
main_keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
load_keymap_from_section ("main", main_keymap, mc_global_keymap);
main_x_keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
screen_keymap = g_array_new(TRUE, FALSE, sizeof(global_key_map_t));
load_keymap_from_section ("panel", screen_keymap, mc_global_keymap);
mc_config_deinit(mc_global_keymap);
}
}

View File

@ -20,6 +20,7 @@ char *load_anon_passwd (void);
void panel_save_setup (struct WPanel *panel, const char *section);
void panel_load_setup (struct WPanel *panel, const char *section);
void save_panel_types (void);
void load_keymap_defs (void);
extern char *profile_name;
extern char *global_profile_name;