Permalink
Browse files

Add "Recent Files" menu

The recent files menu will only remember files opened from Finder and
not files opened from within Vim (via :e etc.).  Recent files will also
be added to the "Recent Items" menu under the Apple menu.

(Patch by Nico Weber with some modifications by Bjorn Winckler.)
  • Loading branch information...
1 parent 1576328 commit 862da53932e7285e38f68d81192ab4c97b06ddb5 @nico nico committed with May 9, 2008
@@ -6,6 +6,8 @@
<string></string>
<key>arrangeInFront:</key>
<string></string>
+ <key>clearRecentDocuments:</key>
+ <string></string>
<key>fileOpen:</key>
<string></string>
<key>findNext:</key>
@@ -38,6 +40,8 @@
<string></string>
<key>performZoom:</key>
<string></string>
+ <key>recentFilesDummy:</key>
+ <string></string>
<key>selectNextWindow:</key>
<string></string>
<key>selectPreviousWindow:</key>
@@ -20,6 +20,8 @@
NSString *openSelectionString;
ATSFontContainerRef fontContainerRef;
NSMutableDictionary *pidArguments;
+
+ NSMenuItem *recentFilesMenuItem;
}
- (void)removeVimController:(id)controller;
@@ -171,20 +171,45 @@ - (void)dealloc
[pidArguments release]; pidArguments = nil;
[vimControllers release]; vimControllers = nil;
[openSelectionString release]; openSelectionString = nil;
+ [recentFilesMenuItem release]; recentFilesMenuItem = nil;
[super dealloc];
}
-#if MM_HANDLE_XCODE_MOD_EVENT
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
+ // Create the "Open Recent" menu. See
+ // http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/
+ // and http://www.cocoabuilder.com/archive/message/cocoa/2007/8/15/187793
+ // for more information.
+ //
+ // The menu needs to be created and be added to a toplevel menu in
+ // applicationWillFinishLaunching at the latest, otherwise it doesn't work.
+
+ recentFilesMenuItem = [[NSMenuItem alloc] initWithTitle:@"Open Recent"
+ action:nil keyEquivalent:@""];
+
+ NSMenu *recentFilesMenu = [[NSMenu alloc] initWithTitle:@"Open Recent"];
+ [recentFilesMenu performSelector:@selector(_setMenuName:)
+ withObject:@"NSRecentDocumentsMenu"];
+
+ [recentFilesMenu addItemWithTitle:@"Clear Menu"
+ action:@selector(clearRecentDocuments:)
+ keyEquivalent:@""];
+ [recentFilesMenuItem setSubmenu:recentFilesMenu];
+ [recentFilesMenu release]; // the menu is retained by recentFilesMenuItem
+ [recentFilesMenuItem setTag:-1]; // must not be 0
+
+ [[[[NSApp mainMenu] itemWithTitle:@"File"] submenu] addItem:recentFilesMenuItem];
+
+#if MM_HANDLE_XCODE_MOD_EVENT
[[NSAppleEventManager sharedAppleEventManager]
setEventHandler:self
andSelector:@selector(handleXcodeModEvent:replyEvent:)
forEventClass:'KAHL'
andEventID:'MOD '];
-}
#endif
+}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
@@ -261,6 +286,18 @@ - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
[arguments setObject:filenames forKey:@"filenames"];
[arguments setObject:[NSNumber numberWithBool:YES] forKey:@"openFiles"];
+ // Add file names to "Recent Files" menu.
+ int i, count = [filenames count];
+ for (i = 0; i < count; ++i) {
+ // Don't add files that are being edited remotely (using ODB).
+ if ([arguments objectForKey:@"remoteID"]) continue;
+
+ NSURL *url = [NSURL fileURLWithPath:[filenames objectAtIndex:i]];
+ if (!url) continue;
+ [[NSDocumentController sharedDocumentController]
+ noteNewRecentDocumentURL:url];
+ }
+
if ((openInTabs && (vc = [self topmostVimController]))
|| (vc = [self findUntitledWindow])) {
// Open files in an already open window.
@@ -599,7 +636,8 @@ - (IBAction)openWebsite:(id)sender
setProtocolForProxy:@protocol(MMBackendProtocol)];
vc = [[[MMVimController alloc]
- initWithBackend:backend pid:pid] autorelease];
+ initWithBackend:backend pid:pid recentFiles:recentFilesMenuItem]
+ autorelease];
if (![vimControllers count]) {
// The first window autosaves its position. (The autosaving
@@ -40,9 +40,12 @@
NSData *resendData;
#endif
NSMenu *lastMenuSearched;
+ NSMenuItem *recentFilesMenuItem;
+ NSMenuItem *recentFilesDummy;
}
-- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
+- (id)initWithBackend:(id)backend pid:(int)processIdentifier
+ recentFiles:(NSMenuItem*)menu;
- (id)backendProxy;
- (int)pid;
- (void)setServerName:(NSString *)name;
@@ -81,6 +81,7 @@ - (void)connectionDidDie:(NSNotification *)notification;
#if MM_RESEND_LAST_FAILURE
- (void)resendTimerFired:(NSTimer *)timer;
#endif
+- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new;
@end
@@ -89,8 +90,12 @@ - (void)resendTimerFired:(NSTimer *)timer;
@implementation MMVimController
- (id)initWithBackend:(id)backend pid:(int)processIdentifier
+ recentFiles:(NSMenuItem*)menu;
{
if ((self = [super init])) {
+
+ recentFilesMenuItem = [menu retain];
+
windowController =
[[MMWindowController alloc] initWithVimController:self];
backendProxy = [backend retain];
@@ -135,6 +140,9 @@ - (void)dealloc
[mainMenuItems release]; mainMenuItems = nil;
[windowController release]; windowController = nil;
+ [recentFilesMenuItem release]; recentFilesMenuItem = nil;
+ [recentFilesDummy release]; recentFilesDummy = nil;
+
[super dealloc];
}
@@ -574,6 +582,14 @@ - (void)updateMainMenu
[NSApp setWindowsMenu:windowMenu];
}
+ // Replace real Recent Files menu in the old menu with the dummy, then
+ // remove dummy from new menu and put Recent Files menu there
+ NSMenuItem *oldItem = (NSMenuItem*)[recentFilesMenuItem representedObject];
+ if (oldItem)
+ [self replaceMenuItem:recentFilesMenuItem with:oldItem];
+ [recentFilesMenuItem setRepresentedObject:recentFilesDummy];
+ [self replaceMenuItem:recentFilesDummy with:recentFilesMenuItem];
+
shouldUpdateMainMenu = NO;
}
@@ -1073,17 +1089,28 @@ - (void)addMenuItemWithTag:(int)tag parent:(NSMenu *)parent
} else {
item = [[[NSMenuItem alloc] init] autorelease];
[item setTitle:title];
- // TODO: Check that 'action' is a valid action (nothing will happen
- // if it isn't, but it would be nice with a warning).
- if (action) [item setAction:NSSelectorFromString(action)];
- else [item setAction:@selector(vimMenuItemAction:)];
- if (tip) [item setToolTip:tip];
-
- if (key != 0) {
- NSString *keyString =
- [NSString stringWithFormat:@"%C", key];
- [item setKeyEquivalent:keyString];
- [item setKeyEquivalentModifierMask:mask];
+
+ if ([action isEqualToString:@"recentFilesDummy:"]) {
+ // Remove the recent files menu item from its current menu
+ // and put it in the current file menu. See -[MMAppController
+ // applicationWillFinishLaunching for more information.
+ //[[recentFilesMenuItem menu] removeItem:recentFilesMenuItem];
+ //item = recentFilesMenuItem;
+ recentFilesDummy = [item retain];
+
+ } else {
+ // TODO: Check that 'action' is a valid action (nothing will
+ // happen if it isn't, but it would be nice with a warning).
+ if (action) [item setAction:NSSelectorFromString(action)];
+ else [item setAction:@selector(vimMenuItemAction:)];
+ if (tip) [item setToolTip:tip];
+
+ if (key != 0) {
+ NSString *keyString =
+ [NSString stringWithFormat:@"%C", key];
+ [item setKeyEquivalent:keyString];
+ [item setKeyEquivalentModifierMask:mask];
+ }
}
}
@@ -1220,6 +1247,14 @@ - (void)resendTimerFired:(NSTimer *)timer
}
#endif
+- (void)replaceMenuItem:(NSMenuItem*)old with:(NSMenuItem*)new
+{
+ NSMenu *menu = [old menu];
+ int index = [menu indexOfItem:old];
+ [menu removeItemAtIndex:index];
+ [menu insertItem:new atIndex:index];
+}
+
@end // MMVimController (Private)
View
@@ -45,6 +45,7 @@ aunmenu File.Save-Exit
an <silent> 10.290 File.New\ Window :maca newWindow:<CR>
an 10.295 File.New\ Tab :tabnew<CR>
an <silent> 10.310 File.&Open\.\.\. :maca fileOpen:<CR>
+an <silent> 10.314 File.Open\ Recent :maca recentFilesDummy:<CR>
an 10.328 File.-SEP0- <Nop>
an <silent> 10.330 File.Close\ Window<Tab>:qa :confirm qa<CR>
an <silent> 10.331 File.Close :maca performClose:<CR>

0 comments on commit 862da53

Please sign in to comment.