Binding numeric keypad keys with Emacs 24 and OS/X
I'm currently trying out the Git HEAD version of Emacs 24 on OS/X as described in this article:
http://www.viget.com/extend/emacs-24-rails-development-environment-from-scratch-to-productive-in-5-minu/
I'd like to bind some of the Macintosh extended keyboard num开发者_Go百科eric keypad keys to Emacs functions, but it doesn't seem to be working. When I do a "c-h k" to check the key details the key presses are not recognized. Ditto if I refer to them in a (global-set-key (kbd "kp-minus") ...) setting.
Is this an issue with using the development version of Emacs 24 or is it something about the Macintosh keyboard hardware and how Emacs sees it? Can anyone advise on the best way to go about this?
Thanks in advance,
Stu
I had the same issue with the keypad keys building emacs 24. The problem is the same with emacs 23. I patched the emacs 24 code as follows to correct the problem. Not sure this is a good solution but it works well enough for me.
index 91f0cbb..d537ee3 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -87,6 +87,7 @@ static unsigned convert_ns_to_X_keysym[] =
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
@@ -134,6 +135,35 @@ static unsigned convert_ns_to_X_keysym[] =
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
+
static Lisp_Object Qmodifier_value;
Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
@@ -1924,13 +1954,33 @@ ns_convert_key (unsigned code)
unsigned keysym;
/* An array would be faster, but less easy to read. */
for (keysym = 0; keysym < last_keysym; keysym += 2)
- if (code == convert_ns_to_X_keysym[keysym])
- return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+
+ if (code == convert_ns_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+ }
return 0;
/* if decide to use keyCode and Carbon table, use this line:
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
+
char *
x_get_keysym_name (int keysym)
@@ -4503,10 +4553,10 @@ ns_term_shutdown (int sig)
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
int left_is_none;
+ unsigned int flags = [theEvent modifierFlags];
NSTRACE (keyDown);
@@ -4550,9 +4600,13 @@ ns_term_shutdown (int sig)
code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
/* (Carbon way: [theEvent keyCode]) */
+
/* is it a "function key"? */
- fnKeysym = ns_convert_key (code);
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
+ fnKeysym = ns_convert_key(code);
if (fnKeysym)
{
/* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
@@ -4565,7 +4619,6 @@ ns_term_shutdown (int sig)
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;
I tried this with an older Emacs:
This is GNU Emacs 22.2.1 (powerpc-apple-darwin9.5.0, GTK+ Version 2.10.13)
Built from the ports collection with +gtk +x11 and used with the X11 server XQuartz 2.1.6 (xorg-server 1.4.2-apple33), when I look with C-h l
I get
<kp-0> ... <kp-9>
for the numbers. and
<kp-enter> <kp-subtract> <kp-multiply> <kp-divide> <kp-equal>
For the other keys.
I'd suggest to build the latest Emacs from MacPorts with the options +gtk and +x11.
Then I'd get the latest XQuartz and run Emacs over X11 (I prefer this to the more native builds because then Emacs always behaves the same regardless if it runs remotely on another OS (usually via ssh -Y
) or locally.
I'll upgrade my ports to the latest Emacs next week and add the result for these also.
The problem is exclusive to the Cocoa variant of emacs. The problem did not exist in the Carbon version, which is emacs22. I updated the patch I posted above, which now works better. It will likely work with the Emacs23 code base using XCode 3. If you are using XCode 4, like me you will need to use the Emacs24 code base which is currently only available in the GIT repository. Here is a very nice description on building Emacs24 via XCode 4
[http://mikbe.tk/2011/04/18/build-emacs-with-xcode-4/][1]
Here's an Emacs 23.3 translation of the Emacs 24 patch M. D. Marchionna's posted on this page.
--- nsterm-orig.m 2011-11-13 17:51:47.000000000 -0500
+++ nsterm.m 2011-11-13 17:39:56.000000000 -0500
@@ -87,6 +87,7 @@
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
@@ -134,6 +135,33 @@
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
/* Lisp communications */
Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line;
@@ -1842,6 +1870,23 @@
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
char *
x_get_keysym_name (int keysym)
@@ -4349,7 +4394,7 @@
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
+ unsigned int flags = [theEvent modifierFlags];
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
@@ -4397,6 +4442,9 @@
/* (Carbon way: [theEvent keyCode]) */
/* is it a "function key"? */
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
fnKeysym = ns_convert_key (code);
if (fnKeysym)
{
@@ -4410,8 +4458,6 @@
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
-
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;
精彩评论