mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-05-28 00:21:57 +02:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8ac483bf8 | |||
| 9f83b2360b | |||
| 88b58bbd9f | |||
| dee796111a | |||
| 8ab6c75d08 | |||
| 3d8abd2669 | |||
| 12bec6e4ef | |||
| d26a1b2aad | |||
| 68799a3f7b | |||
| 164caf3832 | |||
| fa28669748 | |||
| 2fefb81d43 | |||
| 9d568fc7c9 | |||
| 0e6bfe9367 | |||
| 042108b0ad | |||
| 8ee6c93248 | |||
| 3f9f756149 | |||
| f6a5f65011 | |||
| f6e817e253 | |||
| bf22f09010 | |||
| 41c734a1aa | |||
| 65b46aa438 | |||
| 55790c5bb1 | |||
| 160b3ddb75 | |||
| 4bbbab9e56 | |||
| 548238236c | |||
| 1f27812ec0 | |||
| 1b21020c55 | |||
| d6fb745d7b | |||
| b5d1a8c5ba | |||
| 2e80f981c6 | |||
| 43d56b9b31 | |||
| d3b99588e3 | |||
| 80e4ddf501 | |||
| 143c782109 | |||
| a9dce2fa3d | |||
| bd394ba7b4 | |||
| 17b0feb45b | |||
| 9265b87738 | |||
| 84a3908488 | |||
| da50fc7107 | |||
| a2f006b7a5 | |||
| ff477a8d27 | |||
| ef149aa134 | |||
| a6907b971a | |||
| a8b5c51adf | |||
| ee5a7d0bb7 | |||
| dd78d32dd4 | |||
| 1190edd343 | |||
| 0a00f8f69f | |||
| b5b2678f9d | |||
| 1b133a3190 | |||
| 5e1defcf44 | |||
| 0f6e98e9fc | |||
| ed474b1614 | |||
| 518615feff |
@@ -18,5 +18,6 @@ src/auto/pathdef.c
|
||||
src/config.log
|
||||
src/config.status
|
||||
src/objects
|
||||
src/po/*.mo
|
||||
src/tags
|
||||
src/xxd/xxd
|
||||
|
||||
@@ -79,7 +79,7 @@ if &background == "dark"
|
||||
hi DiffChange guibg=MediumPurple4
|
||||
hi DiffDelete gui=bold guifg=White guibg=SlateBlue
|
||||
hi DiffText gui=NONE guifg=White guibg=SteelBlue
|
||||
hi LineNr guifg=#350A5B guibg=Grey5
|
||||
hi LineNr guifg=#552A7B guibg=Grey5
|
||||
hi MatchParen guifg=White guibg=Magenta
|
||||
hi Normal guifg=Grey50 guibg=Grey10
|
||||
hi Search guibg=Blue4 guifg=NONE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 Jan 11
|
||||
*eval.txt* For Vim version 7.1. Last change: 2008 Feb 20
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1638,6 +1638,7 @@ getline( {lnum}) String line {lnum} of current buffer
|
||||
getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
|
||||
getloclist({nr}) List list of location list items
|
||||
getmatches() List list of current matches
|
||||
getpid() Number process ID of Vim
|
||||
getpos( {expr}) List position of cursor, mark, etc.
|
||||
getqflist() List list of quickfix items
|
||||
getreg( [{regname} [, 1]]) String contents of register
|
||||
@@ -3833,6 +3834,10 @@ nr2char({expr}) *nr2char()*
|
||||
characters. nr2char(0) is a real NUL and terminates the
|
||||
string, thus results in an empty string.
|
||||
|
||||
*getpid()*
|
||||
getpid() Return a Number which is the process ID of the Vim process.
|
||||
On Unix this is a unique number. On MS-DOS it's always zero.
|
||||
|
||||
*getpos()*
|
||||
getpos({expr}) Get the position for {expr}. For possible values of {expr}
|
||||
see |line()|.
|
||||
@@ -4523,6 +4528,9 @@ setpos({expr}, {list})
|
||||
character. E.g., a position within a <Tab> or after the last
|
||||
character.
|
||||
|
||||
Returns 0 when the position could be set, -1 otherwise.
|
||||
An error message is given if {expr} is invalid.
|
||||
|
||||
Also see |getpos()|
|
||||
|
||||
This does not restore the preferred column for moving
|
||||
|
||||
+45
-4
@@ -34,9 +34,10 @@ on the MacVim project page >
|
||||
or by posting to the vim_mac mailing list *vim_mac* >
|
||||
http://groups.google.com/group/vim_mac
|
||||
|
||||
Remember to keep checking the project page for new snapshots. (If you
|
||||
downloaded this copy from somewhere else, you might want to go there now to
|
||||
make sure that you have got the latest version.)
|
||||
Remember to keep checking the project page for new snapshots or use the
|
||||
automatic updating feature which can be enabled in the preferences pane. (If
|
||||
you downloaded this copy from somewhere else, you might want to go there now
|
||||
to make sure that you have got the latest version.)
|
||||
|
||||
==============================================================================
|
||||
1. MacVim differences *macvim-differences*
|
||||
@@ -125,6 +126,22 @@ strings like "((3) of 2)" to appear in the window title.
|
||||
These are the non-standard options that MacVim supports:
|
||||
'fullscreen' 'toolbariconsize' 'transparency'
|
||||
|
||||
*macvim-find*
|
||||
Whenever you search for something in Vim (e.g. using "/") the search query is
|
||||
copied to the OS X "Find Pasteboard". The idea is that if you search for
|
||||
something and switch to another application, then you can hit <D-g> (or <D-G>)
|
||||
to repeat the search in the new app. The same feature works if you search in
|
||||
some app, switch to MacVim and hit <D-g>.
|
||||
|
||||
Note that the command |n| is not the same as <D-g>. The former will repeat
|
||||
the last search made in Vim, whereas the latter searches for the string on the
|
||||
OS X Find Pasteboard using the action findNext: (see |:macaction|).
|
||||
|
||||
The <D-g> key equivalent is a great way to bring a search from one window to
|
||||
another in MacVim. Simply search for something in one window (using "/") then
|
||||
switch to another (e.g. with <D-`>) and hit <D-g> and the search will be
|
||||
repeated in the new window.
|
||||
|
||||
==============================================================================
|
||||
2. Starting MacVim *macvim-start*
|
||||
|
||||
@@ -204,6 +221,8 @@ Here is a list of relevant dictionary entries:
|
||||
|
||||
KEY VALUE ~
|
||||
MMCellWidthMultiplier width of a normal glyph in em units [float]
|
||||
MMLoginShellArgument login shell parameter [string]
|
||||
MMLoginShellCommand which shell to use to launch Vim [string]
|
||||
MMNoFontSubstitution disable automatic font substitution [bool]
|
||||
MMTabMaxWidth maximum width of a tab [int]
|
||||
MMTabMinWidth minimum width of a tab [int]
|
||||
@@ -214,6 +233,7 @@ MMTextInsetRight text area offset in pixels [int]
|
||||
MMTextInsetTop text area offset in pixels [int]
|
||||
MMTexturedWindow use brushed metal window (Tiger only) [bool]
|
||||
MMTranslateCtrlClick interpret ctrl-click as right-click [bool]
|
||||
MMZoomBoth zoom button maximizes both directions [bool]
|
||||
|
||||
As an example, if you have more than one mouse button and would wish to free
|
||||
up Ctrl-click so you can bind it to something else, then the appropriate
|
||||
@@ -223,6 +243,23 @@ command is: >
|
||||
If you wish to restore all user defaults to their starting values, open
|
||||
Terminal and type: >
|
||||
defaults delete org.vim.MacVim
|
||||
<
|
||||
*macvim-login-shell*
|
||||
Applications opened from the Finder do not automatically source the user's
|
||||
environment variables (which are typically set in .profile or .bashrc). This
|
||||
presents a problem when using |:!| to execute commands in the shell since e.g.
|
||||
$PATH might not be set properly. To work around this problem MacVim can start
|
||||
new Vim processes via a login shell so that all environment variables are set.
|
||||
|
||||
By default MacVim uses the $SHELL environment variable to determine which
|
||||
shell to use (if $SHELL is not set "/bin/bash" is used). It is possible to
|
||||
override this choice by setting the user default MMLoginShellCommand to the
|
||||
shell that should be used (e.g. "/bin/tcsh"). MacVim tries to make the shell
|
||||
a login shell by prepending argv[0] with a dash. If you use an exotic shell
|
||||
and need to pass it a parameter to make it a login shell then you can set the
|
||||
user default MMLoginShellArgument (e.g. to "-l"). Finally, if the "bash"
|
||||
shell is used, then "-l" is automatically added as an argument. To override
|
||||
this behaviour set MMLoginShellArgument to "--".
|
||||
|
||||
==============================================================================
|
||||
4. Special colors *macvim-colors*
|
||||
@@ -327,11 +364,14 @@ Here is a random assortment of actions from Actions.plist which might be
|
||||
useful.
|
||||
|
||||
Action Description ~
|
||||
findNext: Search forward using the "Find Pasteboard"
|
||||
findPrevious: Search backward using the "Find Pasteboard"
|
||||
fontSizeDown: Decrease font size
|
||||
fontSizeUp: Increase font size
|
||||
newWindow: Open a new (empty) window
|
||||
orderFrontCharacterPalette: Show the the "Special Characters" dialog
|
||||
orderFrontFontPanel: Show the Font panel
|
||||
orderFrontPreferencePanel: Show the Preferences panel
|
||||
performZoom: Zoom window (same as clicking the green blob)
|
||||
selectNextWindow: Select next window (similar to <D-`>)
|
||||
selectPreviousWindow: Select previous window (similar to <S-D-`>)
|
||||
@@ -482,7 +522,8 @@ Scenario: ~
|
||||
When you click the (green) zoom button you want the window to maximize
|
||||
horizontally as well as vertically.
|
||||
Solution: ~
|
||||
Hold down Cmd and click the zoom button.
|
||||
Hold down Cmd and click the zoom button. If you prefer this to be the default
|
||||
action, then set the user default MMZoomBoth (see |macvim-prefs|).
|
||||
|
||||
Scenario: ~
|
||||
Typing feels sluggish when the cursor is just before a right bracket (i.e. ')',
|
||||
|
||||
+9
-3
@@ -1,7 +1,7 @@
|
||||
" Vim support file to switch on loading indent files for file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2005 Mar 28
|
||||
" Last Change: 2008 Feb 22
|
||||
|
||||
if exists("did_indent_on")
|
||||
finish
|
||||
@@ -15,11 +15,17 @@ augroup filetypeindent
|
||||
exe b:undo_indent
|
||||
unlet! b:undo_indent b:did_indent
|
||||
endif
|
||||
if expand("<amatch>") != ""
|
||||
let s = expand("<amatch>")
|
||||
if s != ""
|
||||
if exists("b:did_indent")
|
||||
unlet b:did_indent
|
||||
endif
|
||||
runtime! indent/<amatch>.vim
|
||||
|
||||
" When there is a dot it is used to separate filetype names. Thus for
|
||||
" "aaa.bbb" load "indent/aaa.vim" and then "indent/bbb.vim".
|
||||
for name in split(s, '\.')
|
||||
exe 'runtime! indent/' . name . '.vim'
|
||||
endfor
|
||||
endif
|
||||
endfunc
|
||||
augroup END
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Security/Authorization.h>
|
||||
|
||||
|
||||
@interface AuthorizedShellCommand : NSObject {
|
||||
|
||||
NSArray *commands;
|
||||
|
||||
AuthorizationRef authorizationRef;
|
||||
|
||||
}
|
||||
|
||||
// Pass an array of dictionaries. Each dictionary has to have the following
|
||||
// keys:
|
||||
//
|
||||
// * MMCommand: The command to execute, an NSString (e.g. @"/usr/bin/rm").
|
||||
// * MMArguments: An array of NSStrings, the arguments that are passed to
|
||||
// the command.
|
||||
//
|
||||
- (AuthorizedShellCommand *)initWithCommands:(NSArray *)theCommands;
|
||||
|
||||
// Runs the command passed in the constructor.
|
||||
- (OSStatus)run;
|
||||
|
||||
// This pops up the permission dialog. Called by run.
|
||||
- (OSStatus)askUserForPermission;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
extern NSString *MMCommand;
|
||||
extern NSString *MMArguments;
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
* See README.txt for an overview of the Vim source code.
|
||||
*/
|
||||
/*
|
||||
* AuthorizedCommand
|
||||
*
|
||||
* Runs a set of shell commands which may require authorization. Displays a
|
||||
* gui dialog to ask the user for authorized access.
|
||||
*/
|
||||
|
||||
#import "AuthorizedShellCommand.h"
|
||||
|
||||
#import <Security/AuthorizationTags.h>
|
||||
|
||||
@implementation AuthorizedShellCommand
|
||||
|
||||
- (AuthorizedShellCommand *)initWithCommands:(NSArray *)theCommands
|
||||
{
|
||||
if (![super init])
|
||||
return nil;
|
||||
|
||||
commands = [theCommands retain];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
[commands release];
|
||||
}
|
||||
|
||||
- (OSStatus)run
|
||||
{
|
||||
OSStatus err;
|
||||
int i;
|
||||
const char** arguments = NULL;
|
||||
AuthorizationFlags flags = kAuthorizationFlagDefaults;
|
||||
|
||||
err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
|
||||
flags, &authorizationRef);
|
||||
if (err != errAuthorizationSuccess)
|
||||
return err;
|
||||
|
||||
if ((err = [self askUserForPermission]) != errAuthorizationSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
NSEnumerator* myIterator = [commands objectEnumerator];
|
||||
NSDictionary* currCommand;
|
||||
|
||||
while (currCommand = [myIterator nextObject])
|
||||
{
|
||||
/* do something useful with currCommand */
|
||||
FILE *ioPipe = NULL;
|
||||
char junk[256];
|
||||
|
||||
const char* toolPath = [[currCommand objectForKey:MMCommand] UTF8String];
|
||||
NSArray* argumentStrings = [currCommand objectForKey:MMArguments];
|
||||
arguments = (const char**)malloc(
|
||||
([argumentStrings count] + 1) * sizeof(char*));
|
||||
|
||||
for (i = 0; i < [argumentStrings count]; ++i) {
|
||||
arguments[i] = [[argumentStrings objectAtIndex:i] UTF8String];
|
||||
}
|
||||
arguments[i] = NULL;
|
||||
|
||||
err = AuthorizationExecuteWithPrivileges (authorizationRef, toolPath,
|
||||
kAuthorizationFlagDefaults, (char*const*)arguments, &ioPipe);
|
||||
if (err != errAuthorizationSuccess)
|
||||
goto cleanup;
|
||||
|
||||
#if 0
|
||||
// We use the pipe to signal us when the command has completed
|
||||
char *p;
|
||||
do {
|
||||
p = fgets(junk, sizeof(junk), ioPipe);
|
||||
} while (p);
|
||||
#else
|
||||
for(;;)
|
||||
{
|
||||
int bytesRead = read (fileno (ioPipe),
|
||||
junk, sizeof (junk));
|
||||
if (bytesRead < 1) break;
|
||||
write (fileno (stdout), junk, bytesRead);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (arguments != NULL) {
|
||||
free(arguments);
|
||||
arguments = NULL;
|
||||
}
|
||||
fclose(ioPipe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
cleanup:
|
||||
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
|
||||
authorizationRef = 0;
|
||||
|
||||
if (arguments != NULL)
|
||||
free(arguments);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
- (OSStatus)askUserForPermission
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(authorizationRef != 0);
|
||||
|
||||
// The documentation for AuthorizationItem says that `value` should be
|
||||
// the path to the full posix path for kAuthorizationRightExecute. But
|
||||
// the installer sample "Calling a Privileged Installer" sets it to NULL.
|
||||
// Gotta love Apple's documentation.
|
||||
//
|
||||
// If you don't set `value` correctly, you'll get an
|
||||
// `errAuthorizationToolEnvironmentError` when you try to execute the
|
||||
// command.
|
||||
AuthorizationItem* authItems =
|
||||
malloc([commands count] * sizeof(AuthorizationItem));
|
||||
for (i = 0; i < [commands count]; ++i) {
|
||||
authItems[i].name = kAuthorizationRightExecute;
|
||||
authItems[i].value = (void*)
|
||||
[[[commands objectAtIndex:i] objectForKey:MMCommand] UTF8String];
|
||||
authItems[i].valueLength = strlen(authItems[i].value);
|
||||
authItems[i].flags = 0;
|
||||
}
|
||||
|
||||
AuthorizationRights rights = {
|
||||
[commands count], authItems
|
||||
};
|
||||
|
||||
OSStatus err = AuthorizationCopyRights(authorizationRef, &rights, NULL,
|
||||
kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagPreAuthorize |
|
||||
kAuthorizationFlagExtendRights
|
||||
, NULL);
|
||||
|
||||
free(authItems);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NSString *MMCommand = @"MMCommand";
|
||||
NSString *MMArguments = @"MMArguments";
|
||||
|
||||
@@ -37,4 +37,8 @@ Vim icons made by {\field{\*\fldinst{HYPERLINK "http://www.cs.princeton.edu/~mtw
|
||||
\
|
||||
The default font in MacVim, DejaVu Sans Mono, is based on the Bitstream Vera\'aa and Arev fonts. Bitstream Vera\'aa is \'a9 2003 by Bitstream, Inc. Arev is \'a9 2006 by Tavmjong Bah. The DejaVu changes to these fonts are in the public domain.\
|
||||
\
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.}
|
||||
Thanks to Andy Matuschak for {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt Sparkle}}.\
|
||||
\
|
||||
Thanks to Dave Batton for {\field{\*\fldinst{HYPERLINK "http://www.mere-mortal-software.com/blog/details.php?d=2007-03-11&c=show"}}{\fldrslt DBPrefsWindowController}}.\
|
||||
\
|
||||
Thanks to Allan Odgaard for making the "Edit in TextMate" input manager source code available, and also to Chris Eidhof and Eelco Lempsink for modifying it so that it could be used with any ODB capable editor.}
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// DBPrefsWindowController.h
|
||||
//
|
||||
// Created by Dave Batton
|
||||
// http://www.Mere-Mortal-Software.com/blog/
|
||||
//
|
||||
// Documentation for this class is available here:
|
||||
// http://www.mere-mortal-software.com/blog/details.php?d=2007-03-11
|
||||
//
|
||||
// Copyright 2007. Some rights reserved.
|
||||
// This work is licensed under a Creative Commons license:
|
||||
// http://creativecommons.org/licenses/by/3.0/
|
||||
//
|
||||
// 11 March 2007 : Initial 1.0 release
|
||||
// 15 March 2007 : Version 1.1
|
||||
// Resizing is now handled along with the cross-fade by
|
||||
// the NSViewAnimation routine.
|
||||
// Cut the fade time in half to speed up the window resize.
|
||||
// -setupToolbar is now called each time the window opens so
|
||||
// you can configure it differently each time if you want.
|
||||
// Holding down the shift key will now slow down the animation.
|
||||
// This can be disabled by using the new -setShiftSlowsAnimation:
|
||||
// method.
|
||||
// 23 March 2007 : Version 1.1.1
|
||||
// The initial first responder now gets set when the view is
|
||||
// swapped so that the user can tab to the objects displayed
|
||||
// in the window.
|
||||
// Also added a work-around to Cocoa's insistance on drawing
|
||||
// a focus ring around the first toolbar icon when going from
|
||||
// a view with a focusable item to a view without a focusable item.
|
||||
//
|
||||
// 31 May 2007 : Version 1.1.2
|
||||
// The window's title bar and toolbar heights are now calculated at
|
||||
// runtime, rather than being hard-coded.
|
||||
// Fixed a redraw problem and a window placement problem associated
|
||||
// with large preference windows.
|
||||
// Added some code to supress compiler warnings from unused parameters.
|
||||
// Fixed a couple of objects that weren't being properly released.
|
||||
//
|
||||
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface DBPrefsWindowController : NSWindowController {
|
||||
NSMutableArray *toolbarIdentifiers;
|
||||
NSMutableDictionary *toolbarViews;
|
||||
NSMutableDictionary *toolbarItems;
|
||||
|
||||
BOOL _crossFade;
|
||||
BOOL _shiftSlowsAnimation;
|
||||
|
||||
NSView *contentSubview;
|
||||
NSViewAnimation *viewAnimation;
|
||||
|
||||
NSString *currentPaneIdentifier;
|
||||
}
|
||||
|
||||
|
||||
+ (DBPrefsWindowController *)sharedPrefsWindowController;
|
||||
+ (NSString *)nibName;
|
||||
|
||||
- (void)setupToolbar;
|
||||
- (void)addView:(NSView *)view label:(NSString *)label;
|
||||
- (void)addView:(NSView *)view label:(NSString *)label image:(NSImage *)image;
|
||||
|
||||
- (BOOL)crossFade;
|
||||
- (void)setCrossFade:(BOOL)fade;
|
||||
- (BOOL)shiftSlowsAnimation;
|
||||
- (void)setShiftSlowsAnimation:(BOOL)slows;
|
||||
|
||||
- (void)displayViewForIdentifier:(NSString *)identifier animate:(BOOL)animate;
|
||||
- (void)crossFadeView:(NSView *)oldView withView:(NSView *)newView;
|
||||
- (NSRect)frameForView:(NSView *)view;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,431 @@
|
||||
//
|
||||
// DBPrefsWindowController.m
|
||||
//
|
||||
|
||||
#import "DBPrefsWindowController.h"
|
||||
|
||||
|
||||
static DBPrefsWindowController *_sharedPrefsWindowController = nil;
|
||||
|
||||
|
||||
@implementation DBPrefsWindowController
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Class Methods
|
||||
|
||||
|
||||
+ (DBPrefsWindowController *)sharedPrefsWindowController
|
||||
{
|
||||
if (!_sharedPrefsWindowController) {
|
||||
_sharedPrefsWindowController = [[self alloc] initWithWindowNibName:[self nibName]];
|
||||
}
|
||||
return _sharedPrefsWindowController;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ (NSString *)nibName
|
||||
// Subclasses can override this to use a nib with a different name.
|
||||
{
|
||||
return @"Preferences";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Setup & Teardown
|
||||
|
||||
|
||||
- (id)initWithWindow:(NSWindow *)window
|
||||
// -initWithWindow: is the designated initializer for NSWindowController.
|
||||
{
|
||||
self = [super initWithWindow:nil];
|
||||
if (self != nil) {
|
||||
// Set up an array and some dictionaries to keep track
|
||||
// of the views we'll be displaying.
|
||||
toolbarIdentifiers = [[NSMutableArray alloc] init];
|
||||
toolbarViews = [[NSMutableDictionary alloc] init];
|
||||
toolbarItems = [[NSMutableDictionary alloc] init];
|
||||
|
||||
// Set up an NSViewAnimation to animate the transitions.
|
||||
viewAnimation = [[NSViewAnimation alloc] init];
|
||||
[viewAnimation setAnimationBlockingMode:NSAnimationNonblocking];
|
||||
[viewAnimation setAnimationCurve:NSAnimationEaseInOut];
|
||||
[viewAnimation setDelegate:self];
|
||||
|
||||
[self setCrossFade:YES];
|
||||
[self setShiftSlowsAnimation:YES];
|
||||
}
|
||||
return self;
|
||||
|
||||
(void)window; // To prevent compiler warnings.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
// Create a new window to display the preference views.
|
||||
// If the developer attached a window to this controller
|
||||
// in Interface Builder, it gets replaced with this one.
|
||||
NSPanel *window = [[[NSPanel alloc] initWithContentRect:NSMakeRect(0,0,1000,1000)
|
||||
styleMask:(NSTitledWindowMask |
|
||||
NSClosableWindowMask)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:YES] autorelease];
|
||||
[window setHidesOnDeactivate:NO];
|
||||
[self setWindow:window];
|
||||
contentSubview = [[[NSView alloc] initWithFrame:[[[self window] contentView] frame]] autorelease];
|
||||
[contentSubview setAutoresizingMask:(NSViewMinYMargin | NSViewWidthSizable)];
|
||||
[[[self window] contentView] addSubview:contentSubview];
|
||||
[[self window] setShowsToolbarButton:NO];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void) dealloc {
|
||||
[toolbarIdentifiers release];
|
||||
[toolbarViews release];
|
||||
[toolbarItems release];
|
||||
[viewAnimation release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Configuration
|
||||
|
||||
|
||||
- (void)setupToolbar
|
||||
{
|
||||
// Subclasses must override this method to add items to the
|
||||
// toolbar by calling -addView:label: or -addView:label:image:.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)addView:(NSView *)view label:(NSString *)label
|
||||
{
|
||||
[self addView:view
|
||||
label:label
|
||||
image:[NSImage imageNamed:label]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)addView:(NSView *)view label:(NSString *)label image:(NSImage *)image
|
||||
{
|
||||
NSAssert (view != nil,
|
||||
@"Attempted to add a nil view when calling -addView:label:image:.");
|
||||
|
||||
NSString *identifier = [[label copy] autorelease];
|
||||
|
||||
[toolbarIdentifiers addObject:identifier];
|
||||
[toolbarViews setObject:view forKey:identifier];
|
||||
|
||||
NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier:identifier] autorelease];
|
||||
[item setLabel:label];
|
||||
[item setImage:image];
|
||||
[item setTarget:self];
|
||||
[item setAction:@selector(toggleActivePreferenceView:)];
|
||||
|
||||
[toolbarItems setObject:item forKey:identifier];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Accessor Methods
|
||||
|
||||
|
||||
- (BOOL)crossFade
|
||||
{
|
||||
return _crossFade;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setCrossFade:(BOOL)fade
|
||||
{
|
||||
_crossFade = fade;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (BOOL)shiftSlowsAnimation
|
||||
{
|
||||
return _shiftSlowsAnimation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setShiftSlowsAnimation:(BOOL)slows
|
||||
{
|
||||
_shiftSlowsAnimation = slows;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSString *)currentPaneIdentifier
|
||||
// Subclasses can override this to persist the current preference pane.
|
||||
{
|
||||
return currentPaneIdentifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)setCurrentPaneIdentifier:(NSString *)identifier
|
||||
// Subclasses can override this to persist the current preference pane.
|
||||
{
|
||||
currentPaneIdentifier = identifier;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Overriding Methods
|
||||
|
||||
|
||||
- (IBAction)showWindow:(id)sender
|
||||
{
|
||||
// This forces the resources in the nib to load.
|
||||
(void)[self window];
|
||||
|
||||
// Clear the last setup and get a fresh one.
|
||||
[toolbarIdentifiers removeAllObjects];
|
||||
[toolbarViews removeAllObjects];
|
||||
[toolbarItems removeAllObjects];
|
||||
[self setupToolbar];
|
||||
|
||||
NSAssert (([toolbarIdentifiers count] > 0),
|
||||
@"No items were added to the toolbar in -setupToolbar.");
|
||||
|
||||
if ([[self window] toolbar] == nil) {
|
||||
NSToolbar *toolbar = [[NSToolbar alloc] initWithIdentifier:@"DBPreferencesToolbar"];
|
||||
[toolbar setAllowsUserCustomization:NO];
|
||||
[toolbar setAutosavesConfiguration:NO];
|
||||
[toolbar setSizeMode:NSToolbarSizeModeDefault];
|
||||
[toolbar setDisplayMode:NSToolbarDisplayModeIconAndLabel];
|
||||
[toolbar setDelegate:self];
|
||||
[[self window] setToolbar:toolbar];
|
||||
[toolbar release];
|
||||
}
|
||||
|
||||
if ([toolbarItems objectForKey:[self currentPaneIdentifier]] == nil) {
|
||||
[self setCurrentPaneIdentifier:[toolbarIdentifiers objectAtIndex:0]];
|
||||
}
|
||||
[[[self window] toolbar]
|
||||
setSelectedItemIdentifier:[self currentPaneIdentifier]];
|
||||
[self displayViewForIdentifier:[self currentPaneIdentifier] animate:NO];
|
||||
|
||||
[[self window] center];
|
||||
|
||||
[super showWindow:sender];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Toolbar
|
||||
|
||||
|
||||
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
|
||||
{
|
||||
return toolbarIdentifiers;
|
||||
(void)toolbar;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)identifier willBeInsertedIntoToolbar:(BOOL)willBeInserted
|
||||
{
|
||||
return [toolbarItems objectForKey:identifier];
|
||||
(void)toolbar;
|
||||
(void)willBeInserted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)toggleActivePreferenceView:(NSToolbarItem *)toolbarItem
|
||||
{
|
||||
[self displayViewForIdentifier:[toolbarItem itemIdentifier] animate:YES];
|
||||
[self setCurrentPaneIdentifier:[toolbarItem itemIdentifier]];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)displayViewForIdentifier:(NSString *)identifier animate:(BOOL)animate
|
||||
{
|
||||
// Find the view we want to display.
|
||||
NSView *newView = [toolbarViews objectForKey:identifier];
|
||||
|
||||
// See if there are any visible views.
|
||||
NSView *oldView = nil;
|
||||
if ([[contentSubview subviews] count] > 0) {
|
||||
// Get a list of all of the views in the window. Usually at this
|
||||
// point there is just one visible view. But if the last fade
|
||||
// hasn't finished, we need to get rid of it now before we move on.
|
||||
NSEnumerator *subviewsEnum = [[contentSubview subviews] reverseObjectEnumerator];
|
||||
|
||||
// The first one (last one added) is our visible view.
|
||||
oldView = [subviewsEnum nextObject];
|
||||
|
||||
// Remove any others.
|
||||
NSView *reallyOldView = nil;
|
||||
while ((reallyOldView = [subviewsEnum nextObject]) != nil) {
|
||||
[reallyOldView removeFromSuperviewWithoutNeedingDisplay];
|
||||
}
|
||||
}
|
||||
|
||||
if (![newView isEqualTo:oldView]) {
|
||||
NSRect frame = [newView bounds];
|
||||
frame.origin.y = NSHeight([contentSubview frame]) - NSHeight([newView bounds]);
|
||||
[newView setFrame:frame];
|
||||
[contentSubview addSubview:newView];
|
||||
[[self window] setInitialFirstResponder:newView];
|
||||
|
||||
if (animate && [self crossFade])
|
||||
[self crossFadeView:oldView withView:newView];
|
||||
else {
|
||||
[oldView removeFromSuperviewWithoutNeedingDisplay];
|
||||
[newView setHidden:NO];
|
||||
[[self window] setFrame:[self frameForView:newView] display:YES animate:animate];
|
||||
}
|
||||
|
||||
[[self window] setTitle:[[toolbarItems objectForKey:identifier] label]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Cross-Fading Methods
|
||||
|
||||
|
||||
- (void)crossFadeView:(NSView *)oldView withView:(NSView *)newView
|
||||
{
|
||||
[viewAnimation stopAnimation];
|
||||
|
||||
if ([self shiftSlowsAnimation] && [[[self window] currentEvent] modifierFlags] & NSShiftKeyMask)
|
||||
[viewAnimation setDuration:1.25];
|
||||
else
|
||||
[viewAnimation setDuration:0.25];
|
||||
|
||||
NSDictionary *fadeOutDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
oldView, NSViewAnimationTargetKey,
|
||||
NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey,
|
||||
nil];
|
||||
|
||||
NSDictionary *fadeInDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
newView, NSViewAnimationTargetKey,
|
||||
NSViewAnimationFadeInEffect, NSViewAnimationEffectKey,
|
||||
nil];
|
||||
|
||||
NSDictionary *resizeDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[self window], NSViewAnimationTargetKey,
|
||||
[NSValue valueWithRect:[[self window] frame]], NSViewAnimationStartFrameKey,
|
||||
[NSValue valueWithRect:[self frameForView:newView]], NSViewAnimationEndFrameKey,
|
||||
nil];
|
||||
|
||||
NSArray *animationArray = [NSArray arrayWithObjects:
|
||||
fadeOutDictionary,
|
||||
fadeInDictionary,
|
||||
resizeDictionary,
|
||||
nil];
|
||||
|
||||
[viewAnimation setViewAnimations:animationArray];
|
||||
[viewAnimation startAnimation];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (void)animationDidEnd:(NSAnimation *)animation
|
||||
{
|
||||
NSView *subview;
|
||||
|
||||
// Get a list of all of the views in the window. Hopefully
|
||||
// at this point there are two. One is visible and one is hidden.
|
||||
NSEnumerator *subviewsEnum = [[contentSubview subviews] reverseObjectEnumerator];
|
||||
|
||||
// This is our visible view. Just get past it.
|
||||
subview = [subviewsEnum nextObject];
|
||||
|
||||
// Remove everything else. There should be just one, but
|
||||
// if the user does a lot of fast clicking, we might have
|
||||
// more than one to remove.
|
||||
while ((subview = [subviewsEnum nextObject]) != nil) {
|
||||
[subview removeFromSuperviewWithoutNeedingDisplay];
|
||||
}
|
||||
|
||||
// This is a work-around that prevents the first
|
||||
// toolbar icon from becoming highlighted.
|
||||
[[self window] makeFirstResponder:nil];
|
||||
|
||||
(void)animation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
- (NSRect)frameForView:(NSView *)view
|
||||
// Calculate the window size for the new view.
|
||||
{
|
||||
NSRect windowFrame = [[self window] frame];
|
||||
NSRect contentRect = [[self window] contentRectForFrameRect:windowFrame];
|
||||
float windowTitleAndToolbarHeight = NSHeight(windowFrame) - NSHeight(contentRect);
|
||||
|
||||
windowFrame.size.height = NSHeight([view frame]) + windowTitleAndToolbarHeight;
|
||||
windowFrame.size.width = NSWidth([view frame]);
|
||||
windowFrame.origin.y = NSMaxY([[self window] frame]) - NSHeight(windowFrame);
|
||||
|
||||
return windowFrame;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@end
|
||||
+16
-2
@@ -1,10 +1,24 @@
|
||||
{
|
||||
IBClasses = (
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
CLASS = MMPreferenceController;
|
||||
CLASS = DBPrefsWindowController;
|
||||
LANGUAGE = ObjC;
|
||||
SUPERCLASS = NSWindowController;
|
||||
},
|
||||
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
|
||||
{
|
||||
ACTIONS = {installOdb = id; uninstallOdb = id; };
|
||||
CLASS = MMPreferenceController;
|
||||
LANGUAGE = ObjC;
|
||||
OUTLETS = {
|
||||
editors = NSPopUpButton;
|
||||
generalPreferences = NSView;
|
||||
installOdbButton = NSButton;
|
||||
integrationPreferences = NSView;
|
||||
obdBundleVersionLabel = NSTextField;
|
||||
uninstallOdbButton = NSButton;
|
||||
};
|
||||
SUPERCLASS = DBPrefsWindowController;
|
||||
}
|
||||
);
|
||||
IBVersion = 1;
|
||||
|
||||
+12
-16
@@ -4,28 +4,24 @@
|
||||
<dict>
|
||||
<key>IBDocumentLocation</key>
|
||||
<string>69 14 356 240 0 0 1024 746 </string>
|
||||
<key>IBEditorPositions</key>
|
||||
<dict>
|
||||
<key>191</key>
|
||||
<string>260 290 503 416 0 0 1024 746 </string>
|
||||
</dict>
|
||||
<key>IBFramework Version</key>
|
||||
<string>489.0</string>
|
||||
<key>IBGroupedObjects</key>
|
||||
<dict>
|
||||
<key>0</key>
|
||||
<array>
|
||||
<string>79</string>
|
||||
<string>40</string>
|
||||
</array>
|
||||
<key>2</key>
|
||||
<array>
|
||||
<string>71</string>
|
||||
<string>37</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>IBLastGroupID</key>
|
||||
<string>3</string>
|
||||
<key>IBLastKnownRelativeProjectPath</key>
|
||||
<string>../../MacVim.xcodeproj</string>
|
||||
<key>IBOldestOS</key>
|
||||
<integer>5</integer>
|
||||
<key>IBOpenObjects</key>
|
||||
<array>
|
||||
<integer>5</integer>
|
||||
<integer>191</integer>
|
||||
</array>
|
||||
<key>IBSystem Version</key>
|
||||
<string>8S165</string>
|
||||
<key>targetFramework</key>
|
||||
<string>IBCocoaFramework</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
+16
-1
@@ -484,6 +484,21 @@
|
||||
<string>com.sun.java-class</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>patch</string>
|
||||
<string>diff</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>doc-bm</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Patch File</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
<key>LSIsAppleDefaultForType</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
@@ -530,7 +545,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>VIMM</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>21</string>
|
||||
<string>23</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1010 B |
+138
-51
@@ -30,6 +30,7 @@
|
||||
#import "MMVimController.h"
|
||||
#import "MMWindowController.h"
|
||||
#import "MMPreferenceController.h"
|
||||
#import <unistd.h>
|
||||
|
||||
|
||||
#define MM_HANDLE_XCODE_MOD_EVENT 0
|
||||
@@ -54,6 +55,9 @@ typedef struct
|
||||
#pragma options align=reset
|
||||
|
||||
|
||||
static int executeInLoginShell(NSString *path, NSArray *args);
|
||||
|
||||
|
||||
@interface MMAppController (MMServices)
|
||||
- (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData
|
||||
error:(NSString **)error;
|
||||
@@ -115,6 +119,9 @@ typedef struct
|
||||
[NSNumber numberWithInt:MMUntitledWindowAlways],
|
||||
MMUntitledWindowKey,
|
||||
[NSNumber numberWithBool:NO], MMTexturedWindowKey,
|
||||
[NSNumber numberWithBool:NO], MMZoomBothKey,
|
||||
@"", MMLoginShellCommandKey,
|
||||
@"", MMLoginShellArgumentKey,
|
||||
nil];
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
|
||||
@@ -273,6 +280,13 @@ typedef struct
|
||||
|
||||
pid = [self launchVimProcessWithArguments:fileArgs];
|
||||
|
||||
if (-1 == pid) {
|
||||
// TODO: Notify user of failure?
|
||||
[NSApp replyToOpenOrPrint:
|
||||
NSApplicationDelegateReplyFailure];
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure these files aren't opened again when
|
||||
// connectBackend:pid: is called.
|
||||
[arguments setObject:[NSNumber numberWithBool:NO]
|
||||
@@ -561,7 +575,7 @@ typedef struct
|
||||
|
||||
- (IBAction)orderFrontPreferencePanel:(id)sender
|
||||
{
|
||||
[[MMPreferenceController sharedPreferenceController] showWindow:self];
|
||||
[[MMPreferenceController sharedPrefsWindowController] showWindow:self];
|
||||
}
|
||||
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
@@ -735,68 +749,43 @@ typedef struct
|
||||
|
||||
- (int)launchVimProcessWithArguments:(NSArray *)args
|
||||
{
|
||||
NSString *taskPath = nil;
|
||||
NSArray *taskArgs = nil;
|
||||
int pid = -1;
|
||||
NSString *path = [[NSBundle mainBundle] pathForAuxiliaryExecutable:@"Vim"];
|
||||
|
||||
if (!path) {
|
||||
NSLog(@"ERROR: Vim executable could not be found inside app bundle!");
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:MMLoginShellKey]) {
|
||||
// Run process with a login shell
|
||||
// $SHELL -l -c "exec Vim -g -f args"
|
||||
// (-g for GUI, -f for foreground, i.e. don't fork)
|
||||
NSArray *taskArgs = [NSArray arrayWithObjects:@"-g", @"-f", nil];
|
||||
if (args)
|
||||
taskArgs = [taskArgs arrayByAddingObjectsFromArray:args];
|
||||
|
||||
NSMutableString *execArg = [NSMutableString
|
||||
stringWithFormat:@"exec \"%@\" -g -f", path];
|
||||
if (args) {
|
||||
// Append all arguments while making sure that arguments containing
|
||||
// spaces are enclosed in quotes.
|
||||
NSCharacterSet *space = [NSCharacterSet whitespaceCharacterSet];
|
||||
unsigned i, count = [args count];
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *arg = [args objectAtIndex:i];
|
||||
if (NSNotFound != [arg rangeOfCharacterFromSet:space].location)
|
||||
[execArg appendFormat:@" \"%@\"", arg];
|
||||
else
|
||||
[execArg appendFormat:@" %@", arg];
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the process with a login shell so that users environment
|
||||
// settings get sourced. This does not always happen when MacVim is
|
||||
// started.
|
||||
taskArgs = [NSArray arrayWithObjects:@"-l", @"-c", execArg, nil];
|
||||
taskPath = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey:@"SHELL"];
|
||||
if (!taskPath)
|
||||
taskPath = @"/bin/sh";
|
||||
BOOL useLoginShell = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMLoginShellKey];
|
||||
if (useLoginShell) {
|
||||
// Run process with a login shell, roughly:
|
||||
// echo "exec Vim -g -f args" | ARGV0=-`basename $SHELL` $SHELL [-l]
|
||||
pid = executeInLoginShell(path, taskArgs);
|
||||
} else {
|
||||
// Run process directly:
|
||||
// Vim -g -f args
|
||||
// (-g for GUI, -f for foreground, i.e. don't fork)
|
||||
taskPath = path;
|
||||
taskArgs = [NSArray arrayWithObjects:@"-g", @"-f", nil];
|
||||
if (args)
|
||||
taskArgs = [taskArgs arrayByAddingObjectsFromArray:args];
|
||||
NSTask *task = [NSTask launchedTaskWithLaunchPath:path
|
||||
arguments:taskArgs];
|
||||
pid = task ? [task processIdentifier] : -1;
|
||||
}
|
||||
|
||||
NSTask *task =[NSTask launchedTaskWithLaunchPath:taskPath
|
||||
arguments:taskArgs];
|
||||
//NSLog(@"launch %@ with args=%@ (pid=%d)", taskPath, taskArgs,
|
||||
// [task processIdentifier]);
|
||||
|
||||
int pid = [task processIdentifier];
|
||||
|
||||
// If the process has no arguments, then add a null argument to the
|
||||
// pidArguments dictionary. This is later used to detect that a process
|
||||
// without arguments is being launched.
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
if (-1 != pid) {
|
||||
// NOTE: If the process has no arguments, then add a null argument to
|
||||
// the pidArguments dictionary. This is later used to detect that a
|
||||
// process without arguments is being launched.
|
||||
if (!args)
|
||||
[pidArguments setObject:[NSNull null]
|
||||
forKey:[NSNumber numberWithInt:pid]];
|
||||
} else {
|
||||
NSLog(@"WARNING: %s%@ failed (useLoginShell=%d)", _cmd, args,
|
||||
useLoginShell);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
@@ -1098,3 +1087,101 @@ typedef struct
|
||||
return [self intValue];
|
||||
}
|
||||
@end // NSNumber (MMExtras)
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
executeInLoginShell(NSString *path, NSArray *args)
|
||||
{
|
||||
// Start a login shell and execute the command 'path' with arguments 'args'
|
||||
// in the shell. This ensures that user environment variables are set even
|
||||
// when MacVim was started from the Finder.
|
||||
|
||||
int pid = -1;
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
// Determine which shell to use to execute the command. The user
|
||||
// may decide which shell to use by setting a user default or the
|
||||
// $SHELL environment variable.
|
||||
NSString *shell = [ud stringForKey:MMLoginShellCommandKey];
|
||||
if (!shell || [shell length] == 0)
|
||||
shell = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey:@"SHELL"];
|
||||
if (!shell)
|
||||
shell = @"/bin/bash";
|
||||
|
||||
//NSLog(@"shell = %@", shell);
|
||||
|
||||
// Bash needs the '-l' flag to launch a login shell. The user may add
|
||||
// flags by setting a user default.
|
||||
NSString *shellArgument = [ud stringForKey:MMLoginShellArgumentKey];
|
||||
if (!shellArgument || [shellArgument length] == 0) {
|
||||
if ([[shell lastPathComponent] isEqual:@"bash"])
|
||||
shellArgument = @"-l";
|
||||
else
|
||||
shellArgument = nil;
|
||||
}
|
||||
|
||||
//NSLog(@"shellArgument = %@", shellArgument);
|
||||
|
||||
// Build input string to pipe to the login shell.
|
||||
NSMutableString *input = [NSMutableString stringWithFormat:
|
||||
@"exec \"%@\"", path];
|
||||
if (args) {
|
||||
// Append all arguments, making sure they are properly quoted, even
|
||||
// when they contain single quotes.
|
||||
NSEnumerator *e = [args objectEnumerator];
|
||||
id obj;
|
||||
|
||||
while ((obj = [e nextObject])) {
|
||||
NSMutableString *arg = [NSMutableString stringWithString:obj];
|
||||
[arg replaceOccurrencesOfString:@"'" withString:@"'\"'\"'"
|
||||
options:NSLiteralSearch
|
||||
range:NSMakeRange(0, [arg length])];
|
||||
[input appendFormat:@" '%@'", arg];
|
||||
}
|
||||
}
|
||||
|
||||
// Build the argument vector used to start the login shell.
|
||||
NSString *shellArg0 = [NSString stringWithFormat:@"-%@",
|
||||
[shell lastPathComponent]];
|
||||
char *shellArgv[3] = { (char *)[shellArg0 UTF8String], NULL, NULL };
|
||||
if (shellArgument)
|
||||
shellArgv[1] = (char *)[shellArgument UTF8String];
|
||||
|
||||
// Get the C string representation of the shell path before the fork since
|
||||
// we must not call Foundation functions after a fork.
|
||||
const char *shellPath = [shell fileSystemRepresentation];
|
||||
|
||||
// Fork and execute the process.
|
||||
int ds[2];
|
||||
if (pipe(ds)) return -1;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
return -1;
|
||||
} else if (pid == 0) {
|
||||
// Child process
|
||||
if (close(ds[1]) == -1) exit(255);
|
||||
if (dup2(ds[0], 0) == -1) exit(255);
|
||||
|
||||
execv(shellPath, shellArgv);
|
||||
|
||||
// Never reached unless execv fails
|
||||
exit(255);
|
||||
} else {
|
||||
// Parent process
|
||||
if (close(ds[0]) == -1) return -1;
|
||||
|
||||
// Send input to execute to the child process
|
||||
[input appendString:@"\n"];
|
||||
int bytes = [input lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
if (write(ds[1], [input UTF8String], bytes) != bytes) return -1;
|
||||
if (close(ds[1]) == -1) return -1;
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
NSFont *font;
|
||||
float linespace;
|
||||
|
||||
// From NSTextView
|
||||
NSSize insetSize;
|
||||
|
||||
// From vim-cocoa
|
||||
NSImage *contentImage;
|
||||
NSSize imageSize;
|
||||
@@ -63,6 +66,11 @@ enum { MMMaxCellsPerChar = 2 };
|
||||
- (void)doCommandBySelector:(SEL)selector;
|
||||
- (BOOL)performKeyEquivalent:(NSEvent *)event;
|
||||
|
||||
//
|
||||
// NSTextContainer methods
|
||||
//
|
||||
- (void)setTextContainerInset:(NSSize)inset;
|
||||
|
||||
//
|
||||
// MMAtsuiTextView methods
|
||||
//
|
||||
|
||||
@@ -70,6 +70,7 @@ enum {
|
||||
|
||||
|
||||
@interface MMAtsuiTextView (Drawing)
|
||||
- (NSPoint)originForRow:(int)row column:(int)column;
|
||||
- (NSRect)rectFromRow:(int)row1 column:(int)col1
|
||||
toRow:(int)row2 column:(int)col2;
|
||||
- (NSSize)textAreaSize;
|
||||
@@ -105,6 +106,7 @@ enum {
|
||||
cellSize.width = cellSize.height = 1;
|
||||
contentImage = nil;
|
||||
imageSize = NSZeroSize;
|
||||
insetSize = NSZeroSize;
|
||||
|
||||
[self initAtsuStyles];
|
||||
}
|
||||
@@ -152,17 +154,21 @@ enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTextContainerInset:(NSSize)size
|
||||
{
|
||||
insetSize = size;
|
||||
}
|
||||
|
||||
- (NSRect)rectForRowsInRange:(NSRange)range
|
||||
{
|
||||
// TODO: Add text inset to origin
|
||||
NSRect rect = { 0, 0, 0, 0 };
|
||||
unsigned start = range.location > maxRows ? maxRows : range.location;
|
||||
unsigned length = range.length;
|
||||
|
||||
if (start+length > maxRows)
|
||||
if (start + length > maxRows)
|
||||
length = maxRows - start;
|
||||
|
||||
rect.origin.y = cellSize.height * start;
|
||||
rect.origin.y = cellSize.height * start + insetSize.height;
|
||||
rect.size.height = cellSize.height * length;
|
||||
|
||||
return rect;
|
||||
@@ -170,7 +176,6 @@ enum {
|
||||
|
||||
- (NSRect)rectForColumnsInRange:(NSRange)range
|
||||
{
|
||||
// TODO: Add text inset to origin
|
||||
NSRect rect = { 0, 0, 0, 0 };
|
||||
unsigned start = range.location > maxColumns ? maxColumns : range.location;
|
||||
unsigned length = range.length;
|
||||
@@ -178,7 +183,7 @@ enum {
|
||||
if (start+length > maxColumns)
|
||||
length = maxColumns - start;
|
||||
|
||||
rect.origin.x = cellSize.width * start;
|
||||
rect.origin.x = cellSize.width * start + insetSize.width;
|
||||
rect.size.width = cellSize.width * length;
|
||||
|
||||
return rect;
|
||||
@@ -458,8 +463,14 @@ enum {
|
||||
|
||||
- (void)drawRect:(NSRect)rect
|
||||
{
|
||||
[contentImage drawInRect: rect
|
||||
fromRect: rect
|
||||
NSRect srcRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
|
||||
NSRect dstRect = srcRect;
|
||||
|
||||
dstRect.origin.x += insetSize.width;
|
||||
dstRect.origin.y += insetSize.height;
|
||||
|
||||
[contentImage drawInRect: dstRect
|
||||
fromRect: srcRect
|
||||
operation: NSCompositeCopy
|
||||
fraction: 1.0];
|
||||
}
|
||||
@@ -579,6 +590,11 @@ enum {
|
||||
[self drawInsertionPointAtRow:row column:col shape:shape
|
||||
fraction:percent
|
||||
color:[NSColor colorWithRgbInt:color]];
|
||||
} else if (SetCursorPosDrawType == type) {
|
||||
// TODO: This is used for Voice Over support in MMTextView,
|
||||
// MMAtsuiTextView currently does not support Voice Over.
|
||||
/*cursorRow = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
/*cursorCol = *((int*)bytes);*/ bytes += sizeof(int);
|
||||
} else {
|
||||
NSLog(@"WARNING: Unknown draw type (type=%d)", type);
|
||||
}
|
||||
@@ -599,7 +615,6 @@ enum {
|
||||
- (NSSize)constrainRows:(int *)rows columns:(int *)cols toSize:(NSSize)size
|
||||
{
|
||||
// TODO:
|
||||
// - Take text area inset into consideration
|
||||
// - Rounding errors may cause size change when there should be none
|
||||
// - Desired rows/columns shold not be 'too small'
|
||||
|
||||
@@ -611,18 +626,20 @@ enum {
|
||||
|
||||
if (size.height != desiredSize.height) {
|
||||
float fh = cellSize.height;
|
||||
float ih = 2 * insetSize.height;
|
||||
if (fh < 1.0f) fh = 1.0f;
|
||||
|
||||
desiredRows = floor(size.height/fh);
|
||||
desiredSize.height = fh*desiredRows;
|
||||
desiredRows = floor((size.height - ih)/fh);
|
||||
desiredSize.height = fh*desiredRows + ih;
|
||||
}
|
||||
|
||||
if (size.width != desiredSize.width) {
|
||||
float fw = cellSize.width;
|
||||
float iw = 2 * insetSize.width;
|
||||
if (fw < 1.0f) fw = 1.0f;
|
||||
|
||||
desiredCols = floor(size.width/fw);
|
||||
desiredSize.width = fw*desiredCols;
|
||||
desiredCols = floor((size.width - iw)/fw);
|
||||
desiredSize.width = fw*desiredCols + iw;
|
||||
}
|
||||
|
||||
if (rows) *rows = desiredRows;
|
||||
@@ -635,17 +652,15 @@ enum {
|
||||
{
|
||||
// Compute the size the text view should be for the entire text area and
|
||||
// inset area to be visible with the present number of rows and columns.
|
||||
//
|
||||
// TODO: Add inset area to size.
|
||||
return NSMakeSize(maxColumns*cellSize.width, maxRows*cellSize.height);
|
||||
return NSMakeSize(maxColumns * cellSize.width + 2 * insetSize.width,
|
||||
maxRows * cellSize.height + 2 * insetSize.height);
|
||||
}
|
||||
|
||||
- (NSSize)minSize
|
||||
{
|
||||
// Compute the smallest size the text view is allowed to be.
|
||||
//
|
||||
// TODO: Add inset area to size.
|
||||
return NSMakeSize(MMMinColumns*cellSize.width, MMMinRows*cellSize.height);
|
||||
return NSMakeSize(MMMinColumns * cellSize.width + 2 * insetSize.width,
|
||||
MMMinRows * cellSize.height + 2 * insetSize.height);
|
||||
}
|
||||
|
||||
- (void)changeFont:(id)sender
|
||||
@@ -707,8 +722,7 @@ enum {
|
||||
|
||||
- (BOOL)convertPoint:(NSPoint)point toRow:(int *)row column:(int *)column
|
||||
{
|
||||
// TODO: text inset
|
||||
NSPoint origin = { 0,0 };
|
||||
NSPoint origin = { insetSize.width, insetSize.height };
|
||||
|
||||
if (!(cellSize.width > 0 && cellSize.height > 0))
|
||||
return NO;
|
||||
@@ -864,10 +878,16 @@ enum {
|
||||
|
||||
@implementation MMAtsuiTextView (Drawing)
|
||||
|
||||
- (NSPoint)originForRow:(int)row column:(int)col
|
||||
{
|
||||
return NSMakePoint(col * cellSize.width, row * cellSize.height);
|
||||
}
|
||||
|
||||
- (NSRect)rectFromRow:(int)row1 column:(int)col1
|
||||
toRow:(int)row2 column:(int)col2
|
||||
{
|
||||
return NSMakeRect(col1 * cellSize.width, row1 * cellSize.height,
|
||||
NSPoint origin = [self originForRow: row1 column: col1];
|
||||
return NSMakeRect(origin.x, origin.y,
|
||||
(col2 + 1 - col1) * cellSize.width,
|
||||
(row2 + 1 - row1) * cellSize.height);
|
||||
}
|
||||
@@ -876,7 +896,7 @@ enum {
|
||||
{
|
||||
// Calculate the (desired) size of the text area, i.e. the text view area
|
||||
// minus the inset area.
|
||||
return NSMakeSize(maxColumns*cellSize.width, maxRows*cellSize.height);
|
||||
return NSMakeSize(maxColumns * cellSize.width, maxRows * cellSize.height);
|
||||
}
|
||||
|
||||
- (void)resizeContentImage
|
||||
@@ -906,7 +926,7 @@ enum {
|
||||
// 'string' consists of 'length' utf-16 code pairs and should cover 'cells'
|
||||
// display cells (a normal character takes up one display cell, a wide
|
||||
// character takes up two)
|
||||
ATSUStyle style = atsuStyles[0];
|
||||
ATSUStyle style = (flags & DRAW_WIDE) ? atsuStyles[1] : atsuStyles[0];
|
||||
ATSUTextLayout layout;
|
||||
|
||||
// NSLog(@"drawString: %d", length);
|
||||
@@ -919,6 +939,8 @@ enum {
|
||||
|
||||
NSRect rect = NSMakeRect(col * cellSize.width, row * cellSize.height,
|
||||
length * cellSize.width, cellSize.height);
|
||||
if (flags & DRAW_WIDE)
|
||||
rect.size.width = rect.size.width * 2;
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
|
||||
|
||||
ATSUAttributeTag tags[] = { kATSUCGContextTag };
|
||||
@@ -1003,6 +1025,27 @@ enum {
|
||||
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
|
||||
fraction:(int)percent color:(NSColor *)color
|
||||
{
|
||||
NSPoint origin = [self originForRow:row column:col];
|
||||
NSRect rect = NSMakeRect(origin.x, origin.y,
|
||||
cellSize.width, cellSize.height);
|
||||
|
||||
// NSLog(@"shape = %d, fraction: %d", shape, percent);
|
||||
|
||||
if (MMInsertionPointHorizontal == shape) {
|
||||
int frac = (cellSize.height * percent + 99)/100;
|
||||
rect.origin.y += rect.size.height - frac;
|
||||
rect.size.height = frac;
|
||||
} else if (MMInsertionPointVertical == shape) {
|
||||
int frac = (cellSize.width * percent + 99)/100;
|
||||
rect.size.width = frac;
|
||||
}
|
||||
|
||||
[color set];
|
||||
if (MMInsertionPointHollow == shape) {
|
||||
NSFrameRect(rect);
|
||||
} else {
|
||||
NSRectFill(rect);
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMAtsuiTextView (Drawing)
|
||||
|
||||
+16
-15
@@ -287,28 +287,29 @@ static NSString *MMSymlinkWarningString =
|
||||
}
|
||||
}
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
BOOL ok = NO;
|
||||
@try {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
frontendProxy = [proxy connectBackend:self pid:pid];
|
||||
if (frontendProxy) {
|
||||
[frontendProxy retain];
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
ok = YES;
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when trying to connect backend: \"%@\"", e);
|
||||
}
|
||||
|
||||
if (frontendProxy) {
|
||||
[frontendProxy retain];
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
}
|
||||
|
||||
return connection && frontendProxy;
|
||||
return ok;
|
||||
}
|
||||
|
||||
- (BOOL)openVimWindow
|
||||
|
||||
@@ -9,10 +9,25 @@
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <DBPrefsWindowController.h>
|
||||
|
||||
@interface MMPreferenceController : DBPrefsWindowController {
|
||||
|
||||
IBOutlet NSView *generalPreferences;
|
||||
IBOutlet NSView *integrationPreferences;
|
||||
|
||||
|
||||
// Integration pane
|
||||
NSDictionary *supportedOdbEditors;
|
||||
IBOutlet NSPopUpButton *editors;
|
||||
IBOutlet NSButton *installOdbButton;
|
||||
IBOutlet NSButton *uninstallOdbButton;
|
||||
IBOutlet NSTextField* obdBundleVersionLabel;
|
||||
|
||||
@interface MMPreferenceController : NSWindowController {
|
||||
}
|
||||
|
||||
+ (MMPreferenceController *)sharedPreferenceController;
|
||||
// Integration pane
|
||||
- (IBAction)installOdb:(id)sender;
|
||||
- (IBAction)uninstallOdb:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* vi:set ts=8 sts=4 sw=4 ft=objc:
|
||||
*
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
* VIM - Vi IMproved by Bram Moolenaar
|
||||
* MacVim GUI port by Bjorn Winckler
|
||||
*
|
||||
* Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
* Do ":help credits" in Vim to see a list of people who contributed.
|
||||
@@ -11,27 +11,381 @@
|
||||
#import "MMPreferenceController.h"
|
||||
#import "MacVim.h"
|
||||
|
||||
#import "AuthorizedShellCommand.h"
|
||||
|
||||
// On Leopard, we want to use the images provided by the OS for some of the
|
||||
// toolbar images (NSImageNamePreferencesGeneral and friends). We need to jump
|
||||
// through some hoops to do that in a way that MacVim still _compiles_ on Tiger
|
||||
// (life would be easier if we'd require Leopard for building). See
|
||||
// http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html
|
||||
// and http://developer.apple.com/technotes/tn2002/tn2064.html
|
||||
// for how you'd do it with a Leopard build system, and see
|
||||
// http://lists.cairographics.org/archives/cairo-bugs/2007-December/001818.html
|
||||
// for why this doesn't work here.
|
||||
// Using the system images gives us resolution independence and consistency
|
||||
// with other apps.
|
||||
|
||||
#import <dlfcn.h>
|
||||
|
||||
NSString* nsImageNamePreferencesGeneral = nil;
|
||||
NSString* nsImageNamePreferencesAdvanced = nil;
|
||||
|
||||
static void loadSymbols()
|
||||
{
|
||||
// use dlfcn() instead of the deprecated NSModule api.
|
||||
void *ptr;
|
||||
if ((ptr = dlsym(RTLD_DEFAULT, "NSImageNamePreferencesGeneral")) != NULL)
|
||||
nsImageNamePreferencesGeneral = *(NSString**)ptr;
|
||||
if ((ptr = dlsym(RTLD_DEFAULT, "NSImageNamePreferencesAdvanced")) != NULL)
|
||||
nsImageNamePreferencesAdvanced = *(NSString**)ptr;
|
||||
}
|
||||
|
||||
|
||||
static CFStringRef ODBEDITOR = CFSTR("org.slashpunt.edit_in_odbeditor");
|
||||
static CFStringRef ODB_BUNDLE_IDENTIFIER = CFSTR("ODBEditorBundleIdentifier");
|
||||
static CFStringRef ODB_EDITOR_NAME = CFSTR("ODBEditorName");
|
||||
static NSString *ODBEDITOR_DIR =
|
||||
@"/Library/InputManagers/Edit in ODBEditor";
|
||||
static NSString *ODBEDITOR_PATH =
|
||||
@"/Library/InputManagers/Edit in ODBEditor/Edit in ODBEditor.bundle";
|
||||
|
||||
|
||||
NSString *kOdbEditorNameNone = @"(None)";
|
||||
NSString *kOdbEditorIdentifierNone = @"";
|
||||
|
||||
NSString *kOdbEditorNameBBEdit = @"BBEdit";
|
||||
NSString *kOdbEditorIdentifierBBEdit = @"com.barebones.bbedit";
|
||||
|
||||
NSString *kOdbEditorNameCSSEdit = @"CSSEdit";
|
||||
NSString *kOdbEditorIdentifierCSSEdit = @"com.macrabbit.cssedit";
|
||||
|
||||
NSString *kOdbEditorNameMacVim = @"MacVim";
|
||||
NSString *kOdbEditorIdentifierMacVim = @"org.vim.MacVim";
|
||||
|
||||
NSString *kOdbEditorNameSmultron = @"Smultron";
|
||||
NSString *kOdbEditorIdentifierSmultron = @"org.smultron.Smultron";
|
||||
|
||||
NSString *kOdbEditorNameSubEthaEdit = @"SubEthaEdit";
|
||||
NSString *kOdbEditorIdentifierSubEthaEdit = @"de.codingmonkeys.SubEthaEdit";
|
||||
|
||||
NSString *kOdbEditorNameTextMate = @"TextMate";
|
||||
NSString *kOdbEditorIdentifierTextMate = @"com.macromates.textmate";
|
||||
|
||||
NSString *kOdbEditorNameTextWrangler = @"TextWrangler";
|
||||
NSString *kOdbEditorIdentifierTextWrangler = @"com.barebones.textwrangler";
|
||||
|
||||
NSString *kOdbEditorNameWriteRoom = @"WriteRoom";
|
||||
NSString *kOdbEditorIdentifierWriteRoom = @"com.hogbaysoftware.WriteRoom";
|
||||
|
||||
|
||||
@interface MMPreferenceController (Private)
|
||||
// Integration pane
|
||||
- (void)updateIntegrationPane;
|
||||
- (void)setOdbEditorByName:(NSString *)name;
|
||||
- (NSString *)odbEditorBundleIdentifier;
|
||||
- (NSString *)odbBundleSourceDir;
|
||||
- (NSString *)versionOfBundle:(NSString *)bundlePath;
|
||||
- (NSString *)odbBundleInstalledVersion;
|
||||
- (NSString *)odbBundleInstallVersion;
|
||||
@end
|
||||
|
||||
@implementation MMPreferenceController
|
||||
|
||||
+ (MMPreferenceController *)sharedPreferenceController
|
||||
- (id)initWithWindow:(NSWindow *)window
|
||||
{
|
||||
static MMPreferenceController *singleton = nil;
|
||||
if (!singleton)
|
||||
singleton = [[MMPreferenceController alloc] init];
|
||||
return singleton;
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super initWithWindowNibName:@"Preferences"];
|
||||
if (!self) return nil;
|
||||
|
||||
[self setWindowFrameAutosaveName:@"Preferences"];
|
||||
[[self window] setHidesOnDeactivate:NO];
|
||||
|
||||
self = [super initWithWindow:window];
|
||||
if (self == nil)
|
||||
return nil;
|
||||
// taken from Cyberduck. Thanks :-)
|
||||
supportedOdbEditors = [[NSDictionary alloc] initWithObjectsAndKeys:
|
||||
kOdbEditorIdentifierNone, kOdbEditorNameNone,
|
||||
kOdbEditorIdentifierBBEdit, kOdbEditorNameBBEdit,
|
||||
kOdbEditorIdentifierCSSEdit, kOdbEditorNameCSSEdit,
|
||||
kOdbEditorIdentifierMacVim, kOdbEditorNameMacVim,
|
||||
kOdbEditorIdentifierSmultron, kOdbEditorNameSmultron,
|
||||
kOdbEditorIdentifierSubEthaEdit, kOdbEditorNameSubEthaEdit,
|
||||
kOdbEditorIdentifierTextMate, kOdbEditorNameTextMate,
|
||||
kOdbEditorIdentifierTextWrangler, kOdbEditorNameTextWrangler,
|
||||
kOdbEditorIdentifierWriteRoom, kOdbEditorNameWriteRoom,
|
||||
nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[supportedOdbEditors release]; supportedOdbEditors = nil;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
// fill list of editors in integration pane
|
||||
NSArray *keys = [[supportedOdbEditors allKeys]
|
||||
sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
|
||||
NSMenu *editorsMenu = [editors menu];
|
||||
NSEnumerator *enumerator = [keys objectEnumerator];
|
||||
NSString *key;
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:key];
|
||||
|
||||
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:key
|
||||
action:@selector(odbEditorChanged:)
|
||||
keyEquivalent:@""];
|
||||
[item setTarget:self];
|
||||
if (![identifier isEqualToString:kOdbEditorIdentifierNone]) {
|
||||
NSString *appPath = [[NSWorkspace sharedWorkspace]
|
||||
absolutePathForAppBundleWithIdentifier:identifier];
|
||||
[item setEnabled:appPath != nil];
|
||||
if (appPath != nil) {
|
||||
NSImage *icon = [[NSWorkspace sharedWorkspace]
|
||||
iconForFile:appPath];
|
||||
[icon setSize:NSMakeSize(16, 16)]; // XXX: make res independent
|
||||
[item setImage:icon];
|
||||
}
|
||||
}
|
||||
[editorsMenu addItem:item];
|
||||
[item release];
|
||||
}
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
- (void)setupToolbar
|
||||
{
|
||||
loadSymbols();
|
||||
|
||||
if (nsImageNamePreferencesGeneral != NULL) {
|
||||
[self addView:generalPreferences
|
||||
label:@"General"
|
||||
image:[NSImage imageNamed:nsImageNamePreferencesGeneral]];
|
||||
} else {
|
||||
[self addView:generalPreferences label:@"General"];
|
||||
}
|
||||
|
||||
[self addView:integrationPreferences label:@"Integration"];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)currentPaneIdentifier
|
||||
{
|
||||
// We override this to persist the current pane.
|
||||
return [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:MMCurrentPreferencePaneKey];
|
||||
}
|
||||
|
||||
- (void)setCurrentPaneIdentifier:(NSString *)identifier
|
||||
{
|
||||
// We override this to persist the current pane.
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject:identifier forKey:MMCurrentPreferencePaneKey];
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)validateMenuItem:(NSMenuItem *)item
|
||||
{
|
||||
if ([item action] == @selector(odbEditorChanged:)) {
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:[item title]];
|
||||
if (identifier == nil)
|
||||
return NO;
|
||||
if ([identifier isEqualToString:kOdbEditorIdentifierNone])
|
||||
return YES;
|
||||
return [[NSWorkspace sharedWorkspace]
|
||||
absolutePathForAppBundleWithIdentifier:identifier] != nil;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Integration pane
|
||||
|
||||
- (void)updateIntegrationPane
|
||||
{
|
||||
// XXX: check validation api.
|
||||
// XXX: call this each time the dialog becomes active (so that if the
|
||||
// user changes settings in terminal, the changes are reflected in the
|
||||
// dialog)
|
||||
|
||||
NSString *versionString;
|
||||
|
||||
// Check if ODB path exists before calling isFilePackageAtPath: otherwise
|
||||
// an error is output to stderr on Tiger.
|
||||
BOOL odbIsInstalled =
|
||||
[[NSFileManager defaultManager] fileExistsAtPath:ODBEDITOR_PATH]
|
||||
&& [[NSWorkspace sharedWorkspace] isFilePackageAtPath:ODBEDITOR_PATH];
|
||||
|
||||
// enable/disable buttons
|
||||
[installOdbButton setTitle:@"Install"];
|
||||
if (odbIsInstalled) {
|
||||
[uninstallOdbButton setEnabled:YES];
|
||||
[editors setEnabled:YES];
|
||||
|
||||
NSString *installVersion = [self odbBundleInstallVersion];
|
||||
NSString *installedVersion = [self odbBundleInstalledVersion];
|
||||
switch ([installedVersion compare:installVersion
|
||||
options:NSNumericSearch]) {
|
||||
case NSOrderedAscending:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@, you have %@.",
|
||||
installVersion, installedVersion];
|
||||
[installOdbButton setTitle:@"Update"];
|
||||
[installOdbButton setEnabled:YES];
|
||||
break;
|
||||
case NSOrderedSame:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@. You have the latest version.",
|
||||
installVersion];
|
||||
[installOdbButton setEnabled:NO];
|
||||
break;
|
||||
case NSOrderedDescending:
|
||||
versionString = [NSString stringWithFormat:
|
||||
@"Latest version is %@, you have %@.",
|
||||
installVersion, installedVersion];
|
||||
[installOdbButton setEnabled:NO];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
[installOdbButton setEnabled:YES];
|
||||
[uninstallOdbButton setEnabled:NO];
|
||||
[editors setEnabled:NO];
|
||||
|
||||
versionString = [NSString
|
||||
stringWithFormat:@"Latest version is %@. It is not installed.",
|
||||
[self odbBundleInstallVersion]];
|
||||
}
|
||||
|
||||
[obdBundleVersionLabel setStringValue:versionString];
|
||||
|
||||
// make sure the right editor is selected on the popup button
|
||||
NSString *selectedTitle = kOdbEditorNameNone;
|
||||
NSArray* keys = [supportedOdbEditors
|
||||
allKeysForObject:[self odbEditorBundleIdentifier]];
|
||||
if ([keys count] > 0)
|
||||
selectedTitle = [keys objectAtIndex:0];
|
||||
[editors selectItemWithTitle:selectedTitle];
|
||||
}
|
||||
|
||||
- (void)setOdbEditorByName:(NSString *)name
|
||||
{
|
||||
NSString *identifier = [supportedOdbEditors objectForKey:name];
|
||||
if (identifier != kOdbEditorIdentifierNone) {
|
||||
CFPreferencesSetAppValue(ODB_BUNDLE_IDENTIFIER, identifier, ODBEDITOR);
|
||||
CFPreferencesSetAppValue(ODB_EDITOR_NAME, name, ODBEDITOR);
|
||||
} else {
|
||||
CFPreferencesSetAppValue(ODB_BUNDLE_IDENTIFIER, NULL, ODBEDITOR);
|
||||
CFPreferencesSetAppValue(ODB_EDITOR_NAME, NULL, ODBEDITOR);
|
||||
}
|
||||
CFPreferencesAppSynchronize(ODBEDITOR);
|
||||
}
|
||||
|
||||
// Note that you can't compare the result of this function with ==, you have
|
||||
// to use isStringEqual: (since this returns a new copy of the string).
|
||||
- (NSString *)odbEditorBundleIdentifier
|
||||
{
|
||||
// reading the defaults of a different app is easier with carbon
|
||||
NSString *bundleIdentifier = (NSString*)CFPreferencesCopyAppValue(
|
||||
ODB_BUNDLE_IDENTIFIER, ODBEDITOR);
|
||||
if (bundleIdentifier == nil)
|
||||
return kOdbEditorIdentifierNone;
|
||||
return [bundleIdentifier autorelease];
|
||||
}
|
||||
|
||||
- (void)odbEditorChanged:(id)sender
|
||||
{
|
||||
[self setOdbEditorByName:[sender title]];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleSourceDir
|
||||
{
|
||||
return [[[NSBundle mainBundle] resourcePath]
|
||||
stringByAppendingString:@"/Edit in ODBEditor"];
|
||||
}
|
||||
|
||||
// Returns the CFBundleVersion of a bundle. This assumes a bundle exists
|
||||
// at bundlePath.
|
||||
- (NSString *)versionOfBundle:(NSString *)bundlePath
|
||||
{
|
||||
// -[NSBundle initWithPath:] caches a bundle, so if the bundle is replaced
|
||||
// with a new bundle on disk, we get the old version. So we can't use it :-(
|
||||
|
||||
NSString *infoPath = [bundlePath
|
||||
stringByAppendingString:@"/Contents/Info.plist"];
|
||||
NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:infoPath];
|
||||
return [info objectForKey:@"CFBundleVersion"];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleInstalledVersion
|
||||
{
|
||||
return [self versionOfBundle:ODBEDITOR_PATH];
|
||||
}
|
||||
|
||||
- (NSString *)odbBundleInstallVersion
|
||||
{
|
||||
return [self versionOfBundle:[[self odbBundleSourceDir]
|
||||
stringByAppendingString:@"/Edit in ODBEditor.bundle"]];
|
||||
}
|
||||
|
||||
- (IBAction)installOdb:(id)sender
|
||||
{
|
||||
NSString *source = [self odbBundleSourceDir];
|
||||
|
||||
// It doesn't hurt to rm -rf the InputManager even if it's not there,
|
||||
// the code is simpler that way.
|
||||
NSArray *cmd = [NSArray arrayWithObjects:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/rm", MMCommand,
|
||||
[NSArray arrayWithObjects:@"-rf", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/mkdir", MMCommand,
|
||||
[NSArray arrayWithObjects:@"-p", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/cp", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-R",
|
||||
source, @"/Library/InputManagers", nil], MMArguments,
|
||||
nil],
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/usr/sbin/chown", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-R",
|
||||
@"root:admin", @"/Library/InputManagers", nil], MMArguments,
|
||||
nil],
|
||||
nil
|
||||
];
|
||||
|
||||
AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc]
|
||||
initWithCommands:cmd];
|
||||
OSStatus err = [au run];
|
||||
if (err == errAuthorizationSuccess) {
|
||||
// If the user just installed the input manager and no editor was
|
||||
// selected before, chances are he wants to use MacVim as editor
|
||||
if ([[self odbEditorBundleIdentifier]
|
||||
isEqualToString:kOdbEditorIdentifierNone]) {
|
||||
[self setOdbEditorByName:kOdbEditorNameMacVim];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Failed to install input manager, error is %d", err);
|
||||
}
|
||||
[au release];
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
- (IBAction)uninstallOdb:(id)sender
|
||||
{
|
||||
NSArray *cmd = [NSArray arrayWithObject:
|
||||
[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"/bin/rm", MMCommand,
|
||||
[NSArray arrayWithObjects: @"-rf", ODBEDITOR_DIR, nil], MMArguments,
|
||||
nil]];
|
||||
|
||||
AuthorizedShellCommand *au = [[AuthorizedShellCommand alloc]
|
||||
initWithCommands:cmd];
|
||||
OSStatus err = [au run];
|
||||
if (err != errAuthorizationSuccess)
|
||||
NSLog(@"Failed to uninstall input manager, error is %d", err);
|
||||
[au release];
|
||||
|
||||
[self updateIntegrationPane];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -110,12 +110,6 @@ enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Allow control of text view inset via MMTextInset* user defaults.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int left = [ud integerForKey:MMTextInsetLeftKey];
|
||||
int top = [ud integerForKey:MMTextInsetTopKey];
|
||||
[self setTextContainerInset:NSMakeSize(left, top)];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +104,12 @@ enum {
|
||||
textView = [[MMTextView alloc] initWithFrame:frame];
|
||||
}
|
||||
|
||||
// Allow control of text view inset via MMTextInset* user defaults.
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
int left = [ud integerForKey:MMTextInsetLeftKey];
|
||||
int top = [ud integerForKey:MMTextInsetTopKey];
|
||||
[textView setTextContainerInset:NSMakeSize(left, top)];
|
||||
|
||||
[textView setAutoresizingMask:NSViewNotSizable];
|
||||
[self addSubview:textView];
|
||||
|
||||
@@ -123,7 +129,6 @@ enum {
|
||||
[tabBarControl setDelegate:self];
|
||||
[tabBarControl setHidden:YES];
|
||||
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
[tabBarControl setCellMinWidth:[ud integerForKey:MMTabMinWidthKey]];
|
||||
[tabBarControl setCellMaxWidth:[ud integerForKey:MMTabMaxWidthKey]];
|
||||
[tabBarControl setCellOptimumWidth:
|
||||
|
||||
@@ -487,11 +487,31 @@
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
{
|
||||
static NSCursor *customIbeamCursor = nil;
|
||||
|
||||
if (!customIbeamCursor) {
|
||||
// Use a custom Ibeam cursor that has better contrast against dark
|
||||
// backgrounds.
|
||||
// TODO: Is the hotspot ok?
|
||||
NSImage *ibeamImage = [NSImage imageNamed:@"ibeam"];
|
||||
if (ibeamImage) {
|
||||
NSSize size = [ibeamImage size];
|
||||
NSPoint hotSpot = { size.width*.5f, size.height*.5f };
|
||||
|
||||
customIbeamCursor = [[NSCursor alloc]
|
||||
initWithImage:ibeamImage hotSpot:hotSpot];
|
||||
}
|
||||
if (!customIbeamCursor) {
|
||||
NSLog(@"WARNING: Failed to load custom Ibeam cursor");
|
||||
customIbeamCursor = [NSCursor IBeamCursor];
|
||||
}
|
||||
}
|
||||
|
||||
// This switch should match mshape_names[] in misc2.c.
|
||||
//
|
||||
// TODO: Add missing cursor shapes.
|
||||
switch (shape) {
|
||||
case 2: [[NSCursor IBeamCursor] set]; break;
|
||||
case 2: [customIbeamCursor set]; break;
|
||||
case 3: case 4: [[NSCursor resizeUpDownCursor] set]; break;
|
||||
case 5: case 6: [[NSCursor resizeLeftRightCursor] set]; break;
|
||||
case 9: [[NSCursor crosshairCursor] set]; break;
|
||||
@@ -682,15 +702,24 @@
|
||||
- (NSRect)windowWillUseStandardFrame:(NSWindow *)win
|
||||
defaultFrame:(NSRect)frame
|
||||
{
|
||||
// Keep old width and horizontal position unless user clicked while the
|
||||
// Command key is held down.
|
||||
// By default the window is maximized in the vertical direction only.
|
||||
// Holding down the Cmd key maximizes the window in the horizontal
|
||||
// direction. If the MMZoomBoth user default is set, then the window
|
||||
// maximizes in both directions by default, unless the Cmd key is held in
|
||||
// which case the window only maximizes in the vertical direction.
|
||||
|
||||
NSEvent *event = [NSApp currentEvent];
|
||||
if (!([event type] == NSLeftMouseUp
|
||||
&& [event modifierFlags] & NSCommandKeyMask)) {
|
||||
NSRect currentFrame = [win frame];
|
||||
frame.size.width = currentFrame.size.width;
|
||||
frame.origin.x = currentFrame.origin.x;
|
||||
}
|
||||
BOOL cmdLeftClick = [event type] == NSLeftMouseUp
|
||||
&& [event modifierFlags] & NSCommandKeyMask;
|
||||
BOOL zoomBoth = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMZoomBothKey];
|
||||
|
||||
if ((zoomBoth && !cmdLeftClick) || (!zoomBoth && cmdLeftClick))
|
||||
return frame;
|
||||
|
||||
NSRect currentFrame = [win frame];
|
||||
frame.size.width = currentFrame.size.width;
|
||||
frame.origin.x = currentFrame.origin.x;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -220,6 +220,10 @@ extern NSString *MMLoginShellKey;
|
||||
extern NSString *MMAtsuiRendererKey;
|
||||
extern NSString *MMUntitledWindowKey;
|
||||
extern NSString *MMTexturedWindowKey;
|
||||
extern NSString *MMZoomBothKey;
|
||||
extern NSString *MMCurrentPreferencePaneKey;
|
||||
extern NSString *MMLoginShellCommandKey;
|
||||
extern NSString *MMLoginShellArgumentKey;
|
||||
|
||||
// Enum for MMUntitledWindowKey
|
||||
enum {
|
||||
|
||||
@@ -100,6 +100,10 @@ NSString *MMLoginShellKey = @"MMLoginShell";
|
||||
NSString *MMAtsuiRendererKey = @"MMAtsuiRenderer";
|
||||
NSString *MMUntitledWindowKey = @"MMUntitledWindow";
|
||||
NSString *MMTexturedWindowKey = @"MMTexturedWindow";
|
||||
NSString *MMZoomBothKey = @"MMZoomBoth";
|
||||
NSString *MMCurrentPreferencePaneKey = @"MMCurrentPreferencePane";
|
||||
NSString *MMLoginShellCommandKey = @"MMLoginShellCommand";
|
||||
NSString *MMLoginShellArgumentKey = @"MMLoginShellArgument";
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
031AD5D40D4DE1F60026C5D7 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */; };
|
||||
031AD5EE0D4DE2490026C5D7 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */; };
|
||||
0395A8330D71ED7800881434 /* DBPrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0395A8320D71ED7800881434 /* DBPrefsWindowController.m */; };
|
||||
0395A8AA0D72D88B00881434 /* General.png in Resources */ = {isa = PBXBuildFile; fileRef = 0395A8A90D72D88B00881434 /* General.png */; };
|
||||
0395A95A0D74D47B00881434 /* Integration.png in Resources */ = {isa = PBXBuildFile; fileRef = 0395A9590D74D47B00881434 /* Integration.png */; };
|
||||
0395A9BF0D75D02400881434 /* AuthorizedShellCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */; };
|
||||
0395A9C30D75D04D00881434 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0395A9C20D75D04D00881434 /* Security.framework */; };
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA770D76E77800881434 /* Info */; };
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */; };
|
||||
1D09AB420C6A4D520045497E /* MMTypesetter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D09AB400C6A4D520045497E /* MMTypesetter.m */; };
|
||||
1D0E051C0BA5F83800B6049E /* Colors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1D0E051B0BA5F83800B6049E /* Colors.plist */; };
|
||||
1D1474980C56703C0038FA2B /* MacVim.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1474960C56703C0038FA2B /* MacVim.m */; };
|
||||
@@ -40,6 +47,7 @@
|
||||
1D9918490D299F9900A96335 /* MMAtsuiTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D9918470D299F9900A96335 /* MMAtsuiTextView.m */; };
|
||||
1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 1DD04DEB0C529C5E006CDC2B /* Credits.rtf */; };
|
||||
1DD0C20C0C60FFB4008CD84A /* gvimrc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DD0C20A0C60FF9A008CD84A /* gvimrc */; };
|
||||
1DD3D51E0D82D4C9006E4320 /* ibeam.png in Resources */ = {isa = PBXBuildFile; fileRef = 1DD3D51D0D82D4C9006E4320 /* ibeam.png */; };
|
||||
1DD66ECE0C803D3600EBDAB3 /* MMApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */; };
|
||||
1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */; };
|
||||
1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; };
|
||||
@@ -79,6 +87,20 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0395AA200D76E22700881434 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8D5B49B6048680CD000E48DA;
|
||||
remoteInfo = "Edit in ODBEditor";
|
||||
};
|
||||
0395AA230D76E2F300881434 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
|
||||
remoteInfo = "Edit in ODBEditor";
|
||||
};
|
||||
1D493DB80C52533B00AB718C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */;
|
||||
@@ -96,6 +118,17 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0395AA790D76E77800881434 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "Edit in ODBEditor";
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
0395AAAD0D76E94000881434 /* Edit in ODBEditor.bundle in CopyFiles */,
|
||||
0395AA780D76E77800881434 /* Info in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -133,6 +166,15 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
031AD5D30D4DE1F60026C5D7 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
|
||||
0395A8310D71ED7800881434 /* DBPrefsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBPrefsWindowController.h; sourceTree = "<group>"; };
|
||||
0395A8320D71ED7800881434 /* DBPrefsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBPrefsWindowController.m; sourceTree = "<group>"; };
|
||||
0395A8A90D72D88B00881434 /* General.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = General.png; sourceTree = "<group>"; };
|
||||
0395A9590D74D47B00881434 /* Integration.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Integration.png; sourceTree = "<group>"; };
|
||||
0395A9BD0D75D02400881434 /* AuthorizedShellCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthorizedShellCommand.h; sourceTree = "<group>"; };
|
||||
0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthorizedShellCommand.m; sourceTree = "<group>"; };
|
||||
0395A9C20D75D04D00881434 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
|
||||
0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Edit in ODBEditor.xcodeproj"; path = "edit-in-odb/Edit in ODBEditor.xcodeproj"; sourceTree = "<group>"; };
|
||||
0395AA770D76E77800881434 /* Info */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = Info; path = "edit-in-odb/Info"; sourceTree = "<group>"; };
|
||||
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
@@ -177,6 +219,7 @@
|
||||
1D9918470D299F9900A96335 /* MMAtsuiTextView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMAtsuiTextView.m; sourceTree = "<group>"; };
|
||||
1DD04DEB0C529C5E006CDC2B /* Credits.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
|
||||
1DD0C20A0C60FF9A008CD84A /* gvimrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gvimrc; sourceTree = "<group>"; };
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = ibeam.png; sourceTree = "<group>"; };
|
||||
1DD66ECB0C803D3600EBDAB3 /* MMApplication.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MMApplication.h; sourceTree = "<group>"; };
|
||||
1DD66ECC0C803D3600EBDAB3 /* MMApplication.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MMApplication.m; sourceTree = "<group>"; };
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vim_gloss.icns; sourceTree = "<group>"; };
|
||||
@@ -229,15 +272,37 @@
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
|
||||
1D80FBE40CBBD6F200102A1C /* Carbon.framework in Frameworks */,
|
||||
031AD5D40D4DE1F60026C5D7 /* Sparkle.framework in Frameworks */,
|
||||
0395A9C30D75D04D00881434 /* Security.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0395AA1A0D76E22700881434 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0395AA980D76E86200881434 /* Edit in ODBEditor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */,
|
||||
0395AA770D76E77800881434 /* Info */,
|
||||
);
|
||||
name = "Edit in ODBEditor";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
080E96DDFE201D6D7F000001 /* MacVim Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395A9BD0D75D02400881434 /* AuthorizedShellCommand.h */,
|
||||
0395A9BE0D75D02400881434 /* AuthorizedShellCommand.m */,
|
||||
0395A8310D71ED7800881434 /* DBPrefsWindowController.h */,
|
||||
0395A8320D71ED7800881434 /* DBPrefsWindowController.m */,
|
||||
1DE3F8E80D50F84600052B9E /* MMPreferenceController.h */,
|
||||
1DE3F8E90D50F84600052B9E /* MMPreferenceController.m */,
|
||||
1DE9B94D0D341AB8008FEDD4 /* MMWindow.h */,
|
||||
@@ -339,6 +404,8 @@
|
||||
1D71ACB10BC702AB002F2B60 /* doc-bm-txt.icns */,
|
||||
1D71ACB20BC702AB002F2B60 /* doc-bm-xml.icns */,
|
||||
1D71ACB30BC702AB002F2B60 /* doc-bm.icns */,
|
||||
0395A8A90D72D88B00881434 /* General.png */,
|
||||
0395A9590D74D47B00881434 /* Integration.png */,
|
||||
1DD703B80BA9D15D008679E9 /* vim_gloss.icns */,
|
||||
);
|
||||
name = Icons;
|
||||
@@ -398,6 +465,7 @@
|
||||
29B97317FDCFA39411CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1DD3D51D0D82D4C9006E4320 /* ibeam.png */,
|
||||
1D0F11480D58C77800D5DA09 /* Font */,
|
||||
1DCE78490C460C6C006305A6 /* Icons */,
|
||||
1DE9726C0C48050600F96A9F /* Toolbar */,
|
||||
@@ -417,6 +485,8 @@
|
||||
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0395AA980D76E86200881434 /* Edit in ODBEditor */,
|
||||
0395A9C20D75D04D00881434 /* Security.framework */,
|
||||
1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */,
|
||||
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
|
||||
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
|
||||
@@ -437,11 +507,13 @@
|
||||
1D0DCAD80BA3604D00B6CCFA /* CopyFiles */,
|
||||
1D9EB2840C366D7B0074B739 /* CopyFiles */,
|
||||
1DE608B80C58807F0055263D /* CopyFiles */,
|
||||
0395AA790D76E77800881434 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
1D493DCD0C5254A400AB718C /* PBXTargetDependency */,
|
||||
0395AA240D76E2F300881434 /* PBXTargetDependency */,
|
||||
);
|
||||
name = MacVim;
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
@@ -460,6 +532,10 @@
|
||||
mainGroup = 29B97314FDCFA39411CA2CEA /* MacVim */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 0395AA1A0D76E22700881434 /* Products */;
|
||||
ProjectRef = 0395AA190D76E22700881434 /* Edit in ODBEditor.xcodeproj */;
|
||||
},
|
||||
{
|
||||
ProductGroup = 1D493DB40C52533B00AB718C /* Products */;
|
||||
ProjectRef = 1D493DB30C52533B00AB718C /* PSMTabBarControl.xcodeproj */;
|
||||
@@ -473,6 +549,13 @@
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
0395AA210D76E22700881434 /* Edit in ODBEditor.bundle */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = "Edit in ODBEditor.bundle";
|
||||
remoteRef = 0395AA200D76E22700881434 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
1D493DB90C52533B00AB718C /* PSMTabBarControl.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
@@ -532,6 +615,9 @@
|
||||
1D3D19130CA690FF0004A0A5 /* DejaVuSansMono-Oblique.ttf in Resources */,
|
||||
1D3D19140CA690FF0004A0A5 /* DejaVuSansMono.ttf in Resources */,
|
||||
1DE3F8E70D50F80500052B9E /* Preferences.nib in Resources */,
|
||||
0395A8AA0D72D88B00881434 /* General.png in Resources */,
|
||||
0395A95A0D74D47B00881434 /* Integration.png in Resources */,
|
||||
1DD3D51E0D82D4C9006E4320 /* ibeam.png in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -556,12 +642,19 @@
|
||||
1D9918490D299F9900A96335 /* MMAtsuiTextView.m in Sources */,
|
||||
1DE9B9500D341AB8008FEDD4 /* MMWindow.m in Sources */,
|
||||
1DE3F8EB0D50F84600052B9E /* MMPreferenceController.m in Sources */,
|
||||
0395A8330D71ED7800881434 /* DBPrefsWindowController.m in Sources */,
|
||||
0395A9BF0D75D02400881434 /* AuthorizedShellCommand.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0395AA240D76E2F300881434 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = "Edit in ODBEditor";
|
||||
targetProxy = 0395AA230D76E2F300881434 /* PBXContainerItemProxy */;
|
||||
};
|
||||
1D493DCD0C5254A400AB718C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = PSMTabBarControlFramework;
|
||||
@@ -605,7 +698,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 23;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -646,7 +739,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 23;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -677,7 +770,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 23;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
@@ -416,9 +416,11 @@
|
||||
0259C573FE90428111CA0C5A /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = C056398B08A954F8003078D8 /* Build configuration list for PBXProject "PSMTabBarControl" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 0259C574FE90428111CA0C5A /* PSMTabBarControl */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
53DF68FC067E5B5A0090B5B0 /* PSMTabBarControlFramework */,
|
||||
53DF6901067E5B8E0090B5B0 /* All */,
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
This archive contains a snapshot of 'MacVim.app' and the shell script
|
||||
'mvim'.
|
||||
|
||||
For usage instructions, please start MacVim and type ":h macvim"
|
||||
(without the quotes).
|
||||
|
||||
MacVim requires a PPC or Intel Mac running Mac OS X 10.4 or 10.5.
|
||||
@@ -0,0 +1,345 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 42;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
17085DDA0939627C000D0081 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17085DD90939627C000D0081 /* Carbon.framework */; };
|
||||
174E80980A57DFA5003FB108 /* url map.plist in Resources */ = {isa = PBXBuildFile; fileRef = 174E80970A57DFA5003FB108 /* url map.plist */; };
|
||||
1796636A093A122C00138851 /* Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966367093A122C00138851 /* Edit in ODBEditor.mm */; };
|
||||
1796636B093A122C00138851 /* NSTextView: Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */; };
|
||||
1796636C093A122C00138851 /* WebView: Edit in ODBEditor.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */; };
|
||||
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
|
||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
17085DD90939627C000D0081 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
|
||||
174E80970A57DFA5003FB108 /* url map.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "url map.plist"; sourceTree = "<group>"; };
|
||||
17966367093A122C00138851 /* Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "Edit in ODBEditor.mm"; path = "src/Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "NSTextView: Edit in ODBEditor.mm"; path = "src/NSTextView: Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "WebView: Edit in ODBEditor.mm"; path = "src/WebView: Edit in ODBEditor.mm"; sourceTree = "<group>"; };
|
||||
32DBCF630370AF2F00C91783 /* Edit in ODBEditor_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Edit in ODBEditor_Prefix.pch"; sourceTree = "<group>"; };
|
||||
8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Edit in ODBEditor.bundle"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
8D5B49B3048680CD000E48DA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
|
||||
17085DDA0939627C000D0081 /* Carbon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
089C166AFE841209C02AAC07 /* Edit in TextMate */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
08FB77AFFE84173DC02AAC07 /* Classes */,
|
||||
32C88E010371C26100C91783 /* Other Sources */,
|
||||
089C167CFE841241C02AAC07 /* Resources */,
|
||||
089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
|
||||
19C28FB8FE9D52D311CA2CBB /* Products */,
|
||||
);
|
||||
name = "Edit in TextMate";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17085DD90939627C000D0081 /* Carbon.framework */,
|
||||
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
|
||||
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
|
||||
);
|
||||
name = "Frameworks and Libraries";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
089C167CFE841241C02AAC07 /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
174E80970A57DFA5003FB108 /* url map.plist */,
|
||||
8D5B49B7048680CD000E48DA /* Info.plist */,
|
||||
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
08FB77AFFE84173DC02AAC07 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17966367093A122C00138851 /* Edit in ODBEditor.mm */,
|
||||
17966368093A122C00138851 /* NSTextView: Edit in ODBEditor.mm */,
|
||||
17966369093A122C00138851 /* WebView: Edit in ODBEditor.mm */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
|
||||
);
|
||||
name = "Linked Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
089C167FFE841241C02AAC07 /* AppKit.framework */,
|
||||
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
|
||||
089C1672FE841209C02AAC07 /* Foundation.framework */,
|
||||
);
|
||||
name = "Other Frameworks";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
19C28FB8FE9D52D311CA2CBB /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
32C88E010371C26100C91783 /* Other Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
32DBCF630370AF2F00C91783 /* Edit in ODBEditor_Prefix.pch */,
|
||||
);
|
||||
name = "Other Sources";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8D5B49AC048680CD000E48DA /* Edit in ODBEditor */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Edit in ODBEditor" */;
|
||||
buildPhases = (
|
||||
8D5B49AF048680CD000E48DA /* Resources */,
|
||||
8D5B49B1048680CD000E48DA /* Sources */,
|
||||
8D5B49B3048680CD000E48DA /* Frameworks */,
|
||||
17ECD3290A3A1A6A009A4BA0 /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "Edit in ODBEditor";
|
||||
productInstallPath = "$(HOME)/Library/Bundles";
|
||||
productName = "Edit in TextMate";
|
||||
productReference = 8D5B49B6048680CD000E48DA /* Edit in ODBEditor.bundle */;
|
||||
productType = "com.apple.product-type.bundle";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
089C1669FE841209C02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Edit in ODBEditor" */;
|
||||
compatibilityVersion = "Xcode 2.4";
|
||||
hasScannedForEncodings = 1;
|
||||
mainGroup = 089C166AFE841209C02AAC07 /* Edit in TextMate */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8D5B49AC048680CD000E48DA /* Edit in ODBEditor */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
8D5B49AF048680CD000E48DA /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
|
||||
174E80980A57DFA5003FB108 /* url map.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
17ECD3290A3A1A6A009A4BA0 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if [[ -d ~/Oak/Release/Edit\\ in\\ TextMate.bundle && -d ~/Source/TextMate/resources/Edit\\ in\\ TextMate ]]; then\n cp -pR ~/Oak/Release/Edit\\ in\\ TextMate.bundle ~/Source/TextMate/resources/Edit\\ in\\ TextMate\n touch ~/Source/TextMate/resources/Edit\\ in\\ TextMate\nfi";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8D5B49B1048680CD000E48DA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1796636A093A122C00138851 /* Edit in ODBEditor.mm in Sources */,
|
||||
1796636B093A122C00138851 /* NSTextView: Edit in ODBEditor.mm in Sources */,
|
||||
1796636C093A122C00138851 /* WebView: Edit in ODBEditor.mm in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
089C167EFE841241C02AAC07 /* English */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
1DD3D5530D82D8D7006E4320 /* Universal */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Universal;
|
||||
};
|
||||
1DD3D5540D82D8D7006E4320 /* Universal */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Universal;
|
||||
};
|
||||
1DEB913B08733D840010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
ZERO_LINK = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB913C08733D840010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "Edit in ODBEditor_Prefix.pch";
|
||||
INFOPLIST_FILE = Info.plist;
|
||||
INSTALL_PATH = "";
|
||||
OTHER_LDFLAGS = (
|
||||
"-undefined",
|
||||
dynamic_lookup,
|
||||
);
|
||||
PRODUCT_NAME = "Edit in ODBEditor";
|
||||
SYMROOT = ../build;
|
||||
WRAPPER_EXTENSION = bundle;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
1DEB913F08733D840010E9CD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1DEB914008733D840010E9CD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
GCC_ENABLE_CPP_EXCEPTIONS = NO;
|
||||
GCC_ENABLE_CPP_RTTI = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Edit in ODBEditor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB913B08733D840010E9CD /* Debug */,
|
||||
1DEB913C08733D840010E9CD /* Release */,
|
||||
1DD3D5530D82D8D7006E4320 /* Universal */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Edit in ODBEditor" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1DEB913F08733D840010E9CD /* Debug */,
|
||||
1DEB914008733D840010E9CD /* Release */,
|
||||
1DD3D5540D82D8D7006E4320 /* Universal */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
//
|
||||
// Prefix header for all source files of the 'Edit in ODBEditor' target in the 'Edit in ODBEditor' project.
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BundleName</key>
|
||||
<string>Edit in ODBEditor.bundle</string>
|
||||
<key>LoadBundleOnLaunch</key>
|
||||
<string>YES</string>
|
||||
<key>LocalizedNames</key>
|
||||
<dict>
|
||||
<key>English</key>
|
||||
<string>Edit in ODBEditor</string>
|
||||
</dict>
|
||||
<key>NoMenuEntry</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.slashpunt.edit_in_odbeditor</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.1</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>EditInODBEditor</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
xcodebuild
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Edit in ODBEditor.h
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-26.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'Edit in TextMate.h'
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface EditInODBEditor : NSObject
|
||||
{
|
||||
}
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView;
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView withObject:(NSObject*)anObject;
|
||||
@end
|
||||
@@ -0,0 +1,287 @@
|
||||
//
|
||||
// Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-26.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'Edit in TextMate.mm'
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <map>
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
// from ODBEditorSuite.h
|
||||
#define keyFileSender 'FSnd'
|
||||
#define kODBEditorSuite 'R*ch'
|
||||
#define kAEModifiedFile 'FMod'
|
||||
#define kAEClosedFile 'FCls'
|
||||
|
||||
static NSMutableDictionary* OpenFiles;
|
||||
static NSMutableSet* FailedFiles;
|
||||
static NSString* ODBEditorBundleIdentifier;
|
||||
static NSString* ODBEditorName;
|
||||
|
||||
#pragma options align=mac68k
|
||||
struct PBX_SelectionRange
|
||||
{
|
||||
short unused1; // 0 (not used)
|
||||
short lineNum; // line to select (<0 to specify range)
|
||||
long startRange; // start of selection range (if line < 0)
|
||||
long endRange; // end of selection range (if line < 0)
|
||||
long unused2; // 0 (not used)
|
||||
long theDate; // modification date/time
|
||||
};
|
||||
#pragma options align=reset
|
||||
|
||||
@implementation EditInODBEditor
|
||||
+ (void)setODBEventHandlers
|
||||
{
|
||||
NSAppleEventManager* eventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[eventManager setEventHandler:self andSelector:@selector(handleModifiedFileEvent:withReplyEvent:) forEventClass:kODBEditorSuite andEventID:kAEModifiedFile];
|
||||
[eventManager setEventHandler:self andSelector:@selector(handleClosedFileEvent:withReplyEvent:) forEventClass:kODBEditorSuite andEventID:kAEClosedFile];
|
||||
}
|
||||
|
||||
+ (void)removeODBEventHandlers
|
||||
{
|
||||
NSAppleEventManager* eventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||
[eventManager removeEventHandlerForEventClass:kODBEditorSuite andEventID:kAEModifiedFile];
|
||||
[eventManager removeEventHandlerForEventClass:kODBEditorSuite andEventID:kAEClosedFile];
|
||||
}
|
||||
|
||||
+ (BOOL)launchODBEditor
|
||||
{
|
||||
NSArray* array = [[NSWorkspace sharedWorkspace] launchedApplications];
|
||||
for(unsigned i = [array count]; --i; )
|
||||
{
|
||||
if([[[array objectAtIndex:i] objectForKey:@"NSApplicationBundleIdentifier"] isEqualToString:ODBEditorBundleIdentifier])
|
||||
return YES;
|
||||
}
|
||||
return [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:ODBEditorBundleIdentifier options:0L additionalEventParamDescriptor:nil launchIdentifier:nil];
|
||||
}
|
||||
|
||||
+ (void)asyncEditStringWithOptions:(NSDictionary*)someOptions
|
||||
{
|
||||
NSAutoreleasePool* pool = [NSAutoreleasePool new];
|
||||
|
||||
if(![self launchODBEditor])
|
||||
return;
|
||||
|
||||
/* =========== */
|
||||
|
||||
NSData* targetBundleID = [ODBEditorBundleIdentifier dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSAppleEventDescriptor* targetDescriptor = [NSAppleEventDescriptor descriptorWithDescriptorType:typeApplicationBundleID data:targetBundleID];
|
||||
NSAppleEventDescriptor* appleEvent = [NSAppleEventDescriptor appleEventWithEventClass:kCoreEventClass eventID:kAEOpenDocuments targetDescriptor:targetDescriptor returnID:kAutoGenerateReturnID transactionID:kAnyTransactionID];
|
||||
NSAppleEventDescriptor* replyDescriptor = nil;
|
||||
NSAppleEventDescriptor* errorDescriptor = nil;
|
||||
AEDesc reply = { typeNull, NULL };
|
||||
|
||||
NSString* fileName = [someOptions objectForKey:@"fileName"];
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:typeFileURL data:[[[NSURL fileURLWithPath:fileName] absoluteString] dataUsingEncoding:NSUTF8StringEncoding]] forKeyword:keyDirectObject];
|
||||
|
||||
UInt32 packageType = 0, packageCreator = 0;
|
||||
CFBundleGetPackageInfo(CFBundleGetMainBundle(), &packageType, &packageCreator);
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithTypeCode:packageCreator] forKeyword:keyFileSender];
|
||||
|
||||
if(int line = [[someOptions objectForKey:@"line"] intValue])
|
||||
{
|
||||
PBX_SelectionRange pos = { };
|
||||
pos.lineNum = line;
|
||||
[appleEvent setParamDescriptor:[NSAppleEventDescriptor descriptorWithDescriptorType:typeChar bytes:&pos length:sizeof(pos)] forKeyword:keyAEPosition];
|
||||
}
|
||||
|
||||
OSStatus status = AESend([appleEvent aeDesc], &reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
|
||||
if(status == noErr)
|
||||
{
|
||||
replyDescriptor = [[[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&reply] autorelease];
|
||||
errorDescriptor = [replyDescriptor paramDescriptorForKeyword:keyErrorNumber];
|
||||
if(errorDescriptor != nil)
|
||||
status = [errorDescriptor int32Value];
|
||||
|
||||
if(status != noErr)
|
||||
NSLog(@"%s error %d", _cmd, status), NSBeep();
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
||||
+ (NSString*)extensionForURL:(NSURL*)anURL
|
||||
{
|
||||
NSString* res = nil;
|
||||
if(NSString* urlString = [anURL absoluteString])
|
||||
{
|
||||
NSString* path = [[NSBundle bundleForClass:[self class]] pathForResource:@"url map" ofType:@"plist"];
|
||||
NSMutableDictionary* map = [NSMutableDictionary dictionaryWithContentsOfFile:path];
|
||||
|
||||
NSString* customBindingsPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"Preferences/org.slashpunt.edit_in_odbeditor.plist"];
|
||||
if(NSDictionary* associations = [[NSDictionary dictionaryWithContentsOfFile:customBindingsPath] objectForKey:@"URLAssociations"])
|
||||
[map addEntriesFromDictionary:associations];
|
||||
|
||||
unsigned longestMatch = 0;
|
||||
NSEnumerator* enumerator = [map keyEnumerator];
|
||||
while(NSString* key = [enumerator nextObject])
|
||||
{
|
||||
if([urlString rangeOfString:key].location != NSNotFound && [key length] > longestMatch)
|
||||
{
|
||||
res = [map objectForKey:key];
|
||||
longestMatch = [key length];
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView
|
||||
{
|
||||
[self externalEditString:aString startingAtLine:aLine forView:aView withObject:nil];
|
||||
}
|
||||
|
||||
+ (void)externalEditString:(NSString*)aString startingAtLine:(int)aLine forView:(NSView*)aView withObject:(NSObject*)anObject
|
||||
{
|
||||
Class cl = NSClassFromString(@"WebFrameView");
|
||||
|
||||
NSURL* url = nil;
|
||||
for(NSView* view = aView; view && !url && cl; view = [view superview])
|
||||
{
|
||||
if([view isKindOfClass:cl])
|
||||
url = [[[[(WebFrameView*)view webFrame] dataSource] mainResource] URL];
|
||||
}
|
||||
|
||||
NSString* basename = [[[[aView window] title] componentsSeparatedByString:@"/"] componentsJoinedByString:@"-"] ?: @"untitled";
|
||||
NSString* extension = [self extensionForURL:url] ?: [[[[NSWorkspace sharedWorkspace] activeApplication] objectForKey:@"NSApplicationName"] lowercaseString];
|
||||
NSString* fileName = [NSString stringWithFormat:@"%@/%@.%@", NSTemporaryDirectory(), basename, extension];
|
||||
for(unsigned i = 2; [[NSFileManager defaultManager] fileExistsAtPath:fileName]; i++)
|
||||
fileName = [NSString stringWithFormat:@"%@/%@ %u.%@", NSTemporaryDirectory(), basename, i, extension];
|
||||
|
||||
[[aString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:fileName atomically:NO];
|
||||
fileName = [fileName stringByStandardizingPath];
|
||||
|
||||
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
aString, @"string",
|
||||
aView, @"view",
|
||||
fileName, @"fileName",
|
||||
[NSNumber numberWithInt:aLine], @"line",
|
||||
anObject, @"object", /* last since anObject might be nil */
|
||||
nil];
|
||||
|
||||
[OpenFiles setObject:options forKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
if([OpenFiles count] == 1)
|
||||
[self setODBEventHandlers];
|
||||
[NSThread detachNewThreadSelector:@selector(asyncEditStringWithOptions:) toTarget:self withObject:options];
|
||||
}
|
||||
|
||||
+ (void)handleModifiedFileEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||
{
|
||||
NSAppleEventDescriptor* fileURL = [[event paramDescriptorForKeyword:keyDirectObject] coerceToDescriptorType:typeFileURL];
|
||||
NSString* urlString = [[[NSString alloc] initWithData:[fileURL data] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSString* fileName = [[[NSURL URLWithString:urlString] path] stringByStandardizingPath];
|
||||
NSDictionary* options = [OpenFiles objectForKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
NSView* view = [options objectForKey:@"view"];
|
||||
|
||||
if([view window])
|
||||
{
|
||||
if ([view respondsToSelector:@selector(odbEditorDidModifyString:withObject:)])
|
||||
{
|
||||
NSString* newString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileName] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSObject* anObject = [options objectForKey:@"object"];
|
||||
[view performSelector:@selector(odbEditorDidModifyString:withObject:) withObject:newString withObject:anObject];
|
||||
[FailedFiles removeObject:fileName];
|
||||
fileName = nil;
|
||||
}
|
||||
else if([view respondsToSelector:@selector(odbEditorDidModifyString:)])
|
||||
{
|
||||
NSString* newString = [[[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileName] encoding:NSUTF8StringEncoding] autorelease];
|
||||
[view performSelector:@selector(odbEditorDidModifyString:) withObject:newString];
|
||||
[FailedFiles removeObject:fileName];
|
||||
fileName = nil;
|
||||
}
|
||||
}
|
||||
if (fileName)
|
||||
{
|
||||
[FailedFiles addObject:fileName];
|
||||
NSLog(@"%s view %p, %@, window %@", _cmd, view, view, [view window]);
|
||||
NSLog(@"%s file name %@, options %@", _cmd, fileName, [options description]);
|
||||
NSLog(@"%s all %@", _cmd, [OpenFiles description]);
|
||||
NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)handleClosedFileEvent:(NSAppleEventDescriptor*)event withReplyEvent:(NSAppleEventDescriptor*)replyEvent
|
||||
{
|
||||
NSAppleEventDescriptor* fileURL = [[event paramDescriptorForKeyword:keyDirectObject] coerceToDescriptorType:typeFileURL];
|
||||
NSString* urlString = [[[NSString alloc] initWithData:[fileURL data] encoding:NSUTF8StringEncoding] autorelease];
|
||||
NSString* fileName = [[[NSURL URLWithString:urlString] path] stringByStandardizingPath];
|
||||
|
||||
if([FailedFiles containsObject:fileName])
|
||||
{
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:fileName])
|
||||
[[NSWorkspace sharedWorkspace] selectFile:fileName inFileViewerRootedAtPath:[fileName stringByDeletingLastPathComponent]];
|
||||
[FailedFiles removeObject:fileName];
|
||||
}
|
||||
else
|
||||
{
|
||||
[[NSFileManager defaultManager] removeFileAtPath:fileName handler:nil];
|
||||
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
[OpenFiles removeObjectForKey:[fileName precomposedStringWithCanonicalMapping]];
|
||||
if([OpenFiles count] == 0)
|
||||
[self removeODBEventHandlers];
|
||||
}
|
||||
|
||||
+ (NSMenu*)findEditMenu
|
||||
{
|
||||
NSMenu* mainMenu = [NSApp mainMenu];
|
||||
std::map<size_t, NSMenu*> ranked;
|
||||
for(int i = 0; i != [mainMenu numberOfItems]; i++)
|
||||
{
|
||||
NSMenu* candidate = [[mainMenu itemAtIndex:i] submenu];
|
||||
static SEL const actions[] = { @selector(undo:), @selector(redo:), @selector(cut:), @selector(copy:), @selector(paste:), @selector(delete:), @selector(selectAll:) };
|
||||
size_t score = 0;
|
||||
for(int j = 0; j != sizeof(actions)/sizeof(actions[0]); j++)
|
||||
{
|
||||
if(-1 != [candidate indexOfItemWithTarget:nil andAction:actions[j]])
|
||||
score++;
|
||||
}
|
||||
|
||||
if(score > 0 && ranked.find(score) == ranked.end())
|
||||
ranked[score] = candidate;
|
||||
}
|
||||
return ranked.empty() ? nil : (--ranked.end())->second;
|
||||
}
|
||||
|
||||
+ (void)installMenuItem:(id)sender
|
||||
{
|
||||
if(NSMenu* editMenu = [self findEditMenu])
|
||||
{
|
||||
[editMenu addItem:[NSMenuItem separatorItem]];
|
||||
NSString* ellips = [NSString stringWithUTF8String:"\xe2\x80\xa6"]; // utf-8 for the '...' character (literal utf8 is not allowed in source code)
|
||||
id <NSMenuItem> menuItem = [editMenu addItemWithTitle:[NSString stringWithFormat:@"Edit in %@%@", ODBEditorName, ellips] action:@selector(editInODBEditor:) keyEquivalent:@"E"];
|
||||
[menuItem setKeyEquivalentModifierMask:NSControlKeyMask | NSCommandKeyMask];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)load
|
||||
{
|
||||
OpenFiles = [NSMutableDictionary new];
|
||||
FailedFiles = [NSMutableSet new];
|
||||
NSString* mainBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; // reads app we're used inside off
|
||||
NSString* bundleIdentifier = @"org.slashpunt.edit_in_odbeditor"; // XXX Should this be hardcoded?
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults addSuiteNamed:bundleIdentifier];
|
||||
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"NO", @"DisableEditInODBEditorMenuItem",
|
||||
@"", @"ODBEditorBundleIdentifier",
|
||||
@"<Unknown>", @"ODBEditorName",
|
||||
nil];
|
||||
|
||||
[defaults registerDefaults:appDefaults];
|
||||
|
||||
ODBEditorBundleIdentifier = [defaults stringForKey:@"ODBEditorBundleIdentifier"] ?: @"";
|
||||
ODBEditorName = [defaults stringForKey:@"ODBEditorName"] ?: @"<Unknown>";
|
||||
if([defaults boolForKey:@"DisableEditInODBEditorMenuItem"] == NO
|
||||
&& ![ODBEditorBundleIdentifier isEqualToString:@""]
|
||||
&& ![ODBEditorBundleIdentifier isEqualToString:mainBundleIdentifier])
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(installMenuItem:) name:NSApplicationDidFinishLaunchingNotification object:[NSApplication sharedApplication]];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,60 @@
|
||||
//
|
||||
// NSTextView: Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-27.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'NSTextView: Edit in TextMate.mm'
|
||||
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
@interface NSTextView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender;
|
||||
@end
|
||||
|
||||
@implementation NSTextView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender
|
||||
{
|
||||
if(![self isEditable])
|
||||
return (void)NSBeep();
|
||||
|
||||
NSString* str = [[self textStorage] string];
|
||||
NSRange selectedRange = [self selectedRange];
|
||||
int lineNumber = 0;
|
||||
if(selectedRange.length == 0)
|
||||
{
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
do {
|
||||
NSRange oldRange = range;
|
||||
range = [str lineRangeForRange:NSMakeRange(NSMaxRange(range), 0)];
|
||||
if(NSMaxRange(oldRange) == NSMaxRange(range) || selectedRange.location < NSMaxRange(range))
|
||||
break;
|
||||
lineNumber++;
|
||||
} while(true);
|
||||
selectedRange = NSMakeRange(0, [str length]);
|
||||
}
|
||||
|
||||
[EditInODBEditor externalEditString:[str substringWithRange:selectedRange] startingAtLine:lineNumber forView:self];
|
||||
}
|
||||
|
||||
- (void)odbEditorDidModifyString:(NSString*)newString
|
||||
{
|
||||
NSRange selectedRange = [self selectedRange];
|
||||
BOOL hadSelection = selectedRange.length != 0;
|
||||
selectedRange = hadSelection ? selectedRange : NSMakeRange(0, [[self textStorage] length]);
|
||||
if([self shouldChangeTextInRange:selectedRange replacementString:newString])
|
||||
{
|
||||
if(!hadSelection)
|
||||
[self setSelectedRange:NSMakeRange(0, [[self textStorage] length])];
|
||||
[self insertText:newString];
|
||||
if(hadSelection)
|
||||
[self setSelectedRange:NSMakeRange(selectedRange.location, [newString length])];
|
||||
[self didChangeText];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSBeep();
|
||||
NSLog(@"%s couldn't edit text", _cmd);
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,410 @@
|
||||
//
|
||||
// WebView: Edit in ODBEditor.mm
|
||||
//
|
||||
// Created by Allan Odgaard on 2005-11-27.
|
||||
// See LICENSE for license details
|
||||
//
|
||||
// Generalized by Chris Eidhof and Eelco Lempsink from 'WebView: Edit in TextMate.mm'
|
||||
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
#import <vector>
|
||||
#import "Edit in ODBEditor.h"
|
||||
|
||||
#ifndef sizeofA
|
||||
#define sizeofA(x) (sizeof(x)/sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
// only latest WebKit has this stuff, and it is private
|
||||
@interface DOMHTMLTextAreaElement (DOMHTMLTextAreaElementPrivate)
|
||||
- (int)selectionStart;
|
||||
- (void)setSelectionStart:(int)newSelectionStart;
|
||||
- (int)selectionEnd;
|
||||
- (void)setSelectionEnd:(int)newSelectionEnd;
|
||||
- (void)setSelectionRange:(int)start end:(int)end;
|
||||
@end
|
||||
|
||||
@interface WebView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender;
|
||||
@end
|
||||
|
||||
@interface NSString (EditInODBEditor)
|
||||
- (NSString*)ODB_stringByTrimmingWhitespace;
|
||||
- (NSString*)ODB_stringByReplacingString:(NSString*)aSearchString withString:(NSString*)aReplaceString;
|
||||
- (NSString*)ODB_stringByNbspEscapingSpaces;
|
||||
@end
|
||||
|
||||
@implementation NSString (EditInODBEditor)
|
||||
- (NSString*)ODB_stringByTrimmingWhitespace
|
||||
{
|
||||
NSString* str = self;
|
||||
while([str hasPrefix:@" "])
|
||||
str = [str substringFromIndex:1];
|
||||
|
||||
while([str hasSuffix:@" "])
|
||||
str = [str substringToIndex:[str length]-1];
|
||||
return str;
|
||||
}
|
||||
|
||||
- (NSString*)ODB_stringByReplacingString:(NSString*)aSearchString withString:(NSString*)aReplaceString
|
||||
{
|
||||
return [[self componentsSeparatedByString:aSearchString] componentsJoinedByString:aReplaceString];
|
||||
}
|
||||
|
||||
- (NSString*)ODB_stringByNbspEscapingSpaces
|
||||
{
|
||||
unsigned len = [self length];
|
||||
unichar* buf = new unichar[len];
|
||||
[self getCharacters:buf];
|
||||
for(unsigned i = 0; i != len; i++)
|
||||
{
|
||||
if(buf[i] == ' ' && (i+1 == len || buf[i+1] == ' '))
|
||||
buf[i] = 0xA0;
|
||||
}
|
||||
return [NSString stringWithCharacters:buf length:len];
|
||||
}
|
||||
@end
|
||||
|
||||
struct convert_dom_to_text
|
||||
{
|
||||
convert_dom_to_text (DOMTreeWalker* treeWalker) : string([NSMutableString new]), quoteLevel(0), pendingFlush(NO), pendingWhitespace(NO), didOutputText(NO), atBeginOfLine(YES) { visit_nodes(treeWalker); }
|
||||
~convert_dom_to_text () { [string autorelease]; }
|
||||
operator NSString* () const { return string; }
|
||||
|
||||
private:
|
||||
void enter_block_tag ()
|
||||
{
|
||||
pendingFlush |= didOutputText;
|
||||
didOutputText = NO;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void leave_block_tag ()
|
||||
{
|
||||
pendingFlush |= didOutputText;
|
||||
didOutputText = NO;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void output_text (NSString* str)
|
||||
{
|
||||
if([str isEqualToString:@""])
|
||||
return;
|
||||
|
||||
str = [str ODB_stringByTrimmingWhitespace];
|
||||
if([str isEqualToString:@""])
|
||||
{
|
||||
pendingWhitespace = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
str = [str ODB_stringByReplacingString:[NSString stringWithUTF8String:" "] withString:@" "];
|
||||
|
||||
if(pendingFlush)
|
||||
{
|
||||
[string appendString:@"\n"];
|
||||
pendingFlush = NO;
|
||||
atBeginOfLine = YES;
|
||||
}
|
||||
|
||||
if(atBeginOfLine && quoteLevel)
|
||||
{
|
||||
for(unsigned i = 0; i < quoteLevel; i++)
|
||||
[string appendString:@"> "];
|
||||
}
|
||||
else if(!atBeginOfLine && pendingWhitespace)
|
||||
{
|
||||
[string appendString:@" "];
|
||||
}
|
||||
|
||||
[string appendString:str];
|
||||
atBeginOfLine = NO;
|
||||
didOutputText = YES;
|
||||
pendingWhitespace = NO;
|
||||
}
|
||||
|
||||
void visit_nodes (DOMTreeWalker* treeWalker);
|
||||
|
||||
NSMutableString* string;
|
||||
unsigned quoteLevel;
|
||||
BOOL pendingFlush;
|
||||
BOOL pendingWhitespace;
|
||||
BOOL didOutputText;
|
||||
BOOL atBeginOfLine;
|
||||
};
|
||||
|
||||
struct helper
|
||||
{
|
||||
helper (DOMHTMLTextAreaElement* textArea) : textArea(textArea)
|
||||
{
|
||||
value = [textArea value];
|
||||
selectionStart = [textArea selectionStart];
|
||||
selectionEnd = [textArea selectionEnd];
|
||||
}
|
||||
|
||||
helper () : textArea(nil), value(nil) { }
|
||||
bool should_change () const { return selectionStart != 0 || selectionEnd != [value length]; }
|
||||
bool did_change () const { return selectionStart != [textArea selectionStart] || selectionEnd != [textArea selectionEnd]; }
|
||||
void reset () const
|
||||
{
|
||||
if([textArea value] != value) [textArea setValue:value];
|
||||
if(did_change()) [textArea setSelectionRange:selectionStart end:selectionEnd];
|
||||
}
|
||||
|
||||
static bool usable (DOMNode* node)
|
||||
{
|
||||
static SEL const selectors[] = { @selector(selectionStart), @selector(selectionEnd), @selector(setSelectionStart:), @selector(setSelectionEnd:), @selector(value), @selector(setValue:), @selector(setSelectionRange:end:) };
|
||||
BOOL res = [node isKindOfClass:[DOMHTMLTextAreaElement class]] && ![(DOMHTMLTextAreaElement*)node disabled] && ![(DOMHTMLTextAreaElement*)node readOnly];
|
||||
for(size_t i = 0; i < sizeofA(selectors); ++i)
|
||||
res = res && [node respondsToSelector:selectors[i]];
|
||||
return res;
|
||||
}
|
||||
|
||||
DOMHTMLTextAreaElement* textArea;
|
||||
NSString* value;
|
||||
unsigned long selectionStart;
|
||||
unsigned long selectionEnd;
|
||||
};
|
||||
|
||||
void convert_dom_to_text::visit_nodes (DOMTreeWalker* treeWalker)
|
||||
{
|
||||
for(DOMNode* node = [treeWalker currentNode]; node; node = [treeWalker nextSibling])
|
||||
{
|
||||
if([node nodeType] == DOM_TEXT_NODE)
|
||||
output_text([node nodeValue]);
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BR"])
|
||||
output_text(@"\n"), (atBeginOfLine = YES), (didOutputText = NO);
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"DIV"])
|
||||
enter_block_tag();
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BLOCKQUOTE"])
|
||||
enter_block_tag(), ++quoteLevel;
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"P"])
|
||||
enter_block_tag();
|
||||
|
||||
if([treeWalker firstChild])
|
||||
{
|
||||
visit_nodes(treeWalker);
|
||||
[treeWalker parentNode];
|
||||
}
|
||||
|
||||
if([[[node nodeName] uppercaseString] isEqualToString:@"DIV"])
|
||||
leave_block_tag();
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"BLOCKQUOTE"])
|
||||
leave_block_tag(), --quoteLevel;
|
||||
else if([[[node nodeName] uppercaseString] isEqualToString:@"P"])
|
||||
leave_block_tag();
|
||||
}
|
||||
}
|
||||
|
||||
static DOMHTMLTextAreaElement* find_active_text_area_for_frame (WebFrame* frame)
|
||||
{
|
||||
DOMHTMLTextAreaElement* res = nil;
|
||||
DOMDocument* doc = [frame DOMDocument];
|
||||
if([doc respondsToSelector:@selector(focusNode)])
|
||||
{
|
||||
// OmniWeb 5.6 has a method to get the focused node
|
||||
res = [doc performSelector:@selector(focusNode)];
|
||||
if(!helper::usable(res))
|
||||
res = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The following is a heuristic for finding the active text area:
|
||||
//
|
||||
// 1. If there is just one text area, we use that.
|
||||
//
|
||||
// 2. If there are multiple, we ask the web view to “select all”
|
||||
// which goes to the active text area (hopefully) and then we
|
||||
// check which of the text areas in the DOM actually changed.
|
||||
//
|
||||
// There is a problem if either a text area has no content (in
|
||||
// which case select all makes no changes) or if everything is
|
||||
// already selected. If only one text area is in the state of
|
||||
// “select all would not affect it” and no text areas were
|
||||
// changed, we assume the one with that state is the active.
|
||||
|
||||
std::vector<helper> v;
|
||||
DOMNodeList* textAreas = [doc getElementsByTagName:@"TEXTAREA"];
|
||||
for(unsigned long i = 0; i < [textAreas length]; ++i)
|
||||
{
|
||||
if(helper::usable([textAreas item:i]))
|
||||
v.push_back((DOMHTMLTextAreaElement*)[textAreas item:i]);
|
||||
}
|
||||
|
||||
if(v.size() == 1)
|
||||
{
|
||||
res = v[0].textArea;
|
||||
}
|
||||
else if(v.size() > 1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
if (!it->should_change())
|
||||
[it->textArea setValue:@" "];
|
||||
[[frame webView] selectLine:nil];
|
||||
|
||||
size_t should_change = 0, did_change = 0;
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
did_change += it->did_change() ? 1 : 0;
|
||||
should_change += it->should_change() ? 1 : 0;
|
||||
}
|
||||
|
||||
if(did_change == 1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
res = it->did_change() ? it->textArea : res;
|
||||
}
|
||||
else if(did_change == 0 && should_change == v.size()-1)
|
||||
{
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
res = !it->should_change() ? it->textArea : res;
|
||||
}
|
||||
|
||||
for(std::vector<helper>::iterator it = v.begin(); it != v.end(); ++it)
|
||||
it->reset();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static DOMHTMLTextAreaElement* find_active_text_area (WebView* view)
|
||||
{
|
||||
DOMHTMLTextAreaElement* res = nil;
|
||||
if([view respondsToSelector:@selector(selectedFrame)])
|
||||
res = find_active_text_area_for_frame([view performSelector:@selector(selectedFrame)]);
|
||||
else
|
||||
{
|
||||
WebFrame* frame = [view mainFrame];
|
||||
NSArray* frames = [[NSArray arrayWithObject: frame] arrayByAddingObjectsFromArray: [frame childFrames]];
|
||||
for(unsigned i = 0; i != [frames count] && !res; i++)
|
||||
res = find_active_text_area_for_frame([frames objectAtIndex:i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@implementation WebView (EditInODBEditor)
|
||||
- (void)editInODBEditor:(id)sender
|
||||
{
|
||||
if([self isEditable])
|
||||
{
|
||||
// Mail uses an editable WebView, in which case we want to send the entire page to the ODB Editor
|
||||
|
||||
NSString* const CARET = [NSString stringWithFormat:@"%C", 0xFFFD];
|
||||
NSString* str = @"";
|
||||
int lineNumber = 0;
|
||||
|
||||
DOMDocumentFragment* selection = [[self selectedDOMRange] cloneContents];
|
||||
if(!selection)
|
||||
{
|
||||
[self insertText:CARET]; // ugly hack, but we want to preserve the position of the caret
|
||||
[self selectAll:nil];
|
||||
selection = [[self selectedDOMRange] cloneContents];
|
||||
|
||||
// remove the caret marker. TODO we should start an undo group, so the (chunked) undo doesn’t remove more than just the caret
|
||||
if(NSUndoManager* undoManager = [self undoManager])
|
||||
{
|
||||
if([undoManager canUndo])
|
||||
{
|
||||
[undoManager undo];
|
||||
[self selectAll:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(selection)
|
||||
{
|
||||
str = convert_dom_to_text([[[self mainFrame] DOMDocument] createTreeWalker:selection :DOM_SHOW_ALL :nil :YES]);
|
||||
while([str hasSuffix:@"\n\n"])
|
||||
str = [str substringToIndex:[str length]-1];
|
||||
|
||||
NSArray* split = [str componentsSeparatedByString:CARET];
|
||||
if([split count] == 2)
|
||||
{
|
||||
lineNumber = [[[split objectAtIndex:0] componentsSeparatedByString:@"\n"] count] - 1;
|
||||
str = [split componentsJoinedByString:@""];
|
||||
}
|
||||
}
|
||||
[EditInODBEditor externalEditString:str startingAtLine:lineNumber forView:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Likely the user wants to edit just a text area, so let’s try to find which
|
||||
if(DOMHTMLTextAreaElement* textArea = find_active_text_area(self))
|
||||
{
|
||||
NSString* str = [textArea value];
|
||||
unsigned long selectionStart = [textArea selectionStart];
|
||||
int lineNumber = 0;
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
do {
|
||||
NSRange oldRange = range;
|
||||
range = [str lineRangeForRange:NSMakeRange(NSMaxRange(range), 0)];
|
||||
if(NSMaxRange(oldRange) == NSMaxRange(range) || selectionStart < NSMaxRange(range))
|
||||
break;
|
||||
lineNumber++;
|
||||
} while(true);
|
||||
[EditInODBEditor externalEditString:str startingAtLine:lineNumber forView:self withObject:textArea];
|
||||
}
|
||||
else NSBeep();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)odbEditorDidModifyString:(NSString*)newString withObject:(NSObject*)textArea
|
||||
{
|
||||
if([self isEditable])
|
||||
{
|
||||
NSArray* lines = [newString componentsSeparatedByString:@"\n"];
|
||||
NSMutableString* res = [NSMutableString string];
|
||||
unsigned quoteLevel = 0;
|
||||
for(unsigned i = 0; i != [lines count]; i++)
|
||||
{
|
||||
NSString* line = [lines objectAtIndex:i];
|
||||
|
||||
unsigned newQuoteLevel = 0;
|
||||
while([line hasPrefix:@"> "])
|
||||
{
|
||||
line = [line substringFromIndex:2];
|
||||
newQuoteLevel++;
|
||||
}
|
||||
|
||||
if([line isEqualToString:@">"])
|
||||
{
|
||||
line = @"";
|
||||
newQuoteLevel++;
|
||||
}
|
||||
|
||||
if(newQuoteLevel > quoteLevel)
|
||||
{
|
||||
for(unsigned j = 0; j != newQuoteLevel - quoteLevel; j++)
|
||||
[res appendString:@"<BLOCKQUOTE type=\"cite\">"];
|
||||
}
|
||||
else if(newQuoteLevel < quoteLevel)
|
||||
{
|
||||
for(unsigned j = 0; j != quoteLevel - newQuoteLevel; j++)
|
||||
[res appendString:@"</BLOCKQUOTE>"];
|
||||
}
|
||||
quoteLevel = newQuoteLevel;
|
||||
|
||||
if([line isEqualToString:@""])
|
||||
{
|
||||
[res appendString:@"<DIV><BR></DIV>"];
|
||||
}
|
||||
else
|
||||
{
|
||||
line = [line ODB_stringByNbspEscapingSpaces];
|
||||
line = [line ODB_stringByReplacingString:@"&" withString:@"&"];
|
||||
line = [line ODB_stringByReplacingString:@"<" withString:@"<"];
|
||||
line = [line ODB_stringByReplacingString:@">" withString:@">"];
|
||||
[res appendFormat:@"<DIV>%@</DIV>", line];
|
||||
}
|
||||
}
|
||||
|
||||
[self replaceSelectionWithMarkupString:res];
|
||||
if(![[self selectedDOMRange] cloneContents])
|
||||
[self selectAll:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[(DOMHTMLTextAreaElement*)textArea setValue:newString];
|
||||
}
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
'macromates.com/blog/' = 'markdown';
|
||||
'blacktree.cocoaforge.com/forums/' = 'bbcode';
|
||||
'mail.google.com/' = 'mail';
|
||||
}
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Mon Feb 11 2008
|
||||
" Last Change: Thu Mar 6 2008
|
||||
"
|
||||
" This is a work in progress. If you feel so inclined, please help me improve
|
||||
" this file.
|
||||
@@ -223,6 +223,7 @@ macmenukey Tools.Older\ List <D-C-Up>
|
||||
macmenukey Tools.Newer\ List <D-C-Down>
|
||||
|
||||
macmenukey Window.Minimize <D-m>
|
||||
macmenukey Window.Zoom <D-C-z>
|
||||
macmenukey Window.Toggle\ Full\ Screen\ Mode <D-F>
|
||||
macmenukey Window.Previous\ Tab <D-{>
|
||||
macmenukey Window.Next\ Tab <D-}>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 193 B |
@@ -41,31 +41,94 @@
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 21 released</title>
|
||||
<title>Snapshot 23 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 21 released</h1>
|
||||
<h1>MacVim snapshot 23 released</h1>
|
||||
|
||||
Changes since snapshot 22:
|
||||
|
||||
<ul>
|
||||
<li> The preferences panel has been updated with an "Integration pane". This
|
||||
can be used to easily install (and uninstall) the "Edit in ODBEditor"
|
||||
input manager. The input manager enables you to use MacVim to edit text
|
||||
in any Cocoa text field (e.g. you can use MacVim to edit emails in Mail).
|
||||
Please read the warning on the Integration pane before installing the
|
||||
input manager. (Patch by Nico Weber.) </li>
|
||||
<li> The "Login Shell" preference has been updated so it should now work with
|
||||
most shells. This option ensures that environment variables (e.g. $PATH)
|
||||
are set properly. You should enable it if you ever need to issue shell
|
||||
commands from within MacVim. (Patch by Ben Schmidt.) </li>
|
||||
<li> Added MMZoomBoth user default. Enable this if you prefer the window to
|
||||
maximize in both directions when you press the green "maximize button"
|
||||
(hold down Cmd to temporarily restrict resizing to the vertical direction
|
||||
only). (Requested by Brian McKee.) </li>
|
||||
<li> Added Cmd-Ctrl-z as key equivalent for "Window->Zoom" (this is the same
|
||||
key equivalent as in iTunes) </li>
|
||||
<li> The Vim runtime files have been updated to the latest version </li>
|
||||
<li> MacVim recognizes files with .patch and .diff extension </li>
|
||||
<li> The mouse cursor in insert mode has higher contrast (when used with dark
|
||||
backgrounds). (Requested by Enno et al.) </li>
|
||||
<li> Line numbers (:h 'number') are brighter when bakground=dark. (Requested
|
||||
by Ted Pavlic) </li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Like MacVim? Go to <a href="http://code.google.com/p/macvim/">
|
||||
http://code.google.com/p/macvim/</a> to see how you can show your
|
||||
support.
|
||||
</p>
|
||||
|
||||
]]></description>
|
||||
<pubDate>Sun, 9 Mar 2008 16:43 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-23.tbz"
|
||||
length="8037899"
|
||||
sparkle:version="23"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 22 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 22 released</h1>
|
||||
|
||||
<p><em>This snapshot replaces the broken snapshot 21. If you installed build 21
|
||||
then please update immediately.</em></p>
|
||||
|
||||
<p>Changes since snapshot 20:</p>
|
||||
<ul>
|
||||
<li>Fix forking bug which caused snapshot 21 to lock up OS X</li>
|
||||
<li>The macvim color scheme changed so that line numbers look better when
|
||||
the background is dark (enable line numbers with :set number, set dark
|
||||
the background is dark (enable line numbers with :set number; set dark
|
||||
background with :set bg=dark)</li>
|
||||
<li>Improved support for Voice Over (enable with <D-F5>)</li>
|
||||
<li>Improved support for Voice Over (enable with <D-F5>)</li>
|
||||
<li>System bell support (see :h 'vb' on how to turn it off)</li>
|
||||
<li>MacVim no longer associates to .plist and .dict since these may well be
|
||||
in binary format</li>
|
||||
<li>Added Find Next <D-g>, Find Previous <D-G> and Use Selection for Find
|
||||
<D-e> menu items</li>
|
||||
<li>Added Find Next <D-g>, Find Previous <D-G> and Use Selection
|
||||
for Find <D-e> menu items</li>
|
||||
<li>Track pad scrolling is now force sensitive</li>
|
||||
<li>Added help section on preferences</li>
|
||||
<li>Preferences panel updated (also no longer hides when MacVim loses focus)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>The most exciting new addition in this snapshot is support for <D-g>.
|
||||
It repeats the last search you made in any other application (that supports the
|
||||
Find Pasteboard).</p>
|
||||
<p>This is very useful if you have several windows open in MacVim...try
|
||||
searching for something in one window (using "/"), then switching to another
|
||||
window and hitting <D-g> for an example (after having pressed <D-g>
|
||||
once you can of course use "n" to repeat the search).</p>
|
||||
]]></description>
|
||||
<pubDate>Mon, 11 Feb 2008 22:17 CET</pubDate>
|
||||
<pubDate>Wed, 13 Feb 2008 19:36 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-21.tbz"
|
||||
length="7814596"
|
||||
sparkle:version="21"
|
||||
sparkle:shortVersionString="snapshot 21"
|
||||
url="http://macvim.googlecode.com/files/MacVim-snapshot-22.tbz"
|
||||
length="7812907"
|
||||
sparkle:version="22"
|
||||
sparkle:shortVersionString="7.1"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Increment build number
|
||||
/Developer/Tools/agvtool next-version -all > /dev/null
|
||||
|
||||
# Get current build number
|
||||
BUILDNUM=`/Developer/Tools/agvtool what-version -terse`
|
||||
DEST=~/Desktop/MacVim-snapshot-$BUILDNUM
|
||||
|
||||
echo '****************************************************'
|
||||
echo " BUILDING SNAPSHOT $BUILDNUM"
|
||||
echo '****************************************************'
|
||||
echo ''
|
||||
|
||||
# Build Vim binary
|
||||
echo 'BUILDING VIM BINARY'
|
||||
echo ' running configure...'
|
||||
cd .. && ./configure --enable-gui=macvim --with-mac-arch=both \
|
||||
--with-features=huge --enable-pythoninterp --enable-tclinterp \
|
||||
--enable-cscope \
|
||||
--with-compiledby="Bjorn Winckler <bjorn.winckler@gmail.com>" > /dev/null
|
||||
|
||||
echo ' cleaning...'
|
||||
make clean > /dev/null
|
||||
echo ' calling make...'
|
||||
make > /dev/null
|
||||
echo ' done'
|
||||
|
||||
# Build MacVim.app
|
||||
echo 'BUILDING MacVim.app'
|
||||
cd MacVim
|
||||
echo ' cleaning...'
|
||||
xcodebuild -configuration Universal clean > /dev/null
|
||||
echo ' calling xcodebuild...'
|
||||
xcodebuild -configuration Universal > /dev/null
|
||||
echo ' done'
|
||||
|
||||
# Create archive of build/Universal/MacVim.app
|
||||
echo 'CREATING SNAPSHOT ARCHIVE'
|
||||
echo ' copying MacVim.app and supporting files...'
|
||||
mkdir $DEST
|
||||
cp -pR build/Universal/MacVim.app $DEST/
|
||||
cp -p mvim $DEST/
|
||||
cp -p README-snapshot.txt $DEST/
|
||||
echo ' creating archive....'
|
||||
cd $DEST && cd ..
|
||||
tar cjf MacVim-snapshot-$BUILDNUM.tbz MacVim-snapshot-$BUILDNUM
|
||||
echo ' done'
|
||||
|
||||
echo 'ALL DONE'
|
||||
echo 'Now update the Appcast, commit and tag, then post on vim_mac.'
|
||||
# Update app-cast
|
||||
|
||||
# Commit & tag
|
||||
# git-commit -a -m "$BUILDNUM"
|
||||
# git-tag -a -F tagfile $BUILDNUM
|
||||
|
||||
# Post on vim_mac
|
||||
Vendored
+3
-2
@@ -4669,10 +4669,11 @@ echo "${ECHO_T}$tclver - OK" >&6;
|
||||
echo "$as_me:$LINENO: checking for location of Tcl include" >&5
|
||||
echo $ECHO_N "checking for location of Tcl include... $ECHO_C" >&6
|
||||
if test "x$MACOSX" != "xyes"; then
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include /usr/include/tcl$tclver"
|
||||
else
|
||||
tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
|
||||
fi
|
||||
TCL_INC=
|
||||
for try in $tclinc; do
|
||||
if test -f "$try/tcl.h"; then
|
||||
echo "$as_me:$LINENO: result: $try/tcl.h" >&5
|
||||
@@ -14259,7 +14260,7 @@ echo "${ECHO_T}$TAGPRG" >&6
|
||||
echo "$as_me:$LINENO: checking how to run man with a section nr" >&5
|
||||
echo $ECHO_N "checking how to run man with a section nr... $ECHO_C" >&6
|
||||
MANDEF="man"
|
||||
(eval man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
|
||||
(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&5 && MANDEF="man -s"
|
||||
echo "$as_me:$LINENO: result: $MANDEF" >&5
|
||||
echo "${ECHO_T}$MANDEF" >&6
|
||||
if test "$MANDEF" = "man -s"; then
|
||||
|
||||
+2
-1
@@ -1290,7 +1290,8 @@ getvcol(wp, pos, start, cursor, end)
|
||||
/* If a double-cell char doesn't fit at the end of a line
|
||||
* it wraps to the next line, it's like this char is three
|
||||
* cells wide. */
|
||||
if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol))
|
||||
if (incr == 2 && wp->w_p_wrap && MB_BYTE2LEN(*ptr) > 1
|
||||
&& in_win_border(wp, vcol))
|
||||
{
|
||||
++incr;
|
||||
head = 1;
|
||||
|
||||
+3
-2
@@ -803,11 +803,12 @@ if test "$enable_tclinterp" = "yes"; then
|
||||
|
||||
AC_MSG_CHECKING(for location of Tcl include)
|
||||
if test "x$MACOSX" != "xyes"; then
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/include"
|
||||
tclinc="$tclloc/include $tclloc/include/tcl $tclloc/include/tcl$tclver /usr/local/include /usr/local/include/tcl$tclver /usr/include /usr/include/tcl$tclver"
|
||||
else
|
||||
dnl For Mac OS X 10.3, use the OS-provided framework location
|
||||
tclinc="/System/Library/Frameworks/Tcl.framework/Headers"
|
||||
fi
|
||||
TCL_INC=
|
||||
for try in $tclinc; do
|
||||
if test -f "$try/tcl.h"; then
|
||||
AC_MSG_RESULT($try/tcl.h)
|
||||
@@ -2762,7 +2763,7 @@ AC_MSG_RESULT($TAGPRG) AC_SUBST(TAGPRG)
|
||||
dnl Check how we can run man with a section number
|
||||
AC_MSG_CHECKING(how to run man with a section nr)
|
||||
MANDEF="man"
|
||||
(eval man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
|
||||
(eval MANPAGER=cat PAGER=cat man -s 2 read) < /dev/null > /dev/null 2>&AC_FD_CC && MANDEF="man -s"
|
||||
AC_MSG_RESULT($MANDEF)
|
||||
if test "$MANDEF" = "man -s"; then
|
||||
AC_DEFINE(USEMAN_S)
|
||||
|
||||
+34
-10
@@ -532,6 +532,7 @@ static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getpid __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
@@ -7132,6 +7133,7 @@ static struct fst
|
||||
{"getline", 1, 2, f_getline},
|
||||
{"getloclist", 1, 1, f_getqflist},
|
||||
{"getmatches", 0, 0, f_getmatches},
|
||||
{"getpid", 0, 0, f_getpid},
|
||||
{"getpos", 1, 1, f_getpos},
|
||||
{"getqflist", 0, 0, f_getqflist},
|
||||
{"getreg", 0, 2, f_getreg},
|
||||
@@ -9203,13 +9205,13 @@ f_filewritable(argvars, rettv)
|
||||
rettv->vval.v_number = filewritable(get_tv_string(&argvars[0]));
|
||||
}
|
||||
|
||||
static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir));
|
||||
static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int find_what));
|
||||
|
||||
static void
|
||||
findfilendir(argvars, rettv, dir)
|
||||
findfilendir(argvars, rettv, find_what)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
int dir;
|
||||
int find_what;
|
||||
{
|
||||
#ifdef FEAT_SEARCHPATH
|
||||
char_u *fname;
|
||||
@@ -9254,8 +9256,11 @@ findfilendir(argvars, rettv, dir)
|
||||
vim_free(fresult);
|
||||
fresult = find_file_in_path_option(first ? fname : NULL,
|
||||
first ? (int)STRLEN(fname) : 0,
|
||||
0, first, path, dir, curbuf->b_ffname,
|
||||
dir ? (char_u *)"" : curbuf->b_p_sua);
|
||||
0, first, path,
|
||||
find_what,
|
||||
curbuf->b_ffname,
|
||||
find_what == FINDFILE_DIR
|
||||
? (char_u *)"" : curbuf->b_p_sua);
|
||||
first = FALSE;
|
||||
|
||||
if (fresult != NULL && rettv->v_type == VAR_LIST)
|
||||
@@ -9445,7 +9450,7 @@ f_finddir(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
findfilendir(argvars, rettv, TRUE);
|
||||
findfilendir(argvars, rettv, FINDFILE_DIR);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9456,7 +9461,7 @@ f_findfile(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
findfilendir(argvars, rettv, FALSE);
|
||||
findfilendir(argvars, rettv, FINDFILE_FILE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -10370,6 +10375,18 @@ f_getmatches(argvars, rettv)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* "getpid()" function
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
f_getpid(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
rettv->vval.v_number = mch_get_pid();
|
||||
}
|
||||
|
||||
/*
|
||||
* "getpos(string)" function
|
||||
*/
|
||||
@@ -14796,24 +14813,31 @@ f_setpos(argvars, rettv)
|
||||
int fnum;
|
||||
char_u *name;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
name = get_tv_string_chk(argvars);
|
||||
if (name != NULL)
|
||||
{
|
||||
if (list2fpos(&argvars[1], &pos, &fnum) == OK)
|
||||
{
|
||||
--pos.col;
|
||||
if (name[0] == '.') /* cursor */
|
||||
if (name[0] == '.' && name[1] == NUL)
|
||||
{
|
||||
/* set cursor */
|
||||
if (fnum == curbuf->b_fnum)
|
||||
{
|
||||
curwin->w_cursor = pos;
|
||||
check_cursor();
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
EMSG(_(e_invarg));
|
||||
}
|
||||
else if (name[0] == '\'') /* mark */
|
||||
(void)setmark_pos(name[1], &pos, fnum);
|
||||
else if (name[0] == '\'' && name[1] != NUL && name[2] == NUL)
|
||||
{
|
||||
/* set mark */
|
||||
if (setmark_pos(name[1], &pos, fnum) == OK)
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
else
|
||||
EMSG(_(e_invarg));
|
||||
}
|
||||
|
||||
@@ -365,6 +365,10 @@ ex_sort(eap)
|
||||
int sort_oct; /* sort on octal number */
|
||||
int sort_hex; /* sort on hex number */
|
||||
|
||||
/* Sorting one line is really quick! */
|
||||
if (count <= 1)
|
||||
return;
|
||||
|
||||
if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
|
||||
return;
|
||||
sortbuf1 = NULL;
|
||||
|
||||
@@ -3352,6 +3352,7 @@ set_one_cmd_context(xp, buff)
|
||||
#endif
|
||||
))
|
||||
{
|
||||
len = 0; /* avoid getting stuck when space is in 'isfname' */
|
||||
while (*p != NUL)
|
||||
{
|
||||
#ifdef FEAT_MBYTE
|
||||
|
||||
+4
-3
@@ -5518,10 +5518,11 @@ check_for_bom(p, size, lenp, flags)
|
||||
else if (p[0] == 0xfe && p[1] == 0xff
|
||||
&& (flags == FIO_ALL || flags == FIO_UCS2 || flags == FIO_UTF16))
|
||||
{
|
||||
if (flags == FIO_UTF16)
|
||||
name = "utf-16"; /* FE FF */
|
||||
else
|
||||
/* Default to utf-16, it works also for ucs-2 text. */
|
||||
if (flags == FIO_UCS2)
|
||||
name = "ucs-2"; /* FE FF */
|
||||
else
|
||||
name = "utf-16"; /* FE FF */
|
||||
}
|
||||
else if (size >= 4 && p[0] == 0 && p[1] == 0 && p[2] == 0xfe
|
||||
&& p[3] == 0xff && (flags == FIO_ALL || flags == FIO_UCS4))
|
||||
|
||||
+1
-1
@@ -2307,7 +2307,7 @@ foldUpdateIEMS(wp, top, bot)
|
||||
|
||||
/* If some fold changed, need to redraw and position cursor. */
|
||||
if (fold_changed && wp->w_p_fen)
|
||||
changed_window_setting();
|
||||
changed_window_setting_win(wp);
|
||||
|
||||
/* If we updated folds past "bot", need to redraw more lines. Don't do
|
||||
* this in other situations, the changed lines will be redrawn anyway and
|
||||
|
||||
@@ -163,6 +163,10 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
|
||||
}
|
||||
newargv[argc+1] = NULL;
|
||||
|
||||
/* shut down all the stuff we just started, just to start
|
||||
* it again from the exec :-\ */
|
||||
prepare_getout();
|
||||
|
||||
pid = fork();
|
||||
switch(pid) {
|
||||
case -1:
|
||||
@@ -173,10 +177,6 @@ http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/fork.2.h
|
||||
case 0:
|
||||
/* Child. */
|
||||
|
||||
/* shut down all the stuff we just started, just to start
|
||||
* it again from the exec :-\ */
|
||||
prepare_getout();
|
||||
|
||||
/* make sure we survive our shell */
|
||||
setsid();
|
||||
|
||||
@@ -1383,11 +1383,7 @@ again:
|
||||
out_flush();
|
||||
|
||||
gui.num_cols = (pixel_width - gui_get_base_width()) / gui.char_width;
|
||||
gui.num_rows = (pixel_height - gui_get_base_height()
|
||||
#if !defined(FEAT_GUI_PHOTON) && !defined(FEAT_GUI_MSWIN)
|
||||
+ (gui.char_height / 2)
|
||||
#endif
|
||||
) / gui.char_height;
|
||||
gui.num_rows = (pixel_height - gui_get_base_height()) / gui.char_height;
|
||||
|
||||
gui_position_components(pixel_width);
|
||||
|
||||
|
||||
@@ -79,6 +79,12 @@ setmark_pos(c, pos, fnum)
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (c == '"')
|
||||
{
|
||||
curbuf->b_last_cursor = *pos;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Allow setting '[ and '] for an autocommand that simulates reading a
|
||||
* file. */
|
||||
if (c == '[')
|
||||
|
||||
@@ -360,6 +360,12 @@ enc_alias_table[] =
|
||||
{"ucs4be", IDX_UCS4},
|
||||
{"ucs-4be", IDX_UCS4},
|
||||
{"ucs4le", IDX_UCS4LE},
|
||||
{"utf32", IDX_UCS4},
|
||||
{"utf-32", IDX_UCS4},
|
||||
{"utf32be", IDX_UCS4},
|
||||
{"utf-32be", IDX_UCS4},
|
||||
{"utf32le", IDX_UCS4LE},
|
||||
{"utf-32le", IDX_UCS4LE},
|
||||
{"932", IDX_CP932},
|
||||
{"949", IDX_CP949},
|
||||
{"936", IDX_CP936},
|
||||
|
||||
+29
-14
@@ -2270,13 +2270,16 @@ del_bytes(count, fixpos_arg, use_delcombine)
|
||||
/*
|
||||
* If the old line has been allocated the deletion can be done in the
|
||||
* existing line. Otherwise a new line has to be allocated
|
||||
* Can't do this when using Netbeans, because we would need to invoke
|
||||
* netbeans_removed(), which deallocates the line. Let ml_replace() take
|
||||
* care of notifiying Netbeans.
|
||||
*/
|
||||
was_alloced = ml_line_alloced(); /* check if oldp was allocated */
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
if (was_alloced && usingNetbeans)
|
||||
netbeans_removed(curbuf, lnum, col, count);
|
||||
/* else is handled by ml_replace() */
|
||||
if (usingNetbeans)
|
||||
was_alloced = FALSE;
|
||||
else
|
||||
#endif
|
||||
was_alloced = ml_line_alloced(); /* check if oldp was allocated */
|
||||
if (was_alloced)
|
||||
newp = oldp; /* use same allocated memory */
|
||||
else
|
||||
@@ -3978,7 +3981,7 @@ vim_getenv(name, mustfree)
|
||||
/* remove trailing path separator */
|
||||
#ifndef MACOS_CLASSIC
|
||||
/* With MacOS path (with colons) the final colon is required */
|
||||
/* to avoid confusion between absoulute and relative path */
|
||||
/* to avoid confusion between absolute and relative path */
|
||||
if (pend > p && after_pathsep(p, pend))
|
||||
--pend;
|
||||
#endif
|
||||
@@ -5689,7 +5692,7 @@ cin_is_cpp_baseclass(col)
|
||||
else if (lookfor_ctor_init || class_or_struct)
|
||||
{
|
||||
/* we have something found, that looks like the start of
|
||||
* cpp-base-class-declaration or contructor-initialization */
|
||||
* cpp-base-class-declaration or constructor-initialization */
|
||||
cpp_base_class = TRUE;
|
||||
lookfor_ctor_init = class_or_struct = FALSE;
|
||||
*col = 0;
|
||||
@@ -6146,7 +6149,7 @@ get_c_indent()
|
||||
pos_T our_paren_pos;
|
||||
char_u *start;
|
||||
int start_brace;
|
||||
#define BRACE_IN_COL0 1 /* '{' is in comumn 0 */
|
||||
#define BRACE_IN_COL0 1 /* '{' is in column 0 */
|
||||
#define BRACE_AT_START 2 /* '{' is at start of line */
|
||||
#define BRACE_AT_END 3 /* '{' is at end of line */
|
||||
linenr_T ourscope;
|
||||
@@ -6369,7 +6372,7 @@ get_c_indent()
|
||||
if (curwin->w_cursor.lnum > 1)
|
||||
{
|
||||
/* If the start comment string matches in the previous
|
||||
* line, use the indent of that line pluss offset. If
|
||||
* line, use the indent of that line plus offset. If
|
||||
* the middle comment string matches in the previous
|
||||
* line, use the indent of that line. XXX */
|
||||
look = skipwhite(ml_get(curwin->w_cursor.lnum - 1));
|
||||
@@ -6891,6 +6894,7 @@ get_c_indent()
|
||||
if (trypos != NULL)
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum + 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6951,6 +6955,7 @@ get_c_indent()
|
||||
if (trypos != NULL)
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum + 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -6988,6 +6993,7 @@ get_c_indent()
|
||||
if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum + 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7111,7 +7117,10 @@ get_c_indent()
|
||||
{
|
||||
if (find_last_paren(l, '{', '}') && (trypos =
|
||||
find_start_brace(ind_maxcomment)) != NULL)
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum + 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7227,11 +7236,12 @@ get_c_indent()
|
||||
* case xx: if ( asdf &&
|
||||
* asdf)
|
||||
*/
|
||||
curwin->w_cursor.lnum = trypos->lnum;
|
||||
curwin->w_cursor = *trypos;
|
||||
l = ml_get_curline();
|
||||
if (cin_iscase(l) || cin_isscopedecl(l))
|
||||
{
|
||||
++curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -7251,6 +7261,7 @@ get_c_indent()
|
||||
if (*l == NUL || l[STRLEN(l) - 1] != '\\')
|
||||
break;
|
||||
--curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7584,11 +7595,12 @@ term_again:
|
||||
* case xx: if ( asdf &&
|
||||
* asdf)
|
||||
*/
|
||||
curwin->w_cursor.lnum = trypos->lnum;
|
||||
curwin->w_cursor = *trypos;
|
||||
l = ml_get_curline();
|
||||
if (cin_iscase(l) || cin_isscopedecl(l))
|
||||
{
|
||||
++curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -7649,13 +7661,14 @@ term_again:
|
||||
&& (trypos = find_start_brace(ind_maxcomment))
|
||||
!= NULL) /* XXX */
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum;
|
||||
curwin->w_cursor = *trypos;
|
||||
/* if not "else {" check for terminated again */
|
||||
/* but skip block for "} else {" */
|
||||
l = cin_skipcomment(ml_get_curline());
|
||||
if (*l == '}' || !cin_iselse(l))
|
||||
goto term_again;
|
||||
++curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7724,6 +7737,7 @@ term_again:
|
||||
if ((trypos = find_start_comment(ind_maxcomment)) != NULL)
|
||||
{
|
||||
curwin->w_cursor.lnum = trypos->lnum + 1;
|
||||
curwin->w_cursor.col = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7774,7 +7788,7 @@ term_again:
|
||||
if (find_last_paren(l, '(', ')')
|
||||
&& (trypos = find_match_paren(ind_maxparen,
|
||||
ind_maxcomment)) != NULL)
|
||||
curwin->w_cursor.lnum = trypos->lnum;
|
||||
curwin->w_cursor = *trypos;
|
||||
|
||||
/* For a line ending in ',' that is a continuation line go
|
||||
* back to the first line with a backslash:
|
||||
@@ -7788,6 +7802,7 @@ term_again:
|
||||
if (*l == NUL || l[STRLEN(l) - 1] != '\\')
|
||||
break;
|
||||
--curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0;
|
||||
}
|
||||
|
||||
amount = get_indent(); /* XXX */
|
||||
@@ -7861,7 +7876,7 @@ term_again:
|
||||
|
||||
if ((trypos = find_match_paren(ind_maxparen,
|
||||
ind_maxcomment)) != NULL)
|
||||
curwin->w_cursor.lnum = trypos->lnum;
|
||||
curwin->w_cursor = *trypos;
|
||||
amount = get_indent(); /* XXX */
|
||||
break;
|
||||
}
|
||||
@@ -8222,7 +8237,7 @@ get_lisp_indent()
|
||||
|
||||
if (*that && *that != ';') /* not a comment line */
|
||||
{
|
||||
/* test *that != '(' to accomodate first let/do
|
||||
/* test *that != '(' to accommodate first let/do
|
||||
* argument if it is more than one line */
|
||||
if (!vi_lisp && *that != '(' && *that != '[')
|
||||
firsttry++;
|
||||
|
||||
+232
-218
@@ -3777,9 +3777,9 @@ typedef struct ff_stack
|
||||
char_u ffs_filearray_cur; /* needed for partly handled dirs */
|
||||
|
||||
/* to store status of partly handled directories
|
||||
* 0: we work the on this directory for the first time
|
||||
* 0: we work on this directory for the first time
|
||||
* 1: this directory was partly searched in an earlier step
|
||||
*/
|
||||
*/
|
||||
int ffs_stage;
|
||||
|
||||
/* How deep are we in the directory tree?
|
||||
@@ -3848,6 +3848,7 @@ typedef struct ff_visited_list_hdr
|
||||
* Set the default maximum depth.
|
||||
*/
|
||||
#define FF_MAX_STAR_STAR_EXPAND ((char_u)30)
|
||||
|
||||
/*
|
||||
* The search context:
|
||||
* ffsc_stack_ptr: the stack for the dirs to search
|
||||
@@ -3862,7 +3863,7 @@ typedef struct ff_visited_list_hdr
|
||||
* ffsc_wc_path: the part of the given path containing wildcards
|
||||
* ffsc_level: how many levels of dirs to search downwards
|
||||
* ffsc_stopdirs_v: array of stop directories for upward search
|
||||
* ffsc_need_dir: TRUE if we search for a directory
|
||||
* ffsc_find_what: FINDFILE_BOTH, FINDFILE_DIR or FINDFILE_FILE
|
||||
*/
|
||||
typedef struct ff_search_ctx_T
|
||||
{
|
||||
@@ -3879,11 +3880,9 @@ typedef struct ff_search_ctx_T
|
||||
int ffsc_level;
|
||||
char_u **ffsc_stopdirs_v;
|
||||
#endif
|
||||
int ffsc_need_dir;
|
||||
int ffsc_find_what;
|
||||
} ff_search_ctx_T;
|
||||
|
||||
static ff_search_ctx_T *ff_search_ctx = NULL;
|
||||
|
||||
/* locally needed functions */
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
static int ff_check_visited __ARGS((ff_visited_T **, char_u *, char_u *));
|
||||
@@ -3897,10 +3896,10 @@ static ff_visited_list_hdr_T* ff_get_visited_list __ARGS((char_u *, ff_visited_l
|
||||
static int ff_wc_equal __ARGS((char_u *s1, char_u *s2));
|
||||
#endif
|
||||
|
||||
static void ff_push __ARGS((ff_stack_T *));
|
||||
static ff_stack_T * ff_pop __ARGS((void));
|
||||
static void ff_clear __ARGS((void));
|
||||
static void ff_free_stack_element __ARGS((ff_stack_T *));
|
||||
static void ff_push __ARGS((ff_search_ctx_T *search_ctx, ff_stack_T *stack_ptr));
|
||||
static ff_stack_T *ff_pop __ARGS((ff_search_ctx_T *search_ctx));
|
||||
static void ff_clear __ARGS((ff_search_ctx_T *search_ctx));
|
||||
static void ff_free_stack_element __ARGS((ff_stack_T *stack_ptr));
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
static ff_stack_T *ff_create_stack_element __ARGS((char_u *, char_u *, int, int));
|
||||
#else
|
||||
@@ -3961,6 +3960,9 @@ vim_findnext()
|
||||
* not related to restricts given to the '**' wildcard. If 'level' is 100
|
||||
* and you use '**200' vim_findfile() will stop after 100 levels.
|
||||
*
|
||||
* 'filename' cannot contain wildcards! It is used as-is, no backslashes to
|
||||
* escape special characters.
|
||||
*
|
||||
* If 'stopdirs' is not NULL and nothing is found downward, the search is
|
||||
* restarted on the next higher directory level. This is repeated until the
|
||||
* start-directory of a search is contained in 'stopdirs'. 'stopdirs' has the
|
||||
@@ -3980,74 +3982,74 @@ vim_findnext()
|
||||
* The list of visited files/dirs can also be cleared with the function
|
||||
* vim_findfile_free_visited().
|
||||
*
|
||||
* Set the parameter 'need_dir' to TRUE if you want to search for a directory
|
||||
* instead of a file.
|
||||
* Set the parameter 'find_what' to FINDFILE_DIR if you want to search for
|
||||
* directories only, FINDFILE_FILE for files only, FINDFILE_BOTH for both.
|
||||
*
|
||||
* A search context returned by a previous call to vim_findfile_init() can be
|
||||
* passed in the parameter 'search_ctx'. This context is than reused and
|
||||
* reinitialized with the new parameters. The list of already viseted
|
||||
* passed in the parameter "search_ctx_arg". This context is reused and
|
||||
* reinitialized with the new parameters. The list of already visited
|
||||
* directories from this context is only deleted if the parameter
|
||||
* 'free_visited' is true. Be aware that the passed search_context is freed if
|
||||
* the reinitialization fails.
|
||||
* "free_visited" is true. Be aware that the passed "search_ctx_arg" is freed
|
||||
* if the reinitialization fails.
|
||||
*
|
||||
* If you don't have a search context from a previous call 'search_ctx' must be
|
||||
* NULL.
|
||||
* If you don't have a search context from a previous call "search_ctx_arg"
|
||||
* must be NULL.
|
||||
*
|
||||
* This function silently ignores a few errors, vim_findfile() will have
|
||||
* limited functionality then.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void *
|
||||
vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
search_ctx, tagfile, rel_fname)
|
||||
vim_findfile_init(path, filename, stopdirs, level, free_visited, find_what,
|
||||
search_ctx_arg, tagfile, rel_fname)
|
||||
char_u *path;
|
||||
char_u *filename;
|
||||
char_u *stopdirs;
|
||||
int level;
|
||||
int free_visited;
|
||||
int need_dir;
|
||||
void *search_ctx;
|
||||
int find_what;
|
||||
void *search_ctx_arg;
|
||||
int tagfile;
|
||||
char_u *rel_fname; /* file name to use for "." */
|
||||
{
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
char_u *wc_part;
|
||||
char_u *wc_part;
|
||||
#endif
|
||||
ff_stack_T *sptr;
|
||||
ff_stack_T *sptr;
|
||||
ff_search_ctx_T *search_ctx;
|
||||
|
||||
/* If a search context is given by the caller, reuse it, else allocate a
|
||||
* new one.
|
||||
*/
|
||||
if (search_ctx != NULL)
|
||||
ff_search_ctx = search_ctx;
|
||||
if (search_ctx_arg != NULL)
|
||||
search_ctx = search_ctx_arg;
|
||||
else
|
||||
{
|
||||
ff_search_ctx = (ff_search_ctx_T*)alloc(
|
||||
(unsigned)sizeof(ff_search_ctx_T));
|
||||
if (ff_search_ctx == NULL)
|
||||
search_ctx = (ff_search_ctx_T*)alloc((unsigned)sizeof(ff_search_ctx_T));
|
||||
if (search_ctx == NULL)
|
||||
goto error_return;
|
||||
memset(ff_search_ctx, 0, sizeof(ff_search_ctx_T));
|
||||
memset(search_ctx, 0, sizeof(ff_search_ctx_T));
|
||||
}
|
||||
search_ctx->ffsc_find_what = find_what;
|
||||
|
||||
/* clear the search context, but NOT the visited lists */
|
||||
ff_clear();
|
||||
ff_clear(search_ctx);
|
||||
|
||||
/* clear visited list if wanted */
|
||||
if (free_visited == TRUE)
|
||||
vim_findfile_free_visited(ff_search_ctx);
|
||||
vim_findfile_free_visited(search_ctx);
|
||||
else
|
||||
{
|
||||
/* Reuse old visited lists. Get the visited list for the given
|
||||
* filename. If no list for the current filename exists, creates a new
|
||||
* one.
|
||||
*/
|
||||
ff_search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
|
||||
&ff_search_ctx->ffsc_visited_lists_list);
|
||||
if (ff_search_ctx->ffsc_visited_list == NULL)
|
||||
* one. */
|
||||
search_ctx->ffsc_visited_list = ff_get_visited_list(filename,
|
||||
&search_ctx->ffsc_visited_lists_list);
|
||||
if (search_ctx->ffsc_visited_list == NULL)
|
||||
goto error_return;
|
||||
ff_search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
|
||||
&ff_search_ctx->ffsc_dir_visited_lists_list);
|
||||
if (ff_search_ctx->ffsc_dir_visited_list == NULL)
|
||||
search_ctx->ffsc_dir_visited_list = ff_get_visited_list(filename,
|
||||
&search_ctx->ffsc_dir_visited_lists_list);
|
||||
if (search_ctx->ffsc_dir_visited_list == NULL)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
@@ -4071,12 +4073,11 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
{
|
||||
/* Make the start dir an absolute path name. */
|
||||
vim_strncpy(ff_expand_buffer, rel_fname, len);
|
||||
ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
|
||||
FALSE);
|
||||
search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer, FALSE);
|
||||
}
|
||||
else
|
||||
ff_search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
|
||||
if (ff_search_ctx->ffsc_start_dir == NULL)
|
||||
search_ctx->ffsc_start_dir = vim_strnsave(rel_fname, len);
|
||||
if (search_ctx->ffsc_start_dir == NULL)
|
||||
goto error_return;
|
||||
if (*++path != NUL)
|
||||
++path;
|
||||
@@ -4101,8 +4102,8 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
if (mch_dirname(ff_expand_buffer, MAXPATHL) == FAIL)
|
||||
goto error_return;
|
||||
|
||||
ff_search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
|
||||
if (ff_search_ctx->ffsc_start_dir == NULL)
|
||||
search_ctx->ffsc_start_dir = vim_strsave(ff_expand_buffer);
|
||||
if (search_ctx->ffsc_start_dir == NULL)
|
||||
goto error_return;
|
||||
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
@@ -4110,8 +4111,8 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
* directory (but not for "//machine/dir"). Only use the drive name. */
|
||||
if ((*path == '/' || *path == '\\')
|
||||
&& path[1] != path[0]
|
||||
&& ff_search_ctx->ffsc_start_dir[1] == ':')
|
||||
ff_search_ctx->ffsc_start_dir[2] = NUL;
|
||||
&& search_ctx->ffsc_start_dir[1] == ':')
|
||||
search_ctx->ffsc_start_dir[2] = NUL;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4121,7 +4122,7 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
* If this fails (mem allocation), there is no upward search at all or a
|
||||
* stop directory is not recognized -> continue silently.
|
||||
* If stopdirs just contains a ";" or is empty,
|
||||
* ff_search_ctx->ffsc_stopdirs_v will only contain a NULL pointer. This
|
||||
* search_ctx->ffsc_stopdirs_v will only contain a NULL pointer. This
|
||||
* is handled as unlimited upward search. See function
|
||||
* ff_path_in_stoplist() for details.
|
||||
*/
|
||||
@@ -4134,10 +4135,10 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
walker++;
|
||||
|
||||
dircount = 1;
|
||||
ff_search_ctx->ffsc_stopdirs_v =
|
||||
(char_u **)alloc((unsigned)sizeof(char_u *));
|
||||
search_ctx->ffsc_stopdirs_v =
|
||||
(char_u **)alloc((unsigned)sizeof(char_u *));
|
||||
|
||||
if (ff_search_ctx->ffsc_stopdirs_v != NULL)
|
||||
if (search_ctx->ffsc_stopdirs_v != NULL)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -4145,37 +4146,37 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
void *ptr;
|
||||
|
||||
helper = walker;
|
||||
ptr = vim_realloc(ff_search_ctx->ffsc_stopdirs_v,
|
||||
ptr = vim_realloc(search_ctx->ffsc_stopdirs_v,
|
||||
(dircount + 1) * sizeof(char_u *));
|
||||
if (ptr)
|
||||
ff_search_ctx->ffsc_stopdirs_v = ptr;
|
||||
search_ctx->ffsc_stopdirs_v = ptr;
|
||||
else
|
||||
/* ignore, keep what we have and continue */
|
||||
break;
|
||||
walker = vim_strchr(walker, ';');
|
||||
if (walker)
|
||||
{
|
||||
ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
|
||||
vim_strnsave(helper, (int)(walker - helper));
|
||||
search_ctx->ffsc_stopdirs_v[dircount-1] =
|
||||
vim_strnsave(helper, (int)(walker - helper));
|
||||
walker++;
|
||||
}
|
||||
else
|
||||
/* this might be "", which means ascent till top
|
||||
* of directory tree.
|
||||
*/
|
||||
ff_search_ctx->ffsc_stopdirs_v[dircount-1] =
|
||||
vim_strsave(helper);
|
||||
search_ctx->ffsc_stopdirs_v[dircount-1] =
|
||||
vim_strsave(helper);
|
||||
|
||||
dircount++;
|
||||
|
||||
} while (walker != NULL);
|
||||
ff_search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
|
||||
search_ctx->ffsc_stopdirs_v[dircount-1] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
ff_search_ctx->ffsc_level = level;
|
||||
search_ctx->ffsc_level = level;
|
||||
|
||||
/* split into:
|
||||
* -fix path
|
||||
@@ -4189,8 +4190,7 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
char *errpt;
|
||||
|
||||
/* save the fix part of the path */
|
||||
ff_search_ctx->ffsc_fix_path = vim_strnsave(path,
|
||||
(int)(wc_part - path));
|
||||
search_ctx->ffsc_fix_path = vim_strnsave(path, (int)(wc_part - path));
|
||||
|
||||
/*
|
||||
* copy wc_path and add restricts to the '**' wildcard.
|
||||
@@ -4229,47 +4229,47 @@ vim_findfile_init(path, filename, stopdirs, level, free_visited, need_dir,
|
||||
ff_expand_buffer[len++] = *wc_part++;
|
||||
}
|
||||
ff_expand_buffer[len] = NUL;
|
||||
ff_search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
|
||||
search_ctx->ffsc_wc_path = vim_strsave(ff_expand_buffer);
|
||||
|
||||
if (ff_search_ctx->ffsc_wc_path == NULL)
|
||||
if (search_ctx->ffsc_wc_path == NULL)
|
||||
goto error_return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ff_search_ctx->ffsc_fix_path = vim_strsave(path);
|
||||
search_ctx->ffsc_fix_path = vim_strsave(path);
|
||||
|
||||
if (ff_search_ctx->ffsc_start_dir == NULL)
|
||||
if (search_ctx->ffsc_start_dir == NULL)
|
||||
{
|
||||
/* store the fix part as startdir.
|
||||
* This is needed if the parameter path is fully qualified.
|
||||
*/
|
||||
ff_search_ctx->ffsc_start_dir = vim_strsave(ff_search_ctx->ffsc_fix_path);
|
||||
if (ff_search_ctx->ffsc_start_dir)
|
||||
ff_search_ctx->ffsc_fix_path[0] = NUL;
|
||||
search_ctx->ffsc_start_dir = vim_strsave(search_ctx->ffsc_fix_path);
|
||||
if (search_ctx->ffsc_start_dir)
|
||||
search_ctx->ffsc_fix_path[0] = NUL;
|
||||
}
|
||||
|
||||
/* create an absolute path */
|
||||
STRCPY(ff_expand_buffer, ff_search_ctx->ffsc_start_dir);
|
||||
STRCPY(ff_expand_buffer, search_ctx->ffsc_start_dir);
|
||||
add_pathsep(ff_expand_buffer);
|
||||
STRCAT(ff_expand_buffer, ff_search_ctx->ffsc_fix_path);
|
||||
STRCAT(ff_expand_buffer, search_ctx->ffsc_fix_path);
|
||||
add_pathsep(ff_expand_buffer);
|
||||
|
||||
sptr = ff_create_stack_element(ff_expand_buffer,
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
ff_search_ctx->ffsc_wc_path,
|
||||
search_ctx->ffsc_wc_path,
|
||||
#endif
|
||||
level, 0);
|
||||
|
||||
if (sptr == NULL)
|
||||
goto error_return;
|
||||
|
||||
ff_push(sptr);
|
||||
ff_push(search_ctx, sptr);
|
||||
|
||||
ff_search_ctx->ffsc_file_to_search = vim_strsave(filename);
|
||||
if (ff_search_ctx->ffsc_file_to_search == NULL)
|
||||
search_ctx->ffsc_file_to_search = vim_strsave(filename);
|
||||
if (search_ctx->ffsc_file_to_search == NULL)
|
||||
goto error_return;
|
||||
|
||||
return ff_search_ctx;
|
||||
return search_ctx;
|
||||
|
||||
error_return:
|
||||
/*
|
||||
@@ -4277,7 +4277,7 @@ error_return:
|
||||
* Even when the caller gave us a (perhaps valid) context we free it here,
|
||||
* as we might have already destroyed it.
|
||||
*/
|
||||
vim_findfile_cleanup(ff_search_ctx);
|
||||
vim_findfile_cleanup(search_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4314,7 +4314,9 @@ vim_findfile_stopdir(buf)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clean up the given search context. Can handle a NULL pointer */
|
||||
/*
|
||||
* Clean up the given search context. Can handle a NULL pointer.
|
||||
*/
|
||||
void
|
||||
vim_findfile_cleanup(ctx)
|
||||
void *ctx;
|
||||
@@ -4322,12 +4324,9 @@ vim_findfile_cleanup(ctx)
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
ff_search_ctx = ctx;
|
||||
|
||||
vim_findfile_free_visited(ctx);
|
||||
ff_clear();
|
||||
ff_clear(ctx);
|
||||
vim_free(ctx);
|
||||
ff_search_ctx = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4343,15 +4342,15 @@ vim_findfile_cleanup(ctx)
|
||||
* top of the list).
|
||||
*/
|
||||
char_u *
|
||||
vim_findfile(search_ctx)
|
||||
void *search_ctx;
|
||||
vim_findfile(search_ctx_arg)
|
||||
void *search_ctx_arg;
|
||||
{
|
||||
char_u *file_path;
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
char_u *rest_of_wildcards;
|
||||
char_u *path_end = NULL;
|
||||
#endif
|
||||
ff_stack_T *ctx;
|
||||
ff_stack_T *stackp;
|
||||
#if defined(FEAT_SEARCHPATH) || defined(FEAT_PATH_EXTRA)
|
||||
int len;
|
||||
#endif
|
||||
@@ -4360,11 +4359,12 @@ vim_findfile(search_ctx)
|
||||
#ifdef FEAT_SEARCHPATH
|
||||
char_u *suf;
|
||||
#endif
|
||||
ff_search_ctx_T *search_ctx;
|
||||
|
||||
if (search_ctx == NULL)
|
||||
if (search_ctx_arg == NULL)
|
||||
return NULL;
|
||||
|
||||
ff_search_ctx = (ff_search_ctx_T*)search_ctx;
|
||||
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
|
||||
|
||||
/*
|
||||
* filepath is used as buffer for various actions and as the storage to
|
||||
@@ -4375,8 +4375,9 @@ vim_findfile(search_ctx)
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
/* store the end of the start dir -- needed for upward search */
|
||||
if (ff_search_ctx->ffsc_start_dir != NULL)
|
||||
path_end = &ff_search_ctx->ffsc_start_dir[STRLEN(ff_search_ctx->ffsc_start_dir)];
|
||||
if (search_ctx->ffsc_start_dir != NULL)
|
||||
path_end = &search_ctx->ffsc_start_dir[
|
||||
STRLEN(search_ctx->ffsc_start_dir)];
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
@@ -4393,8 +4394,8 @@ vim_findfile(search_ctx)
|
||||
break;
|
||||
|
||||
/* get directory to work on from stack */
|
||||
ctx = ff_pop();
|
||||
if (ctx == NULL)
|
||||
stackp = ff_pop(search_ctx);
|
||||
if (stackp == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -4414,14 +4415,14 @@ vim_findfile(search_ctx)
|
||||
* /etc/rc.d/init.d is linked to /etc/rc.d -> endless loop)
|
||||
*
|
||||
* This check is only needed for directories we work on for the
|
||||
* first time (hence ctx->ff_filearray == NULL)
|
||||
* first time (hence stackp->ff_filearray == NULL)
|
||||
*/
|
||||
if (ctx->ffs_filearray == NULL
|
||||
&& ff_check_visited(&ff_search_ctx->ffsc_dir_visited_list
|
||||
if (stackp->ffs_filearray == NULL
|
||||
&& ff_check_visited(&search_ctx->ffsc_dir_visited_list
|
||||
->ffvl_visited_list,
|
||||
ctx->ffs_fix_path
|
||||
stackp->ffs_fix_path
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
, ctx->ffs_wc_path
|
||||
, stackp->ffs_wc_path
|
||||
#endif
|
||||
) == FAIL)
|
||||
{
|
||||
@@ -4430,13 +4431,13 @@ vim_findfile(search_ctx)
|
||||
{
|
||||
verbose_enter_scroll();
|
||||
smsg((char_u *)"Already Searched: %s (%s)",
|
||||
ctx->ffs_fix_path, ctx->ffs_wc_path);
|
||||
stackp->ffs_fix_path, stackp->ffs_wc_path);
|
||||
/* don't overwrite this either */
|
||||
msg_puts((char_u *)"\n");
|
||||
verbose_leave_scroll();
|
||||
}
|
||||
#endif
|
||||
ff_free_stack_element(ctx);
|
||||
ff_free_stack_element(stackp);
|
||||
continue;
|
||||
}
|
||||
#ifdef FF_VERBOSE
|
||||
@@ -4444,7 +4445,7 @@ vim_findfile(search_ctx)
|
||||
{
|
||||
verbose_enter_scroll();
|
||||
smsg((char_u *)"Searching: %s (%s)",
|
||||
ctx->ffs_fix_path, ctx->ffs_wc_path);
|
||||
stackp->ffs_fix_path, stackp->ffs_wc_path);
|
||||
/* don't overwrite this either */
|
||||
msg_puts((char_u *)"\n");
|
||||
verbose_leave_scroll();
|
||||
@@ -4452,9 +4453,9 @@ vim_findfile(search_ctx)
|
||||
#endif
|
||||
|
||||
/* check depth */
|
||||
if (ctx->ffs_level <= 0)
|
||||
if (stackp->ffs_level <= 0)
|
||||
{
|
||||
ff_free_stack_element(ctx);
|
||||
ff_free_stack_element(stackp);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -4466,7 +4467,7 @@ vim_findfile(search_ctx)
|
||||
* and all possible expands are returned in one array. We use this
|
||||
* to handle the expansion of '**' into an empty string.
|
||||
*/
|
||||
if (ctx->ffs_filearray == NULL)
|
||||
if (stackp->ffs_filearray == NULL)
|
||||
{
|
||||
char_u *dirptrs[2];
|
||||
|
||||
@@ -4477,19 +4478,19 @@ vim_findfile(search_ctx)
|
||||
dirptrs[1] = NULL;
|
||||
|
||||
/* if we have a start dir copy it in */
|
||||
if (!vim_isAbsName(ctx->ffs_fix_path)
|
||||
&& ff_search_ctx->ffsc_start_dir)
|
||||
if (!vim_isAbsName(stackp->ffs_fix_path)
|
||||
&& search_ctx->ffsc_start_dir)
|
||||
{
|
||||
STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
|
||||
STRCPY(file_path, search_ctx->ffsc_start_dir);
|
||||
add_pathsep(file_path);
|
||||
}
|
||||
|
||||
/* append the fix part of the search path */
|
||||
STRCAT(file_path, ctx->ffs_fix_path);
|
||||
STRCAT(file_path, stackp->ffs_fix_path);
|
||||
add_pathsep(file_path);
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
rest_of_wildcards = ctx->ffs_wc_path;
|
||||
rest_of_wildcards = stackp->ffs_wc_path;
|
||||
if (*rest_of_wildcards != NUL)
|
||||
{
|
||||
len = (int)STRLEN(file_path);
|
||||
@@ -4516,11 +4517,11 @@ vim_findfile(search_ctx)
|
||||
else
|
||||
rest_of_wildcards += 3;
|
||||
|
||||
if (ctx->ffs_star_star_empty == 0)
|
||||
if (stackp->ffs_star_star_empty == 0)
|
||||
{
|
||||
/* if not done before, expand '**' to empty */
|
||||
ctx->ffs_star_star_empty = 1;
|
||||
dirptrs[1] = ctx->ffs_fix_path;
|
||||
stackp->ffs_star_star_empty = 1;
|
||||
dirptrs[1] = stackp->ffs_fix_path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4547,30 +4548,31 @@ vim_findfile(search_ctx)
|
||||
*/
|
||||
if (path_with_url(dirptrs[0]))
|
||||
{
|
||||
ctx->ffs_filearray = (char_u **)
|
||||
stackp->ffs_filearray = (char_u **)
|
||||
alloc((unsigned)sizeof(char *));
|
||||
if (ctx->ffs_filearray != NULL
|
||||
&& (ctx->ffs_filearray[0]
|
||||
if (stackp->ffs_filearray != NULL
|
||||
&& (stackp->ffs_filearray[0]
|
||||
= vim_strsave(dirptrs[0])) != NULL)
|
||||
ctx->ffs_filearray_size = 1;
|
||||
stackp->ffs_filearray_size = 1;
|
||||
else
|
||||
ctx->ffs_filearray_size = 0;
|
||||
stackp->ffs_filearray_size = 0;
|
||||
}
|
||||
else
|
||||
expand_wildcards((dirptrs[1] == NULL) ? 1 : 2, dirptrs,
|
||||
&ctx->ffs_filearray_size,
|
||||
&ctx->ffs_filearray,
|
||||
&stackp->ffs_filearray_size,
|
||||
&stackp->ffs_filearray,
|
||||
EW_DIR|EW_ADDSLASH|EW_SILENT);
|
||||
|
||||
ctx->ffs_filearray_cur = 0;
|
||||
ctx->ffs_stage = 0;
|
||||
stackp->ffs_filearray_cur = 0;
|
||||
stackp->ffs_stage = 0;
|
||||
}
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
else
|
||||
rest_of_wildcards = &ctx->ffs_wc_path[STRLEN(ctx->ffs_wc_path)];
|
||||
rest_of_wildcards = &stackp->ffs_wc_path[
|
||||
STRLEN(stackp->ffs_wc_path)];
|
||||
#endif
|
||||
|
||||
if (ctx->ffs_stage == 0)
|
||||
if (stackp->ffs_stage == 0)
|
||||
{
|
||||
/* this is the first time we work on this directory */
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
@@ -4581,18 +4583,18 @@ vim_findfile(search_ctx)
|
||||
* we don't have further wildcards to expand, so we have to
|
||||
* check for the final file now
|
||||
*/
|
||||
for (i = ctx->ffs_filearray_cur;
|
||||
i < ctx->ffs_filearray_size; ++i)
|
||||
for (i = stackp->ffs_filearray_cur;
|
||||
i < stackp->ffs_filearray_size; ++i)
|
||||
{
|
||||
if (!path_with_url(ctx->ffs_filearray[i])
|
||||
&& !mch_isdir(ctx->ffs_filearray[i]))
|
||||
if (!path_with_url(stackp->ffs_filearray[i])
|
||||
&& !mch_isdir(stackp->ffs_filearray[i]))
|
||||
continue; /* not a directory */
|
||||
|
||||
/* prepare the filename to be checked for existance
|
||||
* below */
|
||||
STRCPY(file_path, ctx->ffs_filearray[i]);
|
||||
STRCPY(file_path, stackp->ffs_filearray[i]);
|
||||
add_pathsep(file_path);
|
||||
STRCAT(file_path, ff_search_ctx->ffsc_file_to_search);
|
||||
STRCAT(file_path, search_ctx->ffsc_file_to_search);
|
||||
|
||||
/*
|
||||
* Try without extra suffix and then with suffixes
|
||||
@@ -4606,12 +4608,15 @@ vim_findfile(search_ctx)
|
||||
{
|
||||
/* if file exists and we didn't already find it */
|
||||
if ((path_with_url(file_path)
|
||||
|| (mch_getperm(file_path) >= 0
|
||||
&& (!ff_search_ctx->ffsc_need_dir
|
||||
|| mch_isdir(file_path))))
|
||||
|| (mch_getperm(file_path) >= 0
|
||||
&& (search_ctx->ffsc_find_what
|
||||
== FINDFILE_BOTH
|
||||
|| ((search_ctx->ffsc_find_what
|
||||
== FINDFILE_DIR)
|
||||
== mch_isdir(file_path)))))
|
||||
#ifndef FF_VERBOSE
|
||||
&& (ff_check_visited(
|
||||
&ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
|
||||
&search_ctx->ffsc_visited_list->ffvl_visited_list,
|
||||
file_path
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
, (char_u *)""
|
||||
@@ -4622,7 +4627,7 @@ vim_findfile(search_ctx)
|
||||
{
|
||||
#ifdef FF_VERBOSE
|
||||
if (ff_check_visited(
|
||||
&ff_search_ctx->ffsc_visited_list->ffvl_visited_list,
|
||||
&search_ctx->ffsc_visited_list->ffvl_visited_list,
|
||||
file_path
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
, (char_u *)""
|
||||
@@ -4643,8 +4648,8 @@ vim_findfile(search_ctx)
|
||||
#endif
|
||||
|
||||
/* push dir to examine rest of subdirs later */
|
||||
ctx->ffs_filearray_cur = i + 1;
|
||||
ff_push(ctx);
|
||||
stackp->ffs_filearray_cur = i + 1;
|
||||
ff_push(search_ctx, stackp);
|
||||
|
||||
simplify_filename(file_path);
|
||||
if (mch_dirname(ff_expand_buffer, MAXPATHL)
|
||||
@@ -4686,19 +4691,22 @@ vim_findfile(search_ctx)
|
||||
* still wildcards left, push the directories for further
|
||||
* search
|
||||
*/
|
||||
for (i = ctx->ffs_filearray_cur;
|
||||
i < ctx->ffs_filearray_size; ++i)
|
||||
for (i = stackp->ffs_filearray_cur;
|
||||
i < stackp->ffs_filearray_size; ++i)
|
||||
{
|
||||
if (!mch_isdir(ctx->ffs_filearray[i]))
|
||||
if (!mch_isdir(stackp->ffs_filearray[i]))
|
||||
continue; /* not a directory */
|
||||
|
||||
ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
|
||||
rest_of_wildcards, ctx->ffs_level - 1, 0));
|
||||
ff_push(search_ctx,
|
||||
ff_create_stack_element(
|
||||
stackp->ffs_filearray[i],
|
||||
rest_of_wildcards,
|
||||
stackp->ffs_level - 1, 0));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ctx->ffs_filearray_cur = 0;
|
||||
ctx->ffs_stage = 1;
|
||||
stackp->ffs_filearray_cur = 0;
|
||||
stackp->ffs_stage = 1;
|
||||
}
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
@@ -4706,23 +4714,25 @@ vim_findfile(search_ctx)
|
||||
* if wildcards contains '**' we have to descent till we reach the
|
||||
* leaves of the directory tree.
|
||||
*/
|
||||
if (STRNCMP(ctx->ffs_wc_path, "**", 2) == 0)
|
||||
if (STRNCMP(stackp->ffs_wc_path, "**", 2) == 0)
|
||||
{
|
||||
for (i = ctx->ffs_filearray_cur;
|
||||
i < ctx->ffs_filearray_size; ++i)
|
||||
for (i = stackp->ffs_filearray_cur;
|
||||
i < stackp->ffs_filearray_size; ++i)
|
||||
{
|
||||
if (fnamecmp(ctx->ffs_filearray[i], ctx->ffs_fix_path) == 0)
|
||||
if (fnamecmp(stackp->ffs_filearray[i],
|
||||
stackp->ffs_fix_path) == 0)
|
||||
continue; /* don't repush same directory */
|
||||
if (!mch_isdir(ctx->ffs_filearray[i]))
|
||||
if (!mch_isdir(stackp->ffs_filearray[i]))
|
||||
continue; /* not a directory */
|
||||
ff_push(ff_create_stack_element(ctx->ffs_filearray[i],
|
||||
ctx->ffs_wc_path, ctx->ffs_level - 1, 1));
|
||||
ff_push(search_ctx,
|
||||
ff_create_stack_element(stackp->ffs_filearray[i],
|
||||
stackp->ffs_wc_path, stackp->ffs_level - 1, 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we are done with the current directory */
|
||||
ff_free_stack_element(ctx);
|
||||
ff_free_stack_element(stackp);
|
||||
|
||||
}
|
||||
|
||||
@@ -4730,40 +4740,40 @@ vim_findfile(search_ctx)
|
||||
/* If we reached this, we didn't find anything downwards.
|
||||
* Let's check if we should do an upward search.
|
||||
*/
|
||||
if (ff_search_ctx->ffsc_start_dir
|
||||
&& ff_search_ctx->ffsc_stopdirs_v != NULL && !got_int)
|
||||
if (search_ctx->ffsc_start_dir
|
||||
&& search_ctx->ffsc_stopdirs_v != NULL && !got_int)
|
||||
{
|
||||
ff_stack_T *sptr;
|
||||
|
||||
/* is the last starting directory in the stop list? */
|
||||
if (ff_path_in_stoplist(ff_search_ctx->ffsc_start_dir,
|
||||
(int)(path_end - ff_search_ctx->ffsc_start_dir),
|
||||
ff_search_ctx->ffsc_stopdirs_v) == TRUE)
|
||||
if (ff_path_in_stoplist(search_ctx->ffsc_start_dir,
|
||||
(int)(path_end - search_ctx->ffsc_start_dir),
|
||||
search_ctx->ffsc_stopdirs_v) == TRUE)
|
||||
break;
|
||||
|
||||
/* cut of last dir */
|
||||
while (path_end > ff_search_ctx->ffsc_start_dir
|
||||
&& vim_ispathsep(*path_end))
|
||||
while (path_end > search_ctx->ffsc_start_dir
|
||||
&& vim_ispathsep(*path_end))
|
||||
path_end--;
|
||||
while (path_end > ff_search_ctx->ffsc_start_dir
|
||||
&& !vim_ispathsep(path_end[-1]))
|
||||
while (path_end > search_ctx->ffsc_start_dir
|
||||
&& !vim_ispathsep(path_end[-1]))
|
||||
path_end--;
|
||||
*path_end = 0;
|
||||
path_end--;
|
||||
|
||||
if (*ff_search_ctx->ffsc_start_dir == 0)
|
||||
if (*search_ctx->ffsc_start_dir == 0)
|
||||
break;
|
||||
|
||||
STRCPY(file_path, ff_search_ctx->ffsc_start_dir);
|
||||
STRCPY(file_path, search_ctx->ffsc_start_dir);
|
||||
add_pathsep(file_path);
|
||||
STRCAT(file_path, ff_search_ctx->ffsc_fix_path);
|
||||
STRCAT(file_path, search_ctx->ffsc_fix_path);
|
||||
|
||||
/* create a new stack entry */
|
||||
sptr = ff_create_stack_element(file_path,
|
||||
ff_search_ctx->ffsc_wc_path, ff_search_ctx->ffsc_level, 0);
|
||||
search_ctx->ffsc_wc_path, search_ctx->ffsc_level, 0);
|
||||
if (sptr == NULL)
|
||||
break;
|
||||
ff_push(sptr);
|
||||
ff_push(search_ctx, sptr);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -4779,16 +4789,17 @@ vim_findfile(search_ctx)
|
||||
* Can handle it if the passed search_context is NULL;
|
||||
*/
|
||||
void
|
||||
vim_findfile_free_visited(search_ctx)
|
||||
void *search_ctx;
|
||||
vim_findfile_free_visited(search_ctx_arg)
|
||||
void *search_ctx_arg;
|
||||
{
|
||||
if (search_ctx == NULL)
|
||||
ff_search_ctx_T *search_ctx;
|
||||
|
||||
if (search_ctx_arg == NULL)
|
||||
return;
|
||||
|
||||
ff_search_ctx = (ff_search_ctx_T *)search_ctx;
|
||||
|
||||
vim_findfile_free_visited_list(&ff_search_ctx->ffsc_visited_lists_list);
|
||||
vim_findfile_free_visited_list(&ff_search_ctx->ffsc_dir_visited_lists_list);
|
||||
search_ctx = (ff_search_ctx_T *)search_ctx_arg;
|
||||
vim_findfile_free_visited_list(&search_ctx->ffsc_visited_lists_list);
|
||||
vim_findfile_free_visited_list(&search_ctx->ffsc_dir_visited_lists_list);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -5103,33 +5114,35 @@ ff_create_stack_element(fix_part,
|
||||
}
|
||||
|
||||
/*
|
||||
* push a dir on the directory stack
|
||||
* Push a dir on the directory stack.
|
||||
*/
|
||||
static void
|
||||
ff_push(ctx)
|
||||
ff_stack_T *ctx;
|
||||
ff_push(search_ctx, stack_ptr)
|
||||
ff_search_ctx_T *search_ctx;
|
||||
ff_stack_T *stack_ptr;
|
||||
{
|
||||
/* check for NULL pointer, not to return an error to the user, but
|
||||
* to prevent a crash */
|
||||
if (ctx != NULL)
|
||||
if (stack_ptr != NULL)
|
||||
{
|
||||
ctx->ffs_prev = ff_search_ctx->ffsc_stack_ptr;
|
||||
ff_search_ctx->ffsc_stack_ptr = ctx;
|
||||
stack_ptr->ffs_prev = search_ctx->ffsc_stack_ptr;
|
||||
search_ctx->ffsc_stack_ptr = stack_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pop a dir from the directory stack
|
||||
* returns NULL if stack is empty
|
||||
* Pop a dir from the directory stack.
|
||||
* Returns NULL if stack is empty.
|
||||
*/
|
||||
static ff_stack_T *
|
||||
ff_pop()
|
||||
ff_pop(search_ctx)
|
||||
ff_search_ctx_T *search_ctx;
|
||||
{
|
||||
ff_stack_T *sptr;
|
||||
|
||||
sptr = ff_search_ctx->ffsc_stack_ptr;
|
||||
if (ff_search_ctx->ffsc_stack_ptr != NULL)
|
||||
ff_search_ctx->ffsc_stack_ptr = ff_search_ctx->ffsc_stack_ptr->ffs_prev;
|
||||
sptr = search_ctx->ffsc_stack_ptr;
|
||||
if (search_ctx->ffsc_stack_ptr != NULL)
|
||||
search_ctx->ffsc_stack_ptr = search_ctx->ffsc_stack_ptr->ffs_prev;
|
||||
|
||||
return sptr;
|
||||
}
|
||||
@@ -5138,62 +5151,63 @@ ff_pop()
|
||||
* free the given stack element
|
||||
*/
|
||||
static void
|
||||
ff_free_stack_element(ctx)
|
||||
ff_stack_T *ctx;
|
||||
ff_free_stack_element(stack_ptr)
|
||||
ff_stack_T *stack_ptr;
|
||||
{
|
||||
/* vim_free handles possible NULL pointers */
|
||||
vim_free(ctx->ffs_fix_path);
|
||||
vim_free(stack_ptr->ffs_fix_path);
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
vim_free(ctx->ffs_wc_path);
|
||||
vim_free(stack_ptr->ffs_wc_path);
|
||||
#endif
|
||||
|
||||
if (ctx->ffs_filearray != NULL)
|
||||
FreeWild(ctx->ffs_filearray_size, ctx->ffs_filearray);
|
||||
if (stack_ptr->ffs_filearray != NULL)
|
||||
FreeWild(stack_ptr->ffs_filearray_size, stack_ptr->ffs_filearray);
|
||||
|
||||
vim_free(ctx);
|
||||
vim_free(stack_ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the search context
|
||||
* Clear the search context, but NOT the visited list.
|
||||
*/
|
||||
static void
|
||||
ff_clear()
|
||||
ff_clear(search_ctx)
|
||||
ff_search_ctx_T *search_ctx;
|
||||
{
|
||||
ff_stack_T *sptr;
|
||||
|
||||
/* clear up stack */
|
||||
while ((sptr = ff_pop()) != NULL)
|
||||
while ((sptr = ff_pop(search_ctx)) != NULL)
|
||||
ff_free_stack_element(sptr);
|
||||
|
||||
vim_free(ff_search_ctx->ffsc_file_to_search);
|
||||
vim_free(ff_search_ctx->ffsc_start_dir);
|
||||
vim_free(ff_search_ctx->ffsc_fix_path);
|
||||
vim_free(search_ctx->ffsc_file_to_search);
|
||||
vim_free(search_ctx->ffsc_start_dir);
|
||||
vim_free(search_ctx->ffsc_fix_path);
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
vim_free(ff_search_ctx->ffsc_wc_path);
|
||||
vim_free(search_ctx->ffsc_wc_path);
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
if (ff_search_ctx->ffsc_stopdirs_v != NULL)
|
||||
if (search_ctx->ffsc_stopdirs_v != NULL)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (ff_search_ctx->ffsc_stopdirs_v[i] != NULL)
|
||||
while (search_ctx->ffsc_stopdirs_v[i] != NULL)
|
||||
{
|
||||
vim_free(ff_search_ctx->ffsc_stopdirs_v[i]);
|
||||
vim_free(search_ctx->ffsc_stopdirs_v[i]);
|
||||
i++;
|
||||
}
|
||||
vim_free(ff_search_ctx->ffsc_stopdirs_v);
|
||||
vim_free(search_ctx->ffsc_stopdirs_v);
|
||||
}
|
||||
ff_search_ctx->ffsc_stopdirs_v = NULL;
|
||||
search_ctx->ffsc_stopdirs_v = NULL;
|
||||
#endif
|
||||
|
||||
/* reset everything */
|
||||
ff_search_ctx->ffsc_file_to_search = NULL;
|
||||
ff_search_ctx->ffsc_start_dir = NULL;
|
||||
ff_search_ctx->ffsc_fix_path = NULL;
|
||||
search_ctx->ffsc_file_to_search = NULL;
|
||||
search_ctx->ffsc_start_dir = NULL;
|
||||
search_ctx->ffsc_fix_path = NULL;
|
||||
#ifdef FEAT_PATH_EXTRA
|
||||
ff_search_ctx->ffsc_wc_path = NULL;
|
||||
ff_search_ctx->ffsc_level = 0;
|
||||
search_ctx->ffsc_wc_path = NULL;
|
||||
search_ctx->ffsc_level = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -5242,7 +5256,7 @@ ff_path_in_stoplist(path, path_len, stopdirs_v)
|
||||
|
||||
#if defined(FEAT_SEARCHPATH) || defined(PROTO)
|
||||
/*
|
||||
* Find the file name "ptr[len]" in the path.
|
||||
* Find the file name "ptr[len]" in the path. Also finds directory names.
|
||||
*
|
||||
* On the first call set the parameter 'first' to TRUE to initialize
|
||||
* the search. For repeating calls to FALSE.
|
||||
@@ -5276,7 +5290,7 @@ find_file_in_path(ptr, len, options, first, rel_fname)
|
||||
{
|
||||
return find_file_in_path_option(ptr, len, options, first,
|
||||
*curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path,
|
||||
FALSE, rel_fname, curbuf->b_p_sua);
|
||||
FINDFILE_BOTH, rel_fname, curbuf->b_p_sua);
|
||||
}
|
||||
|
||||
static char_u *ff_file_to_find = NULL;
|
||||
@@ -5309,17 +5323,17 @@ find_directory_in_path(ptr, len, options, rel_fname)
|
||||
char_u *rel_fname; /* file name searching relative to */
|
||||
{
|
||||
return find_file_in_path_option(ptr, len, options, TRUE, p_cdpath,
|
||||
TRUE, rel_fname, (char_u *)"");
|
||||
FINDFILE_DIR, rel_fname, (char_u *)"");
|
||||
}
|
||||
|
||||
char_u *
|
||||
find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fname, suffixes)
|
||||
find_file_in_path_option(ptr, len, options, first, path_option, find_what, rel_fname, suffixes)
|
||||
char_u *ptr; /* file name */
|
||||
int len; /* length of file name */
|
||||
int options;
|
||||
int first; /* use count'th matching file name */
|
||||
char_u *path_option; /* p_path or p_cdpath */
|
||||
int need_dir; /* looking for directory name */
|
||||
int find_what; /* FINDFILE_FILE, _DIR or _BOTH */
|
||||
char_u *rel_fname; /* file name we are looking relative to. */
|
||||
char_u *suffixes; /* list of suffixes, 'suffixesadd' option */
|
||||
{
|
||||
@@ -5421,12 +5435,14 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
|
||||
#ifdef DJGPP
|
||||
/* "C:" by itself will fail for mch_getperm(),
|
||||
* assume it's always valid. */
|
||||
(need_dir && NameBuff[0] != NUL
|
||||
(find_what != FINDFILE_FILE && NameBuff[0] != NUL
|
||||
&& NameBuff[1] == ':'
|
||||
&& NameBuff[2] == NUL) ||
|
||||
#endif
|
||||
(mch_getperm(NameBuff) >= 0
|
||||
&& (!need_dir || mch_isdir(NameBuff))))
|
||||
&& (find_what == FINDFILE_BOTH
|
||||
|| ((find_what == FINDFILE_DIR)
|
||||
== mch_isdir(NameBuff)))))
|
||||
{
|
||||
file_name = vim_strsave(NameBuff);
|
||||
goto theend;
|
||||
@@ -5457,9 +5473,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
|
||||
{
|
||||
if (did_findfile_init)
|
||||
{
|
||||
ff_search_ctx->ffsc_need_dir = need_dir;
|
||||
file_name = vim_findfile(fdip_search_ctx);
|
||||
ff_search_ctx->ffsc_need_dir = FALSE;
|
||||
if (file_name != NULL)
|
||||
break;
|
||||
|
||||
@@ -5492,7 +5506,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
|
||||
r_ptr = NULL;
|
||||
#endif
|
||||
fdip_search_ctx = vim_findfile_init(buf, ff_file_to_find,
|
||||
r_ptr, 100, FALSE, TRUE,
|
||||
r_ptr, 100, FALSE, find_what,
|
||||
fdip_search_ctx, FALSE, rel_fname);
|
||||
if (fdip_search_ctx != NULL)
|
||||
did_findfile_init = TRUE;
|
||||
@@ -5504,7 +5518,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
|
||||
{
|
||||
if (first == TRUE)
|
||||
{
|
||||
if (need_dir)
|
||||
if (find_what == FINDFILE_DIR)
|
||||
EMSG2(_("E344: Can't find directory \"%s\" in cdpath"),
|
||||
ff_file_to_find);
|
||||
else
|
||||
@@ -5513,7 +5527,7 @@ find_file_in_path_option(ptr, len, options, first, path_option, need_dir, rel_fn
|
||||
}
|
||||
else
|
||||
{
|
||||
if (need_dir)
|
||||
if (find_what == FINDFILE_DIR)
|
||||
EMSG2(_("E346: No more directory \"%s\" found in cdpath"),
|
||||
ff_file_to_find);
|
||||
else
|
||||
|
||||
@@ -692,6 +692,7 @@ op_reindent(oap, how)
|
||||
}
|
||||
}
|
||||
++curwin->w_cursor.lnum;
|
||||
curwin->w_cursor.col = 0; /* make sure it's valid */
|
||||
}
|
||||
|
||||
/* put cursor on first non-blank of indented line */
|
||||
@@ -2197,7 +2198,7 @@ op_tilde(oap)
|
||||
#ifdef FEAT_VISUAL
|
||||
struct block_def bd;
|
||||
#endif
|
||||
int did_change;
|
||||
int did_change = FALSE;
|
||||
|
||||
if (u_save((linenr_T)(oap->start.lnum - 1),
|
||||
(linenr_T)(oap->end.lnum + 1)) == FAIL)
|
||||
@@ -2242,7 +2243,18 @@ op_tilde(oap)
|
||||
else if (!oap->inclusive)
|
||||
dec(&(oap->end));
|
||||
|
||||
did_change = swapchars(oap->op_type, &pos, oap->end.col - pos.col + 1);
|
||||
if (pos.lnum == oap->end.lnum)
|
||||
did_change = swapchars(oap->op_type, &pos,
|
||||
oap->end.col - pos.col + 1);
|
||||
else
|
||||
for (;;)
|
||||
{
|
||||
did_change |= swapchars(oap->op_type, &pos,
|
||||
pos.lnum == oap->end.lnum ? oap->end.col + 1:
|
||||
(int)STRLEN(ml_get_pos(&pos)));
|
||||
if (ltoreq(oap->end, pos) || inc(&pos) == -1)
|
||||
break;
|
||||
}
|
||||
if (did_change)
|
||||
{
|
||||
changed_lines(oap->start.lnum, oap->start.col, oap->end.lnum + 1,
|
||||
@@ -2314,17 +2326,11 @@ swapchars(op_type, pos, length)
|
||||
for (todo = length; todo > 0; --todo)
|
||||
{
|
||||
# ifdef FEAT_MBYTE
|
||||
int pos_col = pos->col;
|
||||
|
||||
if (has_mbyte)
|
||||
/* we're counting bytes, not characters */
|
||||
todo -= (*mb_ptr2len)(ml_get_pos(pos)) - 1;
|
||||
# endif
|
||||
did_change |= swapchar(op_type, pos);
|
||||
# ifdef FEAT_MBYTE
|
||||
/* Changing German sharp s to SS increases the column. */
|
||||
todo += pos->col - pos_col;
|
||||
# endif
|
||||
if (inc(pos) == -1) /* at end of file */
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5705,7 +5705,7 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
|
||||
{
|
||||
if (gvarp == &p_fenc)
|
||||
{
|
||||
if (!curbuf->b_p_ma)
|
||||
if (!curbuf->b_p_ma && opt_flags != OPT_GLOBAL)
|
||||
errmsg = e_modifiable;
|
||||
else if (vim_strchr(*varp, ',') != NULL)
|
||||
/* No comma allowed in 'fileencoding'; catches confusing it
|
||||
|
||||
+13
-1
@@ -195,6 +195,7 @@ static char_u *extra_shell_arg = NULL;
|
||||
static int show_shell_mess = TRUE;
|
||||
#endif
|
||||
static int deadly_signal = 0; /* The signal we caught */
|
||||
static int in_mch_delay = FALSE; /* sleeping in mch_delay() */
|
||||
|
||||
static int curr_tmode = TMODE_COOK; /* contains current terminal mode */
|
||||
|
||||
@@ -538,7 +539,9 @@ mch_delay(msec, ignoreinput)
|
||||
if (ignoreinput)
|
||||
{
|
||||
/* Go to cooked mode without echo, to allow SIGINT interrupting us
|
||||
* here */
|
||||
* here. But we don't want QUIT to kill us (CTRL-\ used in a
|
||||
* shell may produce SIGQUIT). */
|
||||
in_mch_delay = TRUE;
|
||||
old_tmode = curr_tmode;
|
||||
if (curr_tmode == TMODE_RAW)
|
||||
settmode(TMODE_SLEEP);
|
||||
@@ -602,6 +605,7 @@ mch_delay(msec, ignoreinput)
|
||||
#endif
|
||||
|
||||
settmode(old_tmode);
|
||||
in_mch_delay = FALSE;
|
||||
}
|
||||
else
|
||||
WaitForChar(msec);
|
||||
@@ -922,6 +926,14 @@ deathtrap SIGDEFARG(sigarg)
|
||||
#endif
|
||||
|
||||
#ifdef SIGHASARG
|
||||
# ifdef SIGQUIT
|
||||
/* While in mch_delay() we go to cooked mode to allow a CTRL-C to
|
||||
* interrupt us. But in cooked mode we may also get SIGQUIT, e.g., when
|
||||
* pressing CTRL-\, but we don't want Vim to exit then. */
|
||||
if (in_mch_delay && sigarg == SIGQUIT)
|
||||
SIGRETURN;
|
||||
# endif
|
||||
|
||||
/* When SIGHUP, SIGQUIT, etc. are blocked: postpone the effect and return
|
||||
* here. This avoids that a non-reentrant function is interrupted, e.g.,
|
||||
* free(). Calling free() again may then cause a crash. */
|
||||
|
||||
+15
-4
@@ -2644,7 +2644,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
#if defined(FEAT_SIGNS) || (defined(FEAT_QUICKFIX) && defined(FEAT_WINDOWS)) \
|
||||
|| defined(FEAT_SYN_HL) || defined(FEAT_DIFF)
|
||||
# define LINE_ATTR
|
||||
int line_attr = 0; /* atrribute for the whole line */
|
||||
int line_attr = 0; /* attribute for the whole line */
|
||||
#endif
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
matchitem_T *cur; /* points to the match list */
|
||||
@@ -3040,18 +3040,25 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
if (has_spell)
|
||||
{
|
||||
int len;
|
||||
colnr_T linecol = (colnr_T)(ptr - line);
|
||||
hlf_T spell_hlf = HLF_COUNT;
|
||||
|
||||
pos = wp->w_cursor;
|
||||
wp->w_cursor.lnum = lnum;
|
||||
wp->w_cursor.col = (colnr_T)(ptr - line);
|
||||
wp->w_cursor.col = linecol;
|
||||
len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
|
||||
|
||||
/* spell_move_to() may call ml_get() and make "line" invalid */
|
||||
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
|
||||
ptr = line + linecol;
|
||||
|
||||
if (len == 0 || (int)wp->w_cursor.col > ptr - line)
|
||||
{
|
||||
/* no bad word found at line start, don't check until end of a
|
||||
* word */
|
||||
spell_hlf = HLF_COUNT;
|
||||
word_end = (int)(spell_to_word_end(ptr, wp->w_buffer) - line + 1);
|
||||
word_end = (int)(spell_to_word_end(ptr, wp->w_buffer)
|
||||
- line + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8038,9 +8045,13 @@ setcursor()
|
||||
windgoto(W_WINROW(curwin) + curwin->w_wrow,
|
||||
W_WINCOL(curwin) + (
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
/* With 'rightleft' set and the cursor on a double-wide
|
||||
* character, position it on the leftmost column. */
|
||||
curwin->w_p_rl ? ((int)W_WIDTH(curwin) - curwin->w_wcol - (
|
||||
# ifdef FEAT_MBYTE
|
||||
has_mbyte ? (*mb_ptr2cells)(ml_get_cursor()) :
|
||||
(has_mbyte
|
||||
&& (*mb_ptr2cells)(ml_get_cursor()) == 2
|
||||
&& vim_isprintc(gchar_cursor())) ? 2 :
|
||||
# endif
|
||||
1)) :
|
||||
#endif
|
||||
|
||||
+32
-13
@@ -280,7 +280,8 @@ save_re_pat(idx, pat, magic)
|
||||
if (spats[idx].pat != pat)
|
||||
{
|
||||
#if FEAT_GUI_MACVIM
|
||||
gui_macvim_add_to_find_pboard(pat);
|
||||
if (RE_SEARCH == idx)
|
||||
gui_macvim_add_to_find_pboard(pat);
|
||||
#endif
|
||||
vim_free(spats[idx].pat);
|
||||
spats[idx].pat = vim_strsave(pat);
|
||||
@@ -426,7 +427,8 @@ set_last_search_pat(s, idx, magic, setlast)
|
||||
int setlast;
|
||||
{
|
||||
#if FEAT_GUI_MACVIM
|
||||
gui_macvim_add_to_find_pboard(s);
|
||||
if (RE_SEARCH == idx)
|
||||
gui_macvim_add_to_find_pboard(s);
|
||||
#endif
|
||||
|
||||
vim_free(spats[idx].pat);
|
||||
@@ -631,7 +633,7 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
|
||||
#ifdef FEAT_EVAL
|
||||
submatch = first_submatch(®match);
|
||||
#endif
|
||||
/* Line me be past end of buffer for "\n\zs". */
|
||||
/* "lnum" may be past end of buffer for "\n\zs". */
|
||||
if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
|
||||
ptr = (char_u *)"";
|
||||
else
|
||||
@@ -840,21 +842,38 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options & SEARCH_END && !(options & SEARCH_NOOF))
|
||||
/* With the SEARCH_END option move to the last character
|
||||
* of the match. Don't do it for an empty match, end
|
||||
* should be same as start then. */
|
||||
if (options & SEARCH_END && !(options & SEARCH_NOOF)
|
||||
&& !(matchpos.lnum == endpos.lnum
|
||||
&& matchpos.col == endpos.col))
|
||||
{
|
||||
/* For a match in the first column, set the position
|
||||
* on the NUL in the previous line. */
|
||||
pos->lnum = lnum + endpos.lnum;
|
||||
pos->col = endpos.col - 1;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
pos->col = endpos.col;
|
||||
if (endpos.col == 0)
|
||||
{
|
||||
/* 'e' offset may put us just below the last line */
|
||||
if (pos->lnum > buf->b_ml.ml_line_count)
|
||||
ptr = (char_u *)"";
|
||||
else
|
||||
ptr = ml_get_buf(buf, pos->lnum, FALSE);
|
||||
pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
|
||||
if (pos->lnum > 1) /* just in case */
|
||||
{
|
||||
--pos->lnum;
|
||||
pos->col = (colnr_T)STRLEN(ml_get_buf(buf,
|
||||
pos->lnum, FALSE));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
--pos->col;
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte
|
||||
&& pos->lnum <= buf->b_ml.ml_line_count)
|
||||
{
|
||||
ptr = ml_get_buf(buf, pos->lnum, FALSE);
|
||||
pos->col -= (*mb_head_off)(ptr, ptr + pos->col);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2669,8 +2669,8 @@ get_tagfname(tnp, first, buf)
|
||||
|
||||
tnp->tn_search_ctx = vim_findfile_init(buf, filename,
|
||||
r_ptr, 100,
|
||||
FALSE, /* don't free visited list */
|
||||
FALSE, /* we search for a file */
|
||||
FALSE, /* don't free visited list */
|
||||
FINDFILE_FILE, /* we search for a file */
|
||||
tnp->tn_search_ctx, TRUE, curbuf->b_ffname);
|
||||
if (tnp->tn_search_ctx != NULL)
|
||||
tnp->tn_did_filefind_init = TRUE;
|
||||
@@ -2691,6 +2691,7 @@ tagname_free(tnp)
|
||||
{
|
||||
vim_free(tnp->tn_tags);
|
||||
vim_findfile_cleanup(tnp->tn_search_ctx);
|
||||
tnp->tn_search_ctx = NULL;
|
||||
ga_clear_strings(&tag_fnames);
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -4050,15 +4050,17 @@ check_termcode(max_offset, buf, buflen)
|
||||
{
|
||||
/* Check for xterm version string: "<Esc>[>{x};{vers};{y}c". Also
|
||||
* eat other possible responses to t_RV, rxvt returns
|
||||
* "<Esc>[?1;2c". Also accept CSI instead of <Esc>[. */
|
||||
* "<Esc>[?1;2c". Also accept CSI instead of <Esc>[.
|
||||
* mrxvt has been reported to have "+" in the version. Assume
|
||||
* the escape sequence ends with a letter or one of "{|}~". */
|
||||
if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
|
||||
|| (tp[0] == CSI && len >= 2)))
|
||||
{
|
||||
j = 0;
|
||||
extra = 0;
|
||||
for (i = 2 + (tp[0] != CSI);
|
||||
i < len && (VIM_ISDIGIT(tp[i])
|
||||
|| tp[i] == ';' || tp[i] == '.'); ++i)
|
||||
for (i = 2 + (tp[0] != CSI); i < len
|
||||
&& !(tp[i] >= '{' && tp[i] <= '~')
|
||||
&& !ASCII_ISALPHA(tp[i]); ++i)
|
||||
if (tp[i] == ';' && ++j == 1)
|
||||
extra = atoi((char *)tp + i + 1);
|
||||
if (i == len)
|
||||
|
||||
+20
-1
@@ -1,8 +1,12 @@
|
||||
|
||||
Test Visual block mode commands
|
||||
And test "U" in Visual mode, also on German sharp S.
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:so mbyte.vim
|
||||
:" This only works when 'encoding' is "latin1", don't depend on the environment
|
||||
:set enc=latin1
|
||||
/^abcde
|
||||
:" Test shift-right of a block
|
||||
jlllljj>wlljlll>
|
||||
@@ -14,7 +18,22 @@ GklkkkIxyz
|
||||
Gllllkkklllrq
|
||||
:" Test block-change
|
||||
G$khhhhhkkcmno
|
||||
:$-4,$wq! test.out
|
||||
:$-4,$w! test.out
|
||||
:" gUe must uppercase a whole word, also when ß changes to SS
|
||||
Gothe youtußeuu endYpk0wgUe
|
||||
:" gUfx must uppercase until x, inclusive.
|
||||
O- youßtußexu -0fogUfx
|
||||
:" VU must uppercase a whole line
|
||||
YpkVU
|
||||
:" same, when it's the last line in the buffer
|
||||
YPGi111VUddP
|
||||
:" Uppercase two lines
|
||||
Oblah di
|
||||
doh dutVkUj
|
||||
:" Uppercase part of two lines
|
||||
ddppi333k0i222fyllvjfuUk
|
||||
:/^the/,$w >> test.out
|
||||
:qa!
|
||||
ENDTEST
|
||||
|
||||
abcdefghijklm
|
||||
|
||||
@@ -3,3 +3,11 @@ axyzqqqq mno ghijklm
|
||||
axyzqqqqef mno ghijklm
|
||||
axyzqqqqefgmnoklm
|
||||
abcdqqqqijklm
|
||||
the YOUTUSSEUU end
|
||||
- yOUSSTUSSEXu -
|
||||
THE YOUTUSSEUU END
|
||||
111THE YOUTUSSEUU END
|
||||
BLAH DI
|
||||
DOH DUT
|
||||
222the yoUTUSSEUU END
|
||||
333THE YOUTUßeuu end
|
||||
|
||||
Binary file not shown.
@@ -6,6 +6,7 @@ test49.failed, try to add one ore more "G"s at the line ending in "test.out"
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:se nocp nomore viminfo+=nviminfo
|
||||
:lang mess C
|
||||
:so test49.vim
|
||||
GGGGGGGGGGGGGG"rp:.-,$w! test.out
|
||||
:"
|
||||
|
||||
@@ -146,7 +146,7 @@ let l = [0, 1, 2, 3]
|
||||
:try
|
||||
: let n = d[1500]
|
||||
:catch
|
||||
: $put =v:exception[:14] . v:exception[-4:-1]
|
||||
: $put =substitute(v:exception, '\v(.{14}).*( \d{4}).*', '\1\2', '')
|
||||
:endtry
|
||||
:" lookup each items
|
||||
:for i in range(1500)
|
||||
|
||||
+5
-3
@@ -1814,13 +1814,14 @@ u_undoline()
|
||||
if (undo_off)
|
||||
return;
|
||||
|
||||
if (curbuf->b_u_line_ptr == NULL ||
|
||||
curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
|
||||
if (curbuf->b_u_line_ptr == NULL
|
||||
|| curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
beep_flush();
|
||||
return;
|
||||
}
|
||||
/* first save the line for the 'u' command */
|
||||
|
||||
/* first save the line for the 'u' command */
|
||||
if (u_savecommon(curbuf->b_u_line_lnum - 1,
|
||||
curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL)
|
||||
return;
|
||||
@@ -1840,6 +1841,7 @@ u_undoline()
|
||||
curbuf->b_u_line_colnr = curwin->w_cursor.col;
|
||||
curwin->w_cursor.col = t;
|
||||
curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
|
||||
check_cursor_col();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -681,6 +681,56 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
267,
|
||||
/**/
|
||||
266,
|
||||
/**/
|
||||
265,
|
||||
/**/
|
||||
264,
|
||||
/**/
|
||||
263,
|
||||
/**/
|
||||
262,
|
||||
/**/
|
||||
261,
|
||||
/**/
|
||||
260,
|
||||
/**/
|
||||
259,
|
||||
/**/
|
||||
258,
|
||||
/**/
|
||||
257,
|
||||
/**/
|
||||
256,
|
||||
/**/
|
||||
255,
|
||||
/**/
|
||||
254,
|
||||
/**/
|
||||
253,
|
||||
/**/
|
||||
252,
|
||||
/**/
|
||||
251,
|
||||
/**/
|
||||
250,
|
||||
/**/
|
||||
249,
|
||||
/**/
|
||||
248,
|
||||
/**/
|
||||
247,
|
||||
/**/
|
||||
246,
|
||||
/**/
|
||||
245,
|
||||
/**/
|
||||
244,
|
||||
/**/
|
||||
243,
|
||||
/**/
|
||||
242,
|
||||
/**/
|
||||
|
||||
@@ -723,6 +723,11 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
||||
/* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND
|
||||
* is used when executing commands and EW_SILENT for interactive expanding. */
|
||||
|
||||
/* Flags for find_file_*() functions. */
|
||||
#define FINDFILE_FILE 0 /* only files */
|
||||
#define FINDFILE_DIR 1 /* only directories */
|
||||
#define FINDFILE_BOTH 2 /* files and directories */
|
||||
|
||||
#ifdef FEAT_VERTSPLIT
|
||||
# define W_WINCOL(wp) (wp->w_wincol)
|
||||
# define W_WIDTH(wp) (wp->w_width)
|
||||
|
||||
Reference in New Issue
Block a user