Add menu item to toggle the plugin view drawer
[MacVim.git] / src / MacVim / Miscellaneous.m
blobc8aae51003013fdf2d0cce9d96ce4e4dcd9b4ac1
1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
2  *
3  * VIM - Vi IMproved            by Bram Moolenaar
4  *                              MacVim GUI port by Bjorn Winckler
5  *
6  * Do ":help uganda"  in Vim to read copying and usage conditions.
7  * Do ":help credits" in Vim to see a list of people who contributed.
8  * See README.txt for an overview of the Vim source code.
9  */
11 #import "MacVim.h"
12 #import "Miscellaneous.h"
16 // NSUserDefaults keys
17 NSString *MMTabMinWidthKey              = @"MMTabMinWidth";
18 NSString *MMTabMaxWidthKey              = @"MMTabMaxWidth";
19 NSString *MMTabOptimumWidthKey          = @"MMTabOptimumWidth";
20 NSString *MMTextInsetLeftKey            = @"MMTextInsetLeft";
21 NSString *MMTextInsetRightKey           = @"MMTextInsetRight";
22 NSString *MMTextInsetTopKey             = @"MMTextInsetTop";
23 NSString *MMTextInsetBottomKey          = @"MMTextInsetBottom";
24 NSString *MMTerminateAfterLastWindowClosedKey
25                                         = @"MMTerminateAfterLastWindowClosed";
26 NSString *MMTypesetterKey               = @"MMTypesetter";
27 NSString *MMCellWidthMultiplierKey      = @"MMCellWidthMultiplier";
28 NSString *MMBaselineOffsetKey           = @"MMBaselineOffset";
29 NSString *MMTranslateCtrlClickKey       = @"MMTranslateCtrlClick";
30 NSString *MMTopLeftPointKey             = @"MMTopLeftPoint";
31 NSString *MMOpenFilesInTabsKey          = @"MMOpenFilesInTabs";
32 NSString *MMNoFontSubstitutionKey       = @"MMNoFontSubstitution";
33 NSString *MMLoginShellKey               = @"MMLoginShell";
34 NSString *MMAtsuiRendererKey            = @"MMAtsuiRenderer";
35 NSString *MMUntitledWindowKey           = @"MMUntitledWindow";
36 NSString *MMTexturedWindowKey           = @"MMTexturedWindow";
37 NSString *MMZoomBothKey                 = @"MMZoomBoth";
38 NSString *MMCurrentPreferencePaneKey    = @"MMCurrentPreferencePane";
39 NSString *MMLoginShellCommandKey        = @"MMLoginShellCommand";
40 NSString *MMLoginShellArgumentKey       = @"MMLoginShellArgument";
41 NSString *MMDialogsTrackPwdKey          = @"MMDialogsTrackPwd";
43 #ifdef MM_ENABLE_PLUGINS
44 NSString *MMShowLeftPlugInContainerKey     = @"MMShowLeftPlugInContainer";
45 #endif
49 @implementation NSIndexSet (MMExtras)
51 + (id)indexSetWithVimList:(NSString *)list
53     NSMutableIndexSet *idxSet = [NSMutableIndexSet indexSet];
54     NSArray *array = [list componentsSeparatedByString:@"\n"];
55     unsigned i, count = [array count];
57     for (i = 0; i < count; ++i) {
58         NSString *entry = [array objectAtIndex:i];
59         if ([entry intValue] > 0)
60             [idxSet addIndex:i];
61     }
63     return idxSet;
66 @end // NSIndexSet (MMExtras)
71 @implementation NSDocumentController (MMExtras)
73 - (void)noteNewRecentFilePath:(NSString *)path
75     NSURL *url = [NSURL fileURLWithPath:path];
76     if (url)
77         [self noteNewRecentDocumentURL:url];
80 @end // NSDocumentController (MMExtras)
85 @implementation NSOpenPanel (MMExtras)
87 - (void)hiddenFilesButtonToggled:(id)sender
89     [self setShowsHiddenFiles:[sender intValue]];
92 - (void)setShowsHiddenFiles:(BOOL)show
94     // This is undocumented stuff, so be careful. This does the same as
95     //     [[self _navView] setShowsHiddenFiles:show];
96     // but does not produce warnings.
98     if (![self respondsToSelector:@selector(_navView)])
99         return;
101     id navView = [self performSelector:@selector(_navView)];
102     if (![navView respondsToSelector:@selector(setShowsHiddenFiles:)])
103         return;
105     // performSelector:withObject: does not support a BOOL
106     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
107         [navView methodSignatureForSelector:@selector(setShowsHiddenFiles:)]];
108     [invocation setTarget:navView];
109     [invocation setSelector:@selector(setShowsHiddenFiles:)];
110     [invocation setArgument:&show atIndex:2];
111     [invocation invoke];
114 @end // NSOpenPanel (MMExtras)
119 @implementation NSMenu (MMExtras)
121 - (int)indexOfItemWithAction:(SEL)action
123     int i, count = [self numberOfItems];
124     for (i = 0; i < count; ++i) {
125         NSMenuItem *item = [self itemAtIndex:i];
126         if ([item action] == action)
127             return i;
128     }
130     return -1;
133 - (NSMenuItem *)itemWithAction:(SEL)action
135     int idx = [self indexOfItemWithAction:action];
136     return idx >= 0 ? [self itemAtIndex:idx] : nil;
139 - (NSMenu *)findMenuContainingItemWithAction:(SEL)action
141     // NOTE: We only look for the action in the submenus of 'self'
142     int i, count = [self numberOfItems];
143     for (i = 0; i < count; ++i) {
144         NSMenu *menu = [[self itemAtIndex:i] submenu];
145         NSMenuItem *item = [menu itemWithAction:action];
146         if (item) return menu;
147     }
149     return nil;
152 - (NSMenu *)findWindowsMenu
154     return [self findMenuContainingItemWithAction:
155         @selector(performMiniaturize:)];
158 - (NSMenu *)findApplicationMenu
160     // TODO: Just return [self itemAtIndex:0]?
161     return [self findMenuContainingItemWithAction:@selector(terminate:)];
164 - (NSMenu *)findServicesMenu
166     // NOTE!  Our heuristic for finding the "Services" menu is to look for the
167     // second item before the "Hide MacVim" menu item on the "MacVim" menu.
168     // (The item before "Hide MacVim" should be a separator, but this is not
169     // important as long as the item before that is the "Services" menu.)
171     NSMenu *appMenu = [self findApplicationMenu];
172     if (!appMenu) return nil;
174     int idx = [appMenu indexOfItemWithAction: @selector(hide:)];
175     if (idx-2 < 0) return nil;  // idx == -1, if selector not found
177     return [[appMenu itemAtIndex:idx-2] submenu];
180 - (NSMenu *)findFileMenu
182     return [self findMenuContainingItemWithAction:@selector(performClose:)];
185 @end // NSMenu (MMExtras)
190 @implementation NSToolbar (MMExtras)
192 - (int)indexOfItemWithItemIdentifier:(NSString *)identifier
194     NSArray *items = [self items];
195     int i, count = [items count];
196     for (i = 0; i < count; ++i) {
197         id item = [items objectAtIndex:i];
198         if ([[item itemIdentifier] isEqual:identifier])
199             return i;
200     }
202     return NSNotFound;
205 - (NSToolbarItem *)itemAtIndex:(int)idx
207     NSArray *items = [self items];
208     if (idx < 0 || idx >= [items count])
209         return nil;
211     return [items objectAtIndex:idx];
214 - (NSToolbarItem *)itemWithItemIdentifier:(NSString *)identifier
216     int idx = [self indexOfItemWithItemIdentifier:identifier];
217     return idx != NSNotFound ? [self itemAtIndex:idx] : nil;
220 @end // NSToolbar (MMExtras)
225 @implementation NSTabView (MMExtras)
227 - (void)removeAllTabViewItems
229     NSArray *existingItems = [self tabViewItems];
230     NSEnumerator *e = [existingItems objectEnumerator];
231     NSTabViewItem *item;
232     while (item = [e nextObject]){
233         [self removeTabViewItem:item];
234     }
237 @end // NSTabView (MMExtras)
242 @implementation NSNumber (MMExtras)
244 - (int)tag
246     return [self intValue];
249 @end // NSNumber (MMExtras)
254     NSView *
255 openPanelAccessoryView()
257     // Return a new button object for each NSOpenPanel -- several of them
258     // could be displayed at once.
259     // If the accessory view should get more complex, it should probably be
260     // loaded from a nib file.
261     NSButton *button = [[[NSButton alloc]
262         initWithFrame:NSMakeRect(0, 0, 140, 18)] autorelease];
263     [button setTitle:
264         NSLocalizedString(@"Show Hidden Files", @"Open File Dialog")];
265     [button setButtonType:NSSwitchButton];
267     [button setTarget:nil];
268     [button setAction:@selector(hiddenFilesButtonToggled:)];
270     // use the regular control size (checkbox is a bit smaller without this)
271     NSControlSize buttonSize = NSRegularControlSize;
272     float fontSize = [NSFont systemFontSizeForControlSize:buttonSize];
273     NSCell *theCell = [button cell];
274     NSFont *theFont = [NSFont fontWithName:[[theCell font] fontName]
275                                       size:fontSize];
276     [theCell setFont:theFont];
277     [theCell setControlSize:buttonSize];
278     [button sizeToFit];
280     return button;
284     NSString *
285 buildTabDropCommand(NSArray *filenames)
287     // Create a command line string that will open the specified files in tabs.
289     if (!filenames || [filenames count] == 0)
290         return [NSString string];
292     NSMutableString *cmd = [NSMutableString stringWithString:
293             @"<C-\\><C-N>:tab drop"];
295     NSEnumerator *e = [filenames objectEnumerator];
296     id o;
297     while ((o = [e nextObject])) {
298         NSString *file = [o stringByEscapingSpecialFilenameCharacters];
299         [cmd appendString:@" "];
300         [cmd appendString:file];
301     }
303     [cmd appendString:@"|redr|f<CR>"];
305     return cmd;
308     NSString *
309 buildSelectRangeCommand(NSRange range)
311     // Build a command line string that will select the given range of lines.
312     // If range.length == 0, then position the cursor on the given line but do
313     // not select.
315     if (range.location == NSNotFound)
316         return [NSString string];
318     NSString *cmd;
319     if (range.length > 0) {
320         cmd = [NSString stringWithFormat:@"<C-\\><C-N>%dGV%dGz.0",
321                 NSMaxRange(range), range.location];
322     } else {
323         cmd = [NSString stringWithFormat:@"<C-\\><C-N>%dGz.0", range.location];
324     }
326     return cmd;
329     NSString *
330 buildSearchTextCommand(NSString *searchText)
332     // TODO: Searching is an exclusive motion, so if the pattern would match on
333     // row 0 column 0 then this pattern will miss that match.
334     return [NSString stringWithFormat:@"<C-\\><C-N>gg/\\c%@<CR>", searchText];