From 51ba36fd29e074cb83a4296c2d4c51a055541f9e Mon Sep 17 00:00:00 2001 From: Joachim Carlsen Date: Thu, 31 Mar 2016 22:14:48 +0200 Subject: [PATCH 1/4] Added representation of matched text in search as '&' --- XVim/XVimSearch.m | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/XVim/XVimSearch.m b/XVim/XVimSearch.m index 72e7bac9..1ef65bd3 100644 --- a/XVim/XVimSearch.m +++ b/XVim/XVimSearch.m @@ -547,8 +547,23 @@ - (void) updateEndLocationInWindow:(XVimWindow*)window - (void)replaceCurrentInWindow:(XVimWindow*)window findNext:(BOOL)findNext { NSTextView* srcView = [window sourceView]; - - [srcView insertText:self.lastReplacementString replacementRange:self.lastFoundRange]; + + NSString *textToReplace = [[srcView string] substringWithRange:self.lastFoundRange]; + NSString *replacementString = self.lastReplacementString; + NSArray *splitsOnEscapedAmpersands = [replacementString componentsSeparatedByString:@"\\&"]; + NSMutableArray *stringsToJoin = [[NSMutableArray alloc] init]; + + for (NSString* stringWithoutEscapedAmpersands in splitsOnEscapedAmpersands) { + NSArray *splitsOnAmpersands = [stringWithoutEscapedAmpersands componentsSeparatedByString:@"&"]; + NSString *springsWithMatch = [splitsOnAmpersands componentsJoinedByString:textToReplace]; + [stringsToJoin addObject:springsWithMatch]; + } + + if ([stringsToJoin count] > 0) { + replacementString = [stringsToJoin componentsJoinedByString:@"\\&"]; + } + + [srcView insertText:replacementString replacementRange:self.lastFoundRange]; [srcView xvim_moveCursor:self.lastFoundRange.location + self.lastReplacementString.length preserveColumn:NO]; self.numReplacements++; From de6aad9e2f83d7bbc1d83a31c32ffe3e54d409eb Mon Sep 17 00:00:00 2001 From: Joachim Carlsen Date: Fri, 15 Apr 2016 13:06:27 +0200 Subject: [PATCH 2/4] Fixed tests. --- XVim/Info.plist | 1 + XVim/Test/XVimTester+Search.m | 6 ++++++ XVim/XVimSearch.m | 16 ++++++++-------- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/XVim/Info.plist b/XVim/Info.plist index b53f5ddb..09a6404b 100644 --- a/XVim/Info.plist +++ b/XVim/Info.plist @@ -20,6 +20,7 @@ 1 DVTPlugInCompatibilityUUIDs + ACA8656B-FEA8-4B6D-8E4A-93F4C95C362C AD68E85B-441B-4301-B564-A45E4919A6AD A2E4D43F-41F4-4FB9-BB94-7177011C9AED 37B30044-3B14-46BA-ABAA-F01000C27B63 diff --git a/XVim/Test/XVimTester+Search.m b/XVim/Test/XVimTester+Search.m index d7d9eeca..83f9e145 100644 --- a/XVim/Test/XVimTester+Search.m +++ b/XVim/Test/XVimTester+Search.m @@ -88,6 +88,8 @@ - (NSArray*)search_testcases{ static NSString* replace11_result = @"aaa ddd ccc\n" @"aaa.ddd.ccc\n\n"; + static NSString* replace12_result = @"aaa bbbbb ccc\n" + @"bbbbb ccc ccc\n\n"; return [NSArray arrayWithObjects: // // replace(:s) @@ -107,6 +109,9 @@ - (NSArray*)search_testcases{ XVimMakeTestCase(text6, 0, 0, @"Vj:s/$/fffff/g", replace7_result, 32, 0), // $, two XVimMakeTestCase(text7, 0, 0, @"Vj:s/$/fffff/g", replace8_result, 32, 0), + + XVimMakeTestCase(text7, 0, 0, @":%s/bbb/&bb/g", replace12_result, 19, 0), + XVimMakeTestCase(text7, 0, 0, @":%s/bb/&bb/g", replace12_result, 18, 0), // c, quit XVimMakeTestCase(text6, 0, 0, @"Vj:s/ccc/eeeee/gcq", text6, 8, 0), @@ -205,6 +210,7 @@ - (NSArray*)search_testcases{ // search followed by implicit replace. added to cover https://github.com/XVimProject/XVim/issues/730 XVimMakeTestCase(text8, 0, 0, @":set vimregex/bbb:%s//ddd/g", replace11_result, 19, 0), + nil]; } @end diff --git a/XVim/XVimSearch.m b/XVim/XVimSearch.m index 1ef65bd3..7da98f4f 100644 --- a/XVim/XVimSearch.m +++ b/XVim/XVimSearch.m @@ -522,11 +522,11 @@ - (void)substitute:(NSString*)ex_command from:(NSUInteger)from to:(NSUInteger)to } } -- (void)updateStartLocationInWindow:(XVimWindow*)window +- (void)updateStartLocationInWindow:(XVimWindow*)window replacementString:(NSString*)replacementString { // global option on; consider all matches on each line if (self.isGlobal) { - self.replaceStartLocation = self.lastFoundRange.location + self.lastReplacementString.length; + self.replaceStartLocation = self.lastFoundRange.location + replacementString.length; // If search string contained a $, move to the next line if ([self.lastSearchCmd rangeOfString:@"$"].length > 0) { @@ -539,9 +539,9 @@ - (void)updateStartLocationInWindow:(XVimWindow*)window } } -- (void) updateEndLocationInWindow:(XVimWindow*)window +- (void) updateEndLocationInWindow:(XVimWindow*)windo replacementString:(NSString*)replacementString { - self.replaceEndLocation += ([self.lastReplacementString length] - self.lastFoundRange.length); + self.replaceEndLocation += ([replacementString length] - self.lastFoundRange.length); } - (void)replaceCurrentInWindow:(XVimWindow*)window findNext:(BOOL)findNext @@ -564,12 +564,12 @@ - (void)replaceCurrentInWindow:(XVimWindow*)window findNext:(BOOL)findNext } [srcView insertText:replacementString replacementRange:self.lastFoundRange]; - [srcView xvim_moveCursor:self.lastFoundRange.location + self.lastReplacementString.length preserveColumn:NO]; + [srcView xvim_moveCursor:self.lastFoundRange.location + replacementString.length preserveColumn:NO]; self.numReplacements++; if (findNext) { - [self updateStartLocationInWindow:window]; - [self updateEndLocationInWindow:window]; + [self updateStartLocationInWindow:window replacementString:replacementString]; + [self updateEndLocationInWindow:window replacementString:replacementString]; [self findForwardFrom:self.replaceStartLocation to:self.replaceEndLocation inWindow:window]; } else { @@ -593,7 +593,7 @@ - (void)replaceCurrentToEndInWindow:(XVimWindow*)window [srcView insertText:self.lastReplacementString replacementRange:self.lastFoundRange]; self.numReplacements++; - [self updateEndLocationInWindow:window]; + [self updateEndLocationInWindow:window replacementString:self.lastReplacementString]; [self findForwardFrom:self.replaceStartLocation to:self.replaceEndLocation inWindow:window]; } while (self.lastFoundRange.location != NSNotFound); [self showStatusIfDoneInWindow:window]; From d85d7f03eb061cf2ec5d4b603112e70b5ea517f5 Mon Sep 17 00:00:00 2001 From: Joachim Carlsen Date: Fri, 15 Apr 2016 13:43:03 +0200 Subject: [PATCH 3/4] Added feature description to FeatureList.md --- Documents/Users/FeatureList.md | 4 ++++ XVim/XVimSearch.m | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Documents/Users/FeatureList.md b/Documents/Users/FeatureList.md index 3c7045dd..58d06ae0 100644 --- a/Documents/Users/FeatureList.md +++ b/Documents/Users/FeatureList.md @@ -137,6 +137,10 @@ The layout is forced to change with Ctrl-w,s or Ctrl-w,v . Regex search is supported using the [ICU regex](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html) format. +Search and replace using matched string(&) in the replacement text is supported: + +`foo bar` -> `:%s/foo/&bar/` gives `foobar bar` + ## Insert mode commands C-y, C-e diff --git a/XVim/XVimSearch.m b/XVim/XVimSearch.m index 7da98f4f..c1f0da55 100644 --- a/XVim/XVimSearch.m +++ b/XVim/XVimSearch.m @@ -558,7 +558,7 @@ - (void)replaceCurrentInWindow:(XVimWindow*)window findNext:(BOOL)findNext NSString *springsWithMatch = [splitsOnAmpersands componentsJoinedByString:textToReplace]; [stringsToJoin addObject:springsWithMatch]; } - + if ([stringsToJoin count] > 0) { replacementString = [stringsToJoin componentsJoinedByString:@"\\&"]; } From f4380e1fac3d6696538142c28f9a8b050be05239 Mon Sep 17 00:00:00 2001 From: Joachim Carlsen Date: Fri, 15 Apr 2016 13:44:07 +0200 Subject: [PATCH 4/4] Improved the feature description a bit --- Documents/Users/FeatureList.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documents/Users/FeatureList.md b/Documents/Users/FeatureList.md index 58d06ae0..0e59b83f 100644 --- a/Documents/Users/FeatureList.md +++ b/Documents/Users/FeatureList.md @@ -139,7 +139,7 @@ Regex search is supported using the [ICU regex](https://developer.apple.com/libr Search and replace using matched string(&) in the replacement text is supported: -`foo bar` -> `:%s/foo/&bar/` gives `foobar bar` +Applying `:%s/foo/&bar/` to `foo bar` gives `foobar bar` ## Insert mode commands