Auto merge of #2898 - micbou:line-overlapping-chunks, r=micbou
[READY] Apply chunks from bottom to top Without the proposed fix, the test included in that PR fails as follows ``` FAIL: ycm.tests.vimsupport_test.ReplaceChunksInBuffer_LineOverlappingChunks_test ---------------------------------------------------------------------- Traceback (most recent call last): File "C:\Python36\lib\site-packages\nose\case.py", line 198, in runTest self.test(*self.arg) File "C:\Users\micbou\projects\YouCompleteMe\python\ycm\tests\vimsupport_test.py", line 768, in ReplaceChunksInBuffer_LineOverlappingChunks_test AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer ) File "C:\Users\micbou\projects\YouCompleteMe\python\ycm\tests\vimsupport_test.py", line 86, in AssertBuffersAreEqualAsBytes eq_( ToBytes( result_line ), ToBytes( expected_line ) ) AssertionError: b' third line' != b' third ' ``` Found the issue while trying to add code formatting support to the language server completer. The test is based on a real-world scenario when formatting with jdt.ls (for some reason, jdt.ls is including the newline of the previous line when fixing indentation). <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2898) <!-- Reviewable:end -->
This commit is contained in:
commit
39fe6d1f86
@ -183,628 +183,364 @@ def AssertBuffersAreEqualAsBytes( result_buffer, expected_buffer ):
|
|||||||
|
|
||||||
def ReplaceChunk_SingleLine_Repl_1_test():
|
def ReplaceChunk_SingleLine_Repl_1_test():
|
||||||
# Replace with longer range
|
# Replace with longer range
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 5 )
|
start, end = _BuildLocations( 1, 11, 1, 17 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'pie', result_buffer )
|
||||||
end,
|
|
||||||
'How long',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'How long is a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a pie' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 4 )
|
|
||||||
|
|
||||||
# and replace again, using delta
|
# and replace again
|
||||||
start, end = _BuildLocations( 1, 10, 1, 11 )
|
start, end = _BuildLocations( 1, 10, 1, 11 )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
vimsupport.ReplaceChunk( start, end, ' piece of ', result_buffer )
|
||||||
start,
|
|
||||||
end,
|
|
||||||
' piece of ',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
AssertBuffersAreEqualAsBytes( [ 'This is a piece of pie' ], result_buffer )
|
||||||
char_offset += new_char_offset
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'How long is a piece of string' ],
|
|
||||||
result_buffer )
|
|
||||||
eq_( new_line_offset, 0 )
|
|
||||||
eq_( new_char_offset, 9 )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 13 )
|
|
||||||
|
|
||||||
# and once more, for luck
|
# and once more, for luck
|
||||||
start, end = _BuildLocations( 1, 11, 1, 17 )
|
start, end = _BuildLocations( 1, 1, 1, 5 )
|
||||||
|
vimsupport.ReplaceChunk( start, end, 'How long', result_buffer )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
'pie',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
|
||||||
char_offset += new_char_offset
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'How long is a piece of pie' ],
|
AssertBuffersAreEqualAsBytes( [ 'How long is a piece of pie' ],
|
||||||
result_buffer )
|
result_buffer )
|
||||||
eq_( new_line_offset, 0 )
|
|
||||||
eq_( new_char_offset, -3 )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 10 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Repl_2_test():
|
def ReplaceChunk_SingleLine_Repl_2_test():
|
||||||
# Replace with shorter range
|
# Replace with shorter range
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 11, 1, 17 )
|
start, end = _BuildLocations( 1, 11, 1, 17 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'test', result_buffer )
|
||||||
end,
|
|
||||||
'test',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is a test' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a test' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -2 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Repl_3_test():
|
def ReplaceChunk_SingleLine_Repl_3_test():
|
||||||
# Replace with equal range
|
# Replace with equal range
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 6, 1, 8 )
|
start, end = _BuildLocations( 1, 6, 1, 8 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'be', result_buffer )
|
||||||
end,
|
|
||||||
'be',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This be a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This be a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 0 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Add_1_test():
|
def ReplaceChunk_SingleLine_Add_1_test():
|
||||||
# Insert at start
|
# Insert at start
|
||||||
result_buffer = [ 'is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 1 )
|
start, end = _BuildLocations( 1, 1, 1, 1 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'This ', result_buffer )
|
||||||
end,
|
|
||||||
'This ',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 5 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Add_2_test():
|
def ReplaceChunk_SingleLine_Add_2_test():
|
||||||
# Insert at end
|
# Insert at end
|
||||||
result_buffer = [ 'This is a ' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a ' ] )
|
||||||
start, end = _BuildLocations( 1, 11, 1, 11 )
|
start, end = _BuildLocations( 1, 11, 1, 11 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'string', result_buffer )
|
||||||
end,
|
|
||||||
'string',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 6 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Add_3_test():
|
def ReplaceChunk_SingleLine_Add_3_test():
|
||||||
# Insert in the middle
|
# Insert in the middle
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 8, 1, 8 )
|
start, end = _BuildLocations( 1, 8, 1, 8 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, ' not', result_buffer )
|
||||||
end,
|
|
||||||
' not',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is not a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is not a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 4 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Del_1_test():
|
def ReplaceChunk_SingleLine_Del_1_test():
|
||||||
# Delete from start
|
# Delete from start
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 6 )
|
start, end = _BuildLocations( 1, 1, 1, 6 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, '', result_buffer )
|
||||||
end,
|
|
||||||
'',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'is a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'is a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -5 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Del_2_test():
|
def ReplaceChunk_SingleLine_Del_2_test():
|
||||||
# Delete from end
|
# Delete from end
|
||||||
result_buffer = [ 'This is a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
|
||||||
start, end = _BuildLocations( 1, 10, 1, 18 )
|
start, end = _BuildLocations( 1, 10, 1, 18 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, '', result_buffer )
|
||||||
end,
|
|
||||||
'',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is a' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -8 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Del_3_test():
|
def ReplaceChunk_SingleLine_Del_3_test():
|
||||||
# Delete from middle
|
# Delete from middle
|
||||||
result_buffer = [ 'This is not a string' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'This is not a string' ] )
|
||||||
start, end = _BuildLocations( 1, 9, 1, 13 )
|
start, end = _BuildLocations( 1, 9, 1, 13 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, '', result_buffer )
|
||||||
end,
|
|
||||||
'',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -4 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Unicode_ReplaceUnicodeChars_test():
|
def ReplaceChunk_SingleLine_Unicode_ReplaceUnicodeChars_test():
|
||||||
# Replace Unicode characters.
|
# Replace Unicode characters.
|
||||||
result_buffer = [ 'This Uniçø∂‰ string is in the middle' ]
|
result_buffer = VimBuffer(
|
||||||
|
'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
|
||||||
start, end = _BuildLocations( 1, 6, 1, 20 )
|
start, end = _BuildLocations( 1, 6, 1, 20 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'Unicode ', result_buffer )
|
||||||
end,
|
|
||||||
'Unicode ',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This Unicode string is in the middle' ],
|
AssertBuffersAreEqualAsBytes( [ 'This Unicode string is in the middle' ],
|
||||||
result_buffer )
|
result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -6 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Unicode_ReplaceAfterUnicode_test():
|
def ReplaceChunk_SingleLine_Unicode_ReplaceAfterUnicode_test():
|
||||||
# Replace ASCII characters after Unicode characters in the line.
|
# Replace ASCII characters after Unicode characters in the line.
|
||||||
result_buffer = [ 'This Uniçø∂‰ string is in the middle' ]
|
result_buffer = VimBuffer(
|
||||||
|
'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
|
||||||
start, end = _BuildLocations( 1, 30, 1, 43 )
|
start, end = _BuildLocations( 1, 30, 1, 43 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'fåke', result_buffer )
|
||||||
end,
|
|
||||||
'fåke',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'This Uniçø∂‰ string is fåke' ],
|
AssertBuffersAreEqualAsBytes( [ 'This Uniçø∂‰ string is fåke' ],
|
||||||
result_buffer )
|
result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -8 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Unicode_Grown_test():
|
def ReplaceChunk_SingleLine_Unicode_Grown_test():
|
||||||
# Replace ASCII characters after Unicode characters in the line.
|
# Replace ASCII characters after Unicode characters in the line.
|
||||||
result_buffer = [ 'a' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'a' ] )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 2 )
|
start, end = _BuildLocations( 1, 1, 1, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'å', result_buffer )
|
||||||
end,
|
|
||||||
'å',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'å' ], result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'å' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 1 ) # Note: byte difference (a = 1 byte, å = 2 bytes)
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_RemoveSingleLine_test():
|
def ReplaceChunk_RemoveSingleLine_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 1, 3, 1 )
|
start, end = _BuildLocations( 2, 1, 3, 1 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
|
vimsupport.ReplaceChunk( start, end, '', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
# First line is not affected.
|
# First line is not affected.
|
||||||
expected_buffer = [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'aCa' ]
|
'aCa' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, -1 )
|
|
||||||
eq_( char_offset, 0 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleToMultipleLines_test():
|
def ReplaceChunk_SingleToMultipleLines_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 2 )
|
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
|
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
|
||||||
'aEb',
|
|
||||||
'bFBa',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 1 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
# now make another change to the "2nd" line
|
|
||||||
start, end = _BuildLocations( 2, 3, 2, 4 )
|
start, end = _BuildLocations( 2, 3, 2, 4 )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
|
||||||
start,
|
|
||||||
end,
|
|
||||||
'cccc',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
|
||||||
char_offset += new_char_offset
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'aEb',
|
'aBcccc',
|
||||||
'bFBcccc',
|
'aCa' ], result_buffer )
|
||||||
'aCa' ], result_buffer )
|
|
||||||
eq_( line_offset, 1 )
|
# now make another change to the second line
|
||||||
eq_( char_offset, 4 )
|
start, end = _BuildLocations( 2, 2, 2, 2 )
|
||||||
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
|
'aEb',
|
||||||
|
'bFBcccc',
|
||||||
|
'aCa' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleToMultipleLines2_test():
|
def ReplaceChunk_SingleToMultipleLines2_test():
|
||||||
result_buffer = [ 'aAa', 'aBa', 'aCa' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
|
'aBa',
|
||||||
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 2 )
|
start, end = _BuildLocations( 2, 2, 2, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nG', result_buffer )
|
||||||
end,
|
|
||||||
'Eb\nbFb\nG',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
0,
|
'aEb',
|
||||||
0,
|
'bFb',
|
||||||
result_buffer )
|
'GBa',
|
||||||
expected_buffer = [ 'aAa',
|
'aCa' ], result_buffer )
|
||||||
'aEb',
|
|
||||||
'bFb',
|
|
||||||
'GBa',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 2 )
|
|
||||||
eq_( char_offset, 0 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleToMultipleLines3_test():
|
def ReplaceChunk_SingleToMultipleLines3_test():
|
||||||
result_buffer = [ 'aAa', 'aBa', 'aCa' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
|
'aBa',
|
||||||
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 2 )
|
start, end = _BuildLocations( 2, 2, 2, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
|
||||||
end,
|
|
||||||
'Eb\nbFb\nbGb',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
0,
|
'aEb',
|
||||||
0,
|
'bFb',
|
||||||
result_buffer )
|
'bGbBa',
|
||||||
expected_buffer = [ 'aAa',
|
'aCa' ], result_buffer )
|
||||||
'aEb',
|
|
||||||
'bFb',
|
|
||||||
'bGbBa',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 2 )
|
|
||||||
eq_( char_offset, 2 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleToMultipleLinesReplace_test():
|
def ReplaceChunk_SingleToMultipleLinesReplace_test():
|
||||||
result_buffer = [ 'aAa', 'aBa', 'aCa' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
|
'aBa',
|
||||||
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 1, 2, 1, 4 )
|
start, end = _BuildLocations( 1, 2, 1, 4 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
|
||||||
end,
|
|
||||||
'Eb\nbFb\nbGb',
|
AssertBuffersAreEqualAsBytes( [ 'aEb',
|
||||||
0,
|
'bFb',
|
||||||
0,
|
'bGb',
|
||||||
result_buffer )
|
'aBa',
|
||||||
expected_buffer = [ 'aEb',
|
'aCa' ], result_buffer )
|
||||||
'bFb',
|
|
||||||
'bGb',
|
|
||||||
'aBa',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 2 )
|
|
||||||
eq_( char_offset, 0 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleToMultipleLinesReplace_2_test():
|
def ReplaceChunk_SingleToMultipleLinesReplace_2_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 1, 2, 1, 4 )
|
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
|
||||||
end,
|
|
||||||
'Eb\nbFb\nbGb',
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
result_buffer )
|
|
||||||
expected_buffer = [ 'aEb',
|
|
||||||
'bFb',
|
|
||||||
'bGb',
|
|
||||||
'aBa',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 2 )
|
|
||||||
eq_( char_offset, 0 )
|
|
||||||
|
|
||||||
# now do a subsequent change (insert at end of line "1")
|
|
||||||
start, end = _BuildLocations( 1, 4, 1, 4 )
|
start, end = _BuildLocations( 1, 4, 1, 4 )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
|
||||||
start,
|
|
||||||
end,
|
|
||||||
'cccc',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
AssertBuffersAreEqualAsBytes( [ 'aAacccc',
|
||||||
char_offset += new_char_offset
|
'aBa',
|
||||||
|
'aCa', ], result_buffer )
|
||||||
|
|
||||||
|
# now do a subsequent change (insert in the middle of the first line)
|
||||||
|
start, end = _BuildLocations( 1, 2, 1, 4 )
|
||||||
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'aEb',
|
AssertBuffersAreEqualAsBytes( [ 'aEb',
|
||||||
'bFb',
|
'bFb',
|
||||||
'bGbcccc',
|
'bGbcccc',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ], result_buffer )
|
'aCa' ], result_buffer )
|
||||||
|
|
||||||
eq_( line_offset, 2 )
|
|
||||||
eq_( char_offset, 4 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToSingleLine_test():
|
def ReplaceChunk_MultipleLinesToSingleLine_test():
|
||||||
result_buffer = [ 'aAa', 'aBa', 'aCaaaa' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
start, end = _BuildLocations( 2, 2, 3, 2 )
|
'aBa',
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'E',
|
'aCaaaa' ] )
|
||||||
0, 0, result_buffer )
|
start, end = _BuildLocations( 3, 4, 3, 5 )
|
||||||
expected_buffer = [ 'aAa', 'aECaaaa' ]
|
vimsupport.ReplaceChunk( start, end, 'dd\ndd', result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, -1 )
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
eq_( char_offset, 1 )
|
'aBa',
|
||||||
|
'aCadd',
|
||||||
|
'ddaa' ], result_buffer )
|
||||||
|
|
||||||
# make another modification applying offsets
|
# make another modification applying offsets
|
||||||
start, end = _BuildLocations( 3, 3, 3, 4 )
|
start, end = _BuildLocations( 3, 3, 3, 4 )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
|
||||||
start,
|
|
||||||
end,
|
|
||||||
'cccc',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
|
||||||
char_offset += new_char_offset
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'aECccccaaa' ], result_buffer )
|
'aBa',
|
||||||
eq_( line_offset, -1 )
|
'aCccccdd',
|
||||||
eq_( char_offset, 4 )
|
'ddaa' ], result_buffer )
|
||||||
|
|
||||||
# and another, for luck
|
# and another, for luck
|
||||||
start, end = _BuildLocations( 3, 4, 3, 5 )
|
start, end = _BuildLocations( 2, 2, 3, 2 )
|
||||||
( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
|
vimsupport.ReplaceChunk( start, end, 'E', result_buffer )
|
||||||
start,
|
|
||||||
end,
|
|
||||||
'dd\ndd',
|
|
||||||
line_offset,
|
|
||||||
char_offset,
|
|
||||||
result_buffer )
|
|
||||||
|
|
||||||
line_offset += new_line_offset
|
|
||||||
char_offset += new_char_offset
|
|
||||||
|
|
||||||
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'aECccccdd',
|
'aECccccdd',
|
||||||
'ddaa' ], result_buffer )
|
'ddaa' ], result_buffer )
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -2 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToSameMultipleLines_test():
|
def ReplaceChunk_MultipleLinesToSameMultipleLines_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa',
|
'aCa',
|
||||||
'aDe' ]
|
'aDe' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 3, 2 )
|
start, end = _BuildLocations( 2, 2, 3, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'aEb',
|
'aEb',
|
||||||
'bFCa',
|
'bFCa',
|
||||||
'aDe' ]
|
'aDe' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToMoreMultipleLines_test():
|
def ReplaceChunk_MultipleLinesToMoreMultipleLines_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa',
|
'aCa',
|
||||||
'aDe' ]
|
'aDe' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 3, 2 )
|
start, end = _BuildLocations( 2, 2, 3, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbG', result_buffer )
|
||||||
end,
|
|
||||||
'Eb\nbFb\nbG',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
0,
|
'aEb',
|
||||||
0,
|
'bFb',
|
||||||
result_buffer )
|
'bGCa',
|
||||||
expected_buffer = [ 'aAa',
|
'aDe' ], result_buffer )
|
||||||
'aEb',
|
|
||||||
'bFb',
|
|
||||||
'bGCa',
|
|
||||||
'aDe' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 1 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToLessMultipleLines_test():
|
def ReplaceChunk_MultipleLinesToLessMultipleLines_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa',
|
'aCa',
|
||||||
'aDe' ]
|
'aDe' ] )
|
||||||
start, end = _BuildLocations( 1, 2, 3, 2 )
|
start, end = _BuildLocations( 1, 2, 3, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aEb', 'bFCa', 'aDe' ]
|
AssertBuffersAreEqualAsBytes( [ 'aEb',
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
'bFCa',
|
||||||
eq_( line_offset, -1 )
|
'aDe' ], result_buffer )
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToEvenLessMultipleLines_test():
|
def ReplaceChunk_MultipleLinesToEvenLessMultipleLines_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa',
|
'aCa',
|
||||||
'aDe' ]
|
'aDe' ] )
|
||||||
start, end = _BuildLocations( 1, 2, 4, 2 )
|
start, end = _BuildLocations( 1, 2, 4, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
|
vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aEb', 'bFDe' ]
|
AssertBuffersAreEqualAsBytes( [ 'aEb',
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
'bFDe' ], result_buffer )
|
||||||
eq_( line_offset, -2 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SpanBufferEdge_test():
|
def ReplaceChunk_SpanBufferEdge_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 3 )
|
start, end = _BuildLocations( 1, 1, 1, 3 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
|
vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'bDba',
|
AssertBuffersAreEqualAsBytes( [ 'bDba',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_DeleteTextInLine_test():
|
def ReplaceChunk_DeleteTextInLine_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 3 )
|
start, end = _BuildLocations( 2, 2, 2, 3 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
|
vimsupport.ReplaceChunk( start, end, '', result_buffer )
|
||||||
0, 0, result_buffer )
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
expected_buffer = [ 'aAa',
|
'aa',
|
||||||
'aa',
|
'aCa' ], result_buffer )
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, -1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_AddTextInLine_test():
|
def ReplaceChunk_AddTextInLine_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 2 )
|
start, end = _BuildLocations( 2, 2, 2, 2 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
|
vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'abDbBa',
|
'abDbBa',
|
||||||
'aCa' ]
|
'aCa' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 3 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_ReplaceTextInLine_test():
|
def ReplaceChunk_ReplaceTextInLine_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
|
||||||
'aBa',
|
'aBa',
|
||||||
'aCa' ]
|
'aCa' ] )
|
||||||
start, end = _BuildLocations( 2, 2, 2, 3 )
|
start, end = _BuildLocations( 2, 2, 2, 3 )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
|
vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
|
||||||
0, 0, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
AssertBuffersAreEqualAsBytes( [ 'aAa',
|
||||||
'abDba',
|
'abDba',
|
||||||
'aCa' ]
|
'aCa' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 2 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLineOffsetWorks_test():
|
def ReplaceChunk_NewlineChunk_test():
|
||||||
result_buffer = [ 'aAa',
|
result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
|
||||||
'aBa',
|
'second line' ] )
|
||||||
'aCa' ]
|
start, end = _BuildLocations( 1, 11, 2, 1 )
|
||||||
start, end = _BuildLocations( 1, 1, 1, 2 )
|
vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
|
|
||||||
1, 1, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
|
||||||
'abDba',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 0 )
|
|
||||||
eq_( char_offset, 2 )
|
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'first line',
|
||||||
def ReplaceChunk_SingleLineToMultipleLinesOffsetWorks_test():
|
'second line' ], result_buffer )
|
||||||
result_buffer = [ 'aAa',
|
|
||||||
'aBa',
|
|
||||||
'aCa' ]
|
|
||||||
start, end = _BuildLocations( 1, 1, 1, 2 )
|
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Db\nE',
|
|
||||||
1, 1, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
|
||||||
'aDb',
|
|
||||||
'Ea',
|
|
||||||
'aCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 1 )
|
|
||||||
eq_( char_offset, -1 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLinesToSingleLineOffsetWorks_test():
|
|
||||||
result_buffer = [ 'aAa',
|
|
||||||
'aBa',
|
|
||||||
'aCa' ]
|
|
||||||
start, end = _BuildLocations( 1, 1, 2, 2 )
|
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
|
|
||||||
1, 1, result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
|
||||||
'abDbCa' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, -1 )
|
|
||||||
eq_( char_offset, 3 )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_MultipleLineOffsetWorks_test():
|
|
||||||
result_buffer = [ 'aAa',
|
|
||||||
'aBa',
|
|
||||||
'aCa' ]
|
|
||||||
start, end = _BuildLocations( 3, 1, 4, 3 )
|
|
||||||
( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
|
|
||||||
end,
|
|
||||||
'bDb\nbEb\nbFb',
|
|
||||||
-1,
|
|
||||||
1,
|
|
||||||
result_buffer )
|
|
||||||
expected_buffer = [ 'aAa',
|
|
||||||
'abDb',
|
|
||||||
'bEb',
|
|
||||||
'bFba' ]
|
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
eq_( line_offset, 1 )
|
|
||||||
eq_( char_offset, 1 )
|
|
||||||
|
|
||||||
|
|
||||||
def _BuildLocations( start_line, start_column, end_line, end_column ):
|
def _BuildLocations( start_line, start_column, end_line, end_column ):
|
||||||
@ -823,11 +559,10 @@ def ReplaceChunksInBuffer_SortedChunks_test():
|
|||||||
_BuildChunk( 1, 11, 1, 11, ')' )
|
_BuildChunk( 1, 11, 1, 11, ')' )
|
||||||
]
|
]
|
||||||
|
|
||||||
result_buffer = [ 'CT<10 >> 2> ct' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
|
||||||
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer, None )
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
expected_buffer = [ 'CT<(10 >> 2)> ct' ]
|
AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunksInBuffer_UnsortedChunks_test():
|
def ReplaceChunksInBuffer_UnsortedChunks_test():
|
||||||
@ -836,11 +571,78 @@ def ReplaceChunksInBuffer_UnsortedChunks_test():
|
|||||||
_BuildChunk( 1, 4, 1, 4, '(' )
|
_BuildChunk( 1, 4, 1, 4, '(' )
|
||||||
]
|
]
|
||||||
|
|
||||||
result_buffer = [ 'CT<10 >> 2> ct' ]
|
result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
|
||||||
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer, None )
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
expected_buffer = [ 'CT<(10 >> 2)> ct' ]
|
AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
|
||||||
AssertBuffersAreEqualAsBytes( expected_buffer, result_buffer )
|
|
||||||
|
|
||||||
|
def ReplaceChunksInBuffer_LineOverlappingChunks_test():
|
||||||
|
chunks = [
|
||||||
|
_BuildChunk( 1, 11, 2, 1, '\n ' ),
|
||||||
|
_BuildChunk( 2, 12, 3, 1, '\n ' ),
|
||||||
|
_BuildChunk( 3, 11, 4, 1, '\n ' )
|
||||||
|
]
|
||||||
|
|
||||||
|
result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
|
||||||
|
'second line',
|
||||||
|
'third line',
|
||||||
|
'fourth line' ] )
|
||||||
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'first line',
|
||||||
|
' second line',
|
||||||
|
' third line',
|
||||||
|
' fourth line' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
|
def ReplaceChunksInBuffer_OutdentChunks_test():
|
||||||
|
chunks = [
|
||||||
|
_BuildChunk( 1, 1, 1, 5, ' ' ),
|
||||||
|
_BuildChunk( 1, 15, 2, 9, '\n ' ),
|
||||||
|
_BuildChunk( 2, 20, 3, 3, '\n' )
|
||||||
|
]
|
||||||
|
|
||||||
|
result_buffer = VimBuffer( 'buffer', contents = [ ' first line',
|
||||||
|
' second line',
|
||||||
|
' third line' ] )
|
||||||
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ ' first line',
|
||||||
|
' second line',
|
||||||
|
' third line' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
|
def ReplaceChunksInBuffer_OneLineIndentingChunks_test():
|
||||||
|
chunks = [
|
||||||
|
_BuildChunk( 1, 8, 2, 1, '\n ' ),
|
||||||
|
_BuildChunk( 2, 9, 2, 10, '\n ' ),
|
||||||
|
_BuildChunk( 2, 19, 2, 20, '\n ' )
|
||||||
|
]
|
||||||
|
|
||||||
|
result_buffer = VimBuffer( 'buffer', contents = [ 'class {',
|
||||||
|
'method { statement }',
|
||||||
|
'}' ] )
|
||||||
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'class {',
|
||||||
|
' method {',
|
||||||
|
' statement',
|
||||||
|
' }',
|
||||||
|
'}' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
|
def ReplaceChunksInBuffer_SameLocation_test():
|
||||||
|
chunks = [
|
||||||
|
_BuildChunk( 1, 1, 1, 1, 'this ' ),
|
||||||
|
_BuildChunk( 1, 1, 1, 1, 'is ' ),
|
||||||
|
_BuildChunk( 1, 1, 1, 1, 'pure ' )
|
||||||
|
]
|
||||||
|
|
||||||
|
result_buffer = VimBuffer( 'buffer', contents = [ 'folly' ] )
|
||||||
|
vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'this is pure folly' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
@patch( 'ycm.vimsupport.VariableExists', return_value = False )
|
@patch( 'ycm.vimsupport.VariableExists', return_value = False )
|
||||||
|
@ -749,15 +749,14 @@ def ReplaceChunks( chunks ):
|
|||||||
If for some reason a file could not be opened or changed, raises RuntimeError.
|
If for some reason a file could not be opened or changed, raises RuntimeError.
|
||||||
Otherwise, returns no meaningful value."""
|
Otherwise, returns no meaningful value."""
|
||||||
|
|
||||||
# We apply the edits file-wise for efficiency, and because we must track the
|
# We apply the edits file-wise for efficiency.
|
||||||
# file-wise offset deltas (caused by the modifications to the text).
|
|
||||||
chunks_by_file = _SortChunksByFile( chunks )
|
chunks_by_file = _SortChunksByFile( chunks )
|
||||||
|
|
||||||
# We sort the file list simply to enable repeatable testing
|
# We sort the file list simply to enable repeatable testing.
|
||||||
sorted_file_list = sorted( iterkeys( chunks_by_file ) )
|
sorted_file_list = sorted( iterkeys( chunks_by_file ) )
|
||||||
|
|
||||||
# Make sure the user is prepared to have her screen mutilated by the new
|
# Make sure the user is prepared to have her screen mutilated by the new
|
||||||
# buffers
|
# buffers.
|
||||||
num_files_to_open = _GetNumNonVisibleFiles( sorted_file_list )
|
num_files_to_open = _GetNumNonVisibleFiles( sorted_file_list )
|
||||||
|
|
||||||
if num_files_to_open > 0:
|
if num_files_to_open > 0:
|
||||||
@ -770,11 +769,10 @@ def ReplaceChunks( chunks ):
|
|||||||
locations = []
|
locations = []
|
||||||
|
|
||||||
for filepath in sorted_file_list:
|
for filepath in sorted_file_list:
|
||||||
( buffer_num, close_window ) = _OpenFileInSplitIfNeeded( filepath )
|
buffer_num, close_window = _OpenFileInSplitIfNeeded( filepath )
|
||||||
|
|
||||||
ReplaceChunksInBuffer( chunks_by_file[ filepath ],
|
locations.extend( ReplaceChunksInBuffer( chunks_by_file[ filepath ],
|
||||||
vim.buffers[ buffer_num ],
|
vim.buffers[ buffer_num ] ) )
|
||||||
locations )
|
|
||||||
|
|
||||||
# When opening tons of files, we don't want to have a split for each new
|
# When opening tons of files, we don't want to have a split for each new
|
||||||
# file, as this simply does not scale, so we open the window, make the
|
# file, as this simply does not scale, so we open the window, make the
|
||||||
@ -798,101 +796,91 @@ def ReplaceChunks( chunks ):
|
|||||||
warning = False )
|
warning = False )
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunksInBuffer( chunks, vim_buffer, locations ):
|
def ReplaceChunksInBuffer( chunks, vim_buffer ):
|
||||||
"""Apply changes in |chunks| to the buffer-like object |buffer|. Append each
|
"""Apply changes in |chunks| to the buffer-like object |buffer| and return the
|
||||||
chunk's start to the list |locations|"""
|
locations for that buffer."""
|
||||||
|
|
||||||
# We need to track the difference in length, but ensuring we apply fixes
|
# We apply the chunks from the bottom to the top of the buffer so that we
|
||||||
# in ascending order of insertion point.
|
# don't need to adjust the position of the remaining chunks due to text
|
||||||
|
# changes. This assumes that chunks are not overlapping. However, we still
|
||||||
|
# allow multiple chunks to share the same starting position (because of the
|
||||||
|
# language server protocol specs). These chunks must be applied in their order
|
||||||
|
# of appareance. Since Python sorting is stable, if we sort the whole list in
|
||||||
|
# reverse order of location, these chunks will be reversed. Therefore, we
|
||||||
|
# need to fully reverse the list then sort it on the starting position in
|
||||||
|
# reverse order.
|
||||||
|
chunks.reverse()
|
||||||
chunks.sort( key = lambda chunk: (
|
chunks.sort( key = lambda chunk: (
|
||||||
chunk[ 'range' ][ 'start' ][ 'line_num' ],
|
chunk[ 'range' ][ 'start' ][ 'line_num' ],
|
||||||
chunk[ 'range' ][ 'start' ][ 'column_num' ]
|
chunk[ 'range' ][ 'start' ][ 'column_num' ]
|
||||||
) )
|
), reverse = True )
|
||||||
|
|
||||||
# Remember the line number we're processing. Negative line number means we
|
# However, we still want to display the locations from the top of the buffer
|
||||||
# haven't processed any lines yet (by nature of being not equal to any
|
# to its bottom.
|
||||||
# real line number).
|
return reversed( [ ReplaceChunk( chunk[ 'range' ][ 'start' ],
|
||||||
last_line = -1
|
chunk[ 'range' ][ 'end' ],
|
||||||
|
chunk[ 'replacement_text' ],
|
||||||
|
vim_buffer )
|
||||||
|
for chunk in chunks ] )
|
||||||
|
|
||||||
line_delta = 0
|
|
||||||
for chunk in chunks:
|
|
||||||
if chunk[ 'range' ][ 'start' ][ 'line_num' ] != last_line:
|
|
||||||
# If this chunk is on a different line than the previous chunk,
|
|
||||||
# then ignore previous deltas (as offsets won't have changed).
|
|
||||||
last_line = chunk[ 'range' ][ 'end' ][ 'line_num' ]
|
|
||||||
char_delta = 0
|
|
||||||
|
|
||||||
( new_line_delta, new_char_delta ) = ReplaceChunk(
|
def SplitLines( contents ):
|
||||||
chunk[ 'range' ][ 'start' ],
|
"""Return a list of each of the lines in the byte string |contents|.
|
||||||
chunk[ 'range' ][ 'end' ],
|
Behavior is equivalent to str.splitlines with the following exceptions:
|
||||||
chunk[ 'replacement_text' ],
|
- empty strings are returned as [ '' ];
|
||||||
line_delta, char_delta,
|
- a trailing newline is not ignored (i.e. SplitLines( '\n' )
|
||||||
vim_buffer,
|
returns [ '', '' ], not [ '' ] )."""
|
||||||
locations )
|
if contents == b'':
|
||||||
line_delta += new_line_delta
|
return [ b'' ]
|
||||||
char_delta += new_char_delta
|
|
||||||
|
lines = contents.splitlines()
|
||||||
|
|
||||||
|
if contents.endswith( b'\r' ) or contents.endswith( b'\n' ):
|
||||||
|
lines.append( b'' )
|
||||||
|
|
||||||
|
return lines
|
||||||
|
|
||||||
|
|
||||||
# Replace the chunk of text specified by a contiguous range with the supplied
|
# Replace the chunk of text specified by a contiguous range with the supplied
|
||||||
# text.
|
# text and return the location.
|
||||||
# * start and end are objects with line_num and column_num properties
|
# * start and end are objects with line_num and column_num properties
|
||||||
# * the range is inclusive
|
# * the range is inclusive
|
||||||
# * indices are all 1-based
|
# * indices are all 1-based
|
||||||
# * the returned character delta is the delta for the last line
|
|
||||||
#
|
|
||||||
# returns the delta (in lines and characters) that any position after the end
|
|
||||||
# needs to be adjusted by.
|
|
||||||
#
|
#
|
||||||
# NOTE: Works exclusively with bytes() instances and byte offsets as returned
|
# NOTE: Works exclusively with bytes() instances and byte offsets as returned
|
||||||
# by ycmd and used within the Vim buffers
|
# by ycmd and used within the Vim buffers
|
||||||
def ReplaceChunk( start, end, replacement_text, line_delta, char_delta,
|
def ReplaceChunk( start, end, replacement_text, vim_buffer ):
|
||||||
vim_buffer, locations = None ):
|
|
||||||
# ycmd's results are all 1-based, but vim's/python's are all 0-based
|
# ycmd's results are all 1-based, but vim's/python's are all 0-based
|
||||||
# (so we do -1 on all of the values)
|
# (so we do -1 on all of the values)
|
||||||
start_line = start[ 'line_num' ] - 1 + line_delta
|
start_line = start[ 'line_num' ] - 1
|
||||||
end_line = end[ 'line_num' ] - 1 + line_delta
|
end_line = end[ 'line_num' ] - 1
|
||||||
|
|
||||||
source_lines_count = end_line - start_line + 1
|
start_column = start[ 'column_num' ] - 1
|
||||||
start_column = start[ 'column_num' ] - 1 + char_delta
|
|
||||||
end_column = end[ 'column_num' ] - 1
|
end_column = end[ 'column_num' ] - 1
|
||||||
if source_lines_count == 1:
|
|
||||||
end_column += char_delta
|
|
||||||
|
|
||||||
# NOTE: replacement_text is unicode, but all our offsets are byte offsets,
|
# NOTE: replacement_text is unicode, but all our offsets are byte offsets,
|
||||||
# so we convert to bytes
|
# so we convert to bytes
|
||||||
replacement_lines = ToBytes( replacement_text ).splitlines( False )
|
replacement_lines = SplitLines( ToBytes( replacement_text ) )
|
||||||
if not replacement_lines:
|
|
||||||
replacement_lines = [ bytes( b'' ) ]
|
|
||||||
replacement_lines_count = len( replacement_lines )
|
|
||||||
|
|
||||||
# NOTE: Vim buffers are a list of byte objects on Python 2 but unicode
|
# NOTE: Vim buffers are a list of byte objects on Python 2 but unicode
|
||||||
# objects on Python 3.
|
# objects on Python 3.
|
||||||
end_existing_text = ToBytes( vim_buffer[ end_line ] )[ end_column : ]
|
|
||||||
start_existing_text = ToBytes( vim_buffer[ start_line ] )[ : start_column ]
|
start_existing_text = ToBytes( vim_buffer[ start_line ] )[ : start_column ]
|
||||||
|
end_existing_text = ToBytes( vim_buffer[ end_line ] )[ end_column : ]
|
||||||
new_char_delta = ( len( replacement_lines[ -1 ] )
|
|
||||||
- ( end_column - start_column ) )
|
|
||||||
if replacement_lines_count > 1:
|
|
||||||
new_char_delta -= start_column
|
|
||||||
|
|
||||||
replacement_lines[ 0 ] = start_existing_text + replacement_lines[ 0 ]
|
replacement_lines[ 0 ] = start_existing_text + replacement_lines[ 0 ]
|
||||||
replacement_lines[ -1 ] = replacement_lines[ -1 ] + end_existing_text
|
replacement_lines[ -1 ] = replacement_lines[ -1 ] + end_existing_text
|
||||||
|
|
||||||
vim_buffer[ start_line : end_line + 1 ] = replacement_lines[:]
|
vim_buffer[ start_line : end_line + 1 ] = replacement_lines[:]
|
||||||
|
|
||||||
if locations is not None:
|
return {
|
||||||
locations.append( {
|
'bufnr': vim_buffer.number,
|
||||||
'bufnr': vim_buffer.number,
|
'filename': vim_buffer.name,
|
||||||
'filename': vim_buffer.name,
|
# line and column numbers are 1-based in qflist
|
||||||
# line and column numbers are 1-based in qflist
|
'lnum': start_line + 1,
|
||||||
'lnum': start_line + 1,
|
'col': start_column + 1,
|
||||||
'col': start_column + 1,
|
'text': replacement_text,
|
||||||
'text': replacement_text,
|
'type': 'F',
|
||||||
'type': 'F',
|
}
|
||||||
} )
|
|
||||||
|
|
||||||
new_line_delta = replacement_lines_count - source_lines_count
|
|
||||||
return ( new_line_delta, new_char_delta )
|
|
||||||
|
|
||||||
|
|
||||||
def InsertNamespace( namespace ):
|
def InsertNamespace( namespace ):
|
||||||
@ -909,9 +897,9 @@ def InsertNamespace( namespace ):
|
|||||||
if line:
|
if line:
|
||||||
existing_line = LineTextInCurrentBuffer( line )
|
existing_line = LineTextInCurrentBuffer( line )
|
||||||
existing_indent = re.sub( r"\S.*", "", existing_line )
|
existing_indent = re.sub( r"\S.*", "", existing_line )
|
||||||
new_line = "{0}using {1};\n\n".format( existing_indent, namespace )
|
new_line = "{0}using {1};\n".format( existing_indent, namespace )
|
||||||
replace_pos = { 'line_num': line + 1, 'column_num': 1 }
|
replace_pos = { 'line_num': line + 1, 'column_num': 1 }
|
||||||
ReplaceChunk( replace_pos, replace_pos, new_line, 0, 0, vim.current.buffer )
|
ReplaceChunk( replace_pos, replace_pos, new_line, vim.current.buffer )
|
||||||
PostVimMessage( 'Add namespace: {0}'.format( namespace ), warning = False )
|
PostVimMessage( 'Add namespace: {0}'.format( namespace ), warning = False )
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user