Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes = and == functionality to match VIM #502

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Documents/Users/FeatureList.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ J

Normal mode: >, >>, <, <<

## Filter

Normal mode: ==

Visual mode: =

## Case change operations

Normal mode: ~, gu, gU, g~
Expand Down
62 changes: 33 additions & 29 deletions XVim/NSTextView+VimOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -789,29 +789,31 @@ - (void)xvim_filter:(XVimMotion*)motion{
if( self.insertionPoint == 0 && [[self xvim_string] length] == 0 ){
return ;
}

NSUInteger insertionAfterFilter = self.insertionPoint;
NSRange filterRange;
if( self.selectionMode == XVIM_VISUAL_NONE ){
XVimRange to = [self xvim_getMotionRange:self.insertionPoint Motion:motion];
if( to.end == NSNotFound ){
return;

NSArray* ranges = [self xvim_selectedRanges];
self.insertionPoint = [[ranges objectAtIndex:0] rangeValue].location;
NSUInteger insertionAfterFilter = [self.textStorage firstNonblankInLine:self.insertionPoint];

for( NSValue* val in ranges){
NSRange filterRange = val.rangeValue;
NSString *lineString = [[self xvim_string] substringWithRange:filterRange];
NSRange whiteSpaceRange = [lineString rangeOfString:@"^\\s*" options:NSRegularExpressionSearch];
if (whiteSpaceRange.length == filterRange.length) {
whiteSpaceRange.length = whiteSpaceRange.length - 1;
lineString = [lineString stringByReplacingCharactersInRange:whiteSpaceRange withString:@""];
whiteSpaceRange.location = filterRange.location + whiteSpaceRange.location;
[self insertText:lineString replacementRange:filterRange];
filterRange.length = filterRange.length - whiteSpaceRange.length;
}
else {
[self xvim_indentCharacterRange: filterRange];
}
filterRange = [self xvim_getOperationRangeFrom:to.begin To:to.end Type:LINEWISE];
}else{
insertionAfterFilter = [[[self xvim_selectedRanges] lastObject] rangeValue].location;
NSUInteger start = [[[self xvim_selectedRanges] objectAtIndex:0] rangeValue].location;
NSRange lastSelection = [[[self xvim_selectedRanges] lastObject] rangeValue];
NSUInteger end = lastSelection.location + lastSelection.length - 1;
filterRange = NSMakeRange(start, end-start+1);
}

[self xvim_indentCharacterRange: filterRange];

[self xvim_moveCursor:insertionAfterFilter preserveColumn:NO];
[self xvim_changeSelectionMode:XVIM_VISUAL_NONE];
}


- (void)xvim_shiftRight:(XVimMotion*)motion{
[self xvim_shfit:motion right:YES];
}
Expand Down Expand Up @@ -1556,18 +1558,20 @@ - (NSArray*)xvim_selectedRanges{
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,selectionEnd-selectionStart+1)]];
}
}else if(self.selectionMode == XVIM_VISUAL_LINE ){
NSUInteger min = MIN(self.insertionPoint,self.selectionBegin);
NSUInteger max = MAX(self.insertionPoint,self.selectionBegin);
selectionStart = [self.textStorage beginningOfLine:min];
selectionEnd = [self.textStorage endOfLine:max];
if( [self.textStorage isEOF:selectionStart] ){
// EOF can not be selected
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,0)]];
}else if( [self.textStorage isEOF:selectionEnd] ){
selectionEnd--;
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,selectionEnd-selectionStart+1)]];
}else{
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,selectionEnd-selectionStart+1)]];
NSUInteger top = MIN( [self.textStorage lineNumber:self.insertionPoint], [self.textStorage lineNumber:self.selectionBegin] );
NSUInteger bottom = MAX( [self.textStorage lineNumber:self.insertionPoint], [self.textStorage lineNumber:self.selectionBegin] );
for( NSUInteger i = 0; i < bottom-top+1 ; i++ ){
selectionStart = [self.textStorage positionAtLineNumber:top+i column:0];
selectionEnd = [self.textStorage positionAtLineNumber:top+i column:[self.textStorage numberOfLines]];
if( [self.textStorage isEOF:selectionStart] || [self.textStorage isEOL:selectionStart]){
// EOF or EOL can not be selected
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,0)]]; // 0 means No selection. This information is important and used in operators like 'delete'
}else if( [self.textStorage isEOF:selectionEnd] || [self.textStorage isEOL:selectionEnd]){
selectionEnd--;
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,selectionEnd-selectionStart+1)]];
}else{
[rangeArray addObject:[NSValue valueWithRange:NSMakeRange(selectionStart,selectionEnd-selectionStart+1)]];
}
}
}else if( self.selectionMode == XVIM_VISUAL_BLOCK){
// Define the block as a rect by line and column number
Expand Down
27 changes: 23 additions & 4 deletions XVim/Test/XVimTester+Operator.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,16 @@ - (NSArray*)operator_testcases{
@"ddd\n" // 52
@"eee\n" // 56
@"fff\n"; // 60


static NSString* text7 = @"aaa\n" // 0 (index of each WORD)
@"{\n" // 4
@" bbb\n" // 6
@"}\n"; // 18

static NSString* text8 = @" \n"; // 0 (index of each WORD)

static NSString* text9 = @"\t\t\n"; // 0 (index of each WORD)

static NSString* a_result = @"aAa bbXXXb ccc\n";
static NSString* a_result2 = @"aAa bbXXXXXXXXXb ccc\n";
static NSString* a_result3 = @"aXXXaa\n"
Expand Down Expand Up @@ -304,7 +313,14 @@ - (NSArray*)operator_testcases{
@" ddd\n" // 28
@" eee\n" // 38
@" fff"; // 46


static NSString* filter_result0 = @"aaa\n" // 0 (index of each WORD)
@"{\n" // 4
@" bbb\n" // 6
@"}\n"; // 14

static NSString* filter_result1 = @"\n"; // 0 (index of each WORD)

return [NSArray arrayWithObjects:
// All changes/insertions must be repeated by dot(.)
// All insertions must set hat(^) mark
Expand Down Expand Up @@ -485,9 +501,12 @@ - (NSArray*)operator_testcases{
XVimMakeTestCase(text5, 1, 0, @"2<<jjj.", lshift_result2,29, 0),
XVimMakeTestCase(text5,13, 0, @"<<jj`." , lshift_result0,12, 0),
XVimMakeTestCase(text5,13, 0, @"<<jj'." , lshift_result0,16, 0),

// = (filter)

XVimMakeTestCase(text7, 16, 0, @"==", filter_result0, 10, 0),
XVimMakeTestCase(text8, 3, 0, @"==", filter_result1, 0, 0),
XVimMakeTestCase(text9, 1, 0, @"==", filter_result1, 0, 0),

// gu, gU
XVimMakeTestCase(text0, 0, 0, @"guw", guw_result, 0, 0),
XVimMakeTestCase(text0, 0, 0, @"gUw", gUw_result, 0, 0),
Expand Down