mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-05-28 00:21:57 +02:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 204e14b994 | |||
| 2e8bea32db | |||
| e70fb38670 | |||
| 3d56969f47 | |||
| 294d03baf6 | |||
| ac96dc67ba | |||
| 0413dcf3f1 | |||
| 40263195cb | |||
| dd76f85f0b | |||
| e93e9c4201 | |||
| a4a14b39ac | |||
| 49eeb133ac | |||
| 28de969ae3 | |||
| 6961a51e9a | |||
| f679af784b | |||
| fd8e8e0b4f | |||
| cd5ca1918d | |||
| 27d4ee55ae | |||
| 23e38c4298 | |||
| 0486075221 | |||
| 7a010c4a46 | |||
| 9aeade7147 | |||
| 5663536b1f | |||
| 95f42c734a | |||
| e1ece272fa | |||
| 73b5d1837c | |||
| 790f685006 | |||
| a680267d49 | |||
| 5f1547b288 | |||
| 9d9a5983f5 | |||
| 16e57e6189 | |||
| 5d45d4a4d2 | |||
| 0546647038 | |||
| c9ad0b6d4d | |||
| 25306ee0c5 | |||
| 2e024248fa | |||
| 85879328b0 | |||
| 9c530a8030 | |||
| 9105eb1fd0 | |||
| c49868a11f | |||
| 795860de7c | |||
| 90a729a8e4 | |||
| 1a328483b7 | |||
| 5e09d64d77 | |||
| 4591403b7e | |||
| e90f76c1aa | |||
| 8745e4380e | |||
| cd7a1f6539 | |||
| bb21f9f120 | |||
| 38c7ababf6 | |||
| 5aea857883 | |||
| 322b4eec7e | |||
| 886d3d7aed | |||
| b2f7a2f021 | |||
| 4374e9787e | |||
| 080a7c2c6c | |||
| ffef064005 | |||
| d23a68d047 | |||
| c973e12d3e | |||
| 5e0543116b | |||
| d9f633dbb3 | |||
| 32cb07dd61 | |||
| 40ae005819 | |||
| c4e8fcc338 | |||
| 9dbb79f942 | |||
| 031479c46b | |||
| 843a3a41bf | |||
| 01973d329c | |||
| bcfeb7c895 | |||
| 46b250b75f | |||
| 9b06b0a4b2 | |||
| 80b36e7995 | |||
| d29599b7ea | |||
| a63fc2427e |
@@ -1,4 +1,4 @@
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Jan 08
|
||||
*gui_mac.txt* For Vim version 7.2. Last change: 2009 Mar 15
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bjorn Winckler
|
||||
@@ -117,6 +117,11 @@ really bad once you start using tabs. For example, dropping two files, then
|
||||
dropping two more, and switching back to the first tab would cause weird
|
||||
strings like "((3) of 2)" to appear in the window title.
|
||||
|
||||
*macvim-tablabel*
|
||||
Tab labels only show the tail of the file name to make the tabs more readable
|
||||
when editing files in deeply nested folders. Add the line "set guitablabel="
|
||||
to your .gvimrc file to revert back to the default Vim tab label.
|
||||
|
||||
*macvim-options*
|
||||
These are the non-standard options that MacVim supports:
|
||||
'antialias' 'fullscreen' 'fuoptions'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*if_cscop.txt* For Vim version 7.2. Last change: 2005 Mar 29
|
||||
*if_cscop.txt* For Vim version 7.2. Last change: 2009 Mar 18
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Andy Kahn
|
||||
@@ -131,11 +131,22 @@ The available subcommands are:
|
||||
7 or f: Find this file
|
||||
8 or i: Find files #including this file
|
||||
|
||||
For all types, except 4 and 6, leading white space for {name} is
|
||||
removed. For 4 and 6 there is exactly one space between {querytype}
|
||||
and {name}. Further white space is included in {name}.
|
||||
|
||||
EXAMPLES >
|
||||
:cscope find c vim_free
|
||||
:cscope find 3 vim_free
|
||||
:cscope find 3 vim_free
|
||||
<
|
||||
These two examples perform the same query. >
|
||||
These two examples perform the same query: functions calling
|
||||
"vim_free". >
|
||||
|
||||
:cscope find t initOnce
|
||||
:cscope find t initOnce
|
||||
<
|
||||
The first one searches for the text "initOnce", the second one for
|
||||
" initOnce". >
|
||||
|
||||
:cscope find 0 DEFAULT_TERM
|
||||
<
|
||||
|
||||
@@ -4275,9 +4275,6 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
be able to execute Normal mode commands.
|
||||
This is the opposite of the 'keymap' option, where characters are
|
||||
mapped in Insert mode.
|
||||
This only works for 8-bit characters. The value of 'langmap' may be
|
||||
specified with multi-byte characters (e.g., UTF-8), but only the lower
|
||||
8 bits of each character will be used.
|
||||
|
||||
Example (for Greek, in UTF-8): *greek* >
|
||||
:set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz
|
||||
|
||||
+464
-461
File diff suppressed because it is too large
Load Diff
@@ -1153,7 +1153,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>43</string>
|
||||
<string>45</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
int preloadPid;
|
||||
BOOL shouldActivateWhenNextWindowOpens;
|
||||
int numChildProcesses;
|
||||
NSMutableDictionary *inputQueues;
|
||||
int processingFlag;
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
|
||||
FSEventStreamRef fsEventStream;
|
||||
|
||||
+194
-81
@@ -125,6 +125,8 @@ typedef struct
|
||||
- (void)loadDefaultFont;
|
||||
- (int)executeInLoginShell:(NSString *)path arguments:(NSArray *)args;
|
||||
- (void)reapChildProcesses:(id)sender;
|
||||
- (void)processInputQueues:(id)sender;
|
||||
- (void)addVimController:(MMVimController *)vc;
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (void)removePlugInMenu;
|
||||
@@ -208,6 +210,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
cachedVimControllers = [NSMutableArray new];
|
||||
preloadPid = -1;
|
||||
pidArguments = [NSMutableDictionary new];
|
||||
inputQueues = [NSMutableDictionary new];
|
||||
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
NSString *plugInTitle = NSLocalizedString(@"Plug-In",
|
||||
@@ -249,6 +252,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
//NSLog(@"MMAppController dealloc");
|
||||
|
||||
[connection release]; connection = nil;
|
||||
[inputQueues release]; inputQueues = nil;
|
||||
[pidArguments release]; pidArguments = nil;
|
||||
[vimControllers release]; vimControllers = nil;
|
||||
[cachedVimControllers release]; cachedVimControllers = nil;
|
||||
@@ -676,21 +680,26 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
|
||||
NSPoint screenOrigin = [[win screen] frame].origin;
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Try to avoid shifting the new window downwards if it means that
|
||||
// the bottom of the window will be off the screen. E.g. if the
|
||||
// user has set windows to open maximized in the vertical direction
|
||||
// then the new window will cascade horizontally only.
|
||||
topLeft.y = oldTopLeft.y;
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
if ([win screen]) {
|
||||
NSPoint screenOrigin = [[win screen] frame].origin;
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Try to avoid shifting the new window downwards if it means
|
||||
// that the bottom of the window will be off the screen. E.g.
|
||||
// if the user has set windows to open maximized in the
|
||||
// vertical direction then the new window will cascade
|
||||
// horizontally only.
|
||||
topLeft.y = oldTopLeft.y;
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Move the window to the top of the screen if the bottom of the
|
||||
// window is still obscured.
|
||||
topLeft.y = NSMaxY([[win screen] frame]);
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
if ([win frame].origin.y < screenOrigin.y) {
|
||||
// Move the window to the top of the screen if the bottom of
|
||||
// the window is still obscured.
|
||||
topLeft.y = NSMaxY([[win screen] frame]);
|
||||
[win setFrameTopLeftPoint:topLeft];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"[%s] WINDOW NOT ON SCREEN, don't constrain position", _cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,7 +998,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:YES];
|
||||
[panel setAccessoryView:openPanelAccessoryView()];
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
int result = [panel runModalForDirectory:dir file:nil types:nil];
|
||||
if (NSOKButton == result)
|
||||
@@ -1088,64 +1097,79 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
}
|
||||
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
connectBackend:(byref in id <MMBackendProtocol>)backend
|
||||
pid:(int)pid
|
||||
- (MMVimController *)keyVimController
|
||||
{
|
||||
//NSLog(@"Connect backend (pid=%d)", pid);
|
||||
NSNumber *pidKey = [NSNumber numberWithInt:pid];
|
||||
MMVimController *vc = nil;
|
||||
|
||||
@try {
|
||||
[(NSDistantObject*)backend
|
||||
setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
vc = [[[MMVimController alloc] initWithBackend:backend pid:pid]
|
||||
autorelease];
|
||||
|
||||
if (preloadPid == pid) {
|
||||
// This backend was preloaded, so add it to the cache and schedule
|
||||
// another vim process to be preloaded.
|
||||
preloadPid = -1;
|
||||
[vc setIsPreloading:YES];
|
||||
[cachedVimControllers addObject:vc];
|
||||
[self scheduleVimControllerPreloadAfterDelay:1];
|
||||
|
||||
return vc;
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
if (keyWindow) {
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [vimControllers objectAtIndex:i];
|
||||
if ([[[vc windowController] window] isEqual:keyWindow])
|
||||
return vc;
|
||||
}
|
||||
|
||||
[vimControllers addObject:vc];
|
||||
|
||||
id args = [pidArguments objectForKey:pidKey];
|
||||
if (args && [NSNull null] != args)
|
||||
[vc passArguments:args];
|
||||
|
||||
// HACK! MacVim does not get activated if it is launched from the
|
||||
// terminal, so we forcibly activate here unless it is an untitled
|
||||
// window opening. Untitled windows are treated differently, else
|
||||
// MacVim would steal the focus if another app was activated while the
|
||||
// untitled window was loading.
|
||||
if (!args || args != [NSNull null])
|
||||
[self activateWhenNextWindowOpens];
|
||||
|
||||
if (args)
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
|
||||
return vc;
|
||||
}
|
||||
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught in %s: \"%@\"", _cmd, e);
|
||||
|
||||
if (vc)
|
||||
[vimControllers removeObject:vc];
|
||||
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (unsigned)connectBackend:(byref in id <MMBackendProtocol>)proxy pid:(int)pid
|
||||
{
|
||||
//NSLog(@"[%s] pid=%d", _cmd, pid);
|
||||
|
||||
[(NSDistantObject*)proxy setProtocolForProxy:@protocol(MMBackendProtocol)];
|
||||
|
||||
// NOTE: Allocate the vim controller now but don't add it to the list of
|
||||
// controllers since this is a distributed object call and as such can
|
||||
// arrive at unpredictable times (e.g. while iterating the list of vim
|
||||
// controllers).
|
||||
// (What if input arrives before the vim controller is added to the list of
|
||||
// controllers? This should not be a problem since the input isn't
|
||||
// processed immediately (see processInput:forIdentifier:).)
|
||||
MMVimController *vc = [[MMVimController alloc] initWithBackend:proxy
|
||||
pid:pid];
|
||||
[self performSelector:@selector(addVimController:)
|
||||
withObject:vc
|
||||
afterDelay:0];
|
||||
|
||||
[vc release];
|
||||
|
||||
return [vc identifier];
|
||||
}
|
||||
|
||||
- (oneway void)processInput:(in bycopy NSArray *)queue
|
||||
forIdentifier:(unsigned)identifier
|
||||
{
|
||||
// NOTE: Input is not handled immediately since this is a distribued object
|
||||
// call and as such can arrive at unpredictable times. Instead, queue the
|
||||
// input and process it when the run loop is updated.
|
||||
|
||||
if (!(queue && identifier)) {
|
||||
NSLog(@"[%s] Bad input for identifier=%d", _cmd, identifier);
|
||||
return;
|
||||
}
|
||||
|
||||
//NSLog(@"[%s] QUEUE for identifier=%d: <<< %@>>>", _cmd, identifier,
|
||||
// debugStringForMessageQueue(queue));
|
||||
|
||||
NSNumber *key = [NSNumber numberWithUnsignedInt:identifier];
|
||||
NSArray *q = [inputQueues objectForKey:key];
|
||||
if (q) {
|
||||
q = [q arrayByAddingObjectsFromArray:queue];
|
||||
[inputQueues setObject:q forKey:key];
|
||||
} else {
|
||||
[inputQueues setObject:queue forKey:key];
|
||||
}
|
||||
|
||||
// NOTE: We must use "event tracking mode" as well as "default mode",
|
||||
// otherwise the input queue will not be processed e.g. during live
|
||||
// resizing.
|
||||
[self performSelector:@selector(processInputQueues:)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode,
|
||||
NSEventTrackingRunLoopMode, nil]];
|
||||
}
|
||||
|
||||
- (NSArray *)serverList
|
||||
{
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
@@ -1160,21 +1184,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
return array;
|
||||
}
|
||||
|
||||
- (MMVimController *)keyVimController
|
||||
{
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
if (keyWindow) {
|
||||
unsigned i, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [vimControllers objectAtIndex:i];
|
||||
if ([[[vc windowController] window] isEqual:keyWindow])
|
||||
return vc;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end // MMAppController
|
||||
|
||||
|
||||
@@ -2110,4 +2119,108 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processInputQueues:(id)sender
|
||||
{
|
||||
// NOTE: Because we use distributed objects it is quite possible for this
|
||||
// function to be re-entered. This can cause all sorts of unexpected
|
||||
// problems so we guard against it here so that the rest of the code does
|
||||
// not need to worry about it.
|
||||
|
||||
// The processing flag is > 0 if this function is already on the call
|
||||
// stack; < 0 if this function was also re-entered.
|
||||
if (processingFlag != 0) {
|
||||
NSLog(@"[%s] BUSY!", _cmd);
|
||||
processingFlag = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Be _very_ careful that no exceptions can be raised between here
|
||||
// and the point at which 'processingFlag' is reset. Otherwise the above
|
||||
// test could end up always failing and no input queues would ever be
|
||||
// processed!
|
||||
processingFlag = 1;
|
||||
|
||||
// NOTE: New input may arrive while we're busy processing; we deal with
|
||||
// this by putting the current queue aside and creating a new input queue
|
||||
// for future input.
|
||||
NSDictionary *queues = inputQueues;
|
||||
inputQueues = [NSMutableDictionary new];
|
||||
|
||||
// Pass each input queue on to the vim controller with matching
|
||||
// identifier (and note that it could be cached).
|
||||
NSEnumerator *e = [queues keyEnumerator];
|
||||
NSNumber *key;
|
||||
while ((key = [e nextObject])) {
|
||||
unsigned ukey = [key unsignedIntValue];
|
||||
int i = 0, count = [vimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [vimControllers objectAtIndex:i];
|
||||
if (ukey == [vc identifier]) {
|
||||
[vc processInputQueue:[queues objectForKey:key]]; // !exceptions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < count) continue;
|
||||
|
||||
count = [cachedVimControllers count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
MMVimController *vc = [cachedVimControllers objectAtIndex:i];
|
||||
if (ukey == [vc identifier]) {
|
||||
[vc processInputQueue:[queues objectForKey:key]]; // !exceptions
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == count)
|
||||
NSLog(@"[%s] WARNING: No Vim controller for identifier=%d",
|
||||
_cmd, ukey);
|
||||
}
|
||||
|
||||
[queues release];
|
||||
|
||||
// If new input arrived while we were processing it would have been
|
||||
// blocked so we have to schedule it to be processed again.
|
||||
if (processingFlag < 0)
|
||||
[self performSelector:@selector(processInputQueues:)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode,
|
||||
NSEventTrackingRunLoopMode, nil]];
|
||||
|
||||
processingFlag = 0;
|
||||
}
|
||||
|
||||
- (void)addVimController:(MMVimController *)vc
|
||||
{
|
||||
int pid = [vc pid];
|
||||
NSNumber *pidKey = [NSNumber numberWithInt:pid];
|
||||
|
||||
if (preloadPid == pid) {
|
||||
// This controller was preloaded, so add it to the cache and
|
||||
// schedule another vim process to be preloaded.
|
||||
preloadPid = -1;
|
||||
[vc setIsPreloading:YES];
|
||||
[cachedVimControllers addObject:vc];
|
||||
[self scheduleVimControllerPreloadAfterDelay:1];
|
||||
} else {
|
||||
[vimControllers addObject:vc];
|
||||
|
||||
id args = [pidArguments objectForKey:pidKey];
|
||||
if (args && [NSNull null] != args)
|
||||
[vc passArguments:args];
|
||||
|
||||
// HACK! MacVim does not get activated if it is launched from the
|
||||
// terminal, so we forcibly activate here unless it is an untitled
|
||||
// window opening. Untitled windows are treated differently, else
|
||||
// MacVim would steal the focus if another app was activated while the
|
||||
// untitled window was loading.
|
||||
if (!args || args != [NSNull null])
|
||||
[self activateWhenNextWindowOpens];
|
||||
|
||||
if (args)
|
||||
[pidArguments removeObjectForKey:pidKey];
|
||||
}
|
||||
}
|
||||
|
||||
@end // MMAppController (Private)
|
||||
|
||||
@@ -1139,7 +1139,7 @@ defaultLineHeightForFont(NSFont *font)
|
||||
|
||||
if (flags & DRAW_UNDERL)
|
||||
{
|
||||
[fg set];
|
||||
[sp set];
|
||||
NSRectFill(NSMakeRect(rect.origin.x,
|
||||
(row + 1) * cellSize.height + kUnderlineOffset,
|
||||
rect.size.width, kUnderlineHeight));
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
NSMutableArray *inputQueue;
|
||||
NSMutableData *drawData;
|
||||
NSConnection *connection;
|
||||
id frontendProxy;
|
||||
id appProxy;
|
||||
unsigned identifier;
|
||||
NSDictionary *colorDict;
|
||||
NSDictionary *sysColorDict;
|
||||
NSDictionary *actionDict;
|
||||
|
||||
+27
-35
@@ -21,7 +21,7 @@
|
||||
*
|
||||
* It is very important to realize that all state is held by the backend, the
|
||||
* frontend must either ask for state [MMBackend evaluateExpression:] or wait
|
||||
* for the backend to update [MMVimController processCommandQueue:].
|
||||
* for the backend to update [MMAppController processInput:forIdentifier:].
|
||||
*
|
||||
* The client/server functionality of Vim is handled by the backend. It sets
|
||||
* up a named NSConnection to which other Vim processes can connect.
|
||||
@@ -178,7 +178,6 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[inputQueue release]; inputQueue = nil;
|
||||
[outputQueue release]; outputQueue = nil;
|
||||
[drawData release]; drawData = nil;
|
||||
[frontendProxy release]; frontendProxy = nil;
|
||||
[connection release]; connection = nil;
|
||||
[actionDict release]; actionDict = nil;
|
||||
[sysColorDict release]; sysColorDict = nil;
|
||||
@@ -328,29 +327,29 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL ok = NO;
|
||||
@try {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(connectionDidDie:)
|
||||
name:NSConnectionDidDieNotification object:connection];
|
||||
|
||||
id proxy = [connection rootProxy];
|
||||
[proxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
appProxy = [[connection rootProxy] retain];
|
||||
[appProxy setProtocolForProxy:@protocol(MMAppProtocol)];
|
||||
|
||||
// NOTE: We do not set any new timeout values for the connection to the
|
||||
// frontend. This means that if the frontend is "stuck" (e.g. in a
|
||||
// modal loop) then any calls to the frontend will block indefinitely
|
||||
// (the default timeouts are huge).
|
||||
|
||||
int pid = [[NSProcessInfo processInfo] processIdentifier];
|
||||
|
||||
frontendProxy = [proxy connectBackend:self pid:pid];
|
||||
if (frontendProxy) {
|
||||
[frontendProxy retain];
|
||||
[frontendProxy setProtocolForProxy:@protocol(MMFrontendProtocol)];
|
||||
ok = YES;
|
||||
}
|
||||
identifier = [appProxy connectBackend:self pid:pid];
|
||||
return YES;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when trying to connect backend: \"%@\"", e);
|
||||
}
|
||||
|
||||
return ok;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)openGUIWindow
|
||||
@@ -506,10 +505,11 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[self insertVimStateMessage];
|
||||
|
||||
@try {
|
||||
[frontendProxy processCommandQueue:outputQueue];
|
||||
//NSLog(@"[%s] Flushing (count=%d)", _cmd, [outputQueue count]);
|
||||
[appProxy processInput:outputQueue forIdentifier:identifier];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when processing command queue: \"%@\"", e);
|
||||
NSLog(@"[%s] Exception caught: \"%@\"", _cmd, e);
|
||||
NSLog(@"outputQueue(len:%d)=%@", [outputQueue count]/2,
|
||||
outputQueue);
|
||||
if (![connection isValid]) {
|
||||
@@ -575,7 +575,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
// Flush the entire queue in case a VimLeave autocommand added
|
||||
// something to the queue.
|
||||
[self queueMessage:CloseWindowMsgID data:nil];
|
||||
[frontendProxy processCommandQueue:outputQueue];
|
||||
[appProxy processInput:outputQueue forIdentifier:identifier];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when sending CloseWindowMsgID: \"%@\"", e);
|
||||
@@ -695,9 +695,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
{
|
||||
char_u *s = NULL;
|
||||
|
||||
@try {
|
||||
[frontendProxy showSavePanelWithAttributes:attr];
|
||||
[self queueMessage:BrowseForFileMsgID properties:attr];
|
||||
[self flushQueue:YES];
|
||||
|
||||
@try {
|
||||
[self waitForDialogReturn];
|
||||
|
||||
if (dialogReturn && [dialogReturn isKindOfClass:[NSString class]])
|
||||
@@ -706,7 +707,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[dialogReturn release]; dialogReturn = nil;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught when showing save panel: \"%@\"", e);
|
||||
NSLog(@"[%s] Exception caught: \"%@\"", _cmd, e);
|
||||
}
|
||||
|
||||
return (char *)s;
|
||||
@@ -734,9 +735,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
@try {
|
||||
[frontendProxy presentDialogWithAttributes:attr];
|
||||
[self queueMessage:ShowDialogMsgID properties:attr];
|
||||
[self flushQueue:YES];
|
||||
|
||||
@try {
|
||||
[self waitForDialogReturn];
|
||||
|
||||
if (dialogReturn && [dialogReturn isKindOfClass:[NSArray class]]
|
||||
@@ -758,7 +760,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[dialogReturn release]; dialogReturn = nil;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught while showing alert dialog: \"%@\"", e);
|
||||
NSLog(@"[%s] Exception caught: \"%@\"", _cmd, e);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -1107,16 +1109,6 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
[inputQueue addObject:(data ? (id)data : [NSNull null])];
|
||||
}
|
||||
|
||||
- (oneway void)processInputAndData:(in bycopy NSArray *)messages
|
||||
{
|
||||
// This is just a convenience method that allows the frontend to delay
|
||||
// sending messages.
|
||||
int i, count = [messages count];
|
||||
for (i = 1; i < count; i+=2)
|
||||
[self processInput:[[messages objectAtIndex:i-1] intValue]
|
||||
data:[messages objectAtIndex:i]];
|
||||
}
|
||||
|
||||
- (id)evaluateExpressionCocoa:(in bycopy NSString *)expr
|
||||
errorString:(out bycopy NSString **)errstr
|
||||
{
|
||||
@@ -1453,7 +1445,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
if (waitForAck) {
|
||||
// Never received a connection acknowledgement, so die.
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[frontendProxy release]; frontendProxy = nil;
|
||||
[appProxy release]; appProxy = nil;
|
||||
|
||||
// NOTE: We intentionally do not call mch_exit() since this in turn
|
||||
// will lead to -[MMBackend exit] getting called which we want to
|
||||
@@ -2488,9 +2480,9 @@ extern GuiFont gui_mch_retain_font(GuiFont font);
|
||||
if ([args objectForKey:@"remoteID"]) {
|
||||
// NOTE: We have to delay processing any ODB related arguments since
|
||||
// the file(s) may not be opened until the input buffer is processed.
|
||||
[self performSelectorOnMainThread:@selector(startOdbEditWithArguments:)
|
||||
withObject:args
|
||||
waitUntilDone:NO];
|
||||
[self performSelector:@selector(startOdbEditWithArguments:)
|
||||
withObject:args
|
||||
afterDelay:0];
|
||||
}
|
||||
|
||||
NSString *lineString = [args objectForKey:@"cursorLine"];
|
||||
|
||||
@@ -149,8 +149,10 @@
|
||||
|
||||
int fuRows = currRows, fuColumns = currColumns;
|
||||
|
||||
// NOTE: Do not use [NSScreen visibleFrame] when determining the screen
|
||||
// size since it compensates for menu and dock.
|
||||
int maxRows, maxColumns;
|
||||
NSSize size = [[self screen] visibleFrame].size;
|
||||
NSSize size = [[self screen] frame].size;
|
||||
[view constrainRows:&maxRows columns:&maxColumns toSize:size];
|
||||
|
||||
// Store current pre-fu vim size
|
||||
|
||||
@@ -102,8 +102,14 @@ static float MMDragAreaSize = 73.0f;
|
||||
int flags = [event modifierFlags];
|
||||
if ((flags & NSControlKeyMask) ||
|
||||
((flags & NSAlternateKeyMask) && (flags & NSFunctionKeyMask))) {
|
||||
BOOL unmodIsPrintable = YES;
|
||||
NSString *unmod = [event charactersIgnoringModifiers];
|
||||
if (unmod && [unmod length] > 0 && [unmod characterAtIndex:0] < 0x20)
|
||||
unmodIsPrintable = NO;
|
||||
|
||||
NSString *chars = [event characters];
|
||||
if ([chars length] == 1 && [chars characterAtIndex:0] < 0x20) {
|
||||
if ([chars length] == 1 && [chars characterAtIndex:0] < 0x20
|
||||
&& unmodIsPrintable) {
|
||||
// HACK! Send unprintable characters (such as C-@, C-[, C-\, C-],
|
||||
// C-^, C-_) as normal text to be added to the Vim input buffer.
|
||||
// This must be done in order for the backend to be able to
|
||||
|
||||
@@ -20,14 +20,11 @@
|
||||
|
||||
|
||||
|
||||
@interface MMVimController : NSObject <MMFrontendProtocol>
|
||||
{
|
||||
@interface MMVimController : NSObject {
|
||||
unsigned identifier;
|
||||
BOOL isInitialized;
|
||||
MMWindowController *windowController;
|
||||
id backendProxy;
|
||||
BOOL inProcessCommandQueue;
|
||||
NSMutableArray *sendQueue;
|
||||
NSMutableArray *receiveQueue;
|
||||
NSMenu *mainMenu;
|
||||
NSMutableArray *popupMenuItems;
|
||||
NSToolbar *toolbar;
|
||||
@@ -43,6 +40,7 @@
|
||||
}
|
||||
|
||||
- (id)initWithBackend:(id)backend pid:(int)processIdentifier;
|
||||
- (unsigned)identifier;
|
||||
- (id)backendProxy;
|
||||
- (int)pid;
|
||||
- (void)setServerName:(NSString *)name;
|
||||
@@ -65,7 +63,9 @@
|
||||
timeout:(NSTimeInterval)timeout;
|
||||
- (void)addVimInput:(NSString *)string;
|
||||
- (NSString *)evaluateVimExpression:(NSString *)expr;
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr errorString:(NSString **)errstr;
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr
|
||||
errorString:(NSString **)errstr;
|
||||
- (void)processInputQueue:(NSArray *)queue;
|
||||
#ifdef MM_ENABLE_PLUGINS
|
||||
- (MMPlugInInstanceMediator *)instanceMediator;
|
||||
#endif
|
||||
|
||||
+236
-286
@@ -10,17 +10,20 @@
|
||||
/*
|
||||
* MMVimController
|
||||
*
|
||||
* Coordinates input/output to/from backend. Each MMBackend communicates
|
||||
* directly with a MMVimController.
|
||||
* Coordinates input/output to/from backend. A MMVimController sends input
|
||||
* directly to a MMBackend, but communication from MMBackend to MMVimController
|
||||
* goes via MMAppController so that it can coordinate all incoming distributed
|
||||
* object messages.
|
||||
*
|
||||
* MMVimController does not deal with visual presentation. Essentially it
|
||||
* should be able to run with no window present.
|
||||
*
|
||||
* Output from the backend is received in processCommandQueue:. Input is sent
|
||||
* to the backend via sendMessage:data: or addVimInput:. The latter allows
|
||||
* execution of arbitrary strings in the Vim process, much like the Vim script
|
||||
* function remote_send() does. The messages that may be passed between
|
||||
* frontend and backend are defined in an enum in MacVim.h.
|
||||
* Output from the backend is received in processInputQueue: (this message is
|
||||
* called from MMAppController so it is not a DO call). Input is sent to the
|
||||
* backend via sendMessage:data: or addVimInput:. The latter allows execution
|
||||
* of arbitrary strings in the Vim process, much like the Vim script function
|
||||
* remote_send() does. The messages that may be passed between frontend and
|
||||
* backend are defined in an enum in MacVim.h.
|
||||
*/
|
||||
|
||||
#import "MMAppController.h"
|
||||
@@ -49,9 +52,7 @@ static NSTimeInterval MMBackendProxyRequestTimeout = 0;
|
||||
// Timeout used for setDialogReturn:.
|
||||
static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
|
||||
|
||||
// Maximum number of items in the receiveQueue. (It is hard to predict what
|
||||
// consequences changing this number will have.)
|
||||
static int MMReceiveQueueCap = 100;
|
||||
static unsigned identifierCounter = 1;
|
||||
|
||||
static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
@@ -65,7 +66,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
|
||||
@interface MMVimController (Private)
|
||||
- (void)doProcessCommandQueue:(NSArray *)queue;
|
||||
- (void)doProcessInputQueue:(NSArray *)queue;
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data;
|
||||
- (void)savePanelDidEnd:(NSSavePanel *)panel code:(int)code
|
||||
context:(void *)context;
|
||||
@@ -95,6 +96,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
- (void)popupMenuWithAttributes:(NSDictionary *)attrs;
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
- (void)scheduleClose;
|
||||
- (void)handleBrowseForFile:(NSDictionary *)attr;
|
||||
- (void)handleShowDialog:(NSDictionary *)attr;
|
||||
@end
|
||||
|
||||
|
||||
@@ -107,11 +110,12 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
|
||||
// TODO: Come up with a better way of creating an identifier.
|
||||
identifier = identifierCounter++;
|
||||
|
||||
windowController =
|
||||
[[MMWindowController alloc] initWithVimController:self];
|
||||
backendProxy = [backend retain];
|
||||
sendQueue = [NSMutableArray new];
|
||||
receiveQueue = [NSMutableArray new];
|
||||
popupMenuItems = [[NSMutableArray alloc] init];
|
||||
toolbarItemDict = [[NSMutableDictionary alloc] init];
|
||||
pid = processIdentifier;
|
||||
@@ -168,8 +172,6 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
[serverName release]; serverName = nil;
|
||||
[backendProxy release]; backendProxy = nil;
|
||||
[sendQueue release]; sendQueue = nil;
|
||||
[receiveQueue release]; receiveQueue = nil;
|
||||
|
||||
[toolbarItemDict release]; toolbarItemDict = nil;
|
||||
[toolbar release]; toolbar = nil;
|
||||
@@ -183,6 +185,11 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (unsigned)identifier
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
- (MMWindowController *)windowController
|
||||
{
|
||||
return windowController;
|
||||
@@ -321,21 +328,11 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
- (void)sendMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
//NSLog(@"sendMessage:%s (isInitialized=%d inProcessCommandQueue=%d)",
|
||||
// MessageStrings[msgid], isInitialized, inProcessCommandQueue);
|
||||
//NSLog(@"sendMessage:%s (isInitialized=%d)",
|
||||
// MessageStrings[msgid], isInitialized);
|
||||
|
||||
if (!isInitialized) return;
|
||||
|
||||
if (inProcessCommandQueue) {
|
||||
//NSLog(@"In process command queue; delaying message send.");
|
||||
[sendQueue addObject:[NSNumber numberWithInt:msgid]];
|
||||
if (data)
|
||||
[sendQueue addObject:data];
|
||||
else
|
||||
[sendQueue addObject:[NSNull null]];
|
||||
return;
|
||||
}
|
||||
|
||||
@try {
|
||||
[backendProxy processInput:msgid data:data];
|
||||
}
|
||||
@@ -353,7 +350,7 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
// ball forever. In almost all circumstances sendMessage:data: should be
|
||||
// used instead.
|
||||
|
||||
if (!isInitialized || inProcessCommandQueue)
|
||||
if (!isInitialized)
|
||||
return NO;
|
||||
|
||||
if (timeout < 0) timeout = 0;
|
||||
@@ -400,7 +397,8 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
return eval;
|
||||
}
|
||||
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr errorString:(NSString **)errstr
|
||||
- (id)evaluateVimExpressionCocoa:(NSString *)expr
|
||||
errorString:(NSString **)errstr
|
||||
{
|
||||
id eval = nil;
|
||||
|
||||
@@ -423,6 +421,9 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
// Remove any delayed calls made on this object.
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||||
|
||||
isInitialized = NO;
|
||||
[toolbar setDelegate:nil];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@@ -431,204 +432,19 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
[windowController cleanup];
|
||||
}
|
||||
|
||||
- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr
|
||||
- (void)processInputQueue:(NSArray *)queue
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode) {
|
||||
// Delay call until run loop is in default mode.
|
||||
[self performSelectorOnMainThread:
|
||||
@selector(showSavePanelWithAttributes:)
|
||||
withObject:attr
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
return;
|
||||
// NOTE: This method must not raise any exceptions (see comment in the
|
||||
// calling method).
|
||||
@try {
|
||||
[self doProcessInputQueue:queue];
|
||||
[windowController processInputQueueDidFinish];
|
||||
}
|
||||
|
||||
NSString *dir = [attr objectForKey:@"dir"];
|
||||
BOOL saving = [[attr objectForKey:@"saving"] boolValue];
|
||||
|
||||
if (!dir) {
|
||||
// 'dir == nil' means: set dir to the pwd of the Vim process, or let
|
||||
// open dialog decide (depending on the below user default).
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd)
|
||||
dir = [vimState objectForKey:@"pwd"];
|
||||
@catch (NSException *ex) {
|
||||
NSLog(@"[%s] Caught exception (pid=%d): %@", _cmd, pid, ex);
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
[[NSSavePanel savePanel] beginSheetForDirectory:dir file:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
} else {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setAccessoryView:openPanelAccessoryView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil types:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode) {
|
||||
// Delay call until run loop is in default mode.
|
||||
[self performSelectorOnMainThread:
|
||||
@selector(presentDialogWithAttributes:)
|
||||
withObject:attr
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray *buttonTitles = [attr objectForKey:@"buttonTitles"];
|
||||
if (!(buttonTitles && [buttonTitles count])) return;
|
||||
|
||||
int style = [[attr objectForKey:@"alertStyle"] intValue];
|
||||
NSString *message = [attr objectForKey:@"messageText"];
|
||||
NSString *text = [attr objectForKey:@"informativeText"];
|
||||
NSString *textFieldString = [attr objectForKey:@"textFieldString"];
|
||||
MMAlert *alert = [[MMAlert alloc] init];
|
||||
|
||||
// NOTE! This has to be done before setting the informative text.
|
||||
if (textFieldString)
|
||||
[alert setTextFieldString:textFieldString];
|
||||
|
||||
[alert setAlertStyle:style];
|
||||
|
||||
if (message) {
|
||||
[alert setMessageText:message];
|
||||
} else {
|
||||
// If no message text is specified 'Alert' is used, which we don't
|
||||
// want, so set an empty string as message text.
|
||||
[alert setMessageText:@""];
|
||||
}
|
||||
|
||||
if (text) {
|
||||
[alert setInformativeText:text];
|
||||
} else if (textFieldString) {
|
||||
// Make sure there is always room for the input text field.
|
||||
[alert setInformativeText:@""];
|
||||
}
|
||||
|
||||
unsigned i, count = [buttonTitles count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *title = [buttonTitles objectAtIndex:i];
|
||||
// NOTE: The title of the button may contain the character '&' to
|
||||
// indicate that the following letter should be the key equivalent
|
||||
// associated with the button. Extract this letter and lowercase it.
|
||||
NSString *keyEquivalent = nil;
|
||||
NSRange hotkeyRange = [title rangeOfString:@"&"];
|
||||
if (NSNotFound != hotkeyRange.location) {
|
||||
if ([title length] > NSMaxRange(hotkeyRange)) {
|
||||
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
|
||||
keyEquivalent = [[title substringWithRange:keyEquivRange]
|
||||
lowercaseString];
|
||||
}
|
||||
|
||||
NSMutableString *string = [NSMutableString stringWithString:title];
|
||||
[string deleteCharactersInRange:hotkeyRange];
|
||||
title = string;
|
||||
}
|
||||
|
||||
[alert addButtonWithTitle:title];
|
||||
|
||||
// Set key equivalent for the button, but only if NSAlert hasn't
|
||||
// already done so. (Check the documentation for
|
||||
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
|
||||
// automatically assigned.)
|
||||
NSButton *btn = [[alert buttons] lastObject];
|
||||
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
|
||||
[btn setKeyEquivalent:keyEquivalent];
|
||||
}
|
||||
}
|
||||
|
||||
[alert beginSheetModalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
|
||||
[alert release];
|
||||
}
|
||||
|
||||
- (oneway void)processCommandQueue:(in bycopy NSArray *)queue
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
if (inProcessCommandQueue) {
|
||||
// NOTE! If a synchronous DO call is made during
|
||||
// doProcessCommandQueue: below it may happen that this method is
|
||||
// called a second time while the synchronous message is waiting for a
|
||||
// reply (could also happen if doProcessCommandQueue: enters a modal
|
||||
// loop, see comment below). Since this method cannot be considered
|
||||
// reentrant, we queue the input and return immediately.
|
||||
//
|
||||
// If doProcessCommandQueue: enters a modal loop (happens e.g. on
|
||||
// ShowPopupMenuMsgID) then the receiveQueue could grow to become
|
||||
// arbitrarily large because DO calls still get processed. To avoid
|
||||
// this we set a cap on the size of the queue and simply clear it if it
|
||||
// becomes too large. (That is messages will be dropped and hence Vim
|
||||
// and MacVim will at least temporarily be out of sync.)
|
||||
if ([receiveQueue count] >= MMReceiveQueueCap)
|
||||
[receiveQueue removeAllObjects];
|
||||
|
||||
[receiveQueue addObject:queue];
|
||||
return;
|
||||
}
|
||||
|
||||
inProcessCommandQueue = YES;
|
||||
[self doProcessCommandQueue:queue];
|
||||
|
||||
int i;
|
||||
for (i = 0; i < [receiveQueue count]; ++i) {
|
||||
// Note that doProcessCommandQueue: may cause the receiveQueue to grow
|
||||
// or get cleared (due to cap being hit). Make sure to retain the item
|
||||
// to process or it may get released from under us.
|
||||
NSArray *q = [[receiveQueue objectAtIndex:i] retain];
|
||||
[self doProcessCommandQueue:q];
|
||||
[q release];
|
||||
}
|
||||
|
||||
// We assume that the remaining calls make no synchronous DO calls. If
|
||||
// that did happen anyway, the command queue could get processed out of
|
||||
// order.
|
||||
|
||||
// See comment below why this is called here and not later.
|
||||
[windowController processCommandQueueDidFinish];
|
||||
|
||||
// NOTE: Ensure that no calls are made after this "if" clause that may call
|
||||
// sendMessage::. If this happens anyway, such messages will be put on the
|
||||
// send queue and then the queue will not be flushed until the next time
|
||||
// this method is called.
|
||||
if ([sendQueue count] > 0) {
|
||||
@try {
|
||||
[backendProxy processInputAndData:sendQueue];
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
// Connection timed out, just ignore this.
|
||||
//NSLog(@"WARNING! Connection timed out in %s", _cmd);
|
||||
}
|
||||
|
||||
[sendQueue removeAllObjects];
|
||||
}
|
||||
|
||||
[receiveQueue removeAllObjects];
|
||||
inProcessCommandQueue = NO;
|
||||
}
|
||||
|
||||
- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar
|
||||
@@ -659,67 +475,60 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
|
||||
@implementation MMVimController (Private)
|
||||
|
||||
- (void)doProcessCommandQueue:(NSArray *)queue
|
||||
- (void)doProcessInputQueue:(NSArray *)queue
|
||||
{
|
||||
NSMutableArray *delayQueue = nil;
|
||||
|
||||
@try {
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in command "
|
||||
"queue. Skipping...", count);
|
||||
return;
|
||||
}
|
||||
|
||||
//NSLog(@"======== %s BEGIN ========", _cmd);
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode && isUnsafeMessage(msgid)) {
|
||||
// NOTE: Because we may be listening to DO messages in "event
|
||||
// tracking mode" we have to take extra care when doing things
|
||||
// like releasing view items (and other Cocoa objects).
|
||||
// Messages that may be potentially "unsafe" are delayed until
|
||||
// the run loop is back to default mode at which time they are
|
||||
// safe to call again.
|
||||
// A problem with this approach is that it is hard to
|
||||
// classify which messages are unsafe. As a rule of thumb, if
|
||||
// a message may release an object used by the Cocoa framework
|
||||
// (e.g. views) then the message should be considered unsafe.
|
||||
// Delaying messages may have undesired side-effects since it
|
||||
// means that messages may not be processed in the order Vim
|
||||
// sent them, so beware.
|
||||
if (!delayQueue)
|
||||
delayQueue = [NSMutableArray array];
|
||||
|
||||
//NSLog(@"Adding unsafe message '%s' to delay queue (mode=%@)",
|
||||
// MessageStrings[msgid],
|
||||
// [[NSRunLoop currentRunLoop] currentMode]);
|
||||
[delayQueue addObject:value];
|
||||
[delayQueue addObject:data];
|
||||
} else {
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
}
|
||||
//NSLog(@"======== %s END ========", _cmd);
|
||||
unsigned i, count = [queue count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: Uneven number of components (%d) in command "
|
||||
"queue. Skipping...", count);
|
||||
return;
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
NSLog(@"Exception caught whilst processing command queue: %@", e);
|
||||
|
||||
//NSLog(@"======== %s BEGIN ========", _cmd);
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
NSData *data = [queue objectAtIndex:i+1];
|
||||
|
||||
int msgid = *((int*)[value bytes]);
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode]
|
||||
isEqual:NSDefaultRunLoopMode];
|
||||
if (!inDefaultMode && isUnsafeMessage(msgid)) {
|
||||
// NOTE: Because we may be listening to DO messages in "event
|
||||
// tracking mode" we have to take extra care when doing things
|
||||
// like releasing view items (and other Cocoa objects).
|
||||
// Messages that may be potentially "unsafe" are delayed until
|
||||
// the run loop is back to default mode at which time they are
|
||||
// safe to call again.
|
||||
// A problem with this approach is that it is hard to
|
||||
// classify which messages are unsafe. As a rule of thumb, if
|
||||
// a message may release an object used by the Cocoa framework
|
||||
// (e.g. views) then the message should be considered unsafe.
|
||||
// Delaying messages may have undesired side-effects since it
|
||||
// means that messages may not be processed in the order Vim
|
||||
// sent them, so beware.
|
||||
if (!delayQueue)
|
||||
delayQueue = [NSMutableArray array];
|
||||
|
||||
//NSLog(@"Adding unsafe message '%s' to delay queue (mode=%@)",
|
||||
// MessageStrings[msgid],
|
||||
// [[NSRunLoop currentRunLoop] currentMode]);
|
||||
[delayQueue addObject:value];
|
||||
[delayQueue addObject:data];
|
||||
} else {
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
}
|
||||
//NSLog(@"======== %s END ========", _cmd);
|
||||
|
||||
if (delayQueue) {
|
||||
//NSLog(@" Flushing delay queue (%d items)", [delayQueue count]/2);
|
||||
[self performSelectorOnMainThread:@selector(processCommandQueue:)
|
||||
withObject:delayQueue
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
[self performSelector:@selector(processInputQueue:)
|
||||
withObject:delayQueue
|
||||
afterDelay:0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,12 +724,10 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
|
||||
|
||||
// The popup menu enters a modal loop so delay this call so that we
|
||||
// don't block inside processCommandQueue:.
|
||||
[self performSelectorOnMainThread:@selector(popupMenuWithAttributes:)
|
||||
withObject:attrs
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
// don't block inside processInputQueue:.
|
||||
[self performSelector:@selector(popupMenuWithAttributes:)
|
||||
withObject:attrs
|
||||
afterDelay:0];
|
||||
} else if (SetMouseShapeMsgID == msgid) {
|
||||
const void *bytes = [data bytes];
|
||||
int shape = *((int*)bytes); bytes += sizeof(int);
|
||||
@@ -981,6 +788,18 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
showWithText:[dict objectForKey:@"text"]
|
||||
flags:[[dict objectForKey:@"flags"] intValue]];
|
||||
}
|
||||
} else if (ActivateKeyScriptID == msgid) {
|
||||
KeyScript(smKeySysScript);
|
||||
} else if (DeactivateKeyScriptID == msgid) {
|
||||
KeyScript(smKeyRoman);
|
||||
} else if (BrowseForFileMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict)
|
||||
[self handleBrowseForFile:dict];
|
||||
} else if (ShowDialogMsgID == msgid) {
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithData:data];
|
||||
if (dict)
|
||||
[self handleShowDialog:dict];
|
||||
// IMPORTANT: When adding a new message, make sure to update
|
||||
// isUnsafeMessage() if necessary!
|
||||
} else {
|
||||
@@ -1428,13 +1247,142 @@ static BOOL isUnsafeMessage(int msgid);
|
||||
// following call ensures that the vim controller is not released until the
|
||||
// run loop is back in the 'default' mode.
|
||||
[[MMAppController sharedInstance]
|
||||
performSelectorOnMainThread:@selector(removeVimController:)
|
||||
withObject:self
|
||||
waitUntilDone:NO
|
||||
modes:[NSArray arrayWithObject:
|
||||
NSDefaultRunLoopMode]];
|
||||
performSelector:@selector(removeVimController:)
|
||||
withObject:self
|
||||
afterDelay:0];
|
||||
}
|
||||
|
||||
// NSSavePanel delegate
|
||||
- (void)panel:(id)sender willExpand:(BOOL)expanding
|
||||
{
|
||||
// Show or hide the "show hidden files" button
|
||||
if (expanding) {
|
||||
[sender setAccessoryView:showHiddenFilesView()];
|
||||
} else {
|
||||
[sender setShowsHiddenFiles:NO];
|
||||
[sender setAccessoryView:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleBrowseForFile:(NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
NSString *dir = [attr objectForKey:@"dir"];
|
||||
BOOL saving = [[attr objectForKey:@"saving"] boolValue];
|
||||
|
||||
if (!dir) {
|
||||
// 'dir == nil' means: set dir to the pwd of the Vim process, or let
|
||||
// open dialog decide (depending on the below user default).
|
||||
BOOL trackPwd = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:MMDialogsTrackPwdKey];
|
||||
if (trackPwd)
|
||||
dir = [vimState objectForKey:@"pwd"];
|
||||
}
|
||||
|
||||
if (saving) {
|
||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||
|
||||
// The delegate will be notified when the panel is expanded at which
|
||||
// time we may hide/show the "show hidden files" button (this button is
|
||||
// always visible for the open panel since it is always expanded).
|
||||
[panel setDelegate:self];
|
||||
if ([panel isExpanded])
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
} else {
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setAccessoryView:showHiddenFilesView()];
|
||||
|
||||
[panel beginSheetForDirectory:dir file:nil types:nil
|
||||
modalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(savePanelDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleShowDialog:(NSDictionary *)attr
|
||||
{
|
||||
if (!isInitialized) return;
|
||||
|
||||
NSArray *buttonTitles = [attr objectForKey:@"buttonTitles"];
|
||||
if (!(buttonTitles && [buttonTitles count])) return;
|
||||
|
||||
int style = [[attr objectForKey:@"alertStyle"] intValue];
|
||||
NSString *message = [attr objectForKey:@"messageText"];
|
||||
NSString *text = [attr objectForKey:@"informativeText"];
|
||||
NSString *textFieldString = [attr objectForKey:@"textFieldString"];
|
||||
MMAlert *alert = [[MMAlert alloc] init];
|
||||
|
||||
// NOTE! This has to be done before setting the informative text.
|
||||
if (textFieldString)
|
||||
[alert setTextFieldString:textFieldString];
|
||||
|
||||
[alert setAlertStyle:style];
|
||||
|
||||
if (message) {
|
||||
[alert setMessageText:message];
|
||||
} else {
|
||||
// If no message text is specified 'Alert' is used, which we don't
|
||||
// want, so set an empty string as message text.
|
||||
[alert setMessageText:@""];
|
||||
}
|
||||
|
||||
if (text) {
|
||||
[alert setInformativeText:text];
|
||||
} else if (textFieldString) {
|
||||
// Make sure there is always room for the input text field.
|
||||
[alert setInformativeText:@""];
|
||||
}
|
||||
|
||||
unsigned i, count = [buttonTitles count];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSString *title = [buttonTitles objectAtIndex:i];
|
||||
// NOTE: The title of the button may contain the character '&' to
|
||||
// indicate that the following letter should be the key equivalent
|
||||
// associated with the button. Extract this letter and lowercase it.
|
||||
NSString *keyEquivalent = nil;
|
||||
NSRange hotkeyRange = [title rangeOfString:@"&"];
|
||||
if (NSNotFound != hotkeyRange.location) {
|
||||
if ([title length] > NSMaxRange(hotkeyRange)) {
|
||||
NSRange keyEquivRange = NSMakeRange(hotkeyRange.location+1, 1);
|
||||
keyEquivalent = [[title substringWithRange:keyEquivRange]
|
||||
lowercaseString];
|
||||
}
|
||||
|
||||
NSMutableString *string = [NSMutableString stringWithString:title];
|
||||
[string deleteCharactersInRange:hotkeyRange];
|
||||
title = string;
|
||||
}
|
||||
|
||||
[alert addButtonWithTitle:title];
|
||||
|
||||
// Set key equivalent for the button, but only if NSAlert hasn't
|
||||
// already done so. (Check the documentation for
|
||||
// - [NSAlert addButtonWithTitle:] to see what key equivalents are
|
||||
// automatically assigned.)
|
||||
NSButton *btn = [[alert buttons] lastObject];
|
||||
if ([[btn keyEquivalent] length] == 0 && keyEquivalent) {
|
||||
[btn setKeyEquivalent:keyEquivalent];
|
||||
}
|
||||
}
|
||||
|
||||
[alert beginSheetModalForWindow:[windowController window]
|
||||
modalDelegate:self
|
||||
didEndSelector:@selector(alertDidEnd:code:context:)
|
||||
contextInfo:NULL];
|
||||
|
||||
[alert release];
|
||||
}
|
||||
|
||||
|
||||
@end // MMVimController (Private)
|
||||
|
||||
|
||||
@@ -1525,6 +1473,8 @@ isUnsafeMessage(int msgid)
|
||||
EnterFullscreenMsgID, // Modifies delegate of window controller
|
||||
LeaveFullscreenMsgID, // Modifies delegate of window controller
|
||||
CloseWindowMsgID, // See note below
|
||||
BrowseForFileMsgID, // Enters modal loop
|
||||
ShowDialogMsgID, // Enters modal loop
|
||||
};
|
||||
|
||||
// NOTE about CloseWindowMsgID: If this arrives at the same time as say
|
||||
|
||||
+11
-1
@@ -142,8 +142,18 @@
|
||||
|
||||
- (IBAction)zoom:(id)sender
|
||||
{
|
||||
NSScreen *screen = [self screen];
|
||||
if (!screen) {
|
||||
NSLog(@"[%s] WINDOW NOT ON SCREEN, zoom to main screen", _cmd);
|
||||
screen = [NSScreen mainScreen];
|
||||
if (!screen) {
|
||||
NSLog(@"[%s] NO MAIN SCREEN, abort zoom", _cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSRect frame = [self frame];
|
||||
NSRect defaultFrame = [[self screen] visibleFrame];
|
||||
NSRect defaultFrame = [screen visibleFrame];
|
||||
defaultFrame = [[self delegate] windowWillUseStandardFrame:self
|
||||
defaultFrame:defaultFrame];
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
MMVimView *vimView;
|
||||
BOOL setupDone;
|
||||
BOOL shouldResizeVimView;
|
||||
int updateToolbarFlag;
|
||||
BOOL keepOnScreen;
|
||||
BOOL fullscreenEnabled;
|
||||
NSString *windowAutosaveKey;
|
||||
@@ -54,7 +55,7 @@
|
||||
- (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore;
|
||||
- (void)setFont:(NSFont *)font;
|
||||
- (void)setWideFont:(NSFont *)font;
|
||||
- (void)processCommandQueueDidFinish;
|
||||
- (void)processInputQueueDidFinish;
|
||||
- (void)showTabBar:(BOOL)on;
|
||||
- (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode;
|
||||
- (void)setMouseShape:(int)shape;
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
- (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
|
||||
- (void)hideTablineSeparator:(BOOL)hide;
|
||||
- (void)doFindNext:(BOOL)next;
|
||||
- (void)updateToolbar;
|
||||
@end
|
||||
|
||||
|
||||
@@ -307,7 +308,7 @@
|
||||
// NOTE: The only place where the (rows,columns) of the vim view are
|
||||
// modified is here and when entering/leaving full-screen. Setting these
|
||||
// values have no immediate effect, the actual resizing of the view is done
|
||||
// in processCommandQueueDidFinish.
|
||||
// in processInputQueueDidFinish.
|
||||
//
|
||||
// The 'live' flag indicates that this resize originated from a live
|
||||
// resize; it may very well happen that the view is no longer in live
|
||||
@@ -418,16 +419,16 @@
|
||||
[[vimView textView] setWideFont:font];
|
||||
}
|
||||
|
||||
- (void)processCommandQueueDidFinish
|
||||
- (void)processInputQueueDidFinish
|
||||
{
|
||||
// IMPORTANT! No synchronous DO calls are allowed in this method. They
|
||||
// may cause the command queue to get processed out of order.
|
||||
|
||||
// NOTE: Resizing is delayed until after all commands have been processed
|
||||
// since it often happens that more than one command will cause a resize.
|
||||
// If we were to immediately resize then the vim view size would jitter
|
||||
// (e.g. hiding/showing scrollbars often happens several time in one
|
||||
// update).
|
||||
// Also delay toggling the toolbar until after scrollbars otherwise
|
||||
// problems arise when showing toolbar and scrollbar at the same time, i.e.
|
||||
// on "set go+=rT".
|
||||
|
||||
if (shouldResizeVimView) {
|
||||
shouldResizeVimView = NO;
|
||||
@@ -448,6 +449,9 @@
|
||||
|
||||
keepOnScreen = NO;
|
||||
}
|
||||
|
||||
if (updateToolbarFlag != 0)
|
||||
[self updateToolbar];
|
||||
}
|
||||
|
||||
- (void)showTabBar:(BOOL)on
|
||||
@@ -481,21 +485,17 @@
|
||||
|
||||
[toolbar setSizeMode:size];
|
||||
[toolbar setDisplayMode:mode];
|
||||
[toolbar setVisible:on];
|
||||
|
||||
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
|
||||
if (!on) {
|
||||
[self hideTablineSeparator:YES];
|
||||
} else {
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
} else {
|
||||
// Textured windows don't have a line below there title bar, so we
|
||||
// need the separator in this case as well. In fact, the only case
|
||||
// where we don't need the separator is when the tab bar control
|
||||
// is visible (because it brings its own separator).
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
// Positive flag shows toolbar, negative hides it.
|
||||
updateToolbarFlag = on ? 1 : -1;
|
||||
|
||||
// NOTE: If the window is not visible we must toggle the toolbar
|
||||
// immediately, otherwise "set go-=T" in .gvimrc will lead to the toolbar
|
||||
// showing its hide animation every time a new window is opened. (See
|
||||
// processInputQueueDidFinish for the reason why we need to delay toggling
|
||||
// the toolbar when the window is visible.)
|
||||
if (![decoratedWindow isVisible])
|
||||
[self updateToolbar];
|
||||
}
|
||||
|
||||
- (void)setMouseShape:(int)shape
|
||||
@@ -757,7 +757,19 @@
|
||||
|
||||
- (void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
if (setupDone && windowAutosaveKey) {
|
||||
if (!setupDone)
|
||||
return;
|
||||
|
||||
if (fullscreenEnabled) {
|
||||
// HACK! The full-screen is not supposed to be able to be moved. If we
|
||||
// do get here while in full-screen something unexpected happened (e.g.
|
||||
// the full-screen window was on an external display that got
|
||||
// unplugged) and we handle this situation by leaving full-screen.
|
||||
[self leaveFullscreen];
|
||||
return;
|
||||
}
|
||||
|
||||
if (windowAutosaveKey) {
|
||||
NSRect frame = [decoratedWindow frame];
|
||||
NSPoint topLeft = { frame.origin.x, NSMaxY(frame) };
|
||||
NSString *topLeftString = NSStringFromPoint(topLeft);
|
||||
@@ -774,7 +786,11 @@
|
||||
// size in updateResizeConstraints since the screen's visible frame may
|
||||
// change at any time (dock could move, resolution could change, window
|
||||
// could be moved to another screen, ...).
|
||||
if (![win screen])
|
||||
return proposedFrameSize;
|
||||
|
||||
// NOTE: Not called in full-screen mode so use "visibleFrame" instead of
|
||||
// "frame".
|
||||
NSRect maxFrame = [self constrainFrame:[[win screen] visibleFrame]];
|
||||
|
||||
if (proposedFrameSize.width > maxFrame.size.width)
|
||||
@@ -891,24 +907,28 @@
|
||||
|
||||
NSRect newFrame = [decoratedWindow frameRectForContentRect:contentRect];
|
||||
|
||||
// Ensure that the window fits inside the visible part of the screen.
|
||||
NSRect maxFrame = [[decoratedWindow screen] visibleFrame];
|
||||
maxFrame = [self constrainFrame:maxFrame];
|
||||
if ([decoratedWindow screen]) {
|
||||
// Ensure that the window fits inside the visible part of the screen.
|
||||
// NOTE: Not called in full-screen mode so use "visibleFrame' instead
|
||||
// of "frame".
|
||||
NSRect maxFrame = [[decoratedWindow screen] visibleFrame];
|
||||
maxFrame = [self constrainFrame:maxFrame];
|
||||
|
||||
if (newFrame.size.width > maxFrame.size.width) {
|
||||
newFrame.size.width = maxFrame.size.width;
|
||||
newFrame.origin.x = maxFrame.origin.x;
|
||||
}
|
||||
if (newFrame.size.height > maxFrame.size.height) {
|
||||
newFrame.size.height = maxFrame.size.height;
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
}
|
||||
|
||||
if (onScreen) {
|
||||
if (newFrame.origin.y < maxFrame.origin.y)
|
||||
if (newFrame.size.width > maxFrame.size.width) {
|
||||
newFrame.size.width = maxFrame.size.width;
|
||||
newFrame.origin.x = maxFrame.origin.x;
|
||||
}
|
||||
if (newFrame.size.height > maxFrame.size.height) {
|
||||
newFrame.size.height = maxFrame.size.height;
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
if (NSMaxX(newFrame) > NSMaxX(maxFrame))
|
||||
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
|
||||
}
|
||||
|
||||
if (onScreen) {
|
||||
if (newFrame.origin.y < maxFrame.origin.y)
|
||||
newFrame.origin.y = maxFrame.origin.y;
|
||||
if (NSMaxX(newFrame) > NSMaxX(maxFrame))
|
||||
newFrame.origin.x = NSMaxX(maxFrame) - newFrame.size.width;
|
||||
}
|
||||
}
|
||||
|
||||
[decoratedWindow setFrame:newFrame display:YES];
|
||||
@@ -917,7 +937,15 @@
|
||||
- (NSSize)constrainContentSizeToScreenSize:(NSSize)contentSize
|
||||
{
|
||||
NSWindow *win = [self window];
|
||||
NSRect rect = [win contentRectForFrameRect:[[win screen] visibleFrame]];
|
||||
if (![win screen])
|
||||
return contentSize;
|
||||
|
||||
// NOTE: This may be called in both windowed and full-screen mode. The
|
||||
// "visibleFrame" method does not overlap menu and dock so should not be
|
||||
// used in full-screen.
|
||||
NSRect screenRect = fullscreenEnabled ? [[win screen] frame]
|
||||
: [[win screen] visibleFrame];
|
||||
NSRect rect = [win contentRectForFrameRect:screenRect];
|
||||
|
||||
if (contentSize.height > rect.size.height)
|
||||
contentSize.height = rect.size.height;
|
||||
@@ -1025,4 +1053,30 @@
|
||||
[vimController addVimInput:input];
|
||||
}
|
||||
|
||||
- (void)updateToolbar
|
||||
{
|
||||
NSToolbar *toolbar = [decoratedWindow toolbar];
|
||||
if (nil == toolbar || 0 == updateToolbarFlag) return;
|
||||
|
||||
// Positive flag shows toolbar, negative hides it.
|
||||
BOOL on = updateToolbarFlag > 0 ? YES : NO;
|
||||
[toolbar setVisible:on];
|
||||
|
||||
if (([decoratedWindow styleMask] & NSTexturedBackgroundWindowMask) == 0) {
|
||||
if (!on) {
|
||||
[self hideTablineSeparator:YES];
|
||||
} else {
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
} else {
|
||||
// Textured windows don't have a line below there title bar, so we
|
||||
// need the separator in this case as well. In fact, the only case
|
||||
// where we don't need the separator is when the tab bar control
|
||||
// is visible (because it brings its own separator).
|
||||
[self hideTablineSeparator:![[vimView tabBarControl] isHidden]];
|
||||
}
|
||||
|
||||
updateToolbarFlag = 0;
|
||||
}
|
||||
|
||||
@end // MMWindowController (Private)
|
||||
|
||||
+24
-20
@@ -33,7 +33,6 @@
|
||||
//
|
||||
@protocol MMBackendProtocol
|
||||
- (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data;
|
||||
- (oneway void)processInputAndData:(in bycopy NSArray *)messages;
|
||||
- (oneway void)setDialogReturn:(in bycopy id)obj;
|
||||
- (NSString *)evaluateExpression:(in bycopy NSString *)expr;
|
||||
- (id)evaluateExpressionCocoa:(in bycopy NSString *)expr
|
||||
@@ -42,30 +41,23 @@
|
||||
- (oneway void)acknowledgeConnection;
|
||||
@end
|
||||
|
||||
//
|
||||
// This is the protocol MMVimController implements.
|
||||
//
|
||||
// Be very careful if you want to add methods to this protocol. Since DO
|
||||
// messages may arrive while Cocoa is in the middle of processing some other
|
||||
// message be sure to consider reentrancy issues. Look at processCommandQueue:
|
||||
// to see an example of how to deal with this.
|
||||
//
|
||||
@protocol MMFrontendProtocol
|
||||
- (oneway void)processCommandQueue:(in bycopy NSArray *)queue;
|
||||
- (oneway void)showSavePanelWithAttributes:(in bycopy NSDictionary *)attr;
|
||||
- (oneway void)presentDialogWithAttributes:(in bycopy NSDictionary *)attr;
|
||||
@end
|
||||
|
||||
|
||||
//
|
||||
// This is the protocol MMAppController implements.
|
||||
//
|
||||
// It handles connections between MacVim and Vim.
|
||||
// It handles connections between MacVim and Vim and communication from Vim to
|
||||
// MacVim.
|
||||
//
|
||||
// Do not add methods to this interface without a _very_ good reason (if
|
||||
// possible, instead add a new message to the *MsgID enum below and pass it via
|
||||
// processInput:forIdentifier). Methods should not modify the state directly
|
||||
// but should instead delay any potential modifications (see
|
||||
// connectBackend:pid: and processInput:forIdentifier:).
|
||||
//
|
||||
@protocol MMAppProtocol
|
||||
- (byref id <MMFrontendProtocol>)
|
||||
connectBackend:(byref in id <MMBackendProtocol>)backend
|
||||
pid:(int)pid;
|
||||
- (unsigned)connectBackend:(byref in id <MMBackendProtocol>)proxy pid:(int)pid;
|
||||
- (oneway void)processInput:(in bycopy NSArray *)queue
|
||||
forIdentifier:(unsigned)identifier;
|
||||
- (NSArray *)serverList;
|
||||
@end
|
||||
|
||||
@@ -109,7 +101,7 @@
|
||||
extern char *MessageStrings[];
|
||||
|
||||
enum {
|
||||
OpenWindowMsgID = 1,
|
||||
OpenWindowMsgID = 1, // NOTE: FIRST IN ENUM MUST BE 1
|
||||
InsertTextMsgID,
|
||||
KeyDownMsgID,
|
||||
CmdKeyMsgID,
|
||||
@@ -177,6 +169,11 @@ enum {
|
||||
SetFullscreenColorMsgID,
|
||||
ShowFindReplaceDialogMsgID,
|
||||
FindReplaceMsgID,
|
||||
ActivateKeyScriptID,
|
||||
DeactivateKeyScriptID,
|
||||
BrowseForFileMsgID,
|
||||
ShowDialogMsgID,
|
||||
LastMsgID // NOTE: MUST BE LAST MESSAGE IN ENUM!
|
||||
};
|
||||
|
||||
|
||||
@@ -215,6 +212,13 @@ enum {
|
||||
MMTabInfoCount
|
||||
};
|
||||
|
||||
|
||||
// Create a string holding the labels of all messages in message queue for
|
||||
// debugging purposes (condense some messages since there may typically be LOTS
|
||||
// of them on a queue).
|
||||
NSString *debugStringForMessageQueue(NSArray *queue);
|
||||
|
||||
|
||||
// Argument used to stop MacVim from opening an empty window on startup
|
||||
// (techincally this is a user default but should not be used as such).
|
||||
extern NSString *MMNoWindowKey;
|
||||
|
||||
@@ -84,6 +84,11 @@ char *MessageStrings[] =
|
||||
"SetFullscreenColorMsgID",
|
||||
"ShowFindReplaceDialogMsgID",
|
||||
"FindReplaceMsgID",
|
||||
"ActivateKeyScriptID",
|
||||
"DeactivateKeyScriptID",
|
||||
"BrowseForFileMsgID",
|
||||
"ShowDialogMsgID",
|
||||
"END OF MESSAGE IDs" // NOTE: Must be last!
|
||||
};
|
||||
|
||||
|
||||
@@ -98,6 +103,34 @@ NSString *VimPBoardType = @"VimPBoardType";
|
||||
|
||||
|
||||
|
||||
// Create a string holding the labels of all messages in message queue for
|
||||
// debugging purposes (condense some messages since there may typically be LOTS
|
||||
// of them on a queue).
|
||||
NSString *
|
||||
debugStringForMessageQueue(NSArray *queue)
|
||||
{
|
||||
NSMutableString *s = [NSMutableString new];
|
||||
unsigned i, count = [queue count];
|
||||
int item = 0, menu = 0, enable = 0;
|
||||
for (i = 0; i < count; i += 2) {
|
||||
NSData *value = [queue objectAtIndex:i];
|
||||
int msgid = *((int*)[value bytes]);
|
||||
if (msgid < 1 || msgid >= LastMsgID)
|
||||
continue;
|
||||
if (msgid == AddMenuItemMsgID) ++item;
|
||||
else if (msgid == AddMenuMsgID) ++menu;
|
||||
else if (msgid == EnableMenuItemMsgID) ++enable;
|
||||
else [s appendFormat:@"%s ", MessageStrings[msgid]];
|
||||
}
|
||||
if (item > 0) [s appendFormat:@"AddMenuItemMsgID(%d) ", item];
|
||||
if (menu > 0) [s appendFormat:@"AddMenuMsgID(%d) ", menu];
|
||||
if (enable > 0) [s appendFormat:@"EnableMenuItemMsgID(%d) ", enable];
|
||||
|
||||
return [s autorelease];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@implementation NSString (MMExtras)
|
||||
|
||||
|
||||
@@ -737,7 +737,7 @@
|
||||
i386,
|
||||
);
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
CURRENT_PROJECT_VERSION = 45;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -778,7 +778,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
CURRENT_PROJECT_VERSION = 45;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
@@ -810,7 +810,7 @@
|
||||
buildSettings = {
|
||||
ARCHS = "$(NATIVE_ARCH)";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 43;
|
||||
CURRENT_PROJECT_VERSION = 45;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
|
||||
|
||||
@@ -95,7 +95,7 @@ enum {
|
||||
@end
|
||||
|
||||
|
||||
@interface NSOpenPanel (MMExtras)
|
||||
@interface NSSavePanel (MMExtras)
|
||||
- (void)hiddenFilesButtonToggled:(id)sender;
|
||||
- (void)setShowsHiddenFiles:(BOOL)show;
|
||||
@end
|
||||
@@ -130,7 +130,8 @@ enum {
|
||||
|
||||
|
||||
|
||||
// Create a view to be used as accessory for open panel. This function assumes
|
||||
// ownership of the view so do not release it.
|
||||
NSView *openPanelAccessoryView();
|
||||
// Create a view with a "show hidden files" button to be used as accessory for
|
||||
// open/save panels. This function assumes ownership of the view so do not
|
||||
// release it.
|
||||
NSView *showHiddenFilesView();
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
|
||||
|
||||
|
||||
@implementation NSOpenPanel (MMExtras)
|
||||
@implementation NSSavePanel (MMExtras)
|
||||
|
||||
- (void)hiddenFilesButtonToggled:(id)sender
|
||||
{
|
||||
@@ -122,7 +122,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
[invocation invoke];
|
||||
}
|
||||
|
||||
@end // NSOpenPanel (MMExtras)
|
||||
@end // NSSavePanel (MMExtras)
|
||||
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ NSString *MMLoadDefaultFontKey = @"MMLoadDefaultFont";
|
||||
|
||||
|
||||
NSView *
|
||||
openPanelAccessoryView()
|
||||
showHiddenFilesView()
|
||||
{
|
||||
// Return a new button object for each NSOpenPanel -- several of them
|
||||
// could be displayed at once.
|
||||
@@ -272,13 +272,13 @@ openPanelAccessoryView()
|
||||
NSButton *button = [[[NSButton alloc]
|
||||
initWithFrame:NSMakeRect(0, 0, 140, 18)] autorelease];
|
||||
[button setTitle:
|
||||
NSLocalizedString(@"Show Hidden Files", @"Open File Dialog")];
|
||||
NSLocalizedString(@"Show Hidden Files", @"Show Hidden Files Checkbox")];
|
||||
[button setButtonType:NSSwitchButton];
|
||||
|
||||
[button setTarget:nil];
|
||||
[button setAction:@selector(hiddenFilesButtonToggled:)];
|
||||
|
||||
// use the regular control size (checkbox is a bit smaller without this)
|
||||
// Use the regular control size (checkbox is a bit smaller without this)
|
||||
NSControlSize buttonSize = NSRegularControlSize;
|
||||
float fontSize = [NSFont systemFontSizeForControlSize:buttonSize];
|
||||
NSCell *theCell = [button cell];
|
||||
|
||||
+17
-18
@@ -20,16 +20,16 @@ is very easy to pick up if you know C and some object oriented programming.)
|
||||
Each editor window in MacVim runs its own Vim process (but there is always
|
||||
only one MacVim process). Communication between MacVim and a Vim process is
|
||||
done using Distributed Objects (DO). Each Vim process is represented by a
|
||||
backend object (MMBackend) and it communicates with a frontend object in the
|
||||
Vim process (MMVimController). The interface between the backend and frontend
|
||||
backend object (MMBackend) and it communicates with the frontend object in the
|
||||
Vim process (MMAppController). The interface between the backend and frontend
|
||||
is defined in MacVim.h.
|
||||
|
||||
The frontend sends input to the backend by calling
|
||||
-[MMBackend processInput:data:]. The backend queues output on a command queue
|
||||
and sends it to the frontend at opportune times by calling
|
||||
-[MMVimController processCommandQueue:]. These are both asynchronous calls so
|
||||
MacVim can keep drawing and receiving input while Vim is working away, thus
|
||||
always keeping the user interface responsive.
|
||||
-[MMAppController processInput:forIdentifier:]. These are both asynchronous
|
||||
calls so MacVim can keep drawing and receiving input while Vim is working away,
|
||||
thus always keeping the user interface responsive.
|
||||
|
||||
The state of each editor window is kept entirely in the Vim process. MacVim
|
||||
should remain "ignorant" in the sense that it knows nothing of the actual
|
||||
@@ -46,7 +46,7 @@ to MacVim inside -[MMBackend queueVimStateMessage].
|
||||
|
||||
Vim:
|
||||
|
||||
Hooks from within Vim are implmented in gui_macvim.m, the name of such
|
||||
Hooks from within Vim are implemented in gui_macvim.m, the name of such
|
||||
functions usually start with "gui_mch_" and they should simply put a message
|
||||
on the output queue, by calling queueMessage:properties: on the singleton
|
||||
MMBackend object [MMBackend sharedInstance] (see e.g. gui_mch_destroy_menu()).
|
||||
@@ -63,7 +63,7 @@ for some reason fails to update the run loop then incoming DO calls will not
|
||||
be processed and for this reason it is best to avoid making synchronous DO
|
||||
calls from MacVim. (If synchronous calls must be made then it is important to
|
||||
set proper timeouts so that MacVim doesn't "hang", see
|
||||
-[MMVimConroller sendMessageNow:::] to see how this can be done.)
|
||||
-[MMVimController sendMessageNow:::] to see how this can be done.)
|
||||
|
||||
|
||||
MacVim:
|
||||
@@ -71,16 +71,15 @@ MacVim:
|
||||
The main nib of MacVim.app is MainMenu.nib which contains the default menu and
|
||||
an instance of MMAppController, which is connected as the delegate of
|
||||
NSApplication. That means, when MacVim starts it will load this nib file and
|
||||
automatically create an instance of the MMAppController singleton.
|
||||
automatically create an instance of the MMAppController singleton. All
|
||||
incoming distributed object calls go via MMAppController.
|
||||
|
||||
A new editor window is opened by calling
|
||||
-[MMAppController launchVimProcessWithArguments:]. This functions starts a
|
||||
new Vim process (by executing the Vim binary). The Vim process lets MacVim
|
||||
know when it has launched by calling -[MMAppController connectBackend:pid:]
|
||||
and MacVim responds to this message by creating a new frontend object
|
||||
(MMVimController) and returns a proxy to this object back to the Vim process.
|
||||
From this point onward the Vim process communicates directly with the
|
||||
MMVimController.
|
||||
and MacVim responds to this message by creating a new vim controller and
|
||||
returns an identifier for this object back to the Vim process.
|
||||
|
||||
The MMVimController represents the frontend of a Vim process inside MacVim.
|
||||
It coordinates all communication with the Vim process and delegates output
|
||||
@@ -88,7 +87,7 @@ that affects visual presentation to a MMWindowController object. Read the
|
||||
Cocoa documentation on the responsibilities of a window controller.
|
||||
|
||||
Input (keyboard & mouse) handling and drawing is handled by a helper object
|
||||
(MMTextViewHelper) to the current text view (MMTextView, MMAtsuiTextView).
|
||||
(MMTextViewHelper) to the current text view (MMTextView, MMAtsuiTextView, ...).
|
||||
|
||||
|
||||
Distributed Object dangers:
|
||||
@@ -106,7 +105,7 @@ message may arrive.
|
||||
the menu flashes briefly. During this "flash" a modal loop is entered.
|
||||
|
||||
Item 1 can cause a problem if MacVim sends a synchronous message and before a
|
||||
reply reacheds MacVim another message is received. From the source code it
|
||||
reply reaches MacVim another message is received. From the source code it
|
||||
looks like the synchronous message blocks but in fact the other message is
|
||||
executed during this "block". If the other message changes state radically
|
||||
something may go wrong after the synchronous DO message returns.
|
||||
@@ -117,8 +116,8 @@ which may be even more puzzling.
|
||||
One way to alleviate these problems is to ensure a DO message isn't entered
|
||||
twice by setting a boolean at the beginning of the message and clearing it
|
||||
afterwards. If the boolean is already set when entering the call must somehow
|
||||
be delayed. See -[MMVimController processCommandQueue:] for a concrete
|
||||
example.
|
||||
be delayed. See processInput:forIdentifier: and processInputQueues: inside
|
||||
MMAppController for a concrete example.
|
||||
|
||||
Another danger is that we must take care when releasing objects that Cocoa may
|
||||
be using. See -[MMVimController connectionDidDie:] how MacVim releases
|
||||
@@ -133,7 +132,7 @@ what they contain:
|
||||
MMAppController.* Everything related to running the application
|
||||
MMBackend.* Object representing a Vim process in backend
|
||||
MMTextView.* Handles input and drawing
|
||||
MMVimController.* Object representing a Vim Process in frontend
|
||||
MMVimController.* Object representing a Vim process in frontend
|
||||
MMVimView.* Cocoa view object
|
||||
MMWindowController.* Coordinates visual presentation
|
||||
MacVim.* Code shared between MacVim and Vim
|
||||
@@ -161,4 +160,4 @@ The application bundle can be found inside "src/MacVim/build/Release".
|
||||
|
||||
|
||||
Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
November 22, 2008
|
||||
April 5, 2009
|
||||
|
||||
@@ -1265,8 +1265,10 @@ im_set_active(int active)
|
||||
// respectively.
|
||||
SInt32 systemScript = GetScriptManagerVariable(smSysScript);
|
||||
|
||||
if (!p_imdisable && smRoman != systemScript)
|
||||
KeyScript(active ? smKeySysScript : smKeyRoman);
|
||||
if (!p_imdisable && smRoman != systemScript) {
|
||||
int msgid = active ? ActivateKeyScriptID : DeactivateKeyScriptID;
|
||||
[[MMBackend sharedInstance] queueMessage:msgid properties:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-1
@@ -1,7 +1,7 @@
|
||||
" System gvimrc file for MacVim
|
||||
"
|
||||
" Maintainer: Bjorn Winckler <bjorn.winckler@gmail.com>
|
||||
" Last Change: Sun Oct 04 2008
|
||||
" Last Change: Sun Mar 15 2009
|
||||
"
|
||||
" This is a work in progress. If you feel so inclined, please help me improve
|
||||
" this file.
|
||||
@@ -26,6 +26,9 @@ if !exists("colors_name")
|
||||
colorscheme macvim
|
||||
endif
|
||||
|
||||
" To make tabs more readable, the label only contains the tail of the file
|
||||
" name and the buffer modified flag.
|
||||
set guitablabel=%M%t
|
||||
|
||||
|
||||
" Send print jobs to Preview.app. This does not delete the temporary ps file
|
||||
|
||||
@@ -7,7 +7,7 @@ $(OUTDIR)/MacVim-generic.icns: make_icons.py vim-noshadow-512.png loadfont.so En
|
||||
/usr/bin/python make_icons.py $(OUTDIR)
|
||||
|
||||
loadfont.so: loadfont.c
|
||||
python setup.py install --install-lib .
|
||||
/usr/bin/python setup.py install --install-lib .
|
||||
|
||||
Envy\ Code\ R\ Bold.ttf: EnvyCodeR.zip
|
||||
unzip -jo EnvyCodeR.zip
|
||||
|
||||
@@ -40,6 +40,58 @@
|
||||
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
|
||||
-->
|
||||
|
||||
<item>
|
||||
<title>Snapshot 45 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 45 released</h1>
|
||||
|
||||
<p> Changes since snapshot 44:
|
||||
<ul>
|
||||
<li> The toolbar is not hidden by default again (if you prefer having the toolbar hidden, then add the line "set go-=T" to your ~/.gvimrc file) </li>
|
||||
<li> The ATSUI renderer honors the 'guisp' highlighting color </li>
|
||||
<li> Fix the forever bouncing Dock icon bug (Kazuki Sakamoto) </li>
|
||||
<li> Add the "Show Hidden Files" checkbox button to the Save dialog whenever the file browser is expanded </li>
|
||||
<li> Frontend refactoring </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Mon, 13 Apr 2009 19:19 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-45.tbz"
|
||||
length="8135831"
|
||||
sparkle:version="45"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 44 released</title>
|
||||
<description><![CDATA[
|
||||
<h1>MacVim snapshot 44 released</h1>
|
||||
|
||||
<p> Changes since snapshot 43:
|
||||
<ul>
|
||||
<li> The color table had many erroneous entries which have been corrected (Zvezdan Petkovic) </li>
|
||||
<li> Ctrl+tab works again </li>
|
||||
<li> Tab labels only show file tail by default to make them more legible (reset to default by adding "set guitablabel&" to .gvimrc) </li>
|
||||
<li> The number of columns does not change on ":set go+=rT" </li>
|
||||
<li> Fixed problems with view not maximizing when entering full-screen and the Dock was visible </li>
|
||||
<li> Fix various problems related to having windows on a screen that got unplugged (fixes Issue 162) </li>
|
||||
<li> Latest source code version and runtime files (e.g. the Python syntax file is fixed, fixes Issue 160) </li>
|
||||
</ul>
|
||||
</p>
|
||||
]]></description>
|
||||
<pubDate>Sun, 29 Mar 2009 16:56 CET</pubDate>
|
||||
<enclosure type="application/octet-stream"
|
||||
url="http://newmacvim.muskokamug.org/mirror/files/MacVim-snapshot-44.tbz"
|
||||
length="8139075"
|
||||
sparkle:version="44"
|
||||
sparkle:shortVersionString="7.2"
|
||||
/>
|
||||
</item>
|
||||
|
||||
|
||||
<item>
|
||||
<title>Snapshot 43 released</title>
|
||||
<description><![CDATA[
|
||||
|
||||
Vendored
+61
@@ -11565,6 +11565,67 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking for working volatile" >&5
|
||||
$as_echo_n "checking for working volatile... " >&6; }
|
||||
if test "${ac_cv_c_volatile+set}" = set; then
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
volatile int x;
|
||||
int * volatile y = (int *) 0;
|
||||
return !x && !y;
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
|
||||
$as_echo "$ac_try_echo") >&5
|
||||
(eval "$ac_compile") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
$as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; then
|
||||
ac_cv_c_volatile=yes
|
||||
else
|
||||
$as_echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
ac_cv_c_volatile=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5
|
||||
$as_echo "$ac_cv_c_volatile" >&6; }
|
||||
if test $ac_cv_c_volatile = no; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define volatile /**/
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:$LINENO: checking for mode_t" >&5
|
||||
$as_echo_n "checking for mode_t... " >&6; }
|
||||
if test "${ac_cv_type_mode_t+set}" = set; then
|
||||
|
||||
+2
-1
@@ -5108,7 +5108,8 @@ buf_spname(buf)
|
||||
*/
|
||||
FOR_ALL_TAB_WINDOWS(tp, win)
|
||||
if (win->w_buffer == buf)
|
||||
break;
|
||||
goto win_found;
|
||||
win_found:
|
||||
if (win != NULL && win->w_llist_ref != NULL)
|
||||
return _("[Location List]");
|
||||
else
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef volatile
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
|
||||
@@ -2184,6 +2184,7 @@ fi
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_PROG_GCC_TRADITIONAL
|
||||
AC_C_CONST
|
||||
AC_C_VOLATILE
|
||||
AC_TYPE_MODE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_PID_T
|
||||
|
||||
+1
-1
@@ -1153,7 +1153,7 @@ ex_diffoff(eap)
|
||||
|
||||
for (wp = firstwin; wp != NULL; wp = wp->w_next)
|
||||
{
|
||||
if (wp == curwin || eap->forceit)
|
||||
if (wp == curwin || (eap->forceit && wp->w_p_diff))
|
||||
{
|
||||
/* Set 'diff', 'scrollbind' off and 'wrap' on. */
|
||||
wp->w_p_diff = FALSE;
|
||||
|
||||
@@ -7703,9 +7703,7 @@ ins_reg()
|
||||
*/
|
||||
++no_mapping;
|
||||
regname = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(regname, TRUE);
|
||||
#endif
|
||||
if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P)
|
||||
{
|
||||
/* Get a third key for literal register insertion */
|
||||
@@ -7714,9 +7712,7 @@ ins_reg()
|
||||
add_to_showcmd_c(literally);
|
||||
#endif
|
||||
regname = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(regname, TRUE);
|
||||
#endif
|
||||
}
|
||||
--no_mapping;
|
||||
|
||||
|
||||
+39
-17
@@ -6541,6 +6541,7 @@ static sign_T *first_sign = NULL;
|
||||
static int last_sign_typenr = MAX_TYPENR; /* is decremented */
|
||||
|
||||
static void sign_list_defined __ARGS((sign_T *sp));
|
||||
static void sign_undefine __ARGS((sign_T *sp, sign_T *sp_prev));
|
||||
|
||||
/*
|
||||
* ":sign" command
|
||||
@@ -6749,24 +6750,8 @@ ex_sign(eap)
|
||||
/* ":sign list {name}" */
|
||||
sign_list_defined(sp);
|
||||
else
|
||||
{
|
||||
/* ":sign undefine {name}" */
|
||||
vim_free(sp->sn_name);
|
||||
vim_free(sp->sn_icon);
|
||||
#ifdef FEAT_SIGN_ICONS
|
||||
if (sp->sn_image != NULL)
|
||||
{
|
||||
out_flush();
|
||||
gui_mch_destroy_sign(sp->sn_image);
|
||||
}
|
||||
#endif
|
||||
vim_free(sp->sn_text);
|
||||
if (sp_prev == NULL)
|
||||
first_sign = sp->sn_next;
|
||||
else
|
||||
sp_prev->sn_next = sp->sn_next;
|
||||
vim_free(sp);
|
||||
}
|
||||
sign_undefine(sp, sp_prev);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -7014,6 +6999,31 @@ sign_list_defined(sp)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Undefine a sign and free its memory.
|
||||
*/
|
||||
static void
|
||||
sign_undefine(sp, sp_prev)
|
||||
sign_T *sp;
|
||||
sign_T *sp_prev;
|
||||
{
|
||||
vim_free(sp->sn_name);
|
||||
vim_free(sp->sn_icon);
|
||||
#ifdef FEAT_SIGN_ICONS
|
||||
if (sp->sn_image != NULL)
|
||||
{
|
||||
out_flush();
|
||||
gui_mch_destroy_sign(sp->sn_image);
|
||||
}
|
||||
#endif
|
||||
vim_free(sp->sn_text);
|
||||
if (sp_prev == NULL)
|
||||
first_sign = sp->sn_next;
|
||||
else
|
||||
sp_prev->sn_next = sp->sn_next;
|
||||
vim_free(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get highlighting attribute for sign "typenr".
|
||||
* If "line" is TRUE: line highl, if FALSE: text highl.
|
||||
@@ -7088,6 +7098,18 @@ sign_typenr2name(typenr)
|
||||
return (char_u *)_("[Deleted]");
|
||||
}
|
||||
|
||||
#if defined(EXITFREE) || defined(PROTO)
|
||||
/*
|
||||
* Undefine/free all signs.
|
||||
*/
|
||||
void
|
||||
free_signs()
|
||||
{
|
||||
while (first_sign != NULL)
|
||||
sign_undefine(first_sign, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_GUI) || defined(FEAT_CLIENTSERVER) || defined(PROTO)
|
||||
|
||||
+23
-4
@@ -3690,6 +3690,11 @@ set_one_cmd_context(xp, buff)
|
||||
case CMD_highlight:
|
||||
set_context_in_highlight_cmd(xp, arg);
|
||||
break;
|
||||
#ifdef FEAT_CSCOPE
|
||||
case CMD_cscope:
|
||||
set_context_in_cscope_cmd(xp, arg);
|
||||
break;
|
||||
#endif
|
||||
#ifdef FEAT_LISTCMDS
|
||||
case CMD_bdelete:
|
||||
case CMD_bwipeout:
|
||||
@@ -5142,7 +5147,11 @@ uc_add_command(name, name_len, rep, argt, def, flags, compl, compl_arg, force)
|
||||
}
|
||||
|
||||
vim_free(cmd->uc_rep);
|
||||
cmd->uc_rep = 0;
|
||||
cmd->uc_rep = NULL;
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
|
||||
vim_free(cmd->uc_compl_arg);
|
||||
cmd->uc_compl_arg = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -5201,6 +5210,9 @@ static struct
|
||||
{EXPAND_AUGROUP, "augroup"},
|
||||
{EXPAND_BUFFERS, "buffer"},
|
||||
{EXPAND_COMMANDS, "command"},
|
||||
#if defined(FEAT_CSCOPE)
|
||||
{EXPAND_CSCOPE, "cscope"},
|
||||
#endif
|
||||
#if defined(FEAT_EVAL) && defined(FEAT_CMDL_COMPL)
|
||||
{EXPAND_USER_DEFINED, "custom"},
|
||||
{EXPAND_USER_LIST, "customlist"},
|
||||
@@ -5934,7 +5946,7 @@ do_ucmd(eap)
|
||||
char_u *q;
|
||||
|
||||
char_u *start;
|
||||
char_u *end;
|
||||
char_u *end = NULL;
|
||||
char_u *ksp;
|
||||
size_t len, totlen;
|
||||
|
||||
@@ -5959,7 +5971,7 @@ do_ucmd(eap)
|
||||
for (;;)
|
||||
{
|
||||
p = cmd->uc_rep; /* source */
|
||||
q = buf; /* destinateion */
|
||||
q = buf; /* destination */
|
||||
totlen = 0;
|
||||
|
||||
for (;;)
|
||||
@@ -7866,6 +7878,9 @@ free_cd_dir()
|
||||
{
|
||||
vim_free(prev_dir);
|
||||
prev_dir = NULL;
|
||||
|
||||
vim_free(globaldir);
|
||||
globaldir = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7888,6 +7903,10 @@ ex_cd(eap)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (allbuf_locked())
|
||||
return;
|
||||
#endif
|
||||
if (vim_strchr(p_cpo, CPO_CHDIR) != NULL && curbufIsChanged()
|
||||
&& !eap->forceit)
|
||||
{
|
||||
@@ -8812,7 +8831,7 @@ ex_mkrc(eap)
|
||||
else if (*dirnow != NUL
|
||||
&& (ssop_flags & SSOP_CURDIR) && globaldir != NULL)
|
||||
{
|
||||
if (mch_chdir((char *)globaldir) == OK)
|
||||
if (mch_chdir((char *)globaldir) == 0)
|
||||
shorten_fnames(TRUE);
|
||||
}
|
||||
|
||||
|
||||
+22
-6
@@ -2000,8 +2000,8 @@ text_locked_msg()
|
||||
|
||||
#if defined(FEAT_AUTOCMD) || defined(PROTO)
|
||||
/*
|
||||
* Check if "curbuf_lock" is set and return TRUE when it is and give an error
|
||||
* message.
|
||||
* Check if "curbuf_lock" or "allbuf_lock" is set and return TRUE when it is
|
||||
* and give an error message.
|
||||
*/
|
||||
int
|
||||
curbuf_locked()
|
||||
@@ -2011,6 +2011,21 @@ curbuf_locked()
|
||||
EMSG(_("E788: Not allowed to edit another buffer now"));
|
||||
return TRUE;
|
||||
}
|
||||
return allbuf_locked();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if "allbuf_lock" is set and return TRUE when it is and give an error
|
||||
* message.
|
||||
*/
|
||||
int
|
||||
allbuf_locked()
|
||||
{
|
||||
if (allbuf_lock > 0)
|
||||
{
|
||||
EMSG(_("E811: Not allowed to change buffer information now"));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
@@ -4503,6 +4518,9 @@ ExpandFromContext(xp, pat, num_file, file, options)
|
||||
{EXPAND_EVENTS, get_event_name, TRUE},
|
||||
{EXPAND_AUGROUP, get_augroup_name, TRUE},
|
||||
#endif
|
||||
#ifdef FEAT_CSCOPE
|
||||
{EXPAND_CSCOPE, get_cscope_name, TRUE},
|
||||
#endif
|
||||
#if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \
|
||||
&& (defined(FEAT_GETTEXT) || defined(FEAT_MBYTE))
|
||||
{EXPAND_LANGUAGE, get_lang_arg, TRUE},
|
||||
@@ -6050,9 +6068,7 @@ ex_window()
|
||||
# endif
|
||||
return K_IGNORE;
|
||||
}
|
||||
cmdwin_type = ccline.cmdfirstc;
|
||||
if (cmdwin_type == NUL)
|
||||
cmdwin_type = '-';
|
||||
cmdwin_type = get_cmdline_type();
|
||||
|
||||
/* Create the command-line buffer empty. */
|
||||
(void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
|
||||
@@ -6076,7 +6092,7 @@ ex_window()
|
||||
/* Showing the prompt may have set need_wait_return, reset it. */
|
||||
need_wait_return = FALSE;
|
||||
|
||||
histtype = hist_char2type(ccline.cmdfirstc);
|
||||
histtype = hist_char2type(cmdwin_type);
|
||||
if (histtype == HIST_CMD || histtype == HIST_DEBUG)
|
||||
{
|
||||
if (p_wc == TAB)
|
||||
|
||||
+61
-7
@@ -69,7 +69,7 @@ static int apply_autocmds_exarg __ARGS((event_T event, char_u *fname, char_u *fn
|
||||
static int au_find_group __ARGS((char_u *name));
|
||||
|
||||
# define AUGROUP_DEFAULT -1 /* default autocmd group */
|
||||
# define AUGROUP_ERROR -2 /* errornouse autocmd group */
|
||||
# define AUGROUP_ERROR -2 /* erroneous autocmd group */
|
||||
# define AUGROUP_ALL -3 /* all autocmd groups */
|
||||
#endif
|
||||
|
||||
@@ -144,7 +144,9 @@ static int get_mac_fio_flags __ARGS((char_u *ptr));
|
||||
# endif
|
||||
#endif
|
||||
static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
static char *e_auchangedbuf = N_("E812: Autocommands changed buffer or buffer name");
|
||||
#endif
|
||||
|
||||
void
|
||||
filemess(buf, name, s, attr)
|
||||
@@ -295,6 +297,19 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
int conv_restlen = 0; /* nr of bytes in conv_rest[] */
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* Remember the initial values of curbuf, curbuf->b_ffname and
|
||||
* curbuf->b_fname to detect whether they are altered as a result of
|
||||
* executing nasty autocommands. Also check if "fname" and "sfname"
|
||||
* point to one of these values. */
|
||||
buf_T *old_curbuf = curbuf;
|
||||
char_u *old_b_ffname = curbuf->b_ffname;
|
||||
char_u *old_b_fname = curbuf->b_fname;
|
||||
int using_b_ffname = (fname == curbuf->b_ffname)
|
||||
|| (sfname == curbuf->b_ffname);
|
||||
int using_b_fname = (fname == curbuf->b_fname)
|
||||
|| (sfname == curbuf->b_fname);
|
||||
#endif
|
||||
write_no_eol_lnum = 0; /* in case it was set by the previous read */
|
||||
|
||||
/*
|
||||
@@ -589,7 +604,21 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
#ifdef FEAT_QUICKFIX
|
||||
if (!bt_dontwrite(curbuf))
|
||||
#endif
|
||||
{
|
||||
check_need_swap(newfile);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
/* SwapExists autocommand may mess things up */
|
||||
if (curbuf != old_curbuf
|
||||
|| (using_b_ffname
|
||||
&& (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname
|
||||
&& (old_b_fname != curbuf->b_fname)))
|
||||
{
|
||||
EMSG(_(e_auchangedbuf));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (dir_of_file_exists(fname))
|
||||
filemess(curbuf, sfname, (char_u *)_("[New File]"), 0);
|
||||
else
|
||||
@@ -668,6 +697,17 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
#endif
|
||||
{
|
||||
check_need_swap(newfile);
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (!read_stdin && (curbuf != old_curbuf
|
||||
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname && (old_b_fname != curbuf->b_fname))))
|
||||
{
|
||||
EMSG(_(e_auchangedbuf));
|
||||
if (!read_buffer)
|
||||
close(fd);
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
/* Set swap file protection bits after creating it. */
|
||||
if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL)
|
||||
@@ -698,7 +738,6 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
{
|
||||
int m = msg_scroll;
|
||||
int n = msg_scrolled;
|
||||
buf_T *old_curbuf = curbuf;
|
||||
|
||||
/*
|
||||
* The file must be closed again, the autocommands may want to change
|
||||
@@ -740,8 +779,13 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
|
||||
/*
|
||||
* Don't allow the autocommands to change the current buffer.
|
||||
* Try to re-open the file.
|
||||
*
|
||||
* Don't allow the autocommands to change the buffer name either
|
||||
* (cd for example) if it invalidates fname or sfname.
|
||||
*/
|
||||
if (!read_stdin && (curbuf != old_curbuf
|
||||
|| (using_b_ffname && (old_b_ffname != curbuf->b_ffname))
|
||||
|| (using_b_fname && (old_b_fname != curbuf->b_fname))
|
||||
|| (fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) < 0))
|
||||
{
|
||||
--no_wait_return;
|
||||
@@ -5248,13 +5292,16 @@ buf_write_bytes(ip)
|
||||
/* Convert with iconv(). */
|
||||
if (ip->bw_restlen > 0)
|
||||
{
|
||||
char *fp;
|
||||
|
||||
/* Need to concatenate the remainder of the previous call and
|
||||
* the bytes of the current call. Use the end of the
|
||||
* conversion buffer for this. */
|
||||
fromlen = len + ip->bw_restlen;
|
||||
from = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
|
||||
mch_memmove((void *)from, ip->bw_rest, (size_t)ip->bw_restlen);
|
||||
mch_memmove((void *)(from + ip->bw_restlen), buf, (size_t)len);
|
||||
fp = (char *)ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
|
||||
mch_memmove(fp, ip->bw_rest, (size_t)ip->bw_restlen);
|
||||
mch_memmove(fp + ip->bw_restlen, buf, (size_t)len);
|
||||
from = fp;
|
||||
tolen = ip->bw_conv_buflen - fromlen;
|
||||
}
|
||||
else
|
||||
@@ -6328,7 +6375,7 @@ check_timestamps(focus)
|
||||
|
||||
if (!stuff_empty() || global_busy || !typebuf_typed()
|
||||
#ifdef FEAT_AUTOCMD
|
||||
|| autocmd_busy || curbuf_lock > 0
|
||||
|| autocmd_busy || curbuf_lock > 0 || allbuf_lock > 0
|
||||
#endif
|
||||
)
|
||||
need_check_timestamps = TRUE; /* check later */
|
||||
@@ -6536,8 +6583,10 @@ buf_check_timestamp(buf, focus)
|
||||
set_vim_var_string(VV_FCS_REASON, (char_u *)reason, -1);
|
||||
set_vim_var_string(VV_FCS_CHOICE, (char_u *)"", -1);
|
||||
# endif
|
||||
++allbuf_lock;
|
||||
n = apply_autocmds(EVENT_FILECHANGEDSHELL,
|
||||
buf->b_fname, buf->b_fname, FALSE, buf);
|
||||
--allbuf_lock;
|
||||
busy = FALSE;
|
||||
if (n)
|
||||
{
|
||||
@@ -6612,6 +6661,11 @@ buf_check_timestamp(buf, focus)
|
||||
tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg)
|
||||
+ STRLEN(mesg2) + 2));
|
||||
sprintf((char *)tbuf, mesg, path);
|
||||
#ifdef FEAT_EVAL
|
||||
/* Set warningmsg here, before the unimportant and output-specific
|
||||
* mesg2 has been appended. */
|
||||
set_vim_var_string(VV_WARNINGMSG, tbuf, -1);
|
||||
#endif
|
||||
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
|
||||
if (can_reload)
|
||||
{
|
||||
|
||||
@@ -3816,7 +3816,11 @@ showmap(mp, local)
|
||||
int len = 1;
|
||||
|
||||
if (msg_didout || msg_silent != 0)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (got_int) /* 'q' typed at MORE prompt */
|
||||
return;
|
||||
}
|
||||
if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
|
||||
msg_putchar('!'); /* :map! */
|
||||
else if (mp->m_mode & INSERT)
|
||||
|
||||
+17
-6
@@ -482,8 +482,10 @@ EXTERN char *foreground_argument INIT(= NULL);
|
||||
/*
|
||||
* While executing external commands or in Ex mode, should not insert GUI
|
||||
* events in the input buffer: Set hold_gui_events to non-zero.
|
||||
*
|
||||
* volatile because it is used in signal handler sig_sysmouse().
|
||||
*/
|
||||
EXTERN int hold_gui_events INIT(= 0);
|
||||
EXTERN volatile int hold_gui_events INIT(= 0);
|
||||
|
||||
/*
|
||||
* When resizing the shell is postponed, remember the new size, and call
|
||||
@@ -597,7 +599,8 @@ EXTERN int exiting INIT(= FALSE);
|
||||
EXTERN int really_exiting INIT(= FALSE);
|
||||
/* TRUE when we are sure to exit, e.g., after
|
||||
* a deadly signal */
|
||||
EXTERN int full_screen INIT(= FALSE);
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
EXTERN volatile int full_screen INIT(= FALSE);
|
||||
/* TRUE when doing full-screen output
|
||||
* otherwise only writing some messages */
|
||||
|
||||
@@ -616,6 +619,11 @@ EXTERN int textlock INIT(= 0);
|
||||
EXTERN int curbuf_lock INIT(= 0);
|
||||
/* non-zero when the current buffer can't be
|
||||
* changed. Used for FileChangedRO. */
|
||||
EXTERN int allbuf_lock INIT(= 0);
|
||||
/* non-zero when no buffer name can be
|
||||
* changed, no buffer can be deleted and
|
||||
* current directory can't be changed.
|
||||
* Used for SwapExists et al. */
|
||||
#endif
|
||||
#ifdef FEAT_EVAL
|
||||
# define HAVE_SANDBOX
|
||||
@@ -739,10 +747,12 @@ EXTERN JMP_BUF x_jump_env;
|
||||
*/
|
||||
EXTERN JMP_BUF lc_jump_env; /* argument to SETJMP() */
|
||||
# ifdef SIGHASARG
|
||||
EXTERN int lc_signal; /* catched signal number, 0 when no was signal
|
||||
catched; used for mch_libcall() */
|
||||
/* volatile because it is used in signal handlers. */
|
||||
EXTERN volatile int lc_signal; /* caught signal number, 0 when no was signal
|
||||
caught; used for mch_libcall() */
|
||||
# endif
|
||||
EXTERN int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
EXTERN volatile int lc_active INIT(= FALSE); /* TRUE when lc_jump_env is valid. */
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_POSTSCRIPT)
|
||||
@@ -986,7 +996,8 @@ EXTERN int curscript INIT(= 0); /* index in scriptin[] */
|
||||
EXTERN FILE *scriptout INIT(= NULL); /* stream to write script to */
|
||||
EXTERN int read_cmd_fd INIT(= 0); /* fd to read commands from */
|
||||
|
||||
EXTERN int got_int INIT(= FALSE); /* set to TRUE when interrupt
|
||||
/* volatile because it is used in signal handler catch_sigint(). */
|
||||
EXTERN volatile int got_int INIT(= FALSE); /* set to TRUE when interrupt
|
||||
signal occurred */
|
||||
#ifdef USE_TERM_CONSOLE
|
||||
EXTERN int term_console INIT(= FALSE); /* set to TRUE when console used */
|
||||
|
||||
@@ -1291,6 +1291,23 @@ drawBalloon(beval)
|
||||
XtNy, ty,
|
||||
NULL);
|
||||
#endif
|
||||
/* Set tooltip colors */
|
||||
{
|
||||
Arg args[2];
|
||||
|
||||
#ifdef FEAT_GUI_MOTIF
|
||||
args[0].name = XmNbackground;
|
||||
args[0].value = gui.tooltip_bg_pixel;
|
||||
args[1].name = XmNforeground;
|
||||
args[1].value = gui.tooltip_fg_pixel;
|
||||
#else /* Athena */
|
||||
args[0].name = XtNbackground;
|
||||
args[0].value = gui.tooltip_bg_pixel;
|
||||
args[1].name = XtNforeground;
|
||||
args[1].value = gui.tooltip_fg_pixel;
|
||||
#endif
|
||||
XtSetValues(beval->balloonLabel, &args[0], XtNumber(args));
|
||||
}
|
||||
|
||||
XtPopup(beval->balloonShell, XtGrabNone);
|
||||
|
||||
|
||||
+26
-33
@@ -1587,6 +1587,8 @@ gui_mch_uninit()
|
||||
XtCloseDisplay(gui.dpy);
|
||||
gui.dpy = NULL;
|
||||
vimShell = (Widget)0;
|
||||
vim_free(gui_argv);
|
||||
gui_argv = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1761,6 +1763,8 @@ gui_mch_exit(rc)
|
||||
* says that this isn't needed when exiting, so just skip it. */
|
||||
XtCloseDisplay(gui.dpy);
|
||||
#endif
|
||||
vim_free(gui_argv);
|
||||
gui_argv = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3439,47 +3443,37 @@ gui_mch_register_sign(signfile)
|
||||
char_u *signfile;
|
||||
{
|
||||
XpmAttributes attrs;
|
||||
XImage *sign;
|
||||
XImage *sign = NULL;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Setup the color substitution table.
|
||||
*/
|
||||
sign = NULL;
|
||||
if (signfile[0] != NUL && signfile[0] != '-')
|
||||
{
|
||||
sign = (XImage *)alloc(sizeof(XImage));
|
||||
if (sign != NULL)
|
||||
XpmColorSymbol color[5] =
|
||||
{
|
||||
XpmColorSymbol color[5] =
|
||||
{
|
||||
{"none", NULL, 0},
|
||||
{"iconColor1", NULL, 0},
|
||||
{"bottomShadowColor", NULL, 0},
|
||||
{"topShadowColor", NULL, 0},
|
||||
{"selectColor", NULL, 0}
|
||||
};
|
||||
attrs.valuemask = XpmColorSymbols;
|
||||
attrs.numsymbols = 2;
|
||||
attrs.colorsymbols = color;
|
||||
attrs.colorsymbols[0].pixel = gui.back_pixel;
|
||||
attrs.colorsymbols[1].pixel = gui.norm_pixel;
|
||||
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
|
||||
{"none", NULL, 0},
|
||||
{"iconColor1", NULL, 0},
|
||||
{"bottomShadowColor", NULL, 0},
|
||||
{"topShadowColor", NULL, 0},
|
||||
{"selectColor", NULL, 0}
|
||||
};
|
||||
attrs.valuemask = XpmColorSymbols;
|
||||
attrs.numsymbols = 2;
|
||||
attrs.colorsymbols = color;
|
||||
attrs.colorsymbols[0].pixel = gui.back_pixel;
|
||||
attrs.colorsymbols[1].pixel = gui.norm_pixel;
|
||||
status = XpmReadFileToImage(gui.dpy, (char *)signfile,
|
||||
&sign, NULL, &attrs);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
/* Sign width is fixed at two columns now.
|
||||
if (sign->width > gui.sign_width)
|
||||
gui.sign_width = sign->width + 8; */
|
||||
}
|
||||
else
|
||||
{
|
||||
vim_free(sign);
|
||||
sign = NULL;
|
||||
EMSG(_(e_signdata));
|
||||
}
|
||||
if (status == 0)
|
||||
{
|
||||
/* Sign width is fixed at two columns now.
|
||||
if (sign->width > gui.sign_width)
|
||||
gui.sign_width = sign->width + 8; */
|
||||
}
|
||||
else
|
||||
EMSG(_(e_signdata));
|
||||
}
|
||||
|
||||
return (void *)sign;
|
||||
@@ -3489,8 +3483,7 @@ gui_mch_register_sign(signfile)
|
||||
gui_mch_destroy_sign(sign)
|
||||
void *sign;
|
||||
{
|
||||
XFree(((XImage *)sign)->data);
|
||||
vim_free(sign);
|
||||
XDestroyImage((XImage*)sign);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+118
-5
@@ -93,12 +93,117 @@ cs_usage_msg(x)
|
||||
(void)EMSG2(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
|
||||
}
|
||||
|
||||
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
|
||||
|
||||
static enum
|
||||
{
|
||||
EXP_CSCOPE_SUBCMD, /* expand ":cscope" sub-commands */
|
||||
EXP_CSCOPE_FIND, /* expand ":cscope find" arguments */
|
||||
EXP_CSCOPE_KILL /* expand ":cscope kill" arguments */
|
||||
} expand_what;
|
||||
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the cscope command
|
||||
* expansion.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
char_u *
|
||||
get_cscope_name(xp, idx)
|
||||
expand_T *xp;
|
||||
int idx;
|
||||
{
|
||||
switch (expand_what)
|
||||
{
|
||||
case EXP_CSCOPE_SUBCMD:
|
||||
/* Complete with sub-commands of ":cscope":
|
||||
* add, find, help, kill, reset, show */
|
||||
return (char_u *)cs_cmds[idx].name;
|
||||
case EXP_CSCOPE_FIND:
|
||||
{
|
||||
const char *query_type[] =
|
||||
{
|
||||
"c", "d", "e", "f", "g", "i", "s", "t", NULL
|
||||
};
|
||||
|
||||
/* Complete with query type of ":cscope find {query_type}".
|
||||
* {query_type} can be letters (c, d, ... t) or numbers (0, 1,
|
||||
* ..., 8) but only complete with letters, since numbers are
|
||||
* redundant. */
|
||||
return (char_u *)query_type[idx];
|
||||
}
|
||||
case EXP_CSCOPE_KILL:
|
||||
{
|
||||
int i;
|
||||
int current_idx = 0;
|
||||
static char_u connection[2];
|
||||
|
||||
/* ":cscope kill" accepts connection numbers or partial names of
|
||||
* the pathname of the cscope database as argument. Only complete
|
||||
* with connection numbers. -1 can also be used to kill all
|
||||
* connections. */
|
||||
for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
|
||||
{
|
||||
if (csinfo[i].fname == NULL)
|
||||
continue;
|
||||
if (current_idx++ == idx)
|
||||
{
|
||||
/* Connection number fits in one character since
|
||||
* CSCOPE_MAX_CONNECTIONS is < 10 */
|
||||
connection[0] = i + '0';
|
||||
connection[1] = NUL;
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL;
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle command line completion for :cscope command.
|
||||
*/
|
||||
void
|
||||
set_context_in_cscope_cmd(xp, arg)
|
||||
expand_T *xp;
|
||||
char_u *arg;
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
/* Default: expand subcommands */
|
||||
xp->xp_context = EXPAND_CSCOPE;
|
||||
expand_what = EXP_CSCOPE_SUBCMD;
|
||||
xp->xp_pattern = arg;
|
||||
|
||||
/* (part of) subcommand already typed */
|
||||
if (*arg != NUL)
|
||||
{
|
||||
p = skiptowhite(arg);
|
||||
if (*p != NUL) /* past first word */
|
||||
{
|
||||
xp->xp_pattern = skipwhite(p);
|
||||
if (*skiptowhite(xp->xp_pattern) != NUL)
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
else if (STRNICMP(arg, "add", p - arg) == 0)
|
||||
xp->xp_context = EXPAND_FILES;
|
||||
else if (STRNICMP(arg, "kill", p - arg) == 0)
|
||||
expand_what = EXP_CSCOPE_KILL;
|
||||
else if (STRNICMP(arg, "find", p - arg) == 0)
|
||||
expand_what = EXP_CSCOPE_FIND;
|
||||
else
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FEAT_CMDL_COMPL */
|
||||
|
||||
/*
|
||||
* PRIVATE: do_cscope_general
|
||||
*
|
||||
* find the command, print help if invalid, and the then call the
|
||||
* corresponding command function,
|
||||
* called from do_cscope and do_scscope
|
||||
* Find the command, print help if invalid, and then call the corresponding
|
||||
* command function.
|
||||
*/
|
||||
static void
|
||||
do_cscope_general(eap, make_split)
|
||||
@@ -659,6 +764,7 @@ cs_create_cmd(csoption, pattern)
|
||||
{
|
||||
char *cmd;
|
||||
short search;
|
||||
char *pat;
|
||||
|
||||
switch (csoption[0])
|
||||
{
|
||||
@@ -692,10 +798,17 @@ cs_create_cmd(csoption, pattern)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cmd = (char *)alloc((unsigned)(strlen(pattern) + 2))) == NULL)
|
||||
/* Skip white space before the patter, except for text and pattern search,
|
||||
* they may want to use the leading white space. */
|
||||
pat = pattern;
|
||||
if (search != 4 && search != 6)
|
||||
while vim_iswhite(*pat)
|
||||
++pat;
|
||||
|
||||
if ((cmd = (char *)alloc((unsigned)(strlen(pat) + 2))) == NULL)
|
||||
return NULL;
|
||||
|
||||
(void)sprintf(cmd, "%d%s", search, pattern);
|
||||
(void)sprintf(cmd, "%d%s", search, pat);
|
||||
|
||||
return cmd;
|
||||
} /* cs_create_cmd */
|
||||
|
||||
+21
-5
@@ -127,15 +127,31 @@
|
||||
#ifdef FEAT_LANGMAP
|
||||
/*
|
||||
* Adjust chars in a language according to 'langmap' option.
|
||||
* NOTE that there is NO overhead if 'langmap' is not set; but even
|
||||
* when set we only have to do 2 ifs and an array lookup.
|
||||
* NOTE that there is no noticeable overhead if 'langmap' is not set.
|
||||
* When set the overhead for characters < 256 is small.
|
||||
* Don't apply 'langmap' if the character comes from the Stuff buffer.
|
||||
* The do-while is just to ignore a ';' after the macro.
|
||||
*/
|
||||
# define LANGMAP_ADJUST(c, condition) do { \
|
||||
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
|
||||
c = langmap_mapchar[c]; \
|
||||
# ifdef FEAT_MBYTE
|
||||
# define LANGMAP_ADJUST(c, condition) \
|
||||
do { \
|
||||
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \
|
||||
{ \
|
||||
if ((c) < 256) \
|
||||
c = langmap_mapchar[c]; \
|
||||
else \
|
||||
c = langmap_adjust_mb(c); \
|
||||
} \
|
||||
} while (0)
|
||||
# else
|
||||
# define LANGMAP_ADJUST(c, condition) \
|
||||
do { \
|
||||
if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \
|
||||
c = langmap_mapchar[c]; \
|
||||
} while (0)
|
||||
# endif
|
||||
#else
|
||||
# define LANGMAP_ADJUST(c, condition) /* nop */
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
+6
-3
@@ -976,7 +976,7 @@ wait_return(redraw)
|
||||
}
|
||||
}
|
||||
else if (msg_scrolled > Rows - 2
|
||||
&& (c == 'j' || c == K_DOWN || c == 'd'))
|
||||
&& (c == 'j' || c == K_DOWN || c == 'd' || c == 'f'))
|
||||
c = K_IGNORE;
|
||||
}
|
||||
} while ((had_got_int && c == Ctrl_C)
|
||||
@@ -2504,7 +2504,6 @@ do_more_prompt(typed_char)
|
||||
break;
|
||||
|
||||
case 'u': /* Up half a page */
|
||||
case K_PAGEUP:
|
||||
scroll = -(Rows / 2);
|
||||
break;
|
||||
|
||||
@@ -2513,10 +2512,12 @@ do_more_prompt(typed_char)
|
||||
break;
|
||||
|
||||
case 'b': /* one page back */
|
||||
case K_PAGEUP:
|
||||
scroll = -(Rows - 1);
|
||||
break;
|
||||
|
||||
case ' ': /* one extra page */
|
||||
case 'f':
|
||||
case K_PAGEDOWN:
|
||||
case K_LEFTMOUSE:
|
||||
scroll = Rows - 1;
|
||||
@@ -2552,7 +2553,6 @@ do_more_prompt(typed_char)
|
||||
{
|
||||
/* Jump to the choices of the dialog. */
|
||||
retval = TRUE;
|
||||
lines_left = Rows - 1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2560,6 +2560,9 @@ do_more_prompt(typed_char)
|
||||
got_int = TRUE;
|
||||
quit_more = TRUE;
|
||||
}
|
||||
/* When there is some more output (wrapping line) display that
|
||||
* without another prompt. */
|
||||
lines_left = Rows - 1;
|
||||
break;
|
||||
|
||||
#ifdef FEAT_CLIPBOARD
|
||||
|
||||
+6
-2
@@ -2955,6 +2955,8 @@ change_warning(col)
|
||||
int col; /* column for message; non-zero when in insert
|
||||
mode and 'showmode' is on */
|
||||
{
|
||||
static char *w_readonly = N_("W10: Warning: Changing a readonly file");
|
||||
|
||||
if (curbuf->b_did_warn == FALSE
|
||||
&& curbufIsChanged() == 0
|
||||
#ifdef FEAT_AUTOCMD
|
||||
@@ -2977,8 +2979,10 @@ change_warning(col)
|
||||
if (msg_row == Rows - 1)
|
||||
msg_col = col;
|
||||
msg_source(hl_attr(HLF_W));
|
||||
MSG_PUTS_ATTR(_("W10: Warning: Changing a readonly file"),
|
||||
hl_attr(HLF_W) | MSG_HIST);
|
||||
MSG_PUTS_ATTR(_(w_readonly), hl_attr(HLF_W) | MSG_HIST);
|
||||
#ifdef FEAT_EVAL
|
||||
set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_readonly), -1);
|
||||
#endif
|
||||
msg_clr_eos();
|
||||
(void)msg_end();
|
||||
if (msg_silent == 0 && !silent_mode)
|
||||
|
||||
+15
-2
@@ -496,7 +496,8 @@ check_cursor_col()
|
||||
{
|
||||
colnr_T len;
|
||||
#ifdef FEAT_VIRTUALEDIT
|
||||
colnr_T oldcol = curwin->w_cursor.col + curwin->w_cursor.coladd;
|
||||
colnr_T oldcol = curwin->w_cursor.col;
|
||||
colnr_T oldcoladd = curwin->w_cursor.col + curwin->w_cursor.coladd;
|
||||
#endif
|
||||
|
||||
len = (colnr_T)STRLEN(ml_get_curline());
|
||||
@@ -535,7 +536,13 @@ check_cursor_col()
|
||||
if (oldcol == MAXCOL)
|
||||
curwin->w_cursor.coladd = 0;
|
||||
else if (ve_flags == VE_ALL)
|
||||
curwin->w_cursor.coladd = oldcol - curwin->w_cursor.col;
|
||||
{
|
||||
if (oldcoladd > curwin->w_cursor.col)
|
||||
curwin->w_cursor.coladd = oldcoladd - curwin->w_cursor.col;
|
||||
else
|
||||
/* avoid weird number when there is a miscalculation or overflow */
|
||||
curwin->w_cursor.coladd = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1010,6 +1017,9 @@ free_all_mem()
|
||||
# if defined(FEAT_PROFILE)
|
||||
do_cmdline_cmd((char_u *)"profdel *");
|
||||
# endif
|
||||
# if defined(FEAT_KEYMAP)
|
||||
do_cmdline_cmd((char_u *)"set keymap=");
|
||||
#endif
|
||||
|
||||
# ifdef FEAT_TITLE
|
||||
free_titles();
|
||||
@@ -1034,6 +1044,9 @@ free_all_mem()
|
||||
free_regexp_stuff();
|
||||
free_tag_stuff();
|
||||
free_cd_dir();
|
||||
# ifdef FEAT_SIGNS
|
||||
free_signs();
|
||||
# endif
|
||||
# ifdef FEAT_EVAL
|
||||
set_expr_line(NULL);
|
||||
# endif
|
||||
|
||||
@@ -33,7 +33,6 @@ FILE *nb_debug = NULL;
|
||||
u_int nb_dlevel = 0; /* nb_debug verbosity level */
|
||||
|
||||
void nbdb(char *, ...);
|
||||
void nbtrace(char *, ...);
|
||||
|
||||
static int lookup(char *);
|
||||
#ifdef USE_NB_ERRORHANDLER
|
||||
@@ -100,25 +99,6 @@ nbdebug_log_init(
|
||||
} /* end nbdebug_log_init */
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
nbtrace(
|
||||
char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) {
|
||||
va_start(ap, fmt);
|
||||
vfprintf(nb_debug, fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(nb_debug);
|
||||
}
|
||||
|
||||
} /* end nbtrace */
|
||||
|
||||
|
||||
void
|
||||
nbdbg(
|
||||
char *fmt,
|
||||
@@ -136,23 +116,6 @@ nbdbg(
|
||||
} /* end nbdbg */
|
||||
|
||||
|
||||
void
|
||||
nbprt(
|
||||
char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (nb_debug != NULL && nb_dlevel & NB_PRINT) {
|
||||
va_start(ap, fmt);
|
||||
vfprintf(nb_debug, fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(nb_debug);
|
||||
}
|
||||
|
||||
} /* end nbprt */
|
||||
|
||||
|
||||
static int
|
||||
lookup(
|
||||
char *file)
|
||||
|
||||
@@ -43,8 +43,6 @@ typedef enum {
|
||||
|
||||
|
||||
void nbdbg(char *, ...);
|
||||
void nbprt(char *, ...);
|
||||
void nbtrace(char *, ...);
|
||||
|
||||
void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs));
|
||||
void nbdebug_log_init __ARGS((char *log_var, char *level_var));
|
||||
@@ -70,19 +68,5 @@ nbdbg(
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nbprt(
|
||||
char *fmt,
|
||||
...)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nbtrace(
|
||||
char *fmt,
|
||||
...)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* NBDEBUG */
|
||||
#endif /* NBDEBUG_H */
|
||||
|
||||
+3
-3
@@ -1924,7 +1924,7 @@ nb_do_cmd(
|
||||
vim_free(path);
|
||||
if (bufp == NULL)
|
||||
{
|
||||
nbdebug((" File %s not found in setBufferNumber\n", args));
|
||||
nbdebug((" File %s not found in setBufferNumber\n", args));
|
||||
EMSG2("E642: File %s not found in setBufferNumber", args);
|
||||
return FAIL;
|
||||
}
|
||||
@@ -2318,7 +2318,7 @@ nb_do_cmd(
|
||||
}
|
||||
if (pos)
|
||||
{
|
||||
coloncmd(":sign place %d line=%d name=%d buffer=%d",
|
||||
coloncmd(":sign place %d line=%ld name=%d buffer=%d",
|
||||
serNum, pos->lnum, typeNum, buf->bufp->b_fnum);
|
||||
if (typeNum == curPCtype)
|
||||
coloncmd(":sign jump %d buffer=%d", serNum,
|
||||
@@ -2422,7 +2422,7 @@ nb_do_cmd(
|
||||
GUARDED) == 0)
|
||||
{
|
||||
coloncmd(
|
||||
":sign place %d line=%d name=%d buffer=%d",
|
||||
":sign place %d line=%ld name=%d buffer=%d",
|
||||
guardId++, lnum, GUARDED,
|
||||
buf->bufp->b_fnum);
|
||||
}
|
||||
|
||||
@@ -651,10 +651,7 @@ normal_cmd(oap, toplevel)
|
||||
* Get the command character from the user.
|
||||
*/
|
||||
c = safe_vgetc();
|
||||
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(c, TRUE);
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_VISUAL
|
||||
/*
|
||||
@@ -744,9 +741,7 @@ getcount:
|
||||
}
|
||||
++no_zero_mapping; /* don't map zero here */
|
||||
c = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(c, TRUE);
|
||||
#endif
|
||||
--no_zero_mapping;
|
||||
if (ctrl_w)
|
||||
{
|
||||
@@ -769,9 +764,7 @@ getcount:
|
||||
++no_mapping;
|
||||
++allow_keys; /* no mapping for nchar, but keys */
|
||||
c = plain_vgetc(); /* get next character */
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(c, TRUE);
|
||||
#endif
|
||||
--no_mapping;
|
||||
--allow_keys;
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
@@ -959,9 +952,7 @@ getcount:
|
||||
* "gr", "g'" and "g`".
|
||||
*/
|
||||
ca.nchar = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(ca.nchar, TRUE);
|
||||
#endif
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
need_flushbuf |= add_to_showcmd(ca.nchar);
|
||||
#endif
|
||||
@@ -1062,10 +1053,8 @@ getcount:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_LANGMAP
|
||||
/* adjust chars > 127, except after "tTfFr" commands */
|
||||
LANGMAP_ADJUST(*cp, !lang);
|
||||
#endif
|
||||
#ifdef FEAT_RIGHTLEFT
|
||||
/* adjust Hebrew mapped char */
|
||||
if (p_hkmap && lang && KeyTyped)
|
||||
@@ -4649,9 +4638,7 @@ nv_zet(cap)
|
||||
++no_mapping;
|
||||
++allow_keys; /* no mapping for nchar, but allow key codes */
|
||||
nchar = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(nchar, TRUE);
|
||||
#endif
|
||||
--no_mapping;
|
||||
--allow_keys;
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
@@ -5007,9 +4994,7 @@ dozet:
|
||||
++no_mapping;
|
||||
++allow_keys; /* no mapping for nchar, but allow key codes */
|
||||
nchar = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(nchar, TRUE);
|
||||
#endif
|
||||
--no_mapping;
|
||||
--allow_keys;
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
|
||||
@@ -72,11 +72,11 @@ static struct yankreg *y_previous = NULL; /* ptr to last written yankreg */
|
||||
*/
|
||||
struct block_def
|
||||
{
|
||||
int startspaces; /* 'extra' cols of first char */
|
||||
int endspaces; /* 'extra' cols of first char */
|
||||
int startspaces; /* 'extra' cols before first char */
|
||||
int endspaces; /* 'extra' cols after last char */
|
||||
int textlen; /* chars in block */
|
||||
char_u *textstart; /* pointer to 1st char in block */
|
||||
colnr_T textcol; /* cols of chars (at least part.) in block */
|
||||
char_u *textstart; /* pointer to 1st char (partially) in block */
|
||||
colnr_T textcol; /* index of chars (partially) in block */
|
||||
colnr_T start_vcol; /* start col of 1st char wholly inside block */
|
||||
colnr_T end_vcol; /* start col of 1st char wholly after block */
|
||||
#ifdef FEAT_VISUALEXTRA
|
||||
@@ -382,15 +382,14 @@ shift_block(oap, amount)
|
||||
{
|
||||
int left = (oap->op_type == OP_LSHIFT);
|
||||
int oldstate = State;
|
||||
int total, split;
|
||||
char_u *newp, *oldp, *midp, *ptr;
|
||||
int total;
|
||||
char_u *newp, *oldp;
|
||||
int oldcol = curwin->w_cursor.col;
|
||||
int p_sw = (int)curbuf->b_p_sw;
|
||||
int p_ts = (int)curbuf->b_p_ts;
|
||||
struct block_def bd;
|
||||
int internal = 0;
|
||||
int incr;
|
||||
colnr_T vcol, col = 0, ws_vcol;
|
||||
colnr_T ws_vcol;
|
||||
int i = 0, j = 0;
|
||||
int len;
|
||||
|
||||
@@ -456,67 +455,89 @@ shift_block(oap, amount)
|
||||
}
|
||||
else /* left */
|
||||
{
|
||||
vcol = oap->start_vcol;
|
||||
/* walk vcol past ws to be removed */
|
||||
for (midp = oldp + bd.textcol;
|
||||
vcol < (oap->start_vcol + total) && vim_iswhite(*midp); )
|
||||
{
|
||||
incr = lbr_chartabsize_adv(&midp, (colnr_T)vcol);
|
||||
vcol += incr;
|
||||
}
|
||||
/* internal is the block-internal ws replacing a split TAB */
|
||||
if (vcol > (oap->start_vcol + total))
|
||||
{
|
||||
/* we have to split the TAB *(midp-1) */
|
||||
internal = vcol - (oap->start_vcol + total);
|
||||
}
|
||||
/* if 'expandtab' is not set, use TABs */
|
||||
colnr_T destination_col; /* column to which text in block will
|
||||
be shifted */
|
||||
char_u *verbatim_copy_end; /* end of the part of the line which is
|
||||
copied verbatim */
|
||||
colnr_T verbatim_copy_width;/* the (displayed) width of this part
|
||||
of line */
|
||||
unsigned fill; /* nr of spaces that replace a TAB */
|
||||
unsigned new_line_len; /* the length of the line after the
|
||||
block shift */
|
||||
size_t block_space_width;
|
||||
size_t shift_amount;
|
||||
char_u *non_white = bd.textstart;
|
||||
colnr_T non_white_col;
|
||||
|
||||
split = bd.startspaces + internal;
|
||||
if (split > 0)
|
||||
{
|
||||
if (!curbuf->b_p_et)
|
||||
{
|
||||
for (ptr = oldp, col = 0; ptr < oldp+bd.textcol; )
|
||||
col += lbr_chartabsize_adv(&ptr, (colnr_T)col);
|
||||
/*
|
||||
* Firstly, let's find the first non-whitespace character that is
|
||||
* displayed after the block's start column and the character's column
|
||||
* number. Also, let's calculate the width of all the whitespace
|
||||
* characters that are displayed in the block and precede the searched
|
||||
* non-whitespace character.
|
||||
*/
|
||||
|
||||
/* col+1 now equals the start col of the first char of the
|
||||
* block (may be < oap.start_vcol if we're splitting a TAB) */
|
||||
i = ((col % p_ts) + split) / p_ts; /* number of tabs */
|
||||
}
|
||||
if (i)
|
||||
j = ((col % p_ts) + split) % p_ts; /* number of spp */
|
||||
else
|
||||
j = split;
|
||||
/* If "bd.startspaces" is set, "bd.textstart" points to the character,
|
||||
* the part of which is displayed at the block's beginning. Let's start
|
||||
* searching from the next character. */
|
||||
if (bd.startspaces)
|
||||
mb_ptr_adv(non_white);
|
||||
|
||||
/* The character's column is in "bd.start_vcol". */
|
||||
non_white_col = bd.start_vcol;
|
||||
|
||||
while (vim_iswhite(*non_white))
|
||||
{
|
||||
incr = lbr_chartabsize_adv(&non_white, non_white_col);
|
||||
non_white_col += incr;
|
||||
}
|
||||
|
||||
newp = alloc_check(bd.textcol + i + j + (unsigned)STRLEN(midp) + 1);
|
||||
block_space_width = non_white_col - oap->start_vcol;
|
||||
/* We will shift by "total" or "block_space_width", whichever is less.
|
||||
*/
|
||||
shift_amount = (block_space_width < total? block_space_width: total);
|
||||
|
||||
/* The column to which we will shift the text. */
|
||||
destination_col = non_white_col - shift_amount;
|
||||
|
||||
/* Now let's find out how much of the beginning of the line we can
|
||||
* reuse without modification. */
|
||||
verbatim_copy_end = bd.textstart;
|
||||
verbatim_copy_width = bd.start_vcol;
|
||||
|
||||
/* If "bd.startspaces" is set, "bd.textstart" points to the character
|
||||
* preceding the block. We have to subtract its width to obtain its
|
||||
* column number. */
|
||||
if (bd.startspaces)
|
||||
verbatim_copy_width -= bd.start_char_vcols;
|
||||
while (verbatim_copy_width < destination_col)
|
||||
{
|
||||
incr = lbr_chartabsize(verbatim_copy_end, verbatim_copy_width);
|
||||
if (verbatim_copy_width + incr > destination_col)
|
||||
break;
|
||||
verbatim_copy_width += incr;
|
||||
mb_ptr_adv(verbatim_copy_end);
|
||||
}
|
||||
|
||||
/* If "destination_col" is different from the width of the initial
|
||||
* part of the line that will be copied, it means we encountered a tab
|
||||
* character, which we will have to partly replace with spaces. */
|
||||
fill = destination_col - verbatim_copy_width;
|
||||
|
||||
/* The replacement line will consist of:
|
||||
* - the beginning of the original line up to "verbatim_copy_end",
|
||||
* - "fill" number of spaces,
|
||||
* - the rest of the line, pointed to by non_white. */
|
||||
new_line_len = (unsigned)(verbatim_copy_end - oldp)
|
||||
+ fill
|
||||
+ (unsigned)STRLEN(non_white) + 1;
|
||||
|
||||
newp = alloc_check(new_line_len);
|
||||
if (newp == NULL)
|
||||
return;
|
||||
vim_memset(newp, NUL, (size_t)(bd.textcol + i + j + STRLEN(midp) + 1));
|
||||
|
||||
/* copy first part we want to keep */
|
||||
mch_memmove(newp, oldp, (size_t)bd.textcol);
|
||||
/* Now copy any TABS and spp to ensure correct alignment! */
|
||||
while (vim_iswhite(*midp))
|
||||
{
|
||||
if (*midp == TAB)
|
||||
i++;
|
||||
else /*space */
|
||||
j++;
|
||||
midp++;
|
||||
}
|
||||
/* We might have an extra TAB worth of spp now! */
|
||||
if (j / p_ts && !curbuf->b_p_et)
|
||||
{
|
||||
i++;
|
||||
j -= p_ts;
|
||||
}
|
||||
copy_chars(newp + bd.textcol, (size_t)i, TAB);
|
||||
copy_spaces(newp + bd.textcol + i, (size_t)j);
|
||||
|
||||
/* the end */
|
||||
STRMOVE(newp + STRLEN(newp), midp);
|
||||
mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
|
||||
copy_spaces(newp + (verbatim_copy_end - oldp), (size_t)fill);
|
||||
STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
|
||||
}
|
||||
/* replace the line */
|
||||
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
|
||||
@@ -4851,7 +4872,8 @@ paragraph_start(lnum)
|
||||
* - textlen includes the first/last char to be (partly) deleted
|
||||
* - start/endspaces is the number of columns that are taken by the
|
||||
* first/last deleted char minus the number of columns that have to be
|
||||
* deleted. for yank and tilde:
|
||||
* deleted.
|
||||
* for yank and tilde:
|
||||
* - textlen includes the first/last char to be wholly yanked
|
||||
* - start/endspaces is the number of columns of the first/last yanked char
|
||||
* that are to be yanked.
|
||||
|
||||
+147
-27
@@ -5865,14 +5865,28 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
|
||||
/* load or unload key mapping tables */
|
||||
errmsg = keymap_init();
|
||||
|
||||
/* When successfully installed a new keymap switch on using it. */
|
||||
if (*curbuf->b_p_keymap != NUL && errmsg == NULL)
|
||||
if (errmsg == NULL)
|
||||
{
|
||||
curbuf->b_p_iminsert = B_IMODE_LMAP;
|
||||
if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
|
||||
curbuf->b_p_imsearch = B_IMODE_LMAP;
|
||||
set_iminsert_global();
|
||||
set_imsearch_global();
|
||||
if (*curbuf->b_p_keymap != NUL)
|
||||
{
|
||||
/* Installed a new keymap, switch on using it. */
|
||||
curbuf->b_p_iminsert = B_IMODE_LMAP;
|
||||
if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT)
|
||||
curbuf->b_p_imsearch = B_IMODE_LMAP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cleared the keymap, may reset 'iminsert' and 'imsearch'. */
|
||||
if (curbuf->b_p_iminsert == B_IMODE_LMAP)
|
||||
curbuf->b_p_iminsert = B_IMODE_NONE;
|
||||
if (curbuf->b_p_imsearch == B_IMODE_LMAP)
|
||||
curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
|
||||
}
|
||||
if ((opt_flags & OPT_LOCAL) == 0)
|
||||
{
|
||||
set_iminsert_global();
|
||||
set_imsearch_global();
|
||||
}
|
||||
# ifdef FEAT_WINDOWS
|
||||
status_redraw_curbuf();
|
||||
# endif
|
||||
@@ -6076,15 +6090,23 @@ did_set_string_option(opt_idx, varp, new_value_alloced, oldval, errbuf,
|
||||
/* ":set t_Co=0" and ":set t_Co=1" do ":set t_Co=" */
|
||||
if (varp == &T_CCO)
|
||||
{
|
||||
t_colors = atoi((char *)T_CCO);
|
||||
if (t_colors <= 1)
|
||||
int colors = atoi((char *)T_CCO);
|
||||
|
||||
/* Only reinitialize colors if t_Co value has really changed to
|
||||
* avoid expensive reload of colorscheme if t_Co is set to the
|
||||
* same value multiple times. */
|
||||
if (colors != t_colors)
|
||||
{
|
||||
if (new_value_alloced)
|
||||
vim_free(T_CCO);
|
||||
T_CCO = empty_option;
|
||||
t_colors = colors;
|
||||
if (t_colors <= 1)
|
||||
{
|
||||
if (new_value_alloced)
|
||||
vim_free(T_CCO);
|
||||
T_CCO = empty_option;
|
||||
}
|
||||
/* We now have a different color setup, initialize it again. */
|
||||
init_highlight(TRUE, FALSE);
|
||||
}
|
||||
/* We now have a different color setup, initialize it again. */
|
||||
init_highlight(TRUE, FALSE);
|
||||
}
|
||||
ttest(FALSE);
|
||||
if (varp == &T_ME)
|
||||
@@ -7655,9 +7677,13 @@ set_bool_option(opt_idx, varp, value, opt_flags)
|
||||
* set. */
|
||||
if (STRCMP(p_enc, "utf-8") != 0)
|
||||
{
|
||||
static char *w_arabic = N_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'");
|
||||
|
||||
msg_source(hl_attr(HLF_W));
|
||||
MSG_ATTR(_("W17: Arabic requires UTF-8, do ':set encoding=utf-8'"),
|
||||
hl_attr(HLF_W));
|
||||
MSG_ATTR(_(w_arabic), hl_attr(HLF_W));
|
||||
#ifdef FEAT_EVAL
|
||||
set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
# ifdef FEAT_MBYTE
|
||||
@@ -10287,25 +10313,110 @@ wc_use_keyname(varp, wcp)
|
||||
|
||||
#ifdef FEAT_LANGMAP
|
||||
/*
|
||||
* Any character has an equivalent character. This is used for keyboards that
|
||||
* have a special language mode that sends characters above 128 (although
|
||||
* other characters can be translated too).
|
||||
* Any character has an equivalent 'langmap' character. This is used for
|
||||
* keyboards that have a special language mode that sends characters above
|
||||
* 128 (although other characters can be translated too). The "to" field is a
|
||||
* Vim command character. This avoids having to switch the keyboard back to
|
||||
* ASCII mode when leaving Insert mode.
|
||||
*
|
||||
* langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim
|
||||
* commands.
|
||||
* When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of
|
||||
* langmap_entry_T. This does the same as langmap_mapchar[] for characters >=
|
||||
* 256.
|
||||
*/
|
||||
# ifdef FEAT_MBYTE
|
||||
/*
|
||||
* With multi-byte support use growarray for 'langmap' chars >= 256
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int from;
|
||||
int to;
|
||||
} langmap_entry_T;
|
||||
|
||||
static garray_T langmap_mapga;
|
||||
static void langmap_set_entry __ARGS((int from, int to));
|
||||
|
||||
/*
|
||||
* char_u langmap_mapchar[256];
|
||||
* Normally maps each of the 128 upper chars to an <128 ascii char; used to
|
||||
* "translate" native lang chars in normal mode or some cases of
|
||||
* insert mode without having to tediously switch lang mode back&forth.
|
||||
* Search for an entry in "langmap_mapga" for "from". If found set the "to"
|
||||
* field. If not found insert a new entry at the appropriate location.
|
||||
*/
|
||||
static void
|
||||
langmap_set_entry(from, to)
|
||||
int from;
|
||||
int to;
|
||||
{
|
||||
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
|
||||
int a = 0;
|
||||
int b = langmap_mapga.ga_len;
|
||||
|
||||
/* Do a binary search for an existing entry. */
|
||||
while (a != b)
|
||||
{
|
||||
int i = (a + b) / 2;
|
||||
int d = entries[i].from - from;
|
||||
|
||||
if (d == 0)
|
||||
{
|
||||
entries[i].to = to;
|
||||
return;
|
||||
}
|
||||
if (d < 0)
|
||||
a = i + 1;
|
||||
else
|
||||
b = i;
|
||||
}
|
||||
|
||||
if (ga_grow(&langmap_mapga, 1) != OK)
|
||||
return; /* out of memory */
|
||||
|
||||
/* insert new entry at position "a" */
|
||||
entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a;
|
||||
mch_memmove(entries + 1, entries,
|
||||
(langmap_mapga.ga_len - a) * sizeof(langmap_entry_T));
|
||||
++langmap_mapga.ga_len;
|
||||
entries[0].from = from;
|
||||
entries[0].to = to;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply 'langmap' to multi-byte character "c" and return the result.
|
||||
*/
|
||||
int
|
||||
langmap_adjust_mb(c)
|
||||
int c;
|
||||
{
|
||||
langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data);
|
||||
int a = 0;
|
||||
int b = langmap_mapga.ga_len;
|
||||
|
||||
while (a != b)
|
||||
{
|
||||
int i = (a + b) / 2;
|
||||
int d = entries[i].from - c;
|
||||
|
||||
if (d == 0)
|
||||
return entries[i].to; /* found matching entry */
|
||||
if (d < 0)
|
||||
a = i + 1;
|
||||
else
|
||||
b = i;
|
||||
}
|
||||
return c; /* no entry found, return "c" unmodified */
|
||||
}
|
||||
# endif
|
||||
|
||||
static void
|
||||
langmap_init()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++) /* we init with a-one-to one map */
|
||||
langmap_mapchar[i] = i;
|
||||
for (i = 0; i < 256; i++)
|
||||
langmap_mapchar[i] = i; /* we init with a one-to-one map */
|
||||
# ifdef FEAT_MBYTE
|
||||
ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8);
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -10319,7 +10430,10 @@ langmap_set()
|
||||
char_u *p2;
|
||||
int from, to;
|
||||
|
||||
langmap_init(); /* back to one-to-one map first */
|
||||
#ifdef FEAT_MBYTE
|
||||
ga_clear(&langmap_mapga); /* clear the previous map first */
|
||||
#endif
|
||||
langmap_init(); /* back to one-to-one map */
|
||||
|
||||
for (p = p_langmap; p[0] != NUL; )
|
||||
{
|
||||
@@ -10369,7 +10483,13 @@ langmap_set()
|
||||
transchar(from));
|
||||
return;
|
||||
}
|
||||
langmap_mapchar[from & 255] = to;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (from >= 256)
|
||||
langmap_set_entry(from, to);
|
||||
else
|
||||
#endif
|
||||
langmap_mapchar[from & 255] = to;
|
||||
|
||||
/* Advance to next pair */
|
||||
mb_ptr_adv(p);
|
||||
|
||||
+83
-28
@@ -181,7 +181,8 @@ static RETSIGTYPE catch_sigpwr __ARGS(SIGPROTOARG);
|
||||
&& defined(FEAT_TITLE) && !defined(FEAT_GUI_GTK)
|
||||
# define SET_SIG_ALARM
|
||||
static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
|
||||
static int sig_alarm_called;
|
||||
/* volatile because it is used in signal handler sig_alarm(). */
|
||||
static volatile int sig_alarm_called;
|
||||
#endif
|
||||
static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
|
||||
|
||||
@@ -201,13 +202,16 @@ static int save_patterns __ARGS((int num_pat, char_u **pat, int *num_file, char_
|
||||
# define SIG_ERR ((RETSIGTYPE (*)())-1)
|
||||
#endif
|
||||
|
||||
static int do_resize = FALSE;
|
||||
/* volatile because it is used in signal handler sig_winch(). */
|
||||
static volatile int do_resize = FALSE;
|
||||
#ifndef __EMX__
|
||||
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() */
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
static volatile int deadly_signal = 0; /* The signal we caught */
|
||||
/* volatile because it is used in signal handler deathtrap(). */
|
||||
static volatile int in_mch_delay = FALSE; /* sleeping in mch_delay() */
|
||||
|
||||
static int curr_tmode = TMODE_COOK; /* contains current terminal mode */
|
||||
|
||||
@@ -802,7 +806,7 @@ init_signal_stack()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need correct potatotypes for a signal function, otherwise mean compilers
|
||||
* We need correct prototypes for a signal function, otherwise mean compilers
|
||||
* will barf when the second argument to signal() is ``wrong''.
|
||||
* Let me try it with a few tricky defines from my own osdef.h (jw).
|
||||
*/
|
||||
@@ -1068,13 +1072,18 @@ deathtrap SIGDEFARG(sigarg)
|
||||
SIGRETURN;
|
||||
}
|
||||
|
||||
#ifdef _REENTRANT
|
||||
#if defined(_REENTRANT) && defined(SIGCONT)
|
||||
/*
|
||||
* On Solaris with multi-threading, suspending might not work immediately.
|
||||
* Catch the SIGCONT signal, which will be used as an indication whether the
|
||||
* suspending has been done or not.
|
||||
*
|
||||
* On Linux, signal is not always handled immediately either.
|
||||
* See https://bugs.launchpad.net/bugs/291373
|
||||
*
|
||||
* volatile because it is used in in signal handler sigcont_handler().
|
||||
*/
|
||||
static int sigcont_received;
|
||||
static volatile int sigcont_received;
|
||||
static RETSIGTYPE sigcont_handler __ARGS(SIGPROTOARG);
|
||||
|
||||
/*
|
||||
@@ -1118,15 +1127,28 @@ mch_suspend()
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef _REENTRANT
|
||||
# if defined(_REENTRANT) && defined(SIGCONT)
|
||||
sigcont_received = FALSE;
|
||||
# endif
|
||||
kill(0, SIGTSTP); /* send ourselves a STOP signal */
|
||||
# ifdef _REENTRANT
|
||||
/* When we didn't suspend immediately in the kill(), do it now. Happens
|
||||
* on multi-threaded Solaris. */
|
||||
if (!sigcont_received)
|
||||
pause();
|
||||
# if defined(_REENTRANT) && defined(SIGCONT)
|
||||
/*
|
||||
* Wait for the SIGCONT signal to be handled. It generally happens
|
||||
* immediately, but somehow not all the time. Do not call pause()
|
||||
* because there would be race condition which would hang Vim if
|
||||
* signal happened in between the test of sigcont_received and the
|
||||
* call to pause(). If signal is not yet received, call sleep(0)
|
||||
* to just yield CPU. Signal should then be received. If somehow
|
||||
* it's still not received, sleep 1, 2, 3 ms. Don't bother waiting
|
||||
* further if signal is not received after 1+2+3+4 ms (not expected
|
||||
* to happen).
|
||||
*/
|
||||
{
|
||||
long wait;
|
||||
for (wait = 0; !sigcont_received && wait <= 3L; wait++)
|
||||
/* Loop is not entered most of the time */
|
||||
mch_delay(wait, FALSE);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef FEAT_TITLE
|
||||
@@ -1175,7 +1197,7 @@ set_signals()
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
|
||||
#endif
|
||||
#ifdef _REENTRANT
|
||||
#if defined(_REENTRANT) && defined(SIGCONT)
|
||||
signal(SIGCONT, sigcont_handler);
|
||||
#endif
|
||||
|
||||
@@ -1234,7 +1256,7 @@ catch_int_signal()
|
||||
reset_signals()
|
||||
{
|
||||
catch_signals(SIG_DFL, SIG_DFL);
|
||||
#ifdef _REENTRANT
|
||||
#if defined(_REENTRANT) && defined(SIGCONT)
|
||||
/* SIGCONT isn't in the list, because its default action is ignore */
|
||||
signal(SIGCONT, SIG_DFL);
|
||||
#endif
|
||||
@@ -4094,6 +4116,9 @@ mch_call_shell(cmd, options)
|
||||
int fromshell_fd;
|
||||
garray_T ga;
|
||||
int noread_cnt;
|
||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
||||
struct timeval start_tv;
|
||||
# endif
|
||||
|
||||
# ifdef FEAT_GUI
|
||||
if (pty_master_fd >= 0)
|
||||
@@ -4203,7 +4228,9 @@ mch_call_shell(cmd, options)
|
||||
ga_init2(&ga, 1, BUFLEN);
|
||||
|
||||
noread_cnt = 0;
|
||||
|
||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
||||
gettimeofday(&start_tv, NULL);
|
||||
# endif
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
@@ -4216,25 +4243,34 @@ mch_call_shell(cmd, options)
|
||||
* that a typed password is echoed for ssh or gpg command.
|
||||
* Don't get characters when the child has already
|
||||
* finished (wait_pid == 0).
|
||||
* Don't get extra characters when we already have one.
|
||||
* Don't read characters unless we didn't get output for a
|
||||
* while, avoids that ":r !ls" eats typeahead.
|
||||
* while (noread_cnt > 4), avoids that ":r !ls" eats
|
||||
* typeahead.
|
||||
*/
|
||||
len = 0;
|
||||
if (!(options & SHELL_EXPAND)
|
||||
&& ((options &
|
||||
(SHELL_READ|SHELL_WRITE|SHELL_COOKED))
|
||||
!= (SHELL_READ|SHELL_WRITE|SHELL_COOKED)
|
||||
#ifdef FEAT_GUI
|
||||
# ifdef FEAT_GUI
|
||||
|| gui.in_use
|
||||
#endif
|
||||
# endif
|
||||
)
|
||||
&& wait_pid == 0
|
||||
&& (ta_len > 0
|
||||
|| (noread_cnt > 4
|
||||
&& (len = ui_inchar(ta_buf,
|
||||
BUFLEN, 10L, 0)) > 0)))
|
||||
&& (ta_len > 0 || noread_cnt > 4))
|
||||
{
|
||||
if (ta_len == 0)
|
||||
{
|
||||
/* Get extra characters when we don't have any.
|
||||
* Reset the counter and timer. */
|
||||
noread_cnt = 0;
|
||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
||||
gettimeofday(&start_tv, NULL);
|
||||
# endif
|
||||
len = ui_inchar(ta_buf, BUFLEN, 10L, 0);
|
||||
}
|
||||
if (ta_len > 0 || len > 0)
|
||||
{
|
||||
/*
|
||||
* For pipes:
|
||||
* Check for CTRL-C: send interrupt signal to child.
|
||||
@@ -4336,9 +4372,9 @@ mch_call_shell(cmd, options)
|
||||
{
|
||||
ta_len -= len;
|
||||
mch_memmove(ta_buf, ta_buf + len, ta_len);
|
||||
noread_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (got_int)
|
||||
@@ -4445,13 +4481,30 @@ mch_call_shell(cmd, options)
|
||||
cursor_on();
|
||||
out_flush();
|
||||
# if FEAT_GUI_MACVIM
|
||||
if (gui.in_use) {
|
||||
fast_breakcheck();
|
||||
if (gui.in_use)
|
||||
gui_macvim_flush();
|
||||
}
|
||||
# endif
|
||||
if (got_int)
|
||||
break;
|
||||
|
||||
# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
|
||||
{
|
||||
struct timeval now_tv;
|
||||
long msec;
|
||||
|
||||
/* Avoid that we keep looping here without
|
||||
* checking for a CTRL-C for a long time. Don't
|
||||
* break out too often to avoid losing typeahead. */
|
||||
gettimeofday(&now_tv, NULL);
|
||||
msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L
|
||||
+ (now_tv.tv_usec - start_tv.tv_usec) / 1000L;
|
||||
if (msec > 2000)
|
||||
{
|
||||
noread_cnt = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* If we already detected the child has finished break the
|
||||
@@ -5874,7 +5927,9 @@ gpm_open()
|
||||
* we are going to suspend or starting an external process
|
||||
* so we shouldn't have problem with this
|
||||
*/
|
||||
# ifdef SIGTSTP
|
||||
signal(SIGTSTP, restricted ? SIG_IGN : SIG_DFL);
|
||||
# endif
|
||||
return 1; /* succeed */
|
||||
}
|
||||
if (gpm_fd == -2)
|
||||
|
||||
@@ -40,6 +40,7 @@ void global_exe __ARGS((char_u *cmd));
|
||||
int read_viminfo_sub_string __ARGS((vir_T *virp, int force));
|
||||
void write_viminfo_sub_string __ARGS((FILE *fp));
|
||||
void free_old_sub __ARGS((void));
|
||||
void free_signs __ARGS((void));
|
||||
int prepare_tagpreview __ARGS((int undo_sync));
|
||||
void ex_help __ARGS((exarg_T *eap));
|
||||
char_u *check_help_lang __ARGS((char_u *arg));
|
||||
|
||||
@@ -4,6 +4,7 @@ char_u *getcmdline_prompt __ARGS((int firstc, char_u *prompt, int attr, int xp_c
|
||||
int text_locked __ARGS((void));
|
||||
void text_locked_msg __ARGS((void));
|
||||
int curbuf_locked __ARGS((void));
|
||||
int allbuf_locked __ARGS((void));
|
||||
char_u *getexline __ARGS((int c, void *dummy, int indent));
|
||||
char_u *getexmodeline __ARGS((int promptc, void *dummy, int indent));
|
||||
int cmdline_overstrike __ARGS((void));
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* if_cscope.c */
|
||||
char_u *get_cscope_name __ARGS((expand_T *xp, int idx));
|
||||
void set_context_in_cscope_cmd __ARGS((expand_T *xp, char_u *arg));
|
||||
void do_cscope __ARGS((exarg_T *eap));
|
||||
void do_scscope __ARGS((exarg_T *eap));
|
||||
void do_cstag __ARGS((exarg_T *eap));
|
||||
|
||||
@@ -44,6 +44,7 @@ void set_imsearch_global __ARGS((void));
|
||||
void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags));
|
||||
int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file));
|
||||
int ExpandOldSetting __ARGS((int *num_file, char_u ***file));
|
||||
int langmap_adjust_mb __ARGS((int c));
|
||||
int has_format_option __ARGS((int x));
|
||||
int shortmess __ARGS((int x));
|
||||
void vimrc_found __ARGS((char_u *fname, char_u *envname));
|
||||
|
||||
+14
-12
@@ -1419,6 +1419,7 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
int opened_window = FALSE;
|
||||
win_T *win;
|
||||
win_T *altwin;
|
||||
int flags;
|
||||
#endif
|
||||
win_T *oldwin = curwin;
|
||||
int print_message = TRUE;
|
||||
@@ -1531,7 +1532,6 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0))
|
||||
{
|
||||
win_T *wp;
|
||||
int n;
|
||||
|
||||
if (cmdmod.tab != 0)
|
||||
wp = NULL;
|
||||
@@ -1547,13 +1547,16 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
* Split off help window; put it at far top if no position
|
||||
* specified, the current window is vertically split and narrow.
|
||||
*/
|
||||
n = WSP_HELP;
|
||||
flags = WSP_HELP;
|
||||
# ifdef FEAT_VERTSPLIT
|
||||
if (cmdmod.split == 0 && curwin->w_width != Columns
|
||||
&& curwin->w_width < 80)
|
||||
n |= WSP_TOP;
|
||||
flags |= WSP_TOP;
|
||||
# endif
|
||||
if (win_split(0, n) == FAIL)
|
||||
if (qi != &ql_info)
|
||||
flags |= WSP_NEWLOC; /* don't copy the location list */
|
||||
|
||||
if (win_split(0, flags) == FAIL)
|
||||
goto theend;
|
||||
opened_window = TRUE; /* close it when fail */
|
||||
|
||||
@@ -1563,7 +1566,6 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
if (qi != &ql_info) /* not a quickfix list */
|
||||
{
|
||||
/* The new window should use the supplied location list */
|
||||
qf_free_all(curwin);
|
||||
curwin->w_llist = qi;
|
||||
qi->qf_refcount++;
|
||||
}
|
||||
@@ -1610,10 +1612,11 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
{
|
||||
goto_tabpage_win(tp, wp);
|
||||
usable_win = 1;
|
||||
break;
|
||||
goto win_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
win_found:
|
||||
|
||||
/*
|
||||
* If there is only one window and it is the quickfix window, create a
|
||||
@@ -1623,7 +1626,10 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
{
|
||||
ll_ref = curwin->w_llist_ref;
|
||||
|
||||
if (win_split(0, WSP_ABOVE) == FAIL)
|
||||
flags = WSP_ABOVE;
|
||||
if (ll_ref != NULL)
|
||||
flags |= WSP_NEWLOC;
|
||||
if (win_split(0, flags) == FAIL)
|
||||
goto failed; /* not enough room for window */
|
||||
opened_window = TRUE; /* close it when fail */
|
||||
p_swb = empty_option; /* don't split again */
|
||||
@@ -1635,7 +1641,6 @@ qf_jump(qi, dir, errornr, forceit)
|
||||
{
|
||||
/* The new window should use the location list from the
|
||||
* location list window */
|
||||
qf_free_all(curwin);
|
||||
curwin->w_llist = ll_ref;
|
||||
ll_ref->qf_refcount++;
|
||||
}
|
||||
@@ -2310,15 +2315,12 @@ ex_copen(eap)
|
||||
if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow)
|
||||
/* Create the new window at the very bottom. */
|
||||
win_goto(lastwin);
|
||||
if (win_split(height, WSP_BELOW) == FAIL)
|
||||
if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL)
|
||||
return; /* not enough room for window */
|
||||
#ifdef FEAT_SCROLLBIND
|
||||
curwin->w_p_scb = FALSE;
|
||||
#endif
|
||||
|
||||
/* Remove the location list for the quickfix window */
|
||||
qf_free_all(curwin);
|
||||
|
||||
if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow)
|
||||
{
|
||||
/*
|
||||
|
||||
+4
-6
@@ -4532,7 +4532,7 @@ regmatch(scan)
|
||||
cleanup_subexpr();
|
||||
if (!REG_MULTI) /* Single-line regexp */
|
||||
{
|
||||
if (reg_endp[no] == NULL)
|
||||
if (reg_startp[no] == NULL || reg_endp[no] == NULL)
|
||||
{
|
||||
/* Backref was not set: Match an empty string. */
|
||||
len = 0;
|
||||
@@ -4548,7 +4548,7 @@ regmatch(scan)
|
||||
}
|
||||
else /* Multi-line regexp */
|
||||
{
|
||||
if (reg_endpos[no].lnum < 0)
|
||||
if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0)
|
||||
{
|
||||
/* Backref was not set: Match an empty string. */
|
||||
len = 0;
|
||||
@@ -7279,13 +7279,11 @@ reg_submatch(no)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (submatch_match->endp[no] == NULL)
|
||||
s = submatch_match->startp[no];
|
||||
if (s == NULL || submatch_match->endp[no] == NULL)
|
||||
retval = NULL;
|
||||
else
|
||||
{
|
||||
s = submatch_match->startp[no];
|
||||
retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s));
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
||||
+98
-41
@@ -2596,6 +2596,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
int noinvcur = FALSE; /* don't invert the cursor */
|
||||
#ifdef FEAT_VISUAL
|
||||
pos_T *top, *bot;
|
||||
int lnum_in_visual_area = FALSE;
|
||||
#endif
|
||||
pos_T pos;
|
||||
long v;
|
||||
@@ -2792,9 +2793,10 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
top = &VIsual;
|
||||
bot = &curwin->w_cursor;
|
||||
}
|
||||
lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum);
|
||||
if (VIsual_mode == Ctrl_V) /* block mode */
|
||||
{
|
||||
if (lnum >= top->lnum && lnum <= bot->lnum)
|
||||
if (lnum_in_visual_area)
|
||||
{
|
||||
fromcol = wp->w_old_cursor_fcol;
|
||||
tocol = wp->w_old_cursor_lcol;
|
||||
@@ -2887,8 +2889,9 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
}
|
||||
else
|
||||
tocol = MAXCOL;
|
||||
if (fromcol == tocol) /* do at least one character */
|
||||
tocol = fromcol + 1; /* happens when past end of line */
|
||||
/* do at least one character; happens when past end of line */
|
||||
if (fromcol == tocol)
|
||||
tocol = fromcol + 1;
|
||||
area_highlighting = TRUE;
|
||||
attr = hl_attr(HLF_I);
|
||||
}
|
||||
@@ -3420,6 +3423,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
&& (*mb_ptr2cells)(ptr) > 1)
|
||||
#endif
|
||||
|| ((int)vcol_prev == fromcol_prev
|
||||
&& vcol_prev < vcol /* not at margin */
|
||||
&& vcol < tocol))
|
||||
area_attr = attr; /* start highlighting */
|
||||
else if (area_attr != 0
|
||||
@@ -3552,7 +3556,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
/* Use line_attr when not in the Visual or 'incsearch' area
|
||||
* (area_attr may be 0 when "noinvcur" is set). */
|
||||
else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL)
|
||||
|| (vcol < fromcol || vcol >= tocol)))
|
||||
|| vcol < fromcol || vcol_prev < fromcol_prev
|
||||
|| vcol >= tocol))
|
||||
char_attr = line_attr;
|
||||
#endif
|
||||
else
|
||||
@@ -4114,6 +4119,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
# endif
|
||||
(col < W_WIDTH(wp)))
|
||||
&& !(noinvcur
|
||||
&& lnum == wp->w_cursor.lnum
|
||||
&& (colnr_T)vcol == wp->w_virtcol)))
|
||||
&& lcs_eol_one >= 0)
|
||||
{
|
||||
@@ -4255,7 +4261,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
* preedit_changed and commit. Thus Vim can't set "im_is_active", use
|
||||
* im_is_preediting() here. */
|
||||
if (xic != NULL
|
||||
&& lnum == curwin->w_cursor.lnum
|
||||
&& lnum == wp->w_cursor.lnum
|
||||
&& (State & INSERT)
|
||||
&& !p_imdisable
|
||||
&& im_is_preediting()
|
||||
@@ -4264,7 +4270,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
colnr_T tcol;
|
||||
|
||||
if (preedit_end_col == MAXCOL)
|
||||
getvcol(curwin, &(curwin->w_cursor), &tcol, NULL, NULL);
|
||||
getvcol(curwin, &(wp->w_cursor), &tcol, NULL, NULL);
|
||||
else
|
||||
tcol = preedit_end_col;
|
||||
if ((long)preedit_start_col <= vcol && vcol < (long)tcol)
|
||||
@@ -4361,7 +4367,13 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
}
|
||||
#endif
|
||||
if (lcs_eol == lcs_eol_one
|
||||
&& ((area_attr != 0 && vcol == fromcol && c == NUL)
|
||||
&& ((area_attr != 0 && vcol == fromcol
|
||||
#ifdef FEAT_VISUAL
|
||||
&& (VIsual_mode != Ctrl_V
|
||||
|| lnum == VIsual.lnum
|
||||
|| lnum == curwin->w_cursor.lnum)
|
||||
#endif
|
||||
&& c == NUL)
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
/* highlight 'hlsearch' match at end of line */
|
||||
|| (prevcol_hl_flag == TRUE
|
||||
@@ -4455,7 +4467,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
if (c == NUL)
|
||||
{
|
||||
#ifdef FEAT_SYN_HL
|
||||
if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol)
|
||||
if (eol_hl_off > 0 && vcol - eol_hl_off == (long)wp->w_virtcol
|
||||
&& lnum == wp->w_cursor.lnum)
|
||||
{
|
||||
/* highlight last char after line */
|
||||
--col;
|
||||
@@ -4557,7 +4570,8 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
* highlight the cursor position itself. */
|
||||
if (wp->w_p_cuc && vcol == (long)wp->w_virtcol
|
||||
&& lnum != wp->w_cursor.lnum
|
||||
&& draw_state == WL_LINE)
|
||||
&& draw_state == WL_LINE
|
||||
&& !lnum_in_visual_area)
|
||||
{
|
||||
vcol_save_attr = char_attr;
|
||||
char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC));
|
||||
@@ -4660,7 +4674,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
|
||||
--n_skip;
|
||||
|
||||
/* Only advance the "vcol" when after the 'number' column. */
|
||||
if (draw_state >= WL_SBR
|
||||
if (draw_state > WL_NR
|
||||
#ifdef FEAT_DIFF
|
||||
&& filler_todo <= 0
|
||||
#endif
|
||||
@@ -5127,8 +5141,8 @@ screen_line(row, coloff, endcol, clear_width
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_GUI) || defined(UNIX)
|
||||
/* The bold trick makes a single row of pixels appear in the next
|
||||
* character. When a bold character is removed, the next
|
||||
/* The bold trick makes a single column of pixels appear in the
|
||||
* next character. When a bold character is removed, the next
|
||||
* character should be redrawn too. This happens for our own GUI
|
||||
* and for some xterms. */
|
||||
if (
|
||||
@@ -6271,9 +6285,15 @@ screen_puts_len(text, len, row, col, attr)
|
||||
int pcc[MAX_MCO];
|
||||
# endif
|
||||
#endif
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
|
||||
int force_redraw_this;
|
||||
int force_redraw_next = FALSE;
|
||||
#endif
|
||||
int need_redraw;
|
||||
|
||||
if (ScreenLines == NULL || row >= screen_Rows) /* safety check */
|
||||
return;
|
||||
off = LineOffset[row] + col;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
/* When drawing over the right halve of a double-wide char clear out the
|
||||
@@ -6283,10 +6303,21 @@ screen_puts_len(text, len, row, col, attr)
|
||||
&& !gui.in_use
|
||||
# endif
|
||||
&& mb_fix_col(col, row) != col)
|
||||
screen_puts_len((char_u *)" ", 1, row, col - 1, 0);
|
||||
{
|
||||
ScreenLines[off - 1] = ' ';
|
||||
ScreenAttrs[off - 1] = 0;
|
||||
if (enc_utf8)
|
||||
{
|
||||
ScreenLinesUC[off - 1] = 0;
|
||||
ScreenLinesC[0][off - 1] = 0;
|
||||
}
|
||||
/* redraw the previous cell, make it empty */
|
||||
screen_char(off - 1, row, col - 1);
|
||||
/* force the cell at "col" to be redrawn */
|
||||
force_redraw_next = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
off = LineOffset[row] + col;
|
||||
#ifdef FEAT_MBYTE
|
||||
max_off = LineOffset[row] + screen_Columns;
|
||||
#endif
|
||||
@@ -6350,7 +6381,12 @@ screen_puts_len(text, len, row, col, attr)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ScreenLines[off] != c
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
|
||||
force_redraw_this = force_redraw_next;
|
||||
force_redraw_next = FALSE;
|
||||
#endif
|
||||
|
||||
need_redraw = ScreenLines[off] != c
|
||||
#ifdef FEAT_MBYTE
|
||||
|| (mbyte_cells == 2
|
||||
&& ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
|
||||
@@ -6358,24 +6394,24 @@ screen_puts_len(text, len, row, col, attr)
|
||||
&& c == 0x8e
|
||||
&& ScreenLines2[off] != ptr[1])
|
||||
|| (enc_utf8
|
||||
&& (ScreenLinesUC[off] != (u8char_T)u8c
|
||||
&& (ScreenLinesUC[off] != (u8char_T)(c >= 0x80 ? u8c : 0)
|
||||
|| screen_comp_differs(off, u8cc)))
|
||||
#endif
|
||||
|| ScreenAttrs[off] != attr
|
||||
|| exmode_active
|
||||
|| exmode_active;
|
||||
|
||||
if (need_redraw
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
|
||||
|| force_redraw_this
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if defined(FEAT_GUI) || defined(UNIX)
|
||||
/* The bold trick makes a single row of pixels appear in the next
|
||||
* character. When a bold character is removed, the next
|
||||
* character should be redrawn too. This happens for our own GUI
|
||||
* and for some xterms.
|
||||
* Force the redraw by setting the attribute to a different value
|
||||
* than "attr", the contents of ScreenLines[] may be needed by
|
||||
* mb_off2cells() further on.
|
||||
* Don't do this for the last drawn character, because the next
|
||||
* character may not be redrawn. */
|
||||
if (
|
||||
* and for some xterms. */
|
||||
if (need_redraw && ScreenLines[off] != ' ' && (
|
||||
# ifdef FEAT_GUI
|
||||
gui.in_use
|
||||
# endif
|
||||
@@ -6385,23 +6421,14 @@ screen_puts_len(text, len, row, col, attr)
|
||||
# ifdef UNIX
|
||||
term_is_xterm
|
||||
# endif
|
||||
)
|
||||
))
|
||||
{
|
||||
int n;
|
||||
int n = ScreenAttrs[off];
|
||||
|
||||
n = ScreenAttrs[off];
|
||||
# ifdef FEAT_MBYTE
|
||||
if (col + mbyte_cells < screen_Columns
|
||||
&& (n > HL_ALL || (n & HL_BOLD))
|
||||
&& (len < 0 ? ptr[mbyte_blen] != NUL
|
||||
: ptr + mbyte_blen < text + len))
|
||||
ScreenAttrs[off + mbyte_cells] = attr + 1;
|
||||
# else
|
||||
if (col + 1 < screen_Columns
|
||||
&& (n > HL_ALL || (n & HL_BOLD))
|
||||
&& (len < 0 ? ptr[1] != NUL : ptr + 1 < text + len))
|
||||
ScreenLines[off + 1] = 0;
|
||||
# endif
|
||||
if (n > HL_ALL)
|
||||
n = syn_attr2attr(n);
|
||||
if (n & HL_BOLD)
|
||||
force_redraw_next = TRUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -6488,6 +6515,20 @@ screen_puts_len(text, len, row, col, attr)
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FEAT_MBYTE) || defined(FEAT_GUI) || defined(UNIX)
|
||||
/* If we detected the next character needs to be redrawn, but the text
|
||||
* doesn't extend up to there, update the character here. */
|
||||
if (force_redraw_next && col < screen_Columns)
|
||||
{
|
||||
# ifdef FEAT_MBYTE
|
||||
if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1)
|
||||
screen_char_2(off, row, col);
|
||||
else
|
||||
# endif
|
||||
screen_char(off, row, col);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
@@ -7364,7 +7405,11 @@ screenalloc(clear)
|
||||
#endif
|
||||
static int entered = FALSE; /* avoid recursiveness */
|
||||
static int done_outofmem_msg = FALSE; /* did outofmem message */
|
||||
#ifdef FEAT_AUTOCMD
|
||||
int retry_count = 0;
|
||||
|
||||
retry:
|
||||
#endif
|
||||
/*
|
||||
* Allocation of the screen buffers is done only when the size changes and
|
||||
* when Rows and Columns have been set and we have started doing full
|
||||
@@ -7448,10 +7493,13 @@ screenalloc(clear)
|
||||
{
|
||||
outofmem = TRUE;
|
||||
#ifdef FEAT_WINDOWS
|
||||
break;
|
||||
goto give_up;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_WINDOWS
|
||||
give_up:
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
for (i = 0; i < p_mco; ++i)
|
||||
@@ -7636,8 +7684,17 @@ screenalloc(clear)
|
||||
--RedrawingDisabled;
|
||||
|
||||
#ifdef FEAT_AUTOCMD
|
||||
if (starting == 0)
|
||||
/*
|
||||
* Do not apply autocommands more than 3 times to avoid an endless loop
|
||||
* in case applying autocommands always changes Rows or Columns.
|
||||
*/
|
||||
if (starting == 0 && ++retry_count <= 3)
|
||||
{
|
||||
apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf);
|
||||
/* In rare cases, autocommands may have altered Rows or Columns,
|
||||
* jump back to check if we need to allocate the screen again. */
|
||||
goto retry;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -618,7 +618,7 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
taglen_advance(taglen);
|
||||
MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T));
|
||||
|
||||
for (i = 0; i < num_matches; ++i)
|
||||
for (i = 0; i < num_matches && !got_int; ++i)
|
||||
{
|
||||
parse_match(matches[i], &tagp);
|
||||
if (!new_tag && (
|
||||
@@ -655,6 +655,8 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
}
|
||||
if (msg_col > 0)
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
break;
|
||||
msg_advance(15);
|
||||
|
||||
/* print any extra fields */
|
||||
@@ -689,6 +691,8 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
if (msg_col + ptr2cells(p) >= Columns)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
break;
|
||||
msg_advance(15);
|
||||
}
|
||||
p = msg_outtrans_one(p, attr);
|
||||
@@ -704,6 +708,8 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
if (msg_col > 15)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
break;
|
||||
msg_advance(15);
|
||||
}
|
||||
}
|
||||
@@ -734,6 +740,8 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
{
|
||||
if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns)
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
break;
|
||||
msg_advance(15);
|
||||
|
||||
/* skip backslash used for escaping command char */
|
||||
@@ -760,12 +768,9 @@ do_tag(tag, type, count, forceit, verbose)
|
||||
if (msg_col)
|
||||
msg_putchar('\n');
|
||||
ui_breakcheck();
|
||||
if (got_int)
|
||||
{
|
||||
got_int = FALSE; /* only stop the listing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (got_int)
|
||||
got_int = FALSE; /* only stop the listing */
|
||||
ask_for_selection = TRUE;
|
||||
}
|
||||
#if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL)
|
||||
@@ -2542,6 +2547,15 @@ free_tag_stuff()
|
||||
{
|
||||
ga_clear_strings(&tag_fnames);
|
||||
do_tag(NULL, DT_FREE, 0, 0, 0);
|
||||
tag_freematch();
|
||||
|
||||
# if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
|
||||
if (ptag_entry.tagname)
|
||||
{
|
||||
vim_free(ptag_entry.tagname);
|
||||
ptag_entry.tagname = NULL;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
|
||||
test43.out test44.out test45.out test46.out test47.out \
|
||||
test48.out test51.out test53.out test54.out test55.out \
|
||||
test56.out test57.out test58.out test59.out test60.out \
|
||||
test61.out test62.out test63.out test64.out test65.out
|
||||
test61.out test62.out test63.out test64.out test65.out \
|
||||
test66.out
|
||||
|
||||
.SUFFIXES: .in .out
|
||||
|
||||
@@ -110,3 +111,4 @@ test62.out: test62.in
|
||||
test63.out: test63.in
|
||||
test64.out: test64.in
|
||||
test65.out: test65.in
|
||||
test66.out: test66.in
|
||||
|
||||
@@ -26,7 +26,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
|
||||
test15.out test17.out test18.out test21.out test26.out \
|
||||
test30.out test31.out test32.out test33.out test34.out \
|
||||
test37.out test38.out test39.out test40.out test41.out \
|
||||
test42.out test52.out test65.out
|
||||
test42.out test52.out test65.out test66.out
|
||||
|
||||
SCRIPTS32 = test50.out
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ SCRIPTS = test3.out test4.out test5.out test6.out test7.out \
|
||||
test15.out test17.out test18.out test21.out test26.out \
|
||||
test30.out test31.out test32.out test33.out test34.out \
|
||||
test37.out test38.out test39.out test40.out test41.out \
|
||||
test42.out test52.out test65.out
|
||||
test42.out test52.out test65.out test66.out
|
||||
|
||||
SCRIPTS32 = test50.out
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ SCRIPTS = test1.out test3.out test4.out test5.out test6.out \
|
||||
test43.out test44.out test45.out test46.out test47.out \
|
||||
test48.out test51.out test53.out test54.out test55.out \
|
||||
test56.out test57.out test58.out test59.out test60.out \
|
||||
test61.out test62.out test63.out test64.out test65.out
|
||||
test61.out test62.out test63.out test64.out test65.out \
|
||||
test66.out
|
||||
|
||||
.SUFFIXES: .in .out
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Authors: Zoltan Arpadffy, <arpadffy@polarhome.com>
|
||||
# Sandor Kopanyi, <sandor.kopanyi@mailbox.hu>
|
||||
#
|
||||
# Last change: 2008 Aug 19
|
||||
# Last change: 2009 Mar 05
|
||||
#
|
||||
# This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64.
|
||||
# Edit the lines in the Configuration section below to select.
|
||||
@@ -68,7 +68,8 @@ SCRIPT = test1.out test2.out test3.out test4.out test5.out \
|
||||
test43.out test44.out test45.out test46.out \
|
||||
test48.out test51.out test53.out test54.out test55.out \
|
||||
test56.out test57.out test60.out \
|
||||
test61.out test62.out test63.out test64.out test65.out
|
||||
test61.out test62.out test63.out test64.out test65.out \
|
||||
test66.out
|
||||
|
||||
.IFDEF WANT_GUI
|
||||
SCRIPT_GUI = test16.out
|
||||
|
||||
@@ -20,7 +20,7 @@ SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \
|
||||
test48.out test49.out test51.out test52.out test53.out \
|
||||
test54.out test55.out test56.out test57.out test58.out \
|
||||
test59.out test60.out test61.out test62.out test63.out \
|
||||
test64.out test65.out
|
||||
test64.out test65.out test66.out
|
||||
|
||||
SCRIPTS_GUI = test16.out
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Test for visual block shift and tab characters.
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
/^abcdefgh
|
||||
4jI j<<11|D
|
||||
7|a
|
||||
7|a
|
||||
7|a 4k13|4j<
|
||||
:$-4,$w! test.out
|
||||
:$-4,$s/\s\+//g
|
||||
4kI j<<
|
||||
7|a
|
||||
7|a
|
||||
7|a 4k13|4j3<
|
||||
:$-4,$w >> test.out
|
||||
:qa!
|
||||
ENDTEST
|
||||
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
@@ -0,0 +1,10 @@
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghij
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
abcdefghij
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
abc defghijklmnopqrstuvwxyz
|
||||
@@ -691,6 +691,86 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
148,
|
||||
/**/
|
||||
147,
|
||||
/**/
|
||||
146,
|
||||
/**/
|
||||
145,
|
||||
/**/
|
||||
144,
|
||||
/**/
|
||||
143,
|
||||
/**/
|
||||
142,
|
||||
/**/
|
||||
141,
|
||||
/**/
|
||||
140,
|
||||
/**/
|
||||
139,
|
||||
/**/
|
||||
138,
|
||||
/**/
|
||||
137,
|
||||
/**/
|
||||
136,
|
||||
/**/
|
||||
135,
|
||||
/**/
|
||||
134,
|
||||
/**/
|
||||
133,
|
||||
/**/
|
||||
132,
|
||||
/**/
|
||||
131,
|
||||
/**/
|
||||
130,
|
||||
/**/
|
||||
129,
|
||||
/**/
|
||||
128,
|
||||
/**/
|
||||
127,
|
||||
/**/
|
||||
126,
|
||||
/**/
|
||||
125,
|
||||
/**/
|
||||
124,
|
||||
/**/
|
||||
123,
|
||||
/**/
|
||||
122,
|
||||
/**/
|
||||
121,
|
||||
/**/
|
||||
120,
|
||||
/**/
|
||||
119,
|
||||
/**/
|
||||
118,
|
||||
/**/
|
||||
117,
|
||||
/**/
|
||||
116,
|
||||
/**/
|
||||
115,
|
||||
/**/
|
||||
114,
|
||||
/**/
|
||||
113,
|
||||
/**/
|
||||
112,
|
||||
/**/
|
||||
111,
|
||||
/**/
|
||||
110,
|
||||
/**/
|
||||
109,
|
||||
/**/
|
||||
108,
|
||||
/**/
|
||||
|
||||
@@ -710,7 +710,8 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
||||
#define EXPAND_USER_DEFINED 30
|
||||
#define EXPAND_USER_LIST 31
|
||||
#define EXPAND_SHELLCMD 32
|
||||
#define EXPAND_MACACTION 33
|
||||
#define EXPAND_CSCOPE 33
|
||||
#define EXPAND_MACACTION 34
|
||||
|
||||
/* Values for exmode_active (0 is no exmode) */
|
||||
#define EXMODE_NORMAL 1
|
||||
@@ -1060,6 +1061,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
||||
#define WSP_HELP 16 /* creating the help window */
|
||||
#define WSP_BELOW 32 /* put new window below/right */
|
||||
#define WSP_ABOVE 64 /* put new window above/left */
|
||||
#define WSP_NEWLOC 128 /* don't copy location list */
|
||||
|
||||
/*
|
||||
* arguments for gui_set_shellsize()
|
||||
|
||||
+16
-7
@@ -12,7 +12,7 @@
|
||||
static int path_is_url __ARGS((char_u *p));
|
||||
#if defined(FEAT_WINDOWS) || defined(PROTO)
|
||||
static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir));
|
||||
static void win_init __ARGS((win_T *newp, win_T *oldp));
|
||||
static void win_init __ARGS((win_T *newp, win_T *oldp, int flags));
|
||||
static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col));
|
||||
static void frame_setheight __ARGS((frame_T *curfrp, int height));
|
||||
#ifdef FEAT_VERTSPLIT
|
||||
@@ -594,9 +594,7 @@ wingotofile:
|
||||
++allow_keys; /* no mapping for xchar, but allow key codes */
|
||||
if (xchar == NUL)
|
||||
xchar = plain_vgetc();
|
||||
#ifdef FEAT_LANGMAP
|
||||
LANGMAP_ADJUST(xchar, TRUE);
|
||||
#endif
|
||||
--no_mapping;
|
||||
--allow_keys;
|
||||
#ifdef FEAT_CMDL_INFO
|
||||
@@ -913,7 +911,7 @@ win_split_ins(size, flags, newwin, dir)
|
||||
return FAIL;
|
||||
|
||||
/* make the contents of the new window the same as the current one */
|
||||
win_init(wp, curwin);
|
||||
win_init(wp, curwin, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1162,11 +1160,15 @@ win_split_ins(size, flags, newwin, dir)
|
||||
* Initialize window "newp" from window "oldp".
|
||||
* Used when splitting a window and when creating a new tab page.
|
||||
* The windows will both edit the same buffer.
|
||||
* WSP_NEWLOC may be specified in flags to prevent the location list from
|
||||
* being copied.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
win_init(newp, oldp)
|
||||
win_init(newp, oldp, flags)
|
||||
win_T *newp;
|
||||
win_T *oldp;
|
||||
int flags;
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1191,7 +1193,14 @@ win_init(newp, oldp)
|
||||
copy_jumplist(oldp, newp);
|
||||
#endif
|
||||
#ifdef FEAT_QUICKFIX
|
||||
copy_loclist(oldp, newp);
|
||||
if (flags & WSP_NEWLOC)
|
||||
{
|
||||
/* Don't copy the location list. */
|
||||
newp->w_llist = NULL;
|
||||
newp->w_llist_ref = NULL;
|
||||
}
|
||||
else
|
||||
copy_loclist(oldp, newp);
|
||||
#endif
|
||||
if (oldp->w_localdir != NULL)
|
||||
newp->w_localdir = vim_strsave(oldp->w_localdir);
|
||||
@@ -3221,7 +3230,7 @@ win_alloc_firstwin(oldwin)
|
||||
else
|
||||
{
|
||||
/* First window in new tab page, initialize it from "oldwin". */
|
||||
win_init(curwin, oldwin);
|
||||
win_init(curwin, oldwin, 0);
|
||||
|
||||
# ifdef FEAT_SCROLLBIND
|
||||
/* We don't want scroll-binding in the first window. */
|
||||
|
||||
Reference in New Issue
Block a user