-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better support for Bluetooth keyboards (especially ESC). #13
Comments
I'd love to have that too. I actually managed to use the Escape key on my keyboard (by editing the code), but there's still work. Control keys and arrow keys would be nice. |
By the way! BT keyboard works fine, but only if you have your iPad keyboard On Tue, Jun 19, 2012 at 10:18 AM, N-Holzschuch <
|
For the adventurous, I have a patch that allows the use of external keyboards. About 300 lines, so I'm not posting it here, right? What works: arrow keys, escape. In short, it's still a work in progress, but it can be released for use by others. |
I'd love to have this fixed, together with the standard cut, copy & paste bindings (just like MacVim, which also supports Cmd+X,C,V) |
All right, I think I've got it. There's only one file to edit, gui_ios.m. #pragma mark VimAppDelegate
@interface VimAppDelegate : NSObject {
}
@end
@implementation VimAppDelegate with the following code: #pragma mark VimApplication
@interface VimApplication : UIApplication
@end
@implementation VimApplication
// Support for external keyboards
/* Key mapping */
#define vk_Return 0x28
#define vk_Esc 0x29
#define vk_Delete 0x30
#define vk_Tab 0x31
#define vk_F1 0x3a
#define vk_F2 0x3b
#define vk_F3 0x3c
#define vk_F4 0x3d
#define vk_F5 0x3e
#define vk_F6 0x3f
#define vk_F7 0x40
#define vk_F8 0x41
#define vk_F9 0x42
#define vk_F10 0x43
#define vk_F11 0x44
#define vk_F12 0x45
#define vk_F13 0x46
#define vk_F14 0x47
#define vk_F15 0x48
#define vk_Right 0x4F
#define vk_Left 0x50
#define vk_Down 0x51
#define vk_Up 0x52
#define shiftKey 0x20000
#define rightShiftKey 0x200000
#define controlKey 0x100000
#define rightControlKey controlKey // Haven't found a keyboard with a right ctrl key.
#define cmdKey 0x10000
#define rightCmdKey 0x1000000
#define optionKey 0x80000
#define rightOptionKey 0x400000
#define KeySym char
static struct
{
KeySym key_sym;
char_u vim_code0;
char_u vim_code1;
} special_keys[] =
{
{vk_Up, 'k', 'u'},
{vk_Down, 'k', 'd'},
{vk_Left, 'k', 'l'},
{vk_Right, 'k', 'r'},
{vk_Delete, 'k', 'b'},
{vk_F1, 'k', '1'},
{vk_F2, 'k', '2'},
{vk_F3, 'k', '3'},
{vk_F4, 'k', '4'},
{vk_F5, 'k', '5'},
{vk_F6, 'k', '6'},
{vk_F7, 'k', '7'},
{vk_F8, 'k', '8'},
{vk_F9, 'k', '9'},
{vk_F10, 'k', ';'},
{vk_F11, 'F', '1'},
{vk_F12, 'F', '2'},
{vk_F13, 'F', '3'},
{vk_F14, 'F', '4'},
{vk_F15, 'F', '5'},
/* End of list marker: */
{(KeySym)0, 0, 0}
};
/*
* Convert the modifiers of an Event into vim's modifiers (keys)
*/
static int_u
EventFlags2VimModifiers(int eventFlags)
{
int_u vimModifiers = 0x00;
if (eventFlags & (shiftKey | rightShiftKey))
vimModifiers |= MOD_MASK_SHIFT;
if (eventFlags & (optionKey | rightOptionKey))
vimModifiers |= MOD_MASK_ALT;
if (eventFlags & (controlKey | rightControlKey))
vimModifiers |= MOD_MASK_CTRL;
if (eventFlags & (cmdKey | rightCmdKey))
vimModifiers |= MOD_MASK_CMD;
return (vimModifiers);
}
- (void)sendEvent:(UIEvent *)anEvent
{
#define GS_EVENT_TYPE_OFFSET 2
#define GSEVENT_TYPE_KEYUP 11
#define GSEVENT_FLAGS 12
#define GSEVENTKEY_KEYCODE_CHARIGNORINGMOD 15
// Traverse from the UIEvent to the GSEvent to the type
int *eventMemory = (int *)[anEvent performSelector:@selector(_gsEvent)];
int eventType = eventMemory[GS_EVENT_TYPE_OFFSET];
// Look for status bar touches by event type
if (eventType == GSEVENT_TYPE_KEYUP)
{
int eventFlags = eventMemory[GSEVENT_FLAGS];
int tmp = eventMemory[GSEVENTKEY_KEYCODE_CHARIGNORINGMOD];
//which length?
UniChar *keycode = (UniChar *)&tmp; // Cast to silence the warning
char_u result[80];
short len = 0;
// Escape requires special treatment. Maybe also Cmd . / Ctrl-C
if (keycode[0] == vk_Esc) {
char_u escapeString[] = {ESC, 0};
add_to_input_buf(escapeString, 1);
return;
}
if (keycode[0] == vk_Return) {
char_u escapeString[] = {Ctrl_M, 0};
add_to_input_buf(escapeString, 1);
return;
}
// Identify the modifiers (Shift, Ctrl, Alt, Option)
UInt32 vimModifiers = EventFlags2VimModifiers(eventFlags);
// Are we on a special key?
int isSpecial = 0;
int i;
int key_char;
for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
if (special_keys[i].key_sym == keycode[0])
{
key_char = TO_SPECIAL(special_keys[i].vim_code0,
special_keys[i].vim_code1);
key_char = simplify_key(key_char, (int *)&vimModifiers);
isSpecial = TRUE;
break;
}
// Here, we need to be careful: we only insert chars if they won't be handled by insertText
// shift and option + letter are done over there.
if (isSpecial && IS_SPECIAL(key_char))
{
// Special keys: up, down, F1...
if (vimModifiers)
{
// We place the modifiers in the buffer
result[len++] = CSI;
result[len++] = KS_MODIFIER;
result[len++] = vimModifiers;
}
// Then the special key:
result[len++] = CSI;
result[len++] = K_SECOND(key_char);
result[len++] = K_THIRD(key_char);
} else if (vimModifiers & MOD_MASK_CTRL) {
// remove the control modifier
vimModifiers &= ~MOD_MASK_CTRL;
if (vimModifiers)
{
// If there's still sthg else, insert it.
result[len++] = CSI;
result[len++] = KS_MODIFIER;
result[len++] = vimModifiers;
}
result[len++] = keycode[0] - 0x03;
} else if (vimModifiers & MOD_MASK_CMD) {
// Possible to simplify??? Try again with CTRL
result[len++] = CSI;
result[len++] = KS_MODIFIER;
result[len++] = vimModifiers;
result[len++] = keycode[0] + 0x5d;
}
if (len > 0) {
add_to_input_buf(result, len);
return;
}
}
// If we didn't do anything with the event, so we forward it.
// This includes all standard text events.
[super sendEvent:anEvent];
} and in the "main" function, replace the line: int retVal = UIApplicationMain(argc, argv, nil, @"VimAppDelegate"); with: int retVal = UIApplicationMain(argc, argv, @"VimApplication", NSStringFromClass([VimApplication class])); and add a special case in inserttext: - (void)insertText:(NSString *)text {
char_u* keycode = [text UTF8String];
int len = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if ((len > 1) || (keycode[0] != 0xa)) {
// I have to make a special case for Enter
add_to_input_buf(keycode, len);
}
[_textView setNeedsDisplay];
} and that should be all (assuming your keyboard is identical to mine). I have escape, arrows, control/alt/command, function keys... You can add the following lines in your vimrc:
I've been playing with Cmd-A, Cmd-C and Cmd-V all afternoon. |
@N-Holzschuch I know this is a long shot, but have you looked at all into remapping CapsLock? |
I don't know, what do you have in mind? With these changes, caps lock works as a caps lock key. But that's pretty useless, so I guess you want something else. There are many guys who remap the Caps Lock key into an escape key. If that's what you want to do, it can probably be done inside the Objective-C code (but that's not a very beautiful solution; it raises many questions, such as how to deactivate it...) I don't think it can be done in the .vimrc file. You would need to add the following modifier: The problem is that caps lock is a modifier, not a key in itself. I don't know if "pressing caps lock" is an event that gets forwarded to the application. Someone would need to test it. |
@N-Holzschuch That sounds promising. I'd want to remap CapsLock as Control. |
I actually wouldn't - I can use Control just fine in apps like Prompt... On Jul 11, 2012, at 22:31 , Seth Milliken wrote:
|
@rcarmo Just to be clear, I'm not suggesting that this be a hardcoded default, but rather an option. I was trying to glean from @N-Holzschuch whether it was possible to do anything with CapsLock at all. I find Control to be in an awkward position on my Bluetooth keyboard. My left pinky starts to hurt after hacking for a while without CapsLock mapped to Control. |
Sure :) I'm used to it - the same keyboard across all my devices, etc. On 11/07/2012, at 23:19, Seth Millikenreply@reply.github.com wrote:
|
Did the patch from @N-Holzschuch ever get rolled into master as a pull request? |
I use a bluetooth keyboard with my ipad, and I can use esc to exit insert mode when I'm using vim through iSSH, so I know it works. iSSH has really good bluetooth keyboard support, and it would be great if vim supported this too. Not just esc, but control keys.
Thank you for this great app.
The text was updated successfully, but these errors were encountered: