Compare commits

..

29 Commits

Author SHA1 Message Date
Bjorn Winckler ab9df03d0d Snapshot 32 2008-06-22 14:30:09 +02:00
Bjorn Winckler e7b9c11089 Delay display of popup menu
The popup menu enters a modal loop so it is not displayed immediately to
avoid blocking inside processCommandQueue:.
2008-06-21 21:23:30 +02:00
Bjorn Winckler d98996d31c Code cleanup 2008-06-21 21:18:17 +02:00
Bjorn Winckler 40056b05c3 Delay processing unsafe command queue items
Unsafe messages are defined in isUnsafeMessage().  If a message is
unsafe it should only be handled in the default run loop mode.  This is
e.g. to avoid deleting Cocoa objects when a Cocoa message may be busy
processing it (which may happen due to the nature of distributed objects
and the fact that we process DO message in 'event tracking' mode).
2008-06-21 20:32:37 +02:00
Bjorn Winckler a4e3a7370b Search for toolbar icons in 'runtimepath' 2008-06-21 18:14:36 +02:00
Bjorn Winckler 7ad0084f3f Merge upstream 2008-06-21 16:31:00 +02:00
vimboss d165ccb4bc updated for version 7.1-330 2008-06-21 14:30:28 +00:00
vimboss b53ee76b5e updated for version 7.1-329 2008-06-21 12:14:30 +00:00
vimboss 6255f52fc5 updated for version 7.1-328 2008-06-21 11:12:49 +00:00
vimboss f63e3834b4 updated for version 7.1-327 2008-06-20 19:29:35 +00:00
Bjorn Winckler 9338c9c55c Fall back on latin-1 if Vim strings are not valid utf-8 2008-06-20 19:50:22 +02:00
Bjorn Winckler 11a1c2cb92 Never delete toolbar 2008-06-20 19:36:34 +02:00
Bjorn Winckler 59ad683558 Ensure vim controllers are released in default run loop mode
Vim controllers are released when NSConnectionDidDieNotification is
received.  This notification can arrive in pretty much any run loop mode
so we take care not to act on it until the run loop mode is back to
default.  Otherwise we run the risk of releasing objects which Cocoa is
currently using (e.g. view items) and this leads to crashes.
2008-06-20 19:33:34 +02:00
vimboss 95fb95ebcc updated for version 7.1-326 2008-06-20 16:51:41 +00:00
vimboss bc9688ffdc updated for version 7.1-325 2008-06-20 16:31:07 +00:00
vimboss bafdc2c3e1 updated for version 7.1-324 2008-06-20 16:07:02 +00:00
vimboss 279b3f843c updated for version 7.1-323 2008-06-20 15:53:31 +00:00
vimboss 603f746178 updated for version 7.1-322 2008-06-20 15:31:51 +00:00
vimboss 255571d05e updated for version 7.1-321 2008-06-20 14:52:32 +00:00
vimboss 82038bc905 updated for version 7.1-320 2008-06-20 14:32:41 +00:00
vimboss bca5b2086e updated for version 7.1-319 2008-06-20 10:56:16 +00:00
vimboss 67d03b985b updated for version 7.1-318 2008-06-20 09:59:25 +00:00
vimboss 2d36c33fd5 updated for version 7.1-317 2008-06-20 09:40:11 +00:00
vimboss ee9959e56c updated for version 7.1-316 2008-06-20 09:11:34 +00:00
Bjorn Winckler 9ca5f6bcdb Guard against reentrant calls to processCommandQueue:
If processCommandQueue: is called when inProcessCommandQueue is set we
add the input to a receive queue and return.  This is to ensure that
processCommandQueue: can only be called "once at a time".  Reentrant
calls can be caused by calling a synchronous DO message or by entering a
modal loop in the frontend.
2008-06-15 16:11:38 +02:00
vimboss 626995c3e8 updated for version 7.1-315 2008-06-15 12:21:50 +00:00
Bjorn Winckler 634ef3b803 Never translate Ctrl-click if Alt, Shift, or Cmd are pressed 2008-06-13 19:27:56 +02:00
Bjorn Winckler aed4648a3d Make background processes work 2008-06-13 19:12:55 +02:00
Bjorn Winckler cd2f7e9eb1 Flush output queue even when 'exiting' flag is set
There are legitimate instances when the queue should flush even though
Vim is exiting, e.g. to display a 'confirm quit' dialog with 'go+=c'.

This patch has the negative side-effect that the "dropping DO message"
warning may occur more frequently.  Another fix for this problem has to
be devised.
2008-06-13 19:01:56 +02:00
33 changed files with 569 additions and 312 deletions
+4
View File
@@ -3515,6 +3515,10 @@ line({expr}) The result is a Number, which is the line number of the file
returned)
w0 first line visible in current window
w$ last line visible in current window
v In Visual mode: the start of the Visual area (the
cursor is the end). When not in Visual mode
returns the cursor position. Differs from |'<| in
that it's updated right away.
Note that a mark in another file can be used. The line number
then applies to another buffer.
To get the column number use |col()|. To get both use
+10 -2
View File
@@ -36,7 +36,7 @@ The currently preferred method is using the free Visual C++ Toolkit 2003.
Visual Studio
-------------
Building with Visual Studio (VS 98, VS .NET, VS .NET 2003, and VS .NET 2005)
Building with Visual Studio (VS 98, VS .NET, VS .NET 2003, VS 2005, and VS 2008)
is straightforward. (These instructions should also work for VS 4 and VS 5.)
To build Vim from the command line with MSVC, use Make_mvc.mak.
@@ -139,7 +139,7 @@ to debug Vim itself. An earlier version of the Debugging Tools
is also available through the Platform SDK, |ms-platform-sdk|.
Visual C++ 2005 Express Edition
Visual C++ 2005 Express Edition *msvc-2005-express*
-------------------------------
Visual C++ 2005 Express Edition can be downloaded for free from:
@@ -159,6 +159,14 @@ Visual C++ 2008 Express Edition can be downloaded for free from:
This includes the IDE and the debugger. You can build Vim with Make_mvc.mak.
Visual C++ 2008 Express Edition *msvc-2008-express*
-------------------------------
Visual C++ 2008 Express Edition can be downloaded for free from:
http://msdn2.microsoft.com/en-us/express/default.aspx
This includes the IDE and the debugger. You can build Vim with Make_mvc.mak.
2. MinGW
========
+1 -1
View File
@@ -574,7 +574,7 @@
<key>CFBundleSignature</key>
<string>VIMM</string>
<key>CFBundleVersion</key>
<string>31</string>
<string>32</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
+1
View File
@@ -570,6 +570,7 @@ static int executeInLoginShell(NSString *path, NSArray *args);
{
//NSLog(@"%s%@", _cmd, controller);
[controller cleanup];
[[controller windowController] close];
[vimControllers removeObject:controller];
+6 -4
View File
@@ -462,10 +462,9 @@ static NSString *MMSymlinkWarningString =
// NOTE! This method gets called a lot; if we were to flush every time it
// got called MacVim would feel unresponsive. So there is a time out which
// ensures that the queue isn't flushed too often.
if (exiting ||
(!force && lastFlushDate &&
-[lastFlushDate timeIntervalSinceNow] < MMFlushTimeoutInterval &&
[drawData length] < MMFlushQueueLenHint))
if (!force && lastFlushDate
&& -[lastFlushDate timeIntervalSinceNow] < MMFlushTimeoutInterval
&& [drawData length] < MMFlushQueueLenHint)
return;
if ([drawData length] > 0) {
@@ -1847,6 +1846,9 @@ static NSString *MMSymlinkWarningString =
- (void)queueMessage:(int)msgid data:(NSData *)data
{
//if (msgid != EnableMenuItemMsgID)
// NSLog(@"queueMessage:%s", MessageStrings[msgid]);
[outputQueue addObject:[NSData dataWithBytes:&msgid length:sizeof(int)]];
if (data)
[outputQueue addObject:data];
+6 -3
View File
@@ -853,9 +853,12 @@ enum {
NSMutableData *data = [NSMutableData data];
// If desired, intepret Ctrl-Click as a right mouse click.
if ([[NSUserDefaults standardUserDefaults]
boolForKey:MMTranslateCtrlClickKey]
&& button == 0 && flags & NSControlKeyMask) {
BOOL translateCtrlClick = [[NSUserDefaults standardUserDefaults]
boolForKey:MMTranslateCtrlClickKey];
flags = flags & NSDeviceIndependentModifierFlagsMask;
if (translateCtrlClick && button == 0 &&
(flags == NSControlKeyMask ||
flags == (NSControlKeyMask|NSAlphaShiftKeyMask))) {
button = 1;
flags &= ~NSControlKeyMask;
}
+1 -9
View File
@@ -12,10 +12,6 @@
#import "MacVim.h"
// If sendMessage: fails, store the message and resend after a delay.
#define MM_RESEND_LAST_FAILURE 0
@class MMWindowController;
@@ -27,17 +23,13 @@
id backendProxy;
BOOL inProcessCommandQueue;
NSMutableArray *sendQueue;
NSMutableArray *receiveQueue;
NSMenu *mainMenu;
NSMutableArray *popupMenuItems;
NSToolbar *toolbar;
NSMutableDictionary *toolbarItemDict;
int pid;
NSString *serverName;
#ifdef MM_RESEND_LAST_FAILURE
NSTimer *resendTimer;
int resendMsgid;
NSData *resendData;
#endif
NSDictionary *vimState;
}
+187 -103
View File
@@ -41,14 +41,15 @@ static int MMAlertTextFieldHeight = 22;
// sendMessage: to actually reach Vim.
static NSTimeInterval MMBackendProxyRequestTimeout = 0;
#if MM_RESEND_LAST_FAILURE
// If a message send fails, the message will be resent after this many seconds
// have passed. (No queue is kept, only the very last message is resent.)
static NSTimeInterval MMResendInterval = 0.5;
#endif
// 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 BOOL isUnsafeMessage(int msgid);
@interface MMAlert : NSAlert {
NSTextField *textField;
@@ -59,6 +60,7 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
@interface MMVimController (Private)
- (void)doProcessCommandQueue:(NSArray *)queue;
- (void)handleMessage:(int)msgid data:(NSData *)data;
- (void)savePanelDidEnd:(NSSavePanel *)panel code:(int)code
context:(void *)context;
@@ -85,10 +87,8 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
- (void)popupMenuWithDescriptor:(NSArray *)desc
atRow:(NSNumber *)row
column:(NSNumber *)col;
- (void)popupMenuWithAttributes:(NSDictionary *)attrs;
- (void)connectionDidDie:(NSNotification *)notification;
#if MM_RESEND_LAST_FAILURE
- (void)resendTimerFired:(NSTimer *)timer;
#endif
@end
@@ -110,6 +110,7 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[[MMWindowController alloc] initWithVimController:self];
backendProxy = [backend retain];
sendQueue = [NSMutableArray new];
receiveQueue = [NSMutableArray new];
popupMenuItems = [[NSMutableArray alloc] init];
toolbarItemDict = [[NSMutableDictionary alloc] init];
pid = processIdentifier;
@@ -154,13 +155,10 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
//NSLog(@"%@ %s", [self className], _cmd);
isInitialized = NO;
#if MM_RESEND_LAST_FAILURE
[resendData release]; resendData = nil;
#endif
[serverName release]; serverName = nil;
[backendProxy release]; backendProxy = nil;
[sendQueue release]; sendQueue = nil;
[receiveQueue release]; receiveQueue = nil;
[toolbarItemDict release]; toolbarItemDict = nil;
[toolbar release]; toolbar = nil;
@@ -311,42 +309,12 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
return;
}
#if MM_RESEND_LAST_FAILURE
if (resendTimer) {
//NSLog(@"cancelling scheduled resend of %s",
// MessageStrings[resendMsgid]);
[resendTimer invalidate];
[resendTimer release];
resendTimer = nil;
}
if (resendData) {
[resendData release];
resendData = nil;
}
#endif
@try {
[backendProxy processInput:msgid data:data];
}
@catch (NSException *e) {
//NSLog(@"%@ %s Exception caught during DO call: %@",
// [self className], _cmd, e);
#if MM_RESEND_LAST_FAILURE
//NSLog(@"%s failed, scheduling message %s for resend", _cmd,
// MessageStrings[msgid]);
resendMsgid = msgid;
resendData = [data retain];
resendTimer = [NSTimer
scheduledTimerWithTimeInterval:MMResendInterval
target:self
selector:@selector(resendTimerFired:)
userInfo:nil
repeats:NO];
[resendTimer retain];
#endif
}
}
@@ -425,6 +393,7 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
title:(in bycopy NSString *)title
saving:(int)saving
{
// TODO: Delay call until run loop is in default mode.
if (!isInitialized) return;
if (!dir) {
@@ -459,6 +428,7 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
buttonTitles:(in bycopy NSArray *)buttonTitles
textFieldString:(in bycopy NSString *)textFieldString
{
// TODO: Delay call until run loop is in default mode.
if (!(windowController && buttonTitles && [buttonTitles count])) return;
MMAlert *alert = [[MMAlert alloc] init];
@@ -528,34 +498,43 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
{
if (!isInitialized) return;
@try {
unsigned i, count = [queue count];
if (count % 2) {
NSLog(@"WARNING: Uneven number of components (%d) in flush queue "
"message; ignoring this message.", count);
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];
inProcessCommandQueue = YES;
//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]);
[self handleMessage:msgid data:data];
}
//NSLog(@"======== %s END ========", _cmd);
}
@catch (NSException *e) {
NSLog(@"Exception caught whilst processing command queue: %@", e);
[receiveQueue addObject:queue];
return;
}
[windowController processCommandQueueDidFinish];
inProcessCommandQueue = NO;
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.
if ([sendQueue count] > 0) {
@try {
@@ -568,6 +547,10 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[sendQueue removeAllObjects];
}
[windowController processCommandQueueDidFinish];
[receiveQueue removeAllObjects];
inProcessCommandQueue = NO;
}
- (NSToolbarItem *)toolbar:(NSToolbar *)theToolbar
@@ -598,9 +581,74 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
@implementation MMVimController (Private)
- (void)doProcessCommandQueue:(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 listen 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);
}
@catch (NSException *e) {
NSLog(@"Exception caught whilst processing command queue: %@", e);
}
if (delayQueue) {
//NSLog(@" Flushing delay queue (%d items)", [delayQueue count]/2);
[self performSelectorOnMainThread:@selector(processCommandQueue:)
withObject:delayQueue
waitUntilDone:NO
modes:[NSArray arrayWithObject:
NSDefaultRunLoopMode]];
}
}
- (void)handleMessage:(int)msgid data:(NSData *)data
{
//if (msgid != AddMenuMsgID && msgid != AddMenuItemMsgID)
//if (msgid != AddMenuMsgID && msgid != AddMenuItemMsgID &&
// msgid != EnableMenuItemMsgID)
// NSLog(@"%@ %s%s", [self className], _cmd, MessageStrings[msgid]);
if (OpenVimWindowMsgID == msgid) {
@@ -757,9 +805,14 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[actionName release];
} else if (ShowPopupMenuMsgID == msgid) {
NSDictionary *attrs = [NSDictionary dictionaryWithData:data];
[self popupMenuWithDescriptor:[attrs objectForKey:@"descriptor"]
atRow:[attrs objectForKey:@"row"]
column:[attrs objectForKey:@"column"]];
// 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]];
} else if (SetMouseShapeMsgID == msgid) {
const void *bytes = [data bytes];
int shape = *((int*)bytes); bytes += sizeof(int);
@@ -806,6 +859,8 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[vimState release];
vimState = [dict retain];
}
// IMPORTANT: When adding a new message, make sure to update
// isUnsafeMessage() if necessary!
} else {
NSLog(@"WARNING: Unknown message received (msgid=%d)", msgid);
}
@@ -1068,10 +1123,9 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
NSString *rootName = [desc objectAtIndex:0];
if ([rootName isEqual:@"ToolBar"]) {
if (toolbar) {
if ([desc count] == 1) {
[windowController setToolbar:nil];
[toolbar release]; toolbar = nil;
} else if ([desc count] == 2) {
// Only remove toolbar items, never actually remove the toolbar
// itself or strange things may happen.
if ([desc count] == 2) {
int idx = [toolbar indexOfItemWithItemIdentifier:title];
if (idx != NSNotFound)
[toolbar removeItemAtIndex:idx];
@@ -1125,7 +1179,8 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
}
- (void)addToolbarItemToDictionaryWithLabel:(NSString *)title
toolTip:(NSString *)tip icon:(NSString *)icon
toolTip:(NSString *)tip
icon:(NSString *)icon
{
// If the item corresponds to a separator then do nothing, since it is
// already defined by Cocoa.
@@ -1141,6 +1196,8 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[item setAutovalidates:NO];
NSImage *img = [NSImage imageNamed:icon];
if (!img)
img = [[[NSImage alloc] initByReferencingFile:icon] autorelease];
if (!img) {
NSLog(@"WARNING: Could not find image with name '%@' to use as toolbar"
" image for identifier '%@';"
@@ -1157,8 +1214,10 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[item release];
}
- (void)addToolbarItemWithLabel:(NSString *)label tip:(NSString
*)tip icon:(NSString *)icon atIndex:(int)idx
- (void)addToolbarItemWithLabel:(NSString *)label
tip:(NSString *)tip
icon:(NSString *)icon
atIndex:(int)idx
{
if (!toolbar) return;
@@ -1219,16 +1278,32 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
[NSMenu popUpContextMenu:menu withEvent:event forView:textView];
}
- (void)popupMenuWithAttributes:(NSDictionary *)attrs
{
if (!attrs) return;
[self popupMenuWithDescriptor:[attrs objectForKey:@"descriptor"]
atRow:[attrs objectForKey:@"row"]
column:[attrs objectForKey:@"column"]];
}
- (void)connectionDidDie:(NSNotification *)notification
{
//NSLog(@"%@ %s%@", [self className], _cmd, notification);
[self cleanup];
// NOTE! This causes the call to removeVimController: to be delayed.
// NOTE! This notification can arrive at pretty much anytime, e.g. while
// the run loop is the 'event tracking' mode. This means that Cocoa may
// well be in the middle of processing some message while this message is
// received. If we were to remove the vim controller straight away we may
// free objects that Cocoa is currently using (e.g. view objects). The
// 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];
withObject:self
waitUntilDone:NO
modes:[NSArray arrayWithObject:
NSDefaultRunLoopMode]];
}
- (NSString *)description
@@ -1236,26 +1311,6 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
return [NSString stringWithFormat:@"%@ : isInitialized=%d inProcessCommandQueue=%d mainMenu=%@ popupMenuItems=%@ toolbar=%@", [self className], isInitialized, inProcessCommandQueue, mainMenu, popupMenuItems, toolbar];
}
#if MM_RESEND_LAST_FAILURE
- (void)resendTimerFired:(NSTimer *)timer
{
int msgid = resendMsgid;
NSData *data = nil;
[resendTimer release];
resendTimer = nil;
if (!isInitialized)
return;
if (resendData)
data = [resendData copy];
//NSLog(@"Resending message: %s", MessageStrings[msgid]);
[self sendMessage:msgid data:data];
}
#endif
@end // MMVimController (Private)
@@ -1360,3 +1415,32 @@ static NSTimeInterval MMSetDialogReturnTimeout = 1.0;
}
@end // MMAlert
static BOOL
isUnsafeMessage(int msgid)
{
// Messages that may release Cocoa objects must be added to this list. For
// example, UpdateTabBarMsgID may delete NSTabViewItem objects so it goes
// on this list.
static int unsafeMessages[] = { // REASON MESSAGE IS ON THIS LIST:
OpenVimWindowMsgID, // Changes lots of state
UpdateTabBarMsgID, // May delete NSTabViewItem
RemoveMenuItemMsgID, // Deletes NSMenuItem
DestroyScrollbarMsgID, // Deletes NSScroller
ExecuteActionMsgID, // Impossible to predict
ShowPopupMenuMsgID, // Enters modal loop
ActivateMsgID, // ?
EnterFullscreenMsgID, // Modifies delegate of window controller
LeaveFullscreenMsgID, // Modifies delegate of window controller
};
int i, count = sizeof(unsafeMessages)/sizeof(unsafeMessages[0]);
for (i = 0; i < count; ++i)
if (msgid == unsafeMessages[i])
return YES;
return NO;
}
-1
View File
@@ -30,7 +30,6 @@
- (MMVimView *)initWithFrame:(NSRect)frame vimController:(MMVimController *)c;
- (MMTextView *)textView;
- (NSMutableArray *)scrollbars;
- (void)cleanup;
- (NSSize)desiredSize;
+4 -9
View File
@@ -208,11 +208,6 @@ enum {
return textView;
}
- (NSMutableArray *)scrollbars
{
return scrollbars;
}
- (PSMTabBarControl *)tabBarControl
{
return tabBarControl;
@@ -374,7 +369,7 @@ enum {
[scroller setAction:@selector(scroll:)];
[self addSubview:scroller];
[[self scrollbars] addObject:scroller];
[scrollbars addObject:scroller];
[scroller release];
}
@@ -387,7 +382,7 @@ enum {
if (!scroller) return NO;
[scroller removeFromSuperview];
[[self scrollbars] removeObjectAtIndex:idx];
[scrollbars removeObjectAtIndex:idx];
// If a visible scroller was removed then the vim view must resize. This
// is handled by the window controller (the vim view never resizes itself).
@@ -719,9 +714,9 @@ enum {
- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx
{
unsigned i, count = [[self scrollbars] count];
unsigned i, count = [scrollbars count];
for (i = 0; i < count; ++i) {
MMScroller *scroller = [[self scrollbars] objectAtIndex:i];
MMScroller *scroller = [scrollbars objectAtIndex:i];
if ([scroller identifier] == ident) {
if (idx) *idx = i;
return scroller;
+7 -3
View File
@@ -289,9 +289,10 @@
//NSLog(@"setTextDimensionsWithRows:%d columns:%d live:%s", rows, cols,
// live ? "YES" : "NO");
// NOTE: This is the only place where the (rows,columns) of the vim view
// are modified. Setting these values have no immediate effect, the actual
// resizing of the view is done in processCommandQueueDidFinish.
// 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.
//
// 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
@@ -387,6 +388,9 @@
- (void)processCommandQueueDidFinish
{
// 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
+5
View File
@@ -38,6 +38,11 @@
//
// 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)showSavePanelForDirectory:(in bycopy NSString *)dir
+3 -3
View File
@@ -698,7 +698,7 @@
i386,
);
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 31;
CURRENT_PROJECT_VERSION = 32;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
@@ -739,7 +739,7 @@
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 31;
CURRENT_PROJECT_VERSION = 32;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
@@ -770,7 +770,7 @@
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 31;
CURRENT_PROJECT_VERSION = 32;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
+24 -8
View File
@@ -691,11 +691,6 @@ gui_mch_add_menu(vimmenu_T *menu, int idx)
void
gui_mch_add_menu_item(vimmenu_T *menu, int idx)
{
// NOTE! If 'iconfile' is not set but 'iconidx' is, use the name of the
// menu item. (Should correspond to a stock item.)
char_u *icon = menu->iconfile ? menu->iconfile :
menu->iconidx >= 0 ? menu->dname :
NULL;
char_u *tip = menu->strings[MENU_INDEX_TIP]
? menu->strings[MENU_INDEX_TIP] : menu->actext;
NSArray *desc = descriptor_for_menu(menu);
@@ -703,6 +698,18 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)
? [NSString stringWithFormat:@"%C", specialKeyToNSKey(menu->mac_key)]
: [NSString string];
int modifierMask = vimModMaskToEventModifierFlags(menu->mac_mods);
char_u *icon = NULL;
if (menu_is_toolbar(menu->parent->name)) {
char_u fname[MAXPATHL];
// TODO: Ensure menu->iconfile exists (if != NULL)
icon = menu->iconfile;
if (!icon && gui_find_bitmap(menu->name, fname, "bmp") == OK)
icon = fname;
if (!icon && menu->iconidx >= 0)
icon = menu->dname;
}
[[MMBackend sharedInstance] queueMessage:AddMenuItemMsgID properties:
[NSDictionary dictionaryWithObjectsAndKeys:
@@ -2017,17 +2024,26 @@ static int vimModMaskToEventModifierFlags(int mods)
@implementation NSString (VimStrings)
+ (id)stringWithVimString:(char_u *)s
{
// This method ensures a non-nil string is returned. If 's' cannot be
// converted to a utf-8 string it is assumed to be latin-1. If conversion
// still fails an empty NSString is returned.
NSString *string = nil;
if (s) {
#ifdef FEAT_MBYTE
s = CONVERT_TO_UTF8(s);
#endif
NSString *string = [NSString stringWithUTF8String:(char*)s];
string = [NSString stringWithUTF8String:(char*)s];
if (!string) {
// HACK! Apparently 's' is not a valid utf-8 string, maybe it is
// latin-1?
string = [NSString stringWithCString:(char*)s
encoding:NSISOLatin1StringEncoding];
}
#ifdef FEAT_MBYTE
CONVERT_TO_UTF8_FREE(s);
#endif
return string;
}
return [NSString string];
return string != nil ? string : [NSString string];
}
@end
+31
View File
@@ -40,6 +40,37 @@
Sparkle supports updates in zip, tar, tbz, tgz, or dmg format.
-->
<item>
<title>Snapshot 32 released</title>
<description><![CDATA[
<h1>MacVim snapshot 32 released</h1>
<p><em> This snapshot contains fixes for several severe bugs; I strongly suggest
that you update now! </em></p>
<p> Changes since snapshot 31:
<ul>
<li> Fix several bugs that caused MacVim to crash </li>
<li> Console dialogs work once again (set go+=c) </li>
<li> Background processes work (:sh ... &) </li>
<li> Ctrl-Shift can be used for modeless selection </li>
<li> No crashes with HTML plugin </li>
<li> Toolbar is a bit better at finding icons (this still needs some work)
</li>
<li> Latest Vim source code and runtime files merged </li>
</ul>
</p>
]]></description>
<pubDate>Fri, 22 Jun 2008 13:13 CET</pubDate>
<enclosure type="application/octet-stream"
url="http://macvim.googlecode.com/files/MacVim-snapshot-32.tbz"
length="8194915"
sparkle:version="32"
sparkle:shortVersionString="7.1"
/>
</item>
<item>
<title>Snapshot 31 released</title>
<description><![CDATA[
+17 -13
View File
@@ -1113,7 +1113,7 @@ GTK_IPATH = $(GUI_INC_LOC)
GTK_LIBS_DIR = $(GUI_LIB_LOC)
GTK_LIBS1 =
GTK_LIBS2 = $(GTK_LIBNAME)
GTK_INSTALL = install_normal
GTK_INSTALL = install_normal install_gui_extra
GTK_TARGETS = installglinks
GTK_MAN_TARGETS = yes
GTK_TESTTARGET = gui
@@ -1130,7 +1130,7 @@ MOTIF_IPATH = $(GUI_INC_LOC)
MOTIF_LIBS_DIR = $(GUI_LIB_LOC)
MOTIF_LIBS1 =
MOTIF_LIBS2 = $(MOTIF_LIBNAME) -lXt
MOTIF_INSTALL = install_normal
MOTIF_INSTALL = install_normal install_gui_extra
MOTIF_TARGETS = installglinks
MOTIF_MAN_TARGETS = yes
MOTIF_TESTTARGET = gui
@@ -1160,7 +1160,7 @@ ATHENA_IPATH = $(GUI_INC_LOC)
ATHENA_LIBS_DIR = $(GUI_LIB_LOC)
ATHENA_LIBS1 = $(XAW_LIB)
ATHENA_LIBS2 = -lXt
ATHENA_INSTALL = install_normal
ATHENA_INSTALL = install_normal install_gui_extra
ATHENA_TARGETS = installglinks
ATHENA_MAN_TARGETS = yes
ATHENA_TESTTARGET = gui
@@ -1178,7 +1178,7 @@ NEXTAW_IPATH = $(GUI_INC_LOC)
NEXTAW_LIBS_DIR = $(GUI_LIB_LOC)
NEXTAW_LIBS1 = $(NEXTAW_LIB)
NEXTAW_LIBS2 = -lXt
NEXTAW_INSTALL = install_normal
NEXTAW_INSTALL = install_normal install_gui_extra
NEXTAW_TARGETS = installglinks
NEXTAW_MAN_TARGETS = yes
NEXTAW_TESTTARGET = gui
@@ -1203,7 +1203,7 @@ PHOTONGUI_IPATH =
PHOTONGUI_LIBS_DIR =
PHOTONGUI_LIBS1 = -lph -lphexlib
PHOTONGUI_LIBS2 =
PHOTONGUI_INSTALL = install_normal
PHOTONGUI_INSTALL = install_normal install_gui_extra
PHOTONGUI_TARGETS = installglinks
PHOTONGUI_MAN_TARGETS = yes
PHOTONGUI_TESTTARGET = gui
@@ -1219,7 +1219,7 @@ CARBONGUI_IPATH = -I. -Iproto
CARBONGUI_LIBS_DIR =
CARBONGUI_LIBS1 = -framework Carbon
CARBONGUI_LIBS2 =
CARBONGUI_INSTALL = install_macosx
CARBONGUI_INSTALL = install_macosx install_gui_extra
CARBONGUI_TARGETS =
CARBONGUI_MAN_TARGETS =
CARBONGUI_TESTTARGET = gui
@@ -1757,6 +1757,15 @@ testclean:
cd $(PODIR); $(MAKE) checkclean; \
fi
install: $(GUI_INSTALL)
install_normal: installvim installtools $(INSTALL_LANGS) install-icons
install_gui_extra: installgtutorbin
installvim: installvimbin installtutorbin \
installruntime installlinks installmanlinks
#
# Avoid overwriting an existing executable, somebody might be running it and
# overwriting it could cause it to crash. Deleting it is OK, it won't be
@@ -1766,13 +1775,6 @@ testclean:
# If you want to keep an older version, rename it before running "make
# install".
#
install: $(GUI_INSTALL)
install_normal: installvim installtools $(INSTALL_LANGS) install-icons
installvim: installvimbin installtutorbin \
installruntime installlinks installmanlinks
installvimbin: $(VIMTARGET) $(DESTDIR)$(exec_prefix) $(DEST_BIN)
-if test -f $(DEST_BIN)/$(VIMTARGET); then \
mv -f $(DEST_BIN)/$(VIMTARGET) $(DEST_BIN)/$(VIMNAME).rm; \
@@ -1888,6 +1890,8 @@ installmacros: $(DEST_VIM) $(DEST_RT) $(DEST_MACRO)
installtutorbin: $(DEST_VIM)
$(INSTALL_DATA) vimtutor $(DEST_BIN)/$(VIMNAME)tutor
chmod $(SCRIPTMOD) $(DEST_BIN)/$(VIMNAME)tutor
installgtutorbin: $(DEST_VIM)
$(INSTALL_DATA) gvimtutor $(DEST_BIN)/$(GVIMNAME)tutor
chmod $(SCRIPTMOD) $(DEST_BIN)/$(GVIMNAME)tutor
+10 -2
View File
@@ -16927,9 +16927,17 @@ var2fpos(varp, dollar_lnum, fnum)
name = get_tv_string_chk(varp);
if (name == NULL)
return NULL;
if (name[0] == '.') /* cursor */
if (name[0] == '.') /* cursor */
return &curwin->w_cursor;
if (name[0] == '\'') /* mark */
#ifdef FEAT_VISUAL
if (name[0] == 'v' && name[1] == NUL) /* Visual start */
{
if (VIsual_active)
return &VIsual;
return &curwin->w_cursor;
}
#endif
if (name[0] == '\'') /* mark */
{
pp = getmark_fnum(name[1], FALSE, fnum);
if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0)
+4 -2
View File
@@ -2148,7 +2148,9 @@ do_one_cmd(cmdlinep, sourcing,
#endif
if (*p == '!' && ea.cmdidx != CMD_substitute) /* forced commands */
/* forced commands */
if (*p == '!' && ea.cmdidx != CMD_substitute
&& ea.cmdidx != CMD_smagic && ea.cmdidx != CMD_snomagic)
{
++p;
ea.forceit = TRUE;
@@ -9319,7 +9321,7 @@ ex_tag_cmd(eap, name)
break;
default: /* ":tag" */
#ifdef FEAT_CSCOPE
if (p_cst)
if (p_cst && *eap->arg != NUL)
{
do_cstag(eap);
return;
+10 -12
View File
@@ -2053,10 +2053,10 @@ set_cmdspos_cursor()
if (has_mbyte)
correct_cmdspos(i, c);
#endif
/* If the cmdline doesn't fit, put cursor on last visible char. */
/* If the cmdline doesn't fit, show cursor on last visible char.
* Don't move the cursor itself, so we can still append. */
if ((ccline.cmdspos += c) >= m)
{
ccline.cmdpos = i - 1;
ccline.cmdspos -= c;
break;
}
@@ -2829,10 +2829,11 @@ put_on_cmdline(str, len, redraw)
if (has_mbyte)
correct_cmdspos(ccline.cmdpos, c);
#endif
/* Stop cursor at the end of the screen */
if (ccline.cmdspos + c >= m)
break;
ccline.cmdspos += c;
/* Stop cursor at the end of the screen, but do increment the
* insert position, so that entering a very long command
* works, even though you can't see it. */
if (ccline.cmdspos + c < m)
ccline.cmdspos += c;
#ifdef FEAT_MBYTE
if (has_mbyte)
{
@@ -3032,10 +3033,7 @@ cmdline_paste_str(s, literally)
++s;
#ifdef FEAT_MBYTE
if (has_mbyte)
{
c = mb_ptr2char(s);
s += mb_char2len(c);
}
c = mb_cptr2char_adv(&s);
else
#endif
c = *s++;
@@ -3335,7 +3333,7 @@ nextwild(xp, type, options)
/*
* Do wildcard expansion on the string 'str'.
* Chars that should not be expanded must be preceded with a backslash.
* Return a pointer to alloced memory containing the new string.
* Return a pointer to allocated memory containing the new string.
* Return NULL for failure.
*
* "orig" is the originally expanded string, copied to allocated memory. It
@@ -6117,7 +6115,7 @@ ex_window()
exmode_active = save_exmode;
/* Safety check: The old window or buffer was deleted: It's a a bug when
/* Safety check: The old window or buffer was deleted: It's a bug when
* this happens! */
if (!win_valid(old_curwin) || !buf_valid(old_curbuf))
{
+2 -1
View File
@@ -4836,7 +4836,8 @@ ex_gui(eap)
}
#if ((defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) || defined(FEAT_GUI_W32) \
|| defined(FEAT_GUI_PHOTON)) && defined(FEAT_TOOLBAR)) || defined(PROTO)
|| defined(FEAT_GUI_PHOTON)) && defined(FEAT_TOOLBAR) \
|| defined(FEAT_GUI_MACVIM)) || defined(PROTO)
/*
* This is shared between Athena, Motif and GTK.
*/
+10 -10
View File
@@ -686,8 +686,8 @@ manage_centered(dialog_child)
/* Temporarily set value of XmNmappedWhenManaged
to stop the dialog from popping up right away */
XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, 0);
XtVaSetValues(shell, XmNmappedWhenManaged, False, 0);
XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, NULL);
XtVaSetValues(shell, XmNmappedWhenManaged, False, NULL);
XtManageChild(dialog_child);
@@ -723,7 +723,7 @@ manage_centered(dialog_child)
XtMapWidget(shell);
/* Restore the value of XmNmappedWhenManaged */
XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, 0);
XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, NULL);
}
#if defined(FEAT_MENU) || defined(FEAT_SUN_WORKSHOP) \
@@ -1993,7 +1993,7 @@ do_mnemonic(Widget w, unsigned int keycode)
{
if (XtClass(w) == xmRowColumnWidgetClass)
{
XtVaGetValues(w, XmNrowColumnType, &rowColType, 0);
XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
isMenu = (rowColType != (unsigned char)XmWORK_AREA);
}
else
@@ -2001,14 +2001,14 @@ do_mnemonic(Widget w, unsigned int keycode)
if (!isMenu)
{
XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
&numChildren, 0);
&numChildren, NULL);
for (i = 0; i < numChildren; i++)
do_mnemonic(children[i], keycode);
}
}
else
{
XtVaGetValues(w, XmNmnemonic, &mnemonic, 0);
XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
if (mnemonic != '\0')
{
mneString[0] = mnemonic;
@@ -2019,7 +2019,7 @@ do_mnemonic(Widget w, unsigned int keycode)
if (XtClass(w) == xmLabelWidgetClass
|| XtClass(w) == xmLabelGadgetClass)
{
XtVaGetValues(w, XmNuserData, &userData, 0);
XtVaGetValues(w, XmNuserData, &userData, NULL);
if (userData != NULL && XtIsWidget(userData))
XmProcessTraversal(userData, XmTRAVERSE_CURRENT);
}
@@ -2073,7 +2073,7 @@ add_mnemonic_grabs(Widget dialog, Widget w)
{
if (XtClass(w) == xmRowColumnWidgetClass)
{
XtVaGetValues(w, XmNrowColumnType, &rowColType, 0);
XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
isMenu = (rowColType != (unsigned char)XmWORK_AREA);
}
else
@@ -2081,14 +2081,14 @@ add_mnemonic_grabs(Widget dialog, Widget w)
if (!isMenu)
{
XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
&numChildren, 0);
&numChildren, NULL);
for (i = 0; i < numChildren; i++)
add_mnemonic_grabs(dialog, children[i]);
}
}
else
{
XtVaGetValues(w, XmNmnemonic, &mnemonic, 0);
XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
if (mnemonic != '\0')
{
mneString[0] = mnemonic;
+3
View File
@@ -1538,8 +1538,11 @@ gui_mch_init()
attr.depth = DefaultDepthOfScreen(scr);
if (!icon)
{
XpmCreatePixmapFromData(dsp, root_window, magick, &icon,
&icon_mask, &attr);
XpmFreeAttributes(&attr);
}
# ifdef FEAT_GUI_ATHENA
XtVaSetValues(vimShell, XtNiconPixmap, icon, XtNiconMask, icon_mask, NULL);
+93 -81
View File
@@ -50,11 +50,11 @@
#if !defined(FEAT_PYTHON) && defined(PROTO)
/* Use this to be able to generate prototypes without python being used. */
# define PyObject int
# define PyThreadState int
# define PyTypeObject int
struct PyMethodDef { int a; };
# define PySequenceMethods int
# define PyObject Py_ssize_t
# define PyThreadState Py_ssize_t
# define PyTypeObject Py_ssize_t
struct PyMethodDef { Py_ssize_t a; };
# define PySequenceMethods Py_ssize_t
#endif
#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02050000
@@ -64,6 +64,7 @@ struct PyMethodDef { int a; };
# define PyIntIntArgFunc ssizessizeargfunc
# define PyIntObjArgProc ssizeobjargproc
# define PyIntIntObjArgProc ssizessizeobjargproc
# define Py_ssize_t_fmt "n"
#else
# define PyInt int
# define PyInquiry inquiry
@@ -71,6 +72,7 @@ struct PyMethodDef { int a; };
# define PyIntIntArgFunc intintargfunc
# define PyIntObjArgProc intobjargproc
# define PyIntIntObjArgProc intintobjargproc
# define Py_ssize_t_fmt "i"
#endif
/* Parser flags */
@@ -85,9 +87,18 @@ struct PyMethodDef { int a; };
#if defined(DYNAMIC_PYTHON) || defined(PROTO)
# ifndef DYNAMIC_PYTHON
# define HINSTANCE int /* for generating prototypes */
# define HINSTANCE long_u /* for generating prototypes */
# endif
/* This makes if_python.c compile without warnings against Python 2.5
* on Win32 and Win64. */
#undef PyRun_SimpleString
#undef PyArg_Parse
#undef PyArg_ParseTuple
#undef Py_BuildValue
#undef Py_InitModule4
#undef Py_InitModule4_64
/*
* Wrapper defines
*/
@@ -269,7 +280,11 @@ static struct
{"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
{"Py_BuildValue", (PYTHON_PROC*)&dll_Py_BuildValue},
{"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
# if (PY_VERSION_HEX >= 0x02050000) && SIZEOF_SIZE_T != SIZEOF_INT
{"Py_InitModule4_64", (PYTHON_PROC*)&dll_Py_InitModule4},
# else
{"Py_InitModule4", (PYTHON_PROC*)&dll_Py_InitModule4},
# endif
{"Py_Initialize", (PYTHON_PROC*)&dll_Py_Initialize},
{"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
{"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
@@ -339,8 +354,7 @@ python_runtime_link_init(char *libname, int verbose)
* TRUE, else FALSE.
*/
int
python_enabled(verbose)
int verbose;
python_enabled(int verbose)
{
return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK;
}
@@ -374,8 +388,8 @@ get_exceptions()
*/
static void DoPythonCommand(exarg_T *, const char *);
static int RangeStart;
static int RangeEnd;
static PyInt RangeStart;
static PyInt RangeEnd;
static void PythonIO_Flush(void);
static int PythonIO_Init(void);
@@ -384,12 +398,12 @@ static int PythonMod_Init(void);
/* Utility functions for the vim/python interface
* ----------------------------------------------
*/
static PyObject *GetBufferLine(buf_T *, int);
static PyObject *GetBufferLine(buf_T *, PyInt);
static PyObject *GetBufferLineList(buf_T *, PyInt, PyInt);
static int SetBufferLine(buf_T *, int, PyObject *, int *);
static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, int *);
static int InsertBufferLines(buf_T *, int, PyObject *, int *);
static int SetBufferLine(buf_T *, PyInt, PyObject *, PyInt *);
static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, PyInt *);
static int InsertBufferLines(buf_T *, PyInt, PyObject *, PyInt *);
static PyObject *LineToString(const char *);
static char *StringToLine(PyObject *);
@@ -690,7 +704,7 @@ static PyObject *OutputWrite(PyObject *, PyObject *);
static PyObject *OutputWritelines(PyObject *, PyObject *);
typedef void (*writefn)(char_u *);
static void writer(writefn fn, char_u *str, int n);
static void writer(writefn fn, char_u *str, PyInt n);
/* Output object definition
*/
@@ -812,7 +826,7 @@ OutputWritelines(PyObject *self, PyObject *args)
{
PyObject *line = PyList_GetItem(list, i);
char *str;
int len;
PyInt len;
if (!PyArg_Parse(line, "s#", &str, &len)) {
PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
@@ -836,15 +850,15 @@ OutputWritelines(PyObject *self, PyObject *args)
*/
static char_u *buffer = NULL;
static int buffer_len = 0;
static int buffer_size = 0;
static PyInt buffer_len = 0;
static PyInt buffer_size = 0;
static writefn old_fn = NULL;
static void
buffer_ensure(int n)
buffer_ensure(PyInt n)
{
int new_size;
PyInt new_size;
char_u *new_buffer;
if (n < buffer_size)
@@ -884,7 +898,7 @@ PythonIO_Flush(void)
}
static void
writer(writefn fn, char_u *str, int n)
writer(writefn fn, char_u *str, PyInt n)
{
char_u *ptr;
@@ -895,7 +909,7 @@ writer(writefn fn, char_u *str, int n)
while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
{
int len = ptr - str;
PyInt len = ptr - str;
buffer_ensure(buffer_len + len + 1);
@@ -1022,14 +1036,14 @@ typedef struct
{
PyObject_HEAD
BufferObject *buf;
int start;
int end;
PyInt start;
PyInt end;
}
RangeObject;
#define RangeType_Check(obj) ((obj)->ob_type == &RangeType)
static PyObject *RangeNew(buf_T *, int, int);
static PyObject *RangeNew(buf_T *, PyInt, PyInt);
static void RangeDestructor(PyObject *);
static PyObject *RangeGetattr(PyObject *, char *);
@@ -1069,8 +1083,8 @@ static int CurrentSetattr(PyObject *, char *, PyObject *);
static struct PyMethodDef VimMethods[] = {
/* name, function, calling, documentation */
{"command", VimCommand, 1, "" },
{"eval", VimEval, 1, "" },
{"command", VimCommand, 1, "Execute a Vim ex-mode command" },
{"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
{ NULL, NULL, 0, NULL }
};
@@ -1110,7 +1124,7 @@ VimCommand(PyObject *self, PyObject *args)
* Function to translate a typval_T into a PyObject; this will recursively
* translate lists/dictionaries into their Python equivalents.
*
* The depth parameter is too avoid infinite recursion, set it to 1 when
* The depth parameter is to avoid infinite recursion, set it to 1 when
* you call VimToPython.
*/
static PyObject *
@@ -1130,7 +1144,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
/* Check if we run into a recursive loop. The item must be in lookupDict
* then and we can use it again. */
sprintf(ptrBuf, "%ld", (long)our_tv);
sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, (long_u)our_tv);
result = PyDict_GetItemString(lookupDict, ptrBuf);
if (result != NULL)
Py_INCREF(result);
@@ -1184,7 +1198,7 @@ VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
if (our_tv->vval.v_dict != NULL)
{
hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
int todo = ht->ht_used;
long_u todo = ht->ht_used;
hashitem_T *hi;
dictitem_T *di;
@@ -1273,7 +1287,7 @@ CheckBuffer(BufferObject *this)
}
static PyObject *
RBItem(BufferObject *self, PyInt n, int start, int end)
RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
{
if (CheckBuffer(self))
return NULL;
@@ -1288,7 +1302,7 @@ RBItem(BufferObject *self, PyInt n, int start, int end)
}
static PyObject *
RBSlice(BufferObject *self, PyInt lo, PyInt hi, int start, int end)
RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
{
PyInt size;
@@ -1312,9 +1326,9 @@ RBSlice(BufferObject *self, PyInt lo, PyInt hi, int start, int end)
}
static PyInt
RBAssItem(BufferObject *self, PyInt n, PyObject *val, int start, int end, int *new_end)
RBAssItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
{
int len_change;
PyInt len_change;
if (CheckBuffer(self))
return -1;
@@ -1335,10 +1349,10 @@ RBAssItem(BufferObject *self, PyInt n, PyObject *val, int start, int end, int *n
}
static PyInt
RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, int start, int end, int *new_end)
RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
{
int size;
int len_change;
PyInt size;
PyInt len_change;
/* Self must be a valid buffer */
if (CheckBuffer(self))
@@ -1368,19 +1382,19 @@ RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, int start, int
}
static PyObject *
RBAppend(BufferObject *self, PyObject *args, int start, int end, int *new_end)
RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
{
PyObject *lines;
int len_change;
int max;
int n;
PyInt len_change;
PyInt max;
PyInt n;
if (CheckBuffer(self))
return NULL;
max = n = end - start + 1;
if (!PyArg_ParseTuple(args, "O|i", &lines, &n))
if (!PyArg_ParseTuple(args, "O|" Py_ssize_t_fmt, &lines, &n))
return NULL;
if (n < 0 || n > max)
@@ -1405,9 +1419,9 @@ RBAppend(BufferObject *self, PyObject *args, int start, int end, int *new_end)
static struct PyMethodDef BufferMethods[] = {
/* name, function, calling, documentation */
{"append", BufferAppend, 1, "" },
{"mark", BufferMark, 1, "" },
{"range", BufferRange, 1, "" },
{"append", BufferAppend, 1, "Append data to Vim buffer" },
{"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
{"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
{ NULL, NULL, 0, NULL }
};
@@ -1503,9 +1517,9 @@ BufferGetattr(PyObject *self, char *name)
return NULL;
if (strcmp(name, "name") == 0)
return Py_BuildValue("s",this->buf->b_ffname);
return Py_BuildValue("s", this->buf->b_ffname);
else if (strcmp(name, "number") == 0)
return Py_BuildValue("i",this->buf->b_fnum);
return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
else if (strcmp(name,"__members__") == 0)
return Py_BuildValue("[ss]", "name", "number");
else
@@ -1520,14 +1534,13 @@ BufferRepr(PyObject *self)
if (this->buf == INVALID_BUFFER_VALUE)
{
vim_snprintf(repr, 100, _("<buffer object (deleted) at %8lX>"),
(long)(self));
vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
return PyString_FromString(repr);
}
else
{
char *name = (char *)this->buf->b_fname;
int len;
PyInt len;
if (name == NULL)
name = "";
@@ -1572,7 +1585,7 @@ BufferSlice(PyObject *self, PyInt lo, PyInt hi)
BufferAssItem(PyObject *self, PyInt n, PyObject *val)
{
return RBAssItem((BufferObject *)(self), n, val, 1,
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
(PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
NULL);
}
@@ -1580,7 +1593,7 @@ BufferAssItem(PyObject *self, PyInt n, PyObject *val)
BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
{
return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
(PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
NULL);
}
@@ -1588,7 +1601,7 @@ BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
BufferAppend(PyObject *self, PyObject *args)
{
return RBAppend((BufferObject *)(self), args, 1,
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
(PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
NULL);
}
@@ -1633,13 +1646,13 @@ BufferMark(PyObject *self, PyObject *args)
static PyObject *
BufferRange(PyObject *self, PyObject *args)
{
int start;
int end;
PyInt start;
PyInt end;
if (CheckBuffer((BufferObject *)(self)))
return NULL;
if (!PyArg_ParseTuple(args, "ii", &start, &end))
if (!PyArg_ParseTuple(args, Py_ssize_t_fmt Py_ssize_t_fmt, &start, &end))
return NULL;
return RangeNew(((BufferObject *)(self))->buf, start, end);
@@ -1650,7 +1663,7 @@ BufferRange(PyObject *self, PyObject *args)
static struct PyMethodDef RangeMethods[] = {
/* name, function, calling, documentation */
{"append", RangeAppend, 1, "" },
{"append", RangeAppend, 1, "Append data to the Vim range" },
{ NULL, NULL, 0, NULL }
};
@@ -1691,7 +1704,7 @@ static PyTypeObject RangeType = {
*/
static PyObject *
RangeNew(buf_T *buf, int start, int end)
RangeNew(buf_T *buf, PyInt start, PyInt end)
{
BufferObject *bufr;
RangeObject *self;
@@ -1725,9 +1738,9 @@ RangeDestructor(PyObject *self)
RangeGetattr(PyObject *self, char *name)
{
if (strcmp(name, "start") == 0)
return Py_BuildValue("i",((RangeObject *)(self))->start - 1);
return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->start - 1);
else if (strcmp(name, "end") == 0)
return Py_BuildValue("i",((RangeObject *)(self))->end - 1);
return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->end - 1);
else
return Py_FindMethod(RangeMethods, self, name);
}
@@ -1740,8 +1753,8 @@ RangeRepr(PyObject *self)
if (this->buf->buf == INVALID_BUFFER_VALUE)
{
vim_snprintf(repr, 100, "<range object (for deleted buffer) at %8lX>",
(long)(self));
vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
(self));
return PyString_FromString(repr);
}
else
@@ -1869,7 +1882,7 @@ static PyTypeObject BufListType = {
BufListLength(PyObject *self)
{
buf_T *b = firstbuf;
int n = 0;
PyInt n = 0;
while (b)
{
@@ -2115,8 +2128,7 @@ WindowRepr(PyObject *self)
if (this->win == INVALID_WINDOW_VALUE)
{
vim_snprintf(repr, 100, _("<window object (deleted) at %.8lX>"),
(long)(self));
vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
return PyString_FromString(repr);
}
else
@@ -2128,8 +2140,8 @@ WindowRepr(PyObject *self)
++i;
if (w == NULL)
vim_snprintf(repr, 100, _("<window object (unknown) at %.8lX>"),
(long)(self));
vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
(self));
else
vim_snprintf(repr, 100, _("<window %d>"), i);
@@ -2186,7 +2198,7 @@ static PyTypeObject WinListType = {
WinListLength(PyObject *self)
{
win_T *w = firstwin;
int n = 0;
PyInt n = 0;
while (w != NULL)
{
@@ -2254,7 +2266,7 @@ CurrentGetattr(PyObject *self, char *name)
else if (strcmp(name, "window") == 0)
return (PyObject *)WindowNew(curwin);
else if (strcmp(name, "line") == 0)
return GetBufferLine(curbuf, (int)curwin->w_cursor.lnum);
return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
else if (strcmp(name, "range") == 0)
return RangeNew(curbuf, RangeStart, RangeEnd);
else if (strcmp(name,"__members__") == 0)
@@ -2272,7 +2284,7 @@ CurrentSetattr(PyObject *self, char *name, PyObject *value)
{
if (strcmp(name, "line") == 0)
{
if (SetBufferLine(curbuf, (int)curwin->w_cursor.lnum, value, NULL) == FAIL)
if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
return -1;
return 0;
@@ -2344,7 +2356,7 @@ PythonMod_Init(void)
/* Set sys.argv[] to avoid a crash in warn(). */
PySys_SetArgv(1, argv);
mod = Py_InitModule("vim", VimMethods);
mod = Py_InitModule4("vim", VimMethods, (char *)NULL, (PyObject *)NULL, PYTHON_API_VERSION);
dict = PyModule_GetDict(mod);
VimError = Py_BuildValue("s", "vim.error");
@@ -2369,7 +2381,7 @@ PythonMod_Init(void)
* string object.
*/
static PyObject *
GetBufferLine(buf_T *buf, int n)
GetBufferLine(buf_T *buf, PyInt n)
{
return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
}
@@ -2422,7 +2434,7 @@ GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
* deleted).
*/
static void
py_fix_cursor(int lo, int hi, int extra)
py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
{
if (curwin->w_cursor.lnum >= lo)
{
@@ -2454,7 +2466,7 @@ py_fix_cursor(int lo, int hi, int extra)
* is set to the change in the buffer length.
*/
static int
SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
{
/* First of all, we check the thpe of the supplied Python object.
* There are three cases:
@@ -2477,7 +2489,7 @@ SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
{
deleted_lines_mark((linenr_T)n, 1L);
if (buf == curwin->w_buffer)
py_fix_cursor(n, n + 1, -1);
py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
}
curbuf = savebuf;
@@ -2545,7 +2557,7 @@ SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
* is set to the change in the buffer length.
*/
static int
SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_change)
SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
{
/* First of all, we check the thpe of the supplied Python object.
* There are three cases:
@@ -2556,7 +2568,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_chang
if (list == Py_None || list == NULL)
{
PyInt i;
PyInt n = hi - lo;
PyInt n = (int)(hi - lo);
buf_T *savebuf = curbuf;
PyErr_Clear();
@@ -2577,7 +2589,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_chang
deleted_lines_mark((linenr_T)lo, (long)i);
if (buf == curwin->w_buffer)
py_fix_cursor(lo, hi, -n);
py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
}
curbuf = savebuf;
@@ -2595,7 +2607,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_chang
PyInt i;
PyInt new_len = PyList_Size(list);
PyInt old_len = hi - lo;
int extra = 0; /* lines added to text, can be negative */
PyInt extra = 0; /* lines added to text, can be negative */
char **array;
buf_T *savebuf;
@@ -2706,7 +2718,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_chang
changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
if (buf == curwin->w_buffer)
py_fix_cursor(lo, hi, extra);
py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
curbuf = savebuf;
@@ -2734,7 +2746,7 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, int *len_chang
* is set to the change in the buffer length.
*/
static int
InsertBufferLines(buf_T *buf, int n, PyObject *lines, int *len_change)
InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
{
/* First of all, we check the type of the supplied Python object.
* It must be a string or a list, or the call is in error.
+13 -8
View File
@@ -1880,15 +1880,20 @@ ins_bytes_len(p, len)
# ifdef FEAT_MBYTE
int n;
for (i = 0; i < len; i += n)
{
n = (*mb_ptr2len)(p + i);
ins_char_bytes(p + i, n);
}
# else
for (i = 0; i < len; ++i)
ins_char(p[i]);
if (has_mbyte)
for (i = 0; i < len; i += n)
{
if (enc_utf8)
/* avoid reading past p[len] */
n = utfc_ptr2len_len(p + i, len - i);
else
n = (*mb_ptr2len)(p + i);
ins_char_bytes(p + i, n);
}
else
# endif
for (i = 0; i < len; ++i)
ins_char(p[i]);
}
#endif
+29 -10
View File
@@ -209,6 +209,7 @@ typedef struct
{
SmcConn smcconn; /* The SM connection ID */
IceConn iceconn; /* The ICE connection ID */
char *clientid; /* The client ID for the current smc session */
Bool save_yourself; /* If we're in the middle of a save_yourself */
Bool shutdown; /* If we're in shutdown mode */
} xsmp_config_T;
@@ -2279,6 +2280,10 @@ mch_FullName(fname, buf, len, force)
char_u olddir[MAXPATHL];
char_u *p;
int retval = OK;
#ifdef __CYGWIN__
char_u posix_fname[MAX_PATH];
#endif
#ifdef VMS
fname = vms_fixfilename(fname);
@@ -2288,7 +2293,8 @@ mch_FullName(fname, buf, len, force)
/*
* This helps for when "/etc/hosts" is a symlink to "c:/something/hosts".
*/
cygwin_conv_to_posix_path(fname, fname);
cygwin_conv_to_posix_path(fname, posix_fname);
fname = posix_fname;
#endif
/* expand it if forced or not an absolute path */
@@ -2889,16 +2895,28 @@ mch_free_mem()
if (clip_plus.owned)
clip_lose_selection(&clip_plus);
# endif
# if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
# if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)
if (xterm_Shell != (Widget)0)
XtDestroyWidget(xterm_Shell);
# ifndef LESSTIF_VERSION
/* Lesstif crashes here, lose some memory */
if (xterm_dpy != NULL)
XtCloseDisplay(xterm_dpy);
if (app_context != (XtAppContext)NULL)
{
XtDestroyApplicationContext(app_context);
# ifdef FEAT_X11
x11_display = NULL; /* freed by XtDestroyApplicationContext() */
# endif
}
# endif
# endif
# ifdef FEAT_X11
if (x11_display != NULL && x11_display != xterm_dpy)
if (x11_display != NULL
# ifdef FEAT_XCLIPBOARD
&& x11_display != xterm_dpy
# endif
)
XCloseDisplay(x11_display);
# endif
# if defined(HAVE_SIGALTSTACK) || defined(HAVE_SIGSTACK)
@@ -3886,7 +3904,7 @@ mch_call_shell(cmd, options)
/* push stream discipline modules */
if (options & SHELL_COOKED)
SetupSlavePTY(pty_slave_fd);
# ifdef TIOCSCTTY
# if defined(TIOCSCTTY) && !defined(FEAT_GUI_MACVIM)
/* Try to become controlling tty (probably doesn't work,
* unless run by root) */
ioctl(pty_slave_fd, TIOCSCTTY, (char *)NULL);
@@ -6292,22 +6310,22 @@ clear_xterm_clip()
}
if (xterm_dpy != NULL)
{
#if 0
# if 0
/* Lesstif and Solaris crash here, lose some memory */
XtCloseDisplay(xterm_dpy);
#endif
# endif
if (x11_display == xterm_dpy)
x11_display = NULL;
xterm_dpy = NULL;
}
#if 0
# if 0
if (app_context != (XtAppContext)NULL)
{
/* Lesstif and Solaris crash here, lose some memory */
XtDestroyApplicationContext(app_context);
app_context = (XtAppContext)NULL;
}
#endif
# endif
}
# endif
@@ -6559,7 +6577,6 @@ static int dummy;
xsmp_init(void)
{
char errorstring[80];
char *clientid;
SmcCallbacks smcallbacks;
#if 0
SmPropValue smname;
@@ -6601,7 +6618,7 @@ xsmp_init(void)
| SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
&smcallbacks,
NULL,
&clientid,
&xsmp.clientid,
sizeof(errorstring),
errorstring);
if (xsmp.smcconn == NULL)
@@ -6640,6 +6657,8 @@ xsmp_close()
if (xsmp_icefd != -1)
{
SmcCloseConnection(xsmp.smcconn, 0, NULL);
vim_free(xsmp.clientid);
xsmp.clientid = NULL;
xsmp_icefd = -1;
}
}
+7 -1
View File
@@ -432,7 +432,13 @@ typedef struct dsc$descriptor DESC;
* Unix has plenty of memory, use large buffers
*/
#define CMDBUFFSIZE 1024 /* size of the command processing buffer */
#define MAXPATHL 1024 /* Unix has long paths and plenty of memory */
/* Use the system path length if it makes sense. */
#if defined(PATH_MAX) && (PATH_MAX > 1000)
# define MAXPATHL PATH_MAX
#else
# define MAXPATHL 1024
#endif
#define CHECK_INODE /* used when checking if a swap file already
exists for a file */
+30 -18
View File
@@ -3044,6 +3044,7 @@ typedef struct regbehind_S
{
regsave_T save_after;
regsave_T save_behind;
int save_need_clear_subexpr;
save_se_T save_start[NSUBEXP];
save_se_T save_end[NSUBEXP];
} regbehind_T;
@@ -5858,17 +5859,23 @@ save_subexpr(bp)
{
int i;
for (i = 0; i < NSUBEXP; ++i)
/* When "need_clear_subexpr" is set we don't need to save the values, only
* remember that this flag needs to be set again when restoring. */
bp->save_need_clear_subexpr = need_clear_subexpr;
if (!need_clear_subexpr)
{
if (REG_MULTI)
for (i = 0; i < NSUBEXP; ++i)
{
bp->save_start[i].se_u.pos = reg_startpos[i];
bp->save_end[i].se_u.pos = reg_endpos[i];
}
else
{
bp->save_start[i].se_u.ptr = reg_startp[i];
bp->save_end[i].se_u.ptr = reg_endp[i];
if (REG_MULTI)
{
bp->save_start[i].se_u.pos = reg_startpos[i];
bp->save_end[i].se_u.pos = reg_endpos[i];
}
else
{
bp->save_start[i].se_u.ptr = reg_startp[i];
bp->save_end[i].se_u.ptr = reg_endp[i];
}
}
}
}
@@ -5882,17 +5889,22 @@ restore_subexpr(bp)
{
int i;
for (i = 0; i < NSUBEXP; ++i)
/* Only need to restore saved values when they are not to be cleared. */
need_clear_subexpr = bp->save_need_clear_subexpr;
if (!need_clear_subexpr)
{
if (REG_MULTI)
for (i = 0; i < NSUBEXP; ++i)
{
reg_startpos[i] = bp->save_start[i].se_u.pos;
reg_endpos[i] = bp->save_end[i].se_u.pos;
}
else
{
reg_startp[i] = bp->save_start[i].se_u.ptr;
reg_endp[i] = bp->save_end[i].se_u.ptr;
if (REG_MULTI)
{
reg_startpos[i] = bp->save_start[i].se_u.pos;
reg_endpos[i] = bp->save_end[i].se_u.pos;
}
else
{
reg_startp[i] = bp->save_start[i].se_u.ptr;
reg_endp[i] = bp->save_end[i].se_u.ptr;
}
}
}
}
+4 -1
View File
@@ -4863,6 +4863,7 @@ comp_char_differs(off_from, off_to)
* - the (first byte of the) character is different
* - the attributes are different
* - the character is multi-byte and the next byte is different
* - the character is two cells wide and the second cell differs.
*/
static int
char_needs_redraw(off_from, off_to, cols)
@@ -4884,7 +4885,9 @@ char_needs_redraw(off_from, off_to, cols)
|| (enc_utf8
&& (ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
|| (ScreenLinesUC[off_from] != 0
&& comp_char_differs(off_from, off_to))))
&& comp_char_differs(off_from, off_to))
|| (cols > 1 && ScreenLines[off_from + 1]
!= ScreenLines[off_to + 1])))
#endif
))
return TRUE;
+2
View File
@@ -2,6 +2,8 @@ Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
STARTTEST
:set smarttab expandtab ts=8 sw=4
:" make sure that backspace works, no matter what termcap is used
:set t_kD=x7f t_kb=x08
/some
r :set noexpandtab
/other
+2
View File
@@ -3,6 +3,8 @@ Test Virtual replace mode.
STARTTEST
:so small.vim
:" make sure that backspace works, no matter what termcap is used
:set t_kD=x7f t_kb=x08
ggdGa
abcdefghi
jk lmn
View File
View File
+43 -7
View File
@@ -681,6 +681,38 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
330,
/**/
329,
/**/
328,
/**/
327,
/**/
326,
/**/
325,
/**/
324,
/**/
323,
/**/
322,
/**/
321,
/**/
320,
/**/
319,
/**/
318,
/**/
317,
/**/
316,
/**/
315,
/**/
314,
/**/
@@ -1372,12 +1404,12 @@ list_version()
# ifdef FEAT_GUI_W32
# if defined(_MSC_VER) && (_MSC_VER <= 1010)
/* Only MS VC 4.1 and earlier can do Win32s */
MSG_PUTS(_("\nMS-Windows 16/32 bit GUI version"));
MSG_PUTS(_("\nMS-Windows 16/32-bit GUI version"));
# else
# ifdef _WIN64
MSG_PUTS(_("\nMS-Windows 64 bit GUI version"));
MSG_PUTS(_("\nMS-Windows 64-bit GUI version"));
# else
MSG_PUTS(_("\nMS-Windows 32 bit GUI version"));
MSG_PUTS(_("\nMS-Windows 32-bit GUI version"));
# endif
# endif
if (gui_is_win32s())
@@ -1386,17 +1418,21 @@ list_version()
MSG_PUTS(_(" with OLE support"));
# endif
# else
MSG_PUTS(_("\nMS-Windows 32 bit console version"));
# ifdef _WIN64
MSG_PUTS(_("\nMS-Windows 64-bit console version"));
# else
MSG_PUTS(_("\nMS-Windows 32-bit console version"));
# endif
# endif
#endif
#ifdef WIN16
MSG_PUTS(_("\nMS-Windows 16 bit version"));
MSG_PUTS(_("\nMS-Windows 16-bit version"));
#endif
#ifdef MSDOS
# ifdef DJGPP
MSG_PUTS(_("\n32 bit MS-DOS version"));
MSG_PUTS(_("\n32-bit MS-DOS version"));
# else
MSG_PUTS(_("\n16 bit MS-DOS version"));
MSG_PUTS(_("\n16-bit MS-DOS version"));
# endif
#endif
#ifdef MACOS