ODB Editor protocol (aka 'external editor') support

Programs that support ODB asks MacVim to open files. When a file is written or
closed, MacVim notifies the program of these events. (At the moment the 'Burl'
parameter is parsed but ignored. The 'RdEV' parameter is ignored.)
This commit is contained in:
Bjorn Winckler
2007-11-27 21:07:08 +01:00
parent 3a36672982
commit f99ce72a11
19 changed files with 466 additions and 24 deletions
+4
View File
@@ -102,6 +102,10 @@ window, unless Vim is in command-line mode. In command-line mode the names of
the files are added to the command line. Holding down modifier keys whilst
dragging is not supported.
If a file is dropped on the Dock icon, it is always opened in a new tab
regardless of the mode Vim is currently in. The same holds if you
double-click on a file in the Finder.
*macvim-default-menu*
The default menu in MacVim has been changed to conform better with the Apple
Human Interface Guidelines (HIG). At the moment this breaks the localized
+1 -1
View File
@@ -531,7 +531,7 @@
<key>CFBundleIconFile</key>
<string>vim_gloss</string>
<key>CFBundleIdentifier</key>
<string>org.vim.MacVim</string>
<string>org.vim.MacVim-odb</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
+1
View File
@@ -20,6 +20,7 @@
NSString *openSelectionString;
ATSFontContainerRef fontContainerRef;
BOOL untitledWindowOpening;
NSMutableDictionary *pidArguments;
}
- (void)removeVimController:(id)controller;
+141 -17
View File
@@ -32,6 +32,7 @@
// Default timeout intervals on all connections.
static NSTimeInterval MMRequestTimeout = 5;
static NSTimeInterval MMReplyTimeout = 5;
@@ -49,9 +50,13 @@ static NSTimeInterval MMReplyTimeout = 5;
@interface MMAppController (Private)
- (MMVimController *)keyVimController;
- (MMVimController *)topmostVimController;
- (void)launchVimProcessWithArguments:(NSArray *)args;
- (int)launchVimProcessWithArguments:(NSArray *)args;
- (NSArray *)filterFilesAndNotify:(NSArray *)files;
- (NSArray *)filterOpenFilesAndRaiseFirst:(NSArray *)filenames;
- (NSArray *)filterOpenFiles:(NSArray *)filenames remote:(OSType)theID
path:(NSString *)path
token:(NSAppleEventDescriptor *)token;
- (void)handleXcodeModEvent:(NSAppleEventDescriptor *)event
replyEvent:(NSAppleEventDescriptor *)reply;
@end
@interface NSMenu (MMExtras)
@@ -99,6 +104,7 @@ static NSTimeInterval MMReplyTimeout = 5;
fontContainerRef = loadFonts();
vimControllers = [NSMutableArray new];
pidArguments = [NSMutableDictionary new];
// NOTE! If the name of the connection changes here it must also be
// updated in MMBackend.m.
@@ -128,12 +134,22 @@ static NSTimeInterval MMReplyTimeout = 5;
{
//NSLog(@"MMAppController dealloc");
[pidArguments release];
[vimControllers release];
[openSelectionString release];
[super dealloc];
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[[NSAppleEventManager sharedAppleEventManager]
setEventHandler:self
andSelector:@selector(handleXcodeModEvent:replyEvent:)
forEventClass:'KAHL'
andEventID:'MOD '];
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp setServicesProvider:self];
@@ -150,26 +166,79 @@ static NSTimeInterval MMReplyTimeout = 5;
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender
{
//NSLog(@"%s NSapp=%@ theApp=%@", _cmd, NSApp, sender);
[self newWindow:self];
return YES;
}
- (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
{
filenames = [self filterOpenFilesAndRaiseFirst:filenames];
OSType remoteID;
NSString *remotePath;
NSAppleEventDescriptor *remoteToken;
NSAppleEventDescriptor *odbdesc =
[[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
if (![odbdesc paramDescriptorForKeyword:keyFileSender]) {
// The ODB paramaters may hide inside the 'keyAEPropData' descriptor.
odbdesc = [odbdesc paramDescriptorForKeyword:keyAEPropData];
if (![odbdesc paramDescriptorForKeyword:keyFileSender])
odbdesc = nil;
}
if (odbdesc) {
remoteID = [[odbdesc paramDescriptorForKeyword:keyFileSender]
typeCodeValue];
remotePath = [[odbdesc paramDescriptorForKeyword:keyFileCustomPath]
stringValue];
remoteToken = [[odbdesc paramDescriptorForKeyword:keyFileSenderToken]
copy];
//NSLog(@"ODB parameters: ID=0x%x path=%@ token=%@",
// remoteID, remotePath, remoteToken);
}
filenames = [self filterOpenFiles:filenames remote:remoteID path:remotePath
token:remoteToken];
if ([filenames count]) {
MMVimController *vc;
BOOL openInTabs = [[NSUserDefaults standardUserDefaults]
boolForKey:MMOpenFilesInTabsKey];
if (openInTabs && (vc = [self topmostVimController])) {
[vc dropFiles:filenames];
// Open files in tabs in the topmost window.
[vc dropFiles:filenames forceOpen:YES];
if (odbdesc)
[vc odbEdit:filenames server:remoteID path:remotePath
token:remoteToken];
} else {
// Open files in tabs in a new window.
NSMutableArray *args = [NSMutableArray arrayWithObject:@"-p"];
[args addObjectsFromArray:filenames];
[self launchVimProcessWithArguments:args];
int pid = [self launchVimProcessWithArguments:args];
// The Vim process starts asynchronously. Some arguments cannot be
// on the command line, so store them in a dictionary and pass them
// to the process once it has started.
//
// TODO: If the Vim process fails to start, or if it changes PID,
// then the memory allocated for these parameters will leak.
// Ensure that this cannot happen or somehow detect it.
if (odbdesc) {
// The remote token can be arbitrary data so it is cannot
// (without encoding it as text) be passed on the command line.
NSMutableDictionary *args =
[NSMutableDictionary dictionaryWithObjectsAndKeys:
filenames, @"filenames",
[NSNumber numberWithUnsignedInt:remoteID], @"remoteID",
nil];
if (remotePath)
[args setObject:remotePath forKey:@"remotePath"];
if (remoteToken)
[args setObject:remoteToken forKey:@"remoteToken"];
[pidArguments setObject:args
forKey:[NSNumber numberWithInt:pid]];
}
}
}
@@ -232,8 +301,12 @@ static NSTimeInterval MMReplyTimeout = 5;
return reply;
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
- (void)applicationWillTerminate:(NSNotification *)notification
{
[[NSAppleEventManager sharedAppleEventManager]
removeEventHandlerForEventClass:'KAHL'
andEventID:'MOD '];
// This will invalidate all connections (since they were spawned from the
// default connection).
[[NSConnection defaultConnection] invalidate];
@@ -382,8 +455,7 @@ static NSTimeInterval MMReplyTimeout = 5;
connectBackend:(byref in id <MMBackendProtocol>)backend
pid:(int)pid
{
//NSLog(@"Frontend got connection request from backend...adding new "
// "MMVimController");
//NSLog(@"Connect backend (pid=%d)", pid);
[(NSDistantObject*)backend
setProtocolForProxy:@protocol(MMBackendProtocol)];
@@ -410,6 +482,21 @@ static NSTimeInterval MMReplyTimeout = 5;
untitledWindowOpening = NO;
// Arguments to a new Vim process that cannot be passed on the command line
// are stored in a dictionary and passed to the Vim process here.
NSNumber *key = [NSNumber numberWithInt:pid];
NSDictionary *args = [pidArguments objectForKey:key];
if (args) {
if ([args objectForKey:@"remoteID"]) {
[vc odbEdit:[args objectForKey:@"filenames"]
server:[[args objectForKey:@"remoteID"] unsignedIntValue]
path:[args objectForKey:@"remotePath"]
token:[args objectForKey:@"remoteToken"]];
}
[pidArguments removeObjectForKey:key];
}
return vc;
}
@@ -483,7 +570,7 @@ static NSTimeInterval MMReplyTimeout = 5;
vc = [self topmostVimController];
if (vc) {
[vc dropFiles:filenames];
[vc dropFiles:filenames forceOpen:YES];
} else {
[self application:NSApp openFiles:filenames];
}
@@ -528,7 +615,7 @@ static NSTimeInterval MMReplyTimeout = 5;
return nil;
}
- (void)launchVimProcessWithArguments:(NSArray *)args
- (int)launchVimProcessWithArguments:(NSArray *)args
{
NSString *taskPath = nil;
NSArray *taskArgs = nil;
@@ -536,7 +623,7 @@ static NSTimeInterval MMReplyTimeout = 5;
if (!path) {
NSLog(@"ERROR: Vim executable could not be found inside app bundle!");
return;
return 0;
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:MMLoginShellKey]) {
@@ -577,8 +664,12 @@ static NSTimeInterval MMReplyTimeout = 5;
taskArgs = [taskArgs arrayByAddingObjectsFromArray:args];
}
//NSLog(@"Launching: %@ args: %@", taskPath, taskArgs);
[NSTask launchedTaskWithLaunchPath:taskPath arguments:taskArgs];
NSTask *task =[NSTask launchedTaskWithLaunchPath:taskPath
arguments:taskArgs];
//NSLog(@"launch %@ with args=%@ (pid=%d)", [task processIdentifier],
// taskPath, taskArgs);
return [task processIdentifier];
}
- (NSArray *)filterFilesAndNotify:(NSArray *)filenames
@@ -627,12 +718,15 @@ static NSTimeInterval MMReplyTimeout = 5;
return files;
}
- (NSArray *)filterOpenFilesAndRaiseFirst:(NSArray *)filenames
- (NSArray *)filterOpenFiles:(NSArray *)filenames remote:(OSType)theID
path:(NSString *)path
token:(NSAppleEventDescriptor *)token
{
// Check if any of the files in the 'filenames' array are open in any Vim
// process. Remove the files that are open from the 'filenames' array and
// return it. If all files were filtered out, then raise the first file in
// the Vim process it is open.
// the Vim process it is open. Files that are filtered are sent an odb
// open event in case theID is not zero.
MMVimController *raiseController = nil;
NSString *raiseFile = nil;
@@ -658,6 +752,11 @@ static NSTimeInterval MMReplyTimeout = 5;
[[raiseFile retain] autorelease];
}
// Send an odb open event to the Vim process.
if (theID != 0)
[controller odbEdit:[files objectsAtIndexes:idxSet]
server:theID path:path token:token];
// Remove all the files that were open in this Vim process and
// create a new expression to evaluate.
[files removeObjectsAtIndexes:idxSet];
@@ -688,6 +787,31 @@ static NSTimeInterval MMReplyTimeout = 5;
return files;
}
- (void)handleXcodeModEvent:(NSAppleEventDescriptor *)event
replyEvent:(NSAppleEventDescriptor *)reply
{
#if 0
// Xcode sends this event to query MacVim which open files have been
// modified.
NSLog(@"reply:%@", reply);
NSLog(@"event:%@", event);
NSEnumerator *e = [vimControllers objectEnumerator];
id vc;
while ((vc = [e nextObject])) {
DescType type = [reply descriptorType];
unsigned len = [[type data] length];
NSMutableData *data = [NSMutableData data];
[data appendBytes:&type length:sizeof(DescType)];
[data appendBytes:&len length:sizeof(unsigned)];
[data appendBytes:[reply data] length:len];
[vc sendMessage:XcodeModMsgID data:data];
}
#endif
}
@end // MMAppController (Private)
+109 -2
View File
@@ -85,6 +85,8 @@ enum {
- (void)handleSetFont:(NSData *)data;
- (void)handleDropFiles:(NSData *)data;
- (void)handleDropString:(NSData *)data;
- (void)handleOdbEdit:(NSData *)data;
- (void)handleXcodeMod:(NSData *)data;
- (BOOL)checkForModifiedBuffers;
- (void)addInput:(NSString *)input;
@end
@@ -392,10 +394,12 @@ enum {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantPast]];
#if 0
// Keyboard and mouse input is handled directly, other input is queued and
// processed here. This call may enter a blocking loop.
if ([inputQueue count] > 0)
[self processInputQueue];
#endif
}
- (void)flushQueue:(BOOL)force
@@ -451,6 +455,8 @@ enum {
BOOL yn = inputReceived;
inputReceived = NO;
// Keyboard and mouse input is handled directly, other input is queued and
// processed here. This call may enter a blocking loop.
if ([inputQueue count] > 0)
[self processInputQueue];
@@ -1586,6 +1592,10 @@ enum {
const void *bytes = [data bytes];
int shape = *((int*)bytes); bytes += sizeof(int);
update_mouseshape(shape);
} else if (ODBEditMsgID == msgid) {
[self handleOdbEdit:data];
} else if (XcodeModMsgID == msgid) {
[self handleXcodeMod:data];
} else {
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
}
@@ -1959,12 +1969,14 @@ enum {
#ifdef FEAT_DND
const void *bytes = [data bytes];
const void *end = [data bytes] + [data length];
BOOL forceOpen = *((BOOL*)bytes); bytes += sizeof(BOOL);
int n = *((int*)bytes); bytes += sizeof(int);
if (State & CMDLINE) {
if (!forceOpen && (State & CMDLINE)) {
// HACK! If Vim is in command line mode then the files names
// should be added to the command line, instead of opening the
// files in tabs. This is taken care of by gui_handle_drop().
// files in tabs (unless forceOpen is set). This is taken care of by
// gui_handle_drop().
char_u **fnames = (char_u **)alloc(n * sizeof(char_u *));
if (fnames) {
int i = 0;
@@ -1990,7 +2002,12 @@ enum {
// HACK! I'm not sure how to get Vim to open a list of files in
// tabs, so instead I create a ':tab drop' command with all the
// files to open and execute it.
#if 1
NSMutableString *cmd = [NSMutableString stringWithString:@":tab drop"];
#else
NSMutableString *cmd = [NSMutableString stringWithString:
@"<C-\\><C-N>:tab drop"];
#endif
int i;
for (i = 0; i < n && bytes < end; ++i) {
@@ -2003,6 +2020,7 @@ enum {
[cmd appendString:file];
}
#if 1
// By going to the last tabpage we ensure that the new tabs will
// appear last (if this call is left out, the taborder becomes
// messy).
@@ -2025,6 +2043,11 @@ enum {
gui_update_cursor(FALSE, FALSE);
maketitle();
gui_mch_flush();
#else
[cmd appendString:@"|redr|f<CR>"];
[self addInput:cmd];
#endif
}
#endif // FEAT_DND
}
@@ -2064,6 +2087,90 @@ enum {
#endif // FEAT_DND
}
- (void)handleOdbEdit:(NSData *)data
{
#ifdef FEAT_ODB_EDITOR
const void *bytes = [data bytes];
OSType serverID = *((OSType*)bytes); bytes += sizeof(OSType);
char_u *path = NULL;
int pathLen = *((int*)bytes); bytes += sizeof(int);
if (pathLen > 0) {
path = (char_u*)bytes;
bytes += pathLen;
#ifdef FEAT_MBYTE
path = CONVERT_FROM_UTF8(path);
#endif
}
NSAppleEventDescriptor *token = nil;
DescType tokenType = *((DescType*)bytes); bytes += sizeof(DescType);
int descLen = *((int*)bytes); bytes += sizeof(int);
if (descLen > 0) {
token = [NSAppleEventDescriptor descriptorWithDescriptorType:tokenType
bytes:bytes
length:descLen];
bytes += descLen;
}
unsigned i, numFiles = *((unsigned*)bytes); bytes += sizeof(unsigned);
for (i = 0; i < numFiles; ++i) {
int len = *((int*)bytes); bytes += sizeof(int);
char_u *filename = (char_u*)bytes;
#ifdef FEAT_MBYTE
filename = CONVERT_FROM_UTF8(filename);
#endif
buf_T *buf = buflist_findname(filename);
if (buf) {
if (buf->b_odb_token) {
[(NSAppleEventDescriptor*)(buf->b_odb_token) release];
buf->b_odb_token = NULL;
}
if (buf->b_odb_fname) {
vim_free(buf->b_odb_fname);
buf->b_odb_fname = NULL;
}
buf->b_odb_server_id = serverID;
if (token)
buf->b_odb_token = [token retain];
if (path)
buf->b_odb_fname = vim_strsave(path);
} else {
NSLog(@"WARNING: Could not find buffer '%s' for ODB editing.",
filename);
}
#ifdef FEAT_MBYTE
CONVERT_FROM_UTF8_FREE(filename);
#endif
bytes += len;
}
#ifdef FEAT_MBYTE
CONVERT_FROM_UTF8_FREE(path);
#endif
#endif // FEAT_ODB_EDITOR
}
- (void)handleXcodeMod:(NSData *)data
{
#if 0
const void *bytes = [data bytes];
DescType type = *((DescType*)bytes); bytes += sizeof(DescType);
unsigned len = *((unsigned*)bytes); bytes += sizeof(unsigned);
if (0 == len)
return;
NSAppleEventDescriptor *replyEvent = [NSAppleEventDescriptor
descriptorWithDescriptorType:type
bytes:bytes
length:len];
#endif
}
- (BOOL)checkForModifiedBuffers
{
buf_T *buf;
+1 -1
View File
@@ -699,7 +699,7 @@ static NSString *MMKeypadEnterString = @"KA";
return YES;
} else if ([[pboard types] containsObject:NSFilenamesPboardType]) {
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
[[self vimController] dropFiles:files];
[[self vimController] dropFiles:files forceOpen:NO];
return YES;
}
+3 -1
View File
@@ -49,8 +49,10 @@
- (NSString *)serverName;
- (MMWindowController *)windowController;
- (void)cleanup;
- (void)dropFiles:(NSArray *)filenames;
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force;
- (void)dropString:(NSString *)string;
- (void)odbEdit:(NSArray *)filenames server:(OSType)theID path:(NSString *)path
token:(NSAppleEventDescriptor *)token;
- (void)sendMessage:(int)msgid data:(NSData *)data;
- (BOOL)sendMessageNow:(int)msgid data:(NSData *)data
timeout:(NSTimeInterval)timeout;
+56 -2
View File
@@ -182,11 +182,12 @@ static NSTimeInterval MMResendInterval = 0.5;
return pid;
}
- (void)dropFiles:(NSArray *)filenames
- (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force
{
int i, numberOfFiles = [filenames count];
unsigned i, numberOfFiles = [filenames count];
NSMutableData *data = [NSMutableData data];
[data appendBytes:&force length:sizeof(BOOL)];
[data appendBytes:&numberOfFiles length:sizeof(int)];
for (i = 0; i < numberOfFiles; ++i) {
@@ -216,6 +217,59 @@ static NSTimeInterval MMResendInterval = 0.5;
}
}
- (void)odbEdit:(NSArray *)filenames server:(OSType)theID path:(NSString *)path
token:(NSAppleEventDescriptor *)token
{
int len;
unsigned i, numberOfFiles = [filenames count];
NSMutableData *data = [NSMutableData data];
if (0 == numberOfFiles || 0 == theID)
return;
[data appendBytes:&theID length:sizeof(theID)];
if (path && [path length] > 0) {
len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
[data appendBytes:&len length:sizeof(int)];
[data appendBytes:[path UTF8String] length:len];
} else {
len = 0;
[data appendBytes:&len length:sizeof(int)];
}
if (token) {
DescType tokenType = [token descriptorType];
NSData *tokenData = [token data];
len = [tokenData length];
[data appendBytes:&tokenType length:sizeof(tokenType)];
[data appendBytes:&len length:sizeof(int)];
if (len > 0)
[data appendBytes:[tokenData bytes] length:len];
} else {
DescType tokenType = 0;
len = 0;
[data appendBytes:&tokenType length:sizeof(tokenType)];
[data appendBytes:&len length:sizeof(int)];
}
[data appendBytes:&numberOfFiles length:sizeof(int)];
for (i = 0; i < numberOfFiles; ++i) {
NSString *file = [filenames objectAtIndex:i];
len = [file lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if (len > 0) {
++len; // include NUL as well
[data appendBytes:&len length:sizeof(unsigned)];
[data appendBytes:[file UTF8String] length:len];
}
}
[self sendMessage:ODBEditMsgID data:data];
}
- (void)sendMessage:(int)msgid data:(NSData *)data
{
//NSLog(@"sendMessage:%s (isInitialized=%d inProcessCommandQueue=%d)",
+16
View File
@@ -157,6 +157,8 @@ enum {
AddInputMsgID,
SetPreEditPositionMsgID,
TerminateNowMsgID,
ODBEditMsgID,
XcodeModMsgID,
};
@@ -234,3 +236,17 @@ ATSFontContainerRef loadFonts();
@interface NSIndexSet (MMExtras)
+ (id)indexSetWithVimList:(NSString *)list;
@end
// ODB Editor Suite Constants (taken from ODBEditorSuite.h)
#define keyFileSender 'FSnd'
#define keyFileSenderToken 'FTok'
#define keyFileCustomPath 'Burl'
#define kODBEditorSuite 'R*ch'
#define kAEModifiedFile 'FMod'
#define keyNewLocation 'New?'
#define kAEClosedFile 'FCls'
#define keySenderToken 'Tokn'
+2
View File
@@ -70,6 +70,8 @@ char *MessageStrings[] =
"AddInputMsgID",
"SetPreEditPositionMsgID",
"TerminateNowMsgID",
"ODBEditMsgID",
"XcodeModMsgID",
};
+90
View File
@@ -1708,3 +1708,93 @@ serverSendReply(char_u *serverid, char_u *reply)
}
#endif // MAC_CLIENTSERVER
// -- ODB Editor Support ----------------------------------------------------
#ifdef FEAT_ODB_EDITOR
/*
* The ODB Editor protocol works like this:
* - An external program (the server) asks MacVim to open a file and associates
* three things with this file: (1) a server id (a four character code that
* identifies the server), (2) a path that can be used as window title for
* the file (optional), (3) an arbitrary token (optional)
* - When a file is saved or closed, MacVim should tell the server about which
* file was modified and also pass back the token
*
* All communication between MacVim and the server goes via Apple Events.
*/
static OSErr
odb_event(buf_T *buf, const AEEventID action)
{
if (!(buf->b_odb_server_id && buf->b_ffname))
return noErr;
NSAppleEventDescriptor *targetDesc = [NSAppleEventDescriptor
descriptorWithDescriptorType:typeApplSignature
bytes:&buf->b_odb_server_id
length:sizeof(OSType)];
NSString *path = [NSString stringWithUTF8String:(char*)buf->b_ffname];
NSData *pathData = [[[NSURL fileURLWithPath:path] absoluteString]
dataUsingEncoding:NSUTF8StringEncoding];
NSAppleEventDescriptor *pathDesc = [NSAppleEventDescriptor
descriptorWithDescriptorType:typeFileURL data:pathData];
NSAppleEventDescriptor *event = [NSAppleEventDescriptor
appleEventWithEventClass:kODBEditorSuite
eventID:action
targetDescriptor:targetDesc
returnID:kAutoGenerateReturnID
transactionID:kAnyTransactionID];
[event setParamDescriptor:pathDesc forKeyword:keyDirectObject];
if (buf->b_odb_token)
[event setParamDescriptor:buf->b_odb_token forKeyword:keySenderToken];
return AESendMessage([event aeDesc], NULL, kAENoReply | kAENeverInteract,
kAEDefaultTimeout);
}
OSErr
odb_buffer_close(buf_T *buf)
{
OSErr err = noErr;
if (buf) {
err = odb_event(buf, kAEClosedFile);
buf->b_odb_server_id = 0;
if (buf->b_odb_token) {
[(NSAppleEventDescriptor *)(buf->b_odb_token) release];
buf->b_odb_token = NULL;
}
if (buf->b_odb_fname) {
vim_free(buf->b_odb_fname);
buf->b_odb_fname = NULL;
}
}
return err;
}
OSErr
odb_post_buffer_write(buf_T *buf)
{
return buf ? odb_event(buf, kAEModifiedFile) : noErr;
}
void
odb_end(void)
{
buf_T *buf;
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
odb_buffer_close(buf);
}
#endif // FEAT_ODB_EDITOR
+4
View File
@@ -441,6 +441,10 @@ close_buffer(win, buf, action)
if (usingNetbeans)
netbeans_file_closed(buf);
#endif
#ifdef FEAT_ODB_EDITOR
odb_buffer_close(buf);
#endif
/* Change directories when the 'acd' option is set. */
DO_AUTOCHDIR
+9
View File
@@ -10865,6 +10865,9 @@ f_has(argvars, rettv)
#if !defined(USE_SYSTEM) && defined(UNIX)
"fork",
#endif
#ifdef FEAT_FULLSCREEN
"fullscreen",
#endif
#ifdef FEAT_GETTEXT
"gettext",
#endif
@@ -11052,6 +11055,9 @@ f_has(argvars, rettv)
#ifdef FEAT_NETBEANS_INTG
"netbeans_intg",
#endif
#ifdef FEAT_ODB_EDITOR
"odbeditor",
#endif
#ifdef FEAT_SPELL
"spell",
#endif
@@ -11093,6 +11099,9 @@ f_has(argvars, rettv)
#ifdef FEAT_TOOLBAR
"toolbar",
#endif
#ifdef FEAT_TRANSPARENCY
"transparency",
#endif
#ifdef FEAT_USR_CMDS
"user-commands", /* was accidentally included in 5.4 */
"user_commands",
+7
View File
@@ -1282,3 +1282,10 @@
#ifdef FEAT_GUI_MACVIM
# define FEAT_FULLSCREEN
#endif
/*
* +odbeditor ODBEditor protocol support (aka. external editor)
*/
#ifdef FEAT_GUI_MACVIM
# define FEAT_ODB_EDITOR
#endif
+4
View File
@@ -4717,6 +4717,10 @@ nofail:
/* Update machine specific information. */
mch_post_buffer_write(buf);
#endif
#ifdef FEAT_ODB_EDITOR
odb_post_buffer_write(buf);
#endif
return retval;
}
+3
View File
@@ -1375,6 +1375,9 @@ getout(exitval)
#ifdef FEAT_NETBEANS_INTG
netbeans_end();
#endif
#ifdef FEAT_ODB_EDITOR
odb_end();
#endif
#ifdef FEAT_CSCOPE
cs_end();
#endif
+5
View File
@@ -194,3 +194,8 @@ void gui_mch_enter_fullscreen(void);
void gui_mch_leave_fullscreen(void);
void gui_macvim_update_modified_flag();
OSErr odb_buffer_close(buf_T *buf);
OSErr odb_post_buffer_write(buf_T *buf);
void odb_end(void);
+5
View File
@@ -1583,6 +1583,11 @@ struct file_buffer
int b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */
#endif
#ifdef FEAT_ODB_EDITOR
OSType b_odb_server_id; /* FourCC of the ODB server (0 if none) */
void *b_odb_token; /* NSAppleEventDescriptor (optional) */
char_u *b_odb_fname; /* Custom file name (optional) */
#endif
};
+5
View File
@@ -395,6 +395,11 @@ static char *(features[]) =
#else
"-netbeans_intg",
#endif
#ifdef FEAT_ODB_EDITOR
"+odbeditor",
#else
"-odbeditor",
#endif
#ifdef FEAT_GUI_W32
# ifdef FEAT_OLE
"+ole",