diff --git a/runtime/doc/gui_mac.txt b/runtime/doc/gui_mac.txt index 1db8a02093..1fb593ae88 100644 --- a/runtime/doc/gui_mac.txt +++ b/runtime/doc/gui_mac.txt @@ -341,16 +341,16 @@ to "~/.gvimrc": > < *:maca* *:macaction* It is typical for menu items in Cocoa applications to bind to Objective-C -selectors. To support this, MacVim introduces the ":macaction" command. This +selectors. To support this, MacVim introduces the |:macaction| command. This command takes the name of an action message as its only parameter. (An action message is an Objective-C message with "void" return type and a single parameter of type "id".) For example, the "New Window" menu item on the "File" menu is created in the following manner: > :an 10.290 File.New\ Window :macaction newWindow: -Note 1: A menu item which is bound to ":macaction" will automatically be bound +Note 1: A menu item which is bound to |:macaction| will automatically be bound to that action in all modes (as if ":an" was used). It is not possible to -bind to ":macaction" in one mode only. +bind to |:macaction| in one mode only. Note 2: The action is "nil-targeted", which means it is passed down the first responder chain. @@ -361,8 +361,11 @@ application bundle) which contains all actions that may be called. The key in this dictionary is the name of the action message (case sensitive), the value is not used. +Note: The |:macaction| command supports tab-completion so to cycle through +all available commands type ":maca" and keep pressing . + Here is a random assortment of actions from Actions.plist which might be -useful. +useful. Action Description ~ findNext: Search forward using the "Find Pasteboard" diff --git a/src/MacVim/MMBackend.h b/src/MacVim/MMBackend.h index 439c8d450a..9da61501d9 100644 --- a/src/MacVim/MMBackend.h +++ b/src/MacVim/MMBackend.h @@ -24,6 +24,7 @@ id frontendProxy; NSDictionary *colorDict; NSDictionary *sysColorDict; + NSDictionary *actionDict; BOOL inputReceived; BOOL tabBarVisible; unsigned backgroundColor; @@ -54,6 +55,7 @@ - (void)setSpecialColor:(int)color; - (void)setDefaultColorsBackground:(int)bg foreground:(int)fg; - (NSConnection *)connection; +- (NSDictionary *)actionDict; - (BOOL)checkin; - (BOOL)openVimWindow; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 3f1fa06850..128f243dc7 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -142,8 +142,12 @@ static NSString *MMSymlinkWarningString = sysColorDict = [[NSDictionary dictionaryWithContentsOfFile:path] retain]; - if (!(colorDict && sysColorDict)) - NSLog(@"ERROR: Failed to load color dictionaries.%@", + path = [mainBundle pathForResource:@"Actions" ofType:@"plist"]; + if (path) + actionDict = [[NSDictionary dictionaryWithContentsOfFile:path] retain]; + + if (!(colorDict && sysColorDict && actionDict)) + NSLog(@"ERROR: Failed to load dictionaries.%@", MMSymlinkWarningString); return self; @@ -215,6 +219,11 @@ static NSString *MMSymlinkWarningString = return connection; } +- (NSDictionary *)actionDict +{ + return actionDict; +} + - (BOOL)checkin { if (![self connection]) { diff --git a/src/MacVim/gui_macvim.m b/src/MacVim/gui_macvim.m index 2d051d44c3..5abc1f9630 100644 --- a/src/MacVim/gui_macvim.m +++ b/src/MacVim/gui_macvim.m @@ -1478,22 +1478,8 @@ gui_mch_toggle_tearoffs(int enable) static BOOL gui_macvim_is_valid_action(NSString *action) { - static NSDictionary *actionDict = nil; - - if (!actionDict) { - NSBundle *mainBundle = [NSBundle mainBundle]; - NSString *path = [mainBundle pathForResource:@"Actions" - ofType:@"plist"]; - if (path) { - actionDict = [[NSDictionary alloc] initWithContentsOfFile:path]; - } else { - // Allocate bogus dictionary so that error only pops up once. - actionDict = [NSDictionary new]; - EMSG(_("E???: Failed to load action dictionary")); - } - } - - return [actionDict objectForKey:action] != nil; + NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict]; + return actionDict && [actionDict objectForKey:action] != nil; } @@ -1834,3 +1820,35 @@ odb_end(void) } #endif // FEAT_ODB_EDITOR + + + char_u * +get_macaction_name(expand_T *xp, int idx) +{ + static char_u *str = NULL; + NSDictionary *actionDict = [[MMBackend sharedInstance] actionDict]; + + if (nil == actionDict || idx < 0 || idx >= [actionDict count]) + return NULL; + + NSString *string = [[actionDict allKeys] objectAtIndex:idx]; + if (!string) + return NULL; + + char_u *plainStr = (char_u*)[string UTF8String]; + +#ifdef FEAT_MBYTE + if (str) { + vim_free(str); + str = NULL; + } + if (input_conv.vc_type != CONV_NONE) { + int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + str = string_convert(&input_conv, plainStr, &len); + plainStr = str; + } +#endif + + return plainStr; +} + diff --git a/src/ex_docmd.c b/src/ex_docmd.c index b269ed3f81..63a82d824d 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3792,6 +3792,14 @@ set_one_cmd_context(xp, buff) break; #endif +#ifdef FEAT_GUI_MACVIM + case CMD_macaction: + xp->xp_context = EXPAND_MACACTION; + xp->xp_pattern = arg; + break; +#endif + + #endif /* FEAT_CMDL_COMPL */ default: diff --git a/src/ex_getln.c b/src/ex_getln.c index e7f8c1b1c7..2f362b6487 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4449,6 +4449,9 @@ ExpandFromContext(xp, pat, num_file, file, options) {EXPAND_LANGUAGE, get_lang_arg, TRUE}, #endif {EXPAND_ENV_VARS, get_env_name, TRUE}, +#ifdef FEAT_GUI_MACVIM + {EXPAND_MACACTION, get_macaction_name, FALSE}, +#endif }; int i; diff --git a/src/proto/gui_macvim.pro b/src/proto/gui_macvim.pro index b720013bd5..715c549b09 100644 --- a/src/proto/gui_macvim.pro +++ b/src/proto/gui_macvim.pro @@ -201,3 +201,4 @@ OSErr odb_buffer_close(buf_T *buf); OSErr odb_post_buffer_write(buf_T *buf); void odb_end(void); +char_u *get_macaction_name(expand_T *xp, int idx); diff --git a/src/vim.h b/src/vim.h index be52ab14b4..2cd49d7ce8 100644 --- a/src/vim.h +++ b/src/vim.h @@ -689,6 +689,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname); #define EXPAND_USER_DEFINED 30 #define EXPAND_USER_LIST 31 #define EXPAND_SHELLCMD 32 +#define EXPAND_MACACTION 33 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1