mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Make copy/paste respect block-wise selections
When text is copied inside Vim we put both the text and the motion type on the pasteboard. Text copied from outside Vim never contains the motion type so we have to guess between line and character-wise motion types in that case.
This commit is contained in:
@@ -1262,6 +1262,8 @@ static NSString *MMSymlinkWarningString =
|
||||
|
||||
- (BOOL)starRegisterToPasteboard:(byref NSPasteboard *)pboard
|
||||
{
|
||||
// TODO: This method should share code with clip_mch_request_selection().
|
||||
|
||||
if (VIsual_active && (State & NORMAL) && clip_star.available) {
|
||||
// If there is no pasteboard, return YES to indicate that there is text
|
||||
// to copy.
|
||||
|
||||
+6
-1
@@ -238,6 +238,12 @@ enum {
|
||||
|
||||
|
||||
|
||||
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
extern NSString *VimPBoardType;
|
||||
|
||||
|
||||
|
||||
// Loads all fonts in the Resouces folder of the app bundle and returns a font
|
||||
// container reference (which should be used to deactivate the loaded fonts).
|
||||
ATSFontContainerRef loadFonts();
|
||||
@@ -284,4 +290,3 @@ NSString *buildSearchTextCommand(NSString *searchText);
|
||||
|
||||
// MacVim Apple Event Constants
|
||||
#define keyMMUntitledWindow 'MMuw'
|
||||
|
||||
|
||||
@@ -111,6 +111,12 @@ NSString *MMLoginShellArgumentKey = @"MMLoginShellArgument";
|
||||
|
||||
|
||||
|
||||
// Vim pasteboard type (holds motion type + string)
|
||||
NSString *VimPBoardType = @"VimPBoardType";
|
||||
|
||||
|
||||
|
||||
|
||||
ATSFontContainerRef
|
||||
loadFonts()
|
||||
{
|
||||
|
||||
+68
-30
@@ -480,44 +480,75 @@ clip_mch_own_selection(VimClipboard *cbd)
|
||||
clip_mch_request_selection(VimClipboard *cbd)
|
||||
{
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
NSString *pbType = [pb availableTypeFromArray:
|
||||
[NSArray arrayWithObject:NSStringPboardType]];
|
||||
if (pbType) {
|
||||
NSMutableString *string =
|
||||
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPBoardType,
|
||||
NSStringPboardType, nil];
|
||||
NSString *bestType = [pb availableTypeFromArray:supportedTypes];
|
||||
if (!bestType) return;
|
||||
|
||||
int motion_type = MCHAR;
|
||||
NSString *string = nil;
|
||||
|
||||
if ([bestType isEqual:VimPBoardType]) {
|
||||
// This type should consist of an array with two objects:
|
||||
// 1. motion type (NSNumber)
|
||||
// 2. text (NSString)
|
||||
// If this is not the case we fall back on using NSStringPboardType.
|
||||
id plist = [pb propertyListForType:VimPBoardType];
|
||||
if ([plist isKindOfClass:[NSArray class]] && [plist count] == 2) {
|
||||
id obj = [plist objectAtIndex:1];
|
||||
if ([obj isKindOfClass:[NSString class]]) {
|
||||
motion_type = [[plist objectAtIndex:0] intValue];
|
||||
string = obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string) {
|
||||
// Use NSStringPboardType. The motion type is set to line-wise if the
|
||||
// string contains at least one EOL character, otherwise it is set to
|
||||
// character-wise (block-wise is never used).
|
||||
NSMutableString *mstring =
|
||||
[[pb stringForType:NSStringPboardType] mutableCopy];
|
||||
if (!mstring) return;
|
||||
|
||||
// Replace unrecognized end-of-line sequences with \x0a (line feed).
|
||||
NSRange range = { 0, [string length] };
|
||||
unsigned n = [string replaceOccurrencesOfString:@"\x0d\x0a"
|
||||
NSRange range = { 0, [mstring length] };
|
||||
unsigned n = [mstring replaceOccurrencesOfString:@"\x0d\x0a"
|
||||
withString:@"\x0a" options:0
|
||||
range:range];
|
||||
if (0 == n) {
|
||||
n = [string replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
|
||||
n = [mstring replaceOccurrencesOfString:@"\x0d" withString:@"\x0a"
|
||||
options:0 range:range];
|
||||
}
|
||||
|
||||
// Scan for newline character to decide whether the string should be
|
||||
// pasted linewise or characterwise.
|
||||
int type = MCHAR;
|
||||
if (0 < n || NSNotFound != [string rangeOfString:@"\n"].location)
|
||||
type = MLINE;
|
||||
// pasted line-wise or character-wise.
|
||||
motion_type = MCHAR;
|
||||
if (0 < n || NSNotFound != [mstring rangeOfString:@"\n"].location)
|
||||
motion_type = MLINE;
|
||||
|
||||
char_u *str = (char_u*)[string UTF8String];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
str = string_convert(&input_conv, str, &len);
|
||||
#endif
|
||||
|
||||
if (str)
|
||||
clip_yank_selection(type, str, len, cbd);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
#endif
|
||||
string = mstring;
|
||||
}
|
||||
|
||||
if (!(MCHAR == motion_type || MLINE == motion_type || MBLOCK == motion_type
|
||||
|| MAUTO == motion_type))
|
||||
motion_type = MCHAR;
|
||||
|
||||
char_u *str = (char_u*)[string UTF8String];
|
||||
int len = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
str = string_convert(&input_conv, str, &len);
|
||||
#endif
|
||||
|
||||
if (str)
|
||||
clip_yank_selection(motion_type, str, len, cbd);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (input_conv.vc_type != CONV_NONE)
|
||||
vim_free(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -534,8 +565,8 @@ clip_mch_set_selection(VimClipboard *cbd)
|
||||
|
||||
// Get the text to put on the pasteboard.
|
||||
long_u llen = 0; char_u *str = 0;
|
||||
int type = clip_convert_selection(&str, &llen, cbd);
|
||||
if (type < 0)
|
||||
int motion_type = clip_convert_selection(&str, &llen, cbd);
|
||||
if (motion_type < 0)
|
||||
return;
|
||||
|
||||
// TODO: Avoid overflow.
|
||||
@@ -554,9 +585,16 @@ clip_mch_set_selection(VimClipboard *cbd)
|
||||
NSString *string = [[NSString alloc]
|
||||
initWithBytes:str length:len encoding:NSUTF8StringEncoding];
|
||||
|
||||
// See clip_mch_request_selection() for info on pasteboard types.
|
||||
NSPasteboard *pb = [NSPasteboard generalPasteboard];
|
||||
[pb declareTypes:[NSArray arrayWithObject:NSStringPboardType]
|
||||
owner:nil];
|
||||
NSArray *supportedTypes = [NSArray arrayWithObjects:VimPBoardType,
|
||||
NSStringPboardType, nil];
|
||||
[pb declareTypes:supportedTypes owner:nil];
|
||||
|
||||
NSNumber *motion = [NSNumber numberWithInt:motion_type];
|
||||
NSArray *plist = [NSArray arrayWithObjects:motion, string, nil];
|
||||
[pb setPropertyList:plist forType:VimPBoardType];
|
||||
|
||||
[pb setString:string forType:NSStringPboardType];
|
||||
|
||||
[string release];
|
||||
|
||||
Reference in New Issue
Block a user