mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Added partial client/server support (scripting not yet supported)
git-svn-id: http://macvim.googlecode.com/svn/trunk@225 96c4425d-ca35-0410-94e5-3396d5c13a8f
This commit is contained in:
@@ -433,6 +433,43 @@ static NSTimeInterval MMTerminateTimeout = 3;
|
||||
return vc;
|
||||
}
|
||||
|
||||
- (NSArray *)serverList
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *controller = [vimControllers objectAtIndex:i];
|
||||
id proxy = [controller backendProxy];
|
||||
NSConnection *connection = [proxy connectionForProxy];
|
||||
if (!connection)
|
||||
continue;
|
||||
|
||||
// Set low timeouts since we don't want this call to potentially lock
|
||||
// up MacVim for a while.
|
||||
NSTimeInterval req = [connection requestTimeout];
|
||||
NSTimeInterval rep = [connection replyTimeout];
|
||||
[connection setRequestTimeout:0];
|
||||
[connection setReplyTimeout:.1];
|
||||
|
||||
@try {
|
||||
NSString *eval = [proxy evaluateExpression:@"v:servername"];
|
||||
if (eval) {
|
||||
[array addObject:eval];
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"WARNING: Got exception while listing servers: \"%@\"", e);
|
||||
}
|
||||
@finally {
|
||||
[connection setRequestTimeout:req];
|
||||
[connection setReplyTimeout:rep];
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@end // MMAppController
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
- (void)setSpecialColor:(int)color;
|
||||
- (void)setDefaultColorsBackground:(int)bg foreground:(int)fg;
|
||||
|
||||
- (NSString *)macVimConnectionName;
|
||||
- (BOOL)checkin;
|
||||
- (BOOL)openVimWindow;
|
||||
- (void)clearAll;
|
||||
@@ -103,6 +104,7 @@
|
||||
- (void)startBlink;
|
||||
- (void)stopBlink;
|
||||
- (void)adjustLinespace:(int)linespace;
|
||||
- (void)activate;
|
||||
|
||||
- (int)lookupColorWithKey:(NSString *)key;
|
||||
- (BOOL)hasSpecialKeyWithValue:(NSString *)value;
|
||||
|
||||
+39
-4
@@ -135,14 +135,19 @@ enum {
|
||||
[self queueMessage:SetDefaultColorsMsgID data:data];
|
||||
}
|
||||
|
||||
- (NSString *)macVimConnectionName
|
||||
{
|
||||
// NOTE! If the name of the connection changes here it must also be
|
||||
// updated in MMAppController.m.
|
||||
return [NSString stringWithFormat:@"%@-connection",
|
||||
[[NSBundle mainBundle] bundleIdentifier]];
|
||||
}
|
||||
|
||||
- (BOOL)checkin
|
||||
{
|
||||
NSBundle *mainBundle = [NSBundle mainBundle];
|
||||
|
||||
// NOTE! If the name of the connection changes here it must also be
|
||||
// updated in MMAppController.m.
|
||||
NSString *name = [NSString stringWithFormat:@"%@-connection",
|
||||
[mainBundle bundleIdentifier]];
|
||||
NSString *name = [self macVimConnectionName];
|
||||
connection = [NSConnection connectionWithRegisteredName:name host:nil];
|
||||
if (!connection) {
|
||||
#if 0
|
||||
@@ -365,6 +370,12 @@ enum {
|
||||
|
||||
- (void)exit
|
||||
{
|
||||
#ifdef MAC_CLIENTSERVER
|
||||
// The default connection is used for the client/server code.
|
||||
[[NSConnection defaultConnection] setRootObject:nil];
|
||||
[[NSConnection defaultConnection] invalidate];
|
||||
#endif
|
||||
|
||||
// By invalidating the NSConnection the MMWindowController immediately
|
||||
// finds out that the connection is down and as a result
|
||||
// [MMWindowController connectionDidDie:] is invoked.
|
||||
@@ -843,6 +854,11 @@ enum {
|
||||
[self queueMessage:AdjustLinespaceMsgID data:data];
|
||||
}
|
||||
|
||||
- (void)activate
|
||||
{
|
||||
[self queueMessage:ActivateMsgID data:nil];
|
||||
}
|
||||
|
||||
- (int)lookupColorWithKey:(NSString *)key
|
||||
{
|
||||
if (!(key && [key length] > 0))
|
||||
@@ -1003,6 +1019,19 @@ enum {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSString *)evaluateExpression:(in bycopy NSString *)expr
|
||||
{
|
||||
NSString *eval = nil;
|
||||
char_u *res = eval_client_expr_to_string((char_u*)[expr UTF8String]);
|
||||
|
||||
if (res != NULL) {
|
||||
eval = [NSString stringWithUTF8String:(char*)res];
|
||||
vim_free(res);
|
||||
}
|
||||
|
||||
return eval;
|
||||
}
|
||||
|
||||
@end // MMBackend
|
||||
|
||||
|
||||
@@ -1363,6 +1392,12 @@ enum {
|
||||
const void *bytes = [data bytes];
|
||||
int shape = *((int*)bytes); bytes += sizeof(int);
|
||||
update_mouseshape(shape);
|
||||
} else if (ServerAddInputMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
/*int len = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
char_u *cmd = (char_u*)bytes;
|
||||
|
||||
server_to_input_buf(cmd);
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
|
||||
@@ -749,6 +749,9 @@ static NSMenuItem *findMenuItemWithTagInMenu(NSMenu *root, int tag)
|
||||
int linespace = *((int*)bytes); bytes += sizeof(int);
|
||||
|
||||
[windowController adjustLinespace:linespace];
|
||||
} else if (ActivateMsgID == msgid) {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
[[windowController window] makeKeyAndOrderFront:self];
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
- (BOOL)checkForModifiedBuffers;
|
||||
- (oneway void)setDialogReturn:(in bycopy id)obj;
|
||||
- (BOOL)starRegisterToPasteboard:(byref NSPasteboard *)pboard;
|
||||
- (NSString *)evaluateExpression:(in bycopy NSString *)expr;
|
||||
@end
|
||||
|
||||
|
||||
@@ -62,6 +63,7 @@
|
||||
@protocol MMAppProtocol
|
||||
- (byref id <MMFrontendProtocol>)connectBackend:
|
||||
(byref in id <MMBackendProtocol>)backend pid:(int)pid;
|
||||
- (NSArray *)serverList;
|
||||
@end
|
||||
|
||||
|
||||
@@ -119,6 +121,8 @@ enum {
|
||||
MouseMovedMsgID,
|
||||
SetMouseShapeMsgID,
|
||||
AdjustLinespaceMsgID,
|
||||
ActivateMsgID,
|
||||
ServerAddInputMsgID,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ char *MessageStrings[] =
|
||||
"MouseMovedMsgID",
|
||||
"SetMouseShapeMsgID",
|
||||
"AdjustLinespaceMsgID",
|
||||
"ActivateMsgID",
|
||||
"ServerAddInputMsgID",
|
||||
};
|
||||
|
||||
|
||||
|
||||
+209
@@ -1247,6 +1247,7 @@ gui_mch_invert_rectangle(int r, int c, int nr, int nc)
|
||||
void
|
||||
gui_mch_set_foreground(void)
|
||||
{
|
||||
[[MMBackend sharedInstance] activate];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1326,3 +1327,211 @@ gui_macvim_is_valid_action(NSString *action)
|
||||
|
||||
return [actionDict objectForKey:action] != nil;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- Client/Server ---------------------------------------------------------
|
||||
|
||||
#ifdef MAC_CLIENTSERVER
|
||||
|
||||
//
|
||||
// NOTE: Client/Server stuff only works with the GUI. Theoretically it would
|
||||
// be possible to make this code work with terminal Vim, but it would require
|
||||
// that a run-loop is set up and checked, etc.
|
||||
//
|
||||
|
||||
static unsigned MMServerMax = 1000;
|
||||
static NSTimeInterval MMEvaluateExpressionTimeout = 3;
|
||||
static NSTimeInterval MMServerListTimeout = 3;
|
||||
|
||||
|
||||
static NSString *
|
||||
shortToLongName(NSString *shortName)
|
||||
{
|
||||
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
|
||||
|
||||
return [NSString stringWithFormat:@"%@.%@", bundleIdentifier, shortName];
|
||||
}
|
||||
|
||||
|
||||
static NSString *
|
||||
longToShortName(NSString *longName)
|
||||
{
|
||||
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
|
||||
NSRange range = [longName rangeOfString:bundleIdentifier];
|
||||
|
||||
return NSNotFound != range.location
|
||||
? [longName substringFromIndex:1+NSMaxRange(range)]
|
||||
: longName;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Register connection with 'name'. The actual connection is named something
|
||||
* like 'org.vim.MacVim.VIM3', whereas the server is called 'VIM3'.
|
||||
*/
|
||||
void
|
||||
serverSetName(char_u *name)
|
||||
{
|
||||
NSString *baseName =
|
||||
shortToLongName([NSString stringWithUTF8String:(char*)name]);
|
||||
NSString *longName = baseName;
|
||||
NSConnection *connection = [NSConnection defaultConnection];
|
||||
unsigned i;
|
||||
|
||||
for (i = 1; i < MMServerMax; ++i) {
|
||||
//NSLog(@"Client-Server: Try to register connection '%@'", longName);
|
||||
if ([connection registerName:longName]) {
|
||||
NSString *shortName = longToShortName(longName);
|
||||
|
||||
//NSLog(@"Client-Server: Did register server '%@'", shortName);
|
||||
serverName = vim_strsave((char_u*)[shortName UTF8String]);
|
||||
#ifdef FEAT_EVAL
|
||||
set_vim_var_string(VV_SEND_SERVER, serverName, -1);
|
||||
#endif
|
||||
#ifdef FEAT_TITLE
|
||||
need_maketitle = TRUE;
|
||||
#endif
|
||||
|
||||
// Don't wait for requests (time-out means that the message is
|
||||
// dropped).
|
||||
[connection setRequestTimeout:0];
|
||||
//[connection setReplyTimeout:MMReplyTimeout];
|
||||
[connection setRootObject:[MMBackend sharedInstance]];
|
||||
break;
|
||||
}
|
||||
|
||||
longName = [NSString stringWithFormat:@"%@%d", baseName, i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send to an instance of Vim.
|
||||
* Returns 0 for OK, negative for an error.
|
||||
*/
|
||||
int
|
||||
serverSendToVim(char_u *name, char_u *cmd, char_u **result,
|
||||
int *server, int asExpr, int silent)
|
||||
{
|
||||
//NSLog(@"serverSendToVim(name=%s, cmd=%s, asExpr=%d, silent=%d)",
|
||||
// name, cmd, asExpr, silent);
|
||||
|
||||
NSString *longName =
|
||||
shortToLongName([NSString stringWithUTF8String:(char*)name]);
|
||||
NSConnection *connection = [NSConnection
|
||||
connectionWithRegisteredName:longName host:nil];
|
||||
|
||||
if (!connection) {
|
||||
if (!silent)
|
||||
EMSG2(_(e_noserver), name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
[connection setRequestTimeout:0];
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
// Expressions need to wait for a reply; otherwise just send off the input
|
||||
// asynchronously.
|
||||
if (asExpr) {
|
||||
[connection setReplyTimeout:MMEvaluateExpressionTimeout];
|
||||
@try {
|
||||
NSString *expr = [NSString stringWithUTF8String:(char*)cmd];
|
||||
NSString *eval = [proxy evaluateExpression:expr];
|
||||
if (result) {
|
||||
*result = (eval ? vim_strsave((char_u*)[eval UTF8String])
|
||||
: vim_strsave((char_u*)_(e_invexprmsg)));
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"WARNING: Caught exception during expression evaluation "
|
||||
"\"%@\"", e);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
int len = 1 + STRLEN(cmd);
|
||||
NSMutableData *data = [NSMutableData data];
|
||||
|
||||
[data appendBytes:&len length:sizeof(int)];
|
||||
[data appendBytes:cmd length:len];
|
||||
|
||||
[proxy processInput:ServerAddInputMsgID data:data];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ask MacVim for the names of all Vim servers.
|
||||
*/
|
||||
char_u *
|
||||
serverGetVimNames(void)
|
||||
{
|
||||
char_u *names = NULL;
|
||||
NSString *name = [[MMBackend sharedInstance] macVimConnectionName];
|
||||
NSConnection *connection = [NSConnection connectionWithRegisteredName:name
|
||||
host:nil];
|
||||
if (connection) {
|
||||
NSArray *serverNames = nil;
|
||||
id proxy = [connection rootProxy];
|
||||
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
[connection setRequestTimeout:0];
|
||||
[connection setReplyTimeout:MMServerListTimeout];
|
||||
|
||||
@try {
|
||||
serverNames = [proxy serverList];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when listing servers: \"%@\"", e);
|
||||
}
|
||||
|
||||
if (serverNames) {
|
||||
NSString *string = [serverNames componentsJoinedByString:@"\n"];
|
||||
names = vim_strsave((char_u*)[string UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check for replies from 'serverid'.
|
||||
* Return TRUE and a non-malloc'ed string if there is. Else return FALSE.
|
||||
*/
|
||||
int
|
||||
serverPeekReply(char_u *serverid, char_u **str)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait for replies from server 'name'.
|
||||
* Return 0 and the malloc'ed string when a reply is available.
|
||||
* Return -1 on error.
|
||||
*/
|
||||
int
|
||||
serverReadReply(char_u *name, char_u **str)
|
||||
{
|
||||
//NSLog(@"serverReadReply(name=%s)", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send a reply string (notification) to client with id "name".
|
||||
* Return -1 if the window is invalid.
|
||||
*/
|
||||
int
|
||||
serverSendReply(char_u *name, char_u *reply)
|
||||
{
|
||||
//NSLog(@"serverSendReply(name=%s, reply=%s)", name, reply);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // MAC_CLIENTSERVER
|
||||
|
||||
Reference in New Issue
Block a user