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 3 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
13 changes: 8 additions & 5 deletions XVim/NSTextView+VimOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -789,8 +789,8 @@ - (void)xvim_filter:(XVimMotion*)motion{
if( self.insertionPoint == 0 && [[self xvim_string] length] == 0 ){
return ;
}
NSUInteger insertionAfterFilter = self.insertionPoint;

NSUInteger insertionAfterFilter;
NSRange filterRange;
if( self.selectionMode == XVIM_VISUAL_NONE ){
XVimRange to = [self xvim_getMotionRange:self.insertionPoint Motion:motion];
Expand All @@ -799,19 +799,22 @@ - (void)xvim_filter:(XVimMotion*)motion{
}
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);
}


NSString *lineString = [[self xvim_string] substringWithRange:filterRange];
NSRange whiteSpaceRange = [lineString rangeOfString:@"^\\s*" options:NSRegularExpressionSearch];
lineString = [lineString stringByReplacingCharactersInRange:whiteSpaceRange withString:@""];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JugglerShu - Maybe you can help point me in the correct direction here. The problem is that I need to remove the whitespace from the actual line of the file here and write it back. This isn't happening here as I thought as the line below test = FALSE; should has 8 spaces. If you == on that line in VIM all of the whitespace should be removed which is not happening.

    if( test )
    {
        test = FALSE;

    }

I have the range of the whiteSpaceRange and the filterRange as well as the substring of the filterRange. However what I'm not sure about is the best way to "edit" the line of the actual file to remove the whitespace or if if it's even allowed to edit from the NSTextView+VimOperation. Just wanted to see what your thoughts were about this and how best to "edit" this line to remove all the found whitespace characters.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the way forward would be to find the start of the line you are on and the line the end position is on. yank that, filter it, delete the lines using

- (void)xvim_deleteLinesFrom:(NSUInteger)line1 to:(NSUInteger)line2; 

then insert the filtered text back using

- (void)xvim_insertText:(NSString*)str line:(NSUInteger)line column:(NSUInteger)column;

both are methods on the category:

@interface NSTextView (VimOperation)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's one of the solutions I was thinking about too as well as just deleting all the text on the line if it's all whitespace however I wasn't sure if there was a more optimized solution. I was hoping for something more like NSString stringByReplacingCharactersInRange:withString: if possible though although I haven't found anything like that yet.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt that it needs to be super optimized an operation as the files most people work on are on the order of 1000 LOC. this feature should be tested thoroughly with test cases though because it's potentially destructive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, anything is fine as far as it is working.
But usually when you want to edit text in XVim text view, think followings in order.

1. Find if there is a method named with "xvim_" which solves your problem (and use it if found)
2. Use [self insertText:replacementRange:] for any edit(insert,delete,replace) of a text. (This is handled by an undo manager properly)
3. If you find some editing operation is shared by several Vim commands, think about create xvim_ prefixed method in NSTextView+VimOperation category.

I wonder if your code here is handled by an undo manager properly.

Let me know if you have further questions.

Thank you for your great improvements!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the great feedback @weaksauce and @JugglerShu. I'll update taking into consideration the ideas above and make sure I handle adding some more tests like for undo and visual. 👍


[self xvim_indentCharacterRange: filterRange];
insertionAfterFilter = [self.textStorage firstNonblankInLine:self.insertionPoint];
[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
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