Use option as meta key

Added a buffer local option called 'macmeta' which when set causes
MacVim not to interpret option+key presses thus enabling the user to
bind to <M-..>.  Also updated the documentation and added 'macmeta' to
the .vim syntax file.
This commit is contained in:
Bjorn Winckler
2008-10-12 14:05:42 +02:00
parent 275fc44523
commit 1957b370bb
8 changed files with 100 additions and 9 deletions
+12
View File
@@ -4493,6 +4493,18 @@ A jump table for the options with a short description can be found at |Q_op|.
'termencoding'.
Note: MacVim does not use this option.
*'macmeta'* *'mmta'* *'nomacmeta'* *'nommta'*
'macmeta' boolean (default off)
local to buffer
{only available in MacVim GUI}
Use option (alt) as meta key. When on, option-key presses are not
interpreted, thus enabling bindings to <M-..>. When off, option-key
presses are interpreted by the selected input method and inserted as
text.
Note: Some keys (e.g. <M-F1>, <M-Tab>, <M-Return>, <M-Left>) can be
bound with the Meta flag even when this option is disabled, but this
is not the case for the majority of keys (e.g. <M-a>, <M-`>).
*'magic'* *'nomagic'*
'magic' boolean (default on)
global
+1
View File
@@ -767,6 +767,7 @@ Short explanation of each option: *option-list*
'listchars' 'lcs' characters for displaying in list mode
'loadplugins' 'lpl' load plugin scripts when starting up
'macatsui' Mac GUI: use ATSUI text drawing
'macmeta' 'mmta' use option as meta key (MacVim GUI only)
'magic' changes special characters in search patterns
'makeef' 'mef' name of the errorfile for ":make"
'makeprg' 'mp' program to use for the ":make" command
+3
View File
@@ -623,6 +623,9 @@ if has("gui")
call <SID>BinOptionG("fullscreen", &fullscreen)
call append("$", "fuoptions\tcontrol how fullscreen mode should behave")
call <SID>OptionG("fuoptions", &fuoptions)
call append("$", "macmeta\tuse option as meta key")
call append("$", "\t(local to buffer)")
call <SID>BinOptionL("mmta")
endif
endif
+48 -9
View File
@@ -1521,10 +1521,13 @@ static NSString *MMSymlinkWarningString =
// We take this approach of "pushing" the state to MacVim to avoid having
// to make synchronous calls from MacVim to Vim in order to get state.
BOOL mmta = curbuf ? curbuf->b_p_mmta : NO;
NSDictionary *vimState = [NSDictionary dictionaryWithObjectsAndKeys:
[[NSFileManager defaultManager] currentDirectoryPath], @"pwd",
[NSNumber numberWithInt:p_mh], @"p_mh",
[NSNumber numberWithBool:[self unusedEditor]], @"unusedEditor",
[NSNumber numberWithBool:mmta], @"p_mmta",
nil];
// Put the state before all other messages.
@@ -1796,6 +1799,7 @@ static NSString *MMSymlinkWarningString =
- (void)handleKeyDown:(NSString *)key modifiers:(int)mods
{
// TODO: This code is a horrible mess -- clean up!
char_u special[3];
char_u modChars[3];
char_u *chars = (char_u*)[key UTF8String];
@@ -1858,9 +1862,52 @@ static NSString *MMSymlinkWarningString =
}
mods &= ~MOD_MASK_ALT;
}
} else if (1 == length && chars[0] < 0x80 && (mods & MOD_MASK_ALT)) {
// META key is treated separately. This code was taken from gui_w48.c
// and gui_gtk_x11.c.
char_u string[7];
int ch = simplify_key(chars[0], &mods);
// Remove the SHIFT modifier for keys where it's already included,
// e.g., '(' and '*'
if (ch < 0x100 && !isalpha(ch) && isprint(ch))
mods &= ~MOD_MASK_SHIFT;
// Interpret the ALT key as making the key META, include SHIFT, etc.
ch = extract_modifiers(ch, &mods);
if (ch == CSI)
ch = K_CSI;
int len = 0;
if (mods) {
string[len++] = CSI;
string[len++] = KS_MODIFIER;
string[len++] = mods;
}
if (IS_SPECIAL(ch)) {
string[len++] = CSI;
string[len++] = K_SECOND(ch);
string[len++] = K_THIRD(ch);
} else {
string[len++] = ch;
#ifdef FEAT_MBYTE
// TODO: What if 'enc' is not "utf-8"?
if (enc_utf8 && (ch & 0x80)) { // convert to utf-8
string[len++] = ch & 0xbf;
string[len-2] = ((unsigned)ch >> 6) + 0xc0;
if (string[len-1] == CSI) {
string[len++] = KS_EXTRA;
string[len++] = (int)KE_CSI;
}
}
#endif
}
add_to_input_buf(string, len);
return;
} else if (length > 0) {
unichar c = [key characterAtIndex:0];
//NSLog(@"non-special: %@ (hex=%x, mods=%d)", key,
// [key characterAtIndex:0], mods);
@@ -1875,14 +1922,6 @@ static NSString *MMSymlinkWarningString =
//NSLog(@"clear shift ctrl");
}
// HACK! All Option+key presses go via 'insert text' messages, except
// for <M-Space>. If the Alt flag is not cleared for <M-Space> it does
// not work to map to it.
if (0xa0 == c && !(mods & MOD_MASK_CMD)) {
//NSLog(@"clear alt");
mods &= ~MOD_MASK_ALT;
}
#ifdef FEAT_MBYTE
if (input_conv.vc_type != CONV_NONE) {
conv_str = string_convert(&input_conv, chars, &length);
+11
View File
@@ -111,6 +111,17 @@ static float MMDragAreaSize = 73.0f;
} else {
[self dispatchKeyEvent:event];
}
} else if ((flags & NSAlternateKeyMask) &&
[[[[self vimController] vimState] objectForKey:@"p_mmta"]
boolValue]) {
// If the 'macmeta' option is set, then send Alt+key presses directly
// to Vim without interpreting the key press.
NSString *unmod = [event charactersIgnoringModifiers];
int len = [unmod lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const char *bytes = [unmod UTF8String];
[self sendKeyDown:bytes length:len modifiers:flags
isARepeat:[event isARepeat]];
} else {
[textView interpretKeyEvents:[NSArray arrayWithObject:event]];
}
+19
View File
@@ -138,6 +138,9 @@
#define PV_ML OPT_BUF(BV_ML)
#define PV_MOD OPT_BUF(BV_MOD)
#define PV_MPS OPT_BUF(BV_MPS)
#ifdef FEAT_GUI_MACVIM
#define PV_MMTA OPT_BUF(BV_MMTA)
#endif
#define PV_NF OPT_BUF(BV_NF)
#ifdef FEAT_OSFILETYPE
# define PV_OFT OPT_BUF(BV_OFT)
@@ -322,6 +325,9 @@ static int p_lisp;
#endif
static int p_ml;
static int p_ma;
#ifdef FEAT_GUI_MACVIM
static int p_mmta;
#endif
static int p_mod;
static char_u *p_mps;
static char_u *p_nf;
@@ -1658,6 +1664,13 @@ static struct vimoption
(char_u *)&p_macatsui, PV_NONE,
{(char_u *)TRUE, (char_u *)0L}},
#endif
{"macmeta", "mmta", P_BOOL|P_VI_DEF,
#ifdef FEAT_GUI_MACVIM
(char_u *)&p_mmta, PV_MMTA,
#else
(char_u *)NULL, PV_NONE,
#endif
{(char_u *)FALSE, (char_u *)0L}},
{"magic", NULL, P_BOOL|P_VI_DEF,
(char_u *)&p_magic, PV_NONE,
{(char_u *)TRUE, (char_u *)0L}},
@@ -9235,6 +9248,9 @@ get_varp(p)
#endif
case PV_ML: return (char_u *)&(curbuf->b_p_ml);
case PV_MPS: return (char_u *)&(curbuf->b_p_mps);
#ifdef FEAT_GUI_MACVIM
case PV_MMTA: return (char_u *)&(curbuf->b_p_mmta);
#endif
case PV_MA: return (char_u *)&(curbuf->b_p_ma);
case PV_MOD: return (char_u *)&(curbuf->b_changed);
case PV_NF: return (char_u *)&(curbuf->b_p_nf);
@@ -9606,6 +9622,9 @@ buf_copy_options(buf, flags)
#ifdef FEAT_KEYMAP
buf->b_p_keymap = vim_strsave(p_keymap);
buf->b_kmap_state |= KEYMAP_INIT;
#endif
#ifdef FEAT_GUI_MACVIM
buf->b_p_mmta = p_mmta;
#endif
/* This isn't really an option, but copying the langmap and IME
* state from the current buffer is better than resetting it. */
+3
View File
@@ -981,6 +981,9 @@ enum
, BV_ML
, BV_MOD
, BV_MPS
#ifdef FEAT_GUI_MACVIM
, BV_MMTA
#endif
, BV_NF
#ifdef FEAT_OSFILETYPE
, BV_OFT
+3
View File
@@ -1456,6 +1456,9 @@ struct file_buffer
char_u *b_p_dict; /* 'dictionary' local value */
char_u *b_p_tsr; /* 'thesaurus' local value */
#endif
#ifdef FEAT_GUI_MACVIM
int b_p_mmta; /* 'macmeta' local value */
#endif
/* end of buffer options */