From 2dbe83f70442d8a39484271ad4dbd048748e8e10 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Wed, 30 Jan 2008 22:05:55 +0100 Subject: [PATCH] Warn if multiple tabs or windows are open when quitting --- src/MacVim/MMAppController.m | 98 ++++++++++++++++++++++++++---------- src/MacVim/MMVimController.h | 1 + src/MacVim/MMVimController.m | 12 +++++ 3 files changed, 84 insertions(+), 27 deletions(-) diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 442b42df8a..cd27f6b1e0 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -333,8 +333,56 @@ typedef struct reply = NSTerminateCancel; [alert release]; + } else { + // No unmodified buffers, but give a warning if there are multiple + // windows and/or tabs open. + int numWindows = [vimControllers count]; + int numTabs = 0; + + e = [vimControllers objectEnumerator]; + id vc; + while ((vc = [e nextObject])) { + NSString *eval = [vc evaluateVimExpression:@"tabpagenr('$')"]; + if (eval) { + int count = [eval intValue]; + if (count > 0 && count < INT_MAX) + numTabs += count; + } + } + + if (numWindows > 1 || numTabs > 1) { + NSAlert *alert = [[NSAlert alloc] init]; + [alert addButtonWithTitle:@"Quit"]; + [alert addButtonWithTitle:@"Cancel"]; + [alert setMessageText:@"Are you sure you want to quit MacVim?"]; + + NSString *info = nil; + if (numWindows > 1) { + if (numTabs > numWindows) + info = [NSString stringWithFormat:@"There are %d windows " + "open in MacVim, with a total of %d tabs. Do you want " + "to quit anyway?", numWindows, numTabs]; + else + info = [NSString stringWithFormat:@"There are %d windows " + "open in MacVim. Do you want to quit anyway?", + numWindows]; + + [alert setAlertStyle:NSWarningAlertStyle]; + } else { + info = [NSString stringWithFormat:@"There are %d tabs open " + "in MacVim. Do you want to quit anyway?", numTabs]; + } + + [alert setInformativeText:info]; + + if ([alert runModal] != NSAlertFirstButtonReturn) + reply = NSTerminateCancel; + + [alert release]; + } } + // Tell all Vim processes to terminate now (otherwise they'll leave swap // files behind). if (NSTerminateNow == reply) { @@ -824,36 +872,32 @@ typedef struct for (i = 0; i < count && [files count]; ++i) { MMVimController *controller = [vimControllers objectAtIndex:i]; - id proxy = [controller backendProxy]; - @try { - // Query Vim for which files in the 'files' array are open. - NSString *eval = [proxy evaluateExpression:expr]; - NSIndexSet *idxSet = [NSIndexSet indexSetWithVimList:eval]; - if ([idxSet count]) { - if (!raiseFile) { - // Remember the file and which Vim that has it open so that - // we can raise it later on. - raiseController = controller; - raiseFile = [files objectAtIndex:[idxSet firstIndex]]; - [[raiseFile retain] autorelease]; - } + // Query Vim for which files in the 'files' array are open. + NSString *eval = [controller evaluateVimExpression:expr]; + if (!eval) continue; - // Pass (ODB/Xcode/Spotlight) arguments to this process. - [localArgs setObject:[files objectsAtIndexes:idxSet] - forKey:@"filenames"]; - [self passArguments:localArgs toVimController:controller]; - - // Remove all the files that were open in this Vim process and - // create a new expression to evaluate. - [files removeObjectsAtIndexes:idxSet]; - expr = [NSString stringWithFormat: - @"map([\"%@\"],\"bufloaded(v:val)\")", - [files componentsJoinedByString:@"\",\""]]; + NSIndexSet *idxSet = [NSIndexSet indexSetWithVimList:eval]; + if ([idxSet count]) { + if (!raiseFile) { + // Remember the file and which Vim that has it open so that + // we can raise it later on. + raiseController = controller; + raiseFile = [files objectAtIndex:[idxSet firstIndex]]; + [[raiseFile retain] autorelease]; } - } - @catch (NSException *e) { - // Do nothing ... + + // Pass (ODB/Xcode/Spotlight) arguments to this process. + [localArgs setObject:[files objectsAtIndexes:idxSet] + forKey:@"filenames"]; + [self passArguments:localArgs toVimController:controller]; + + // Remove all the files that were open in this Vim process and + // create a new expression to evaluate. + [files removeObjectsAtIndexes:idxSet]; + expr = [NSString stringWithFormat: + @"map([\"%@\"],\"bufloaded(v:val)\")", + [files componentsJoinedByString:@"\",\""]]; } } diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index 65b60ff365..a4889de3fc 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -57,5 +57,6 @@ - (BOOL)sendMessageNow:(int)msgid data:(NSData *)data timeout:(NSTimeInterval)timeout; - (void)addVimInput:(NSString *)string; +- (NSString *)evaluateVimExpression:(NSString *)expr; - (void)updateMainMenu; @end diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index a0d4559dcf..5bdc08e334 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -348,6 +348,18 @@ static NSTimeInterval MMResendInterval = 0.5; } } +- (NSString *)evaluateVimExpression:(NSString *)expr +{ + NSString *eval = nil; + + @try { + eval = [backendProxy evaluateExpression:expr]; + } + @catch (NSException *ex) { /* do nothing */ } + + return eval; +} + - (id)backendProxy { return backendProxy;