Auto merge of #2951 - micbou:replace-chunk-out-of-range, r=puremourning
[READY] Fix index error when applying a chunk at the end of file
When sending a request to the server, [we add a newline to the buffer contents to match what gets saved to disk](d3381411a0/python/ycm/vimsupport.py (L117)
). If the server generates a chunk containing that newline, this chunk goes past the Vim buffer contents since there is actually no new line, which raises an `IndexError` exception when applying the chunk. We fix the issue by recomputing the end position of where the chunk is applied and by removing all trailing characters in the chunk.
Steps to reproduce the issue:
- create a `Test.java` file with the following contents:
```java
package Test;$
$
```
where `$` represents an end of line;
- issue the `:YcmCompleter Format` command.
<!-- 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/2951)
<!-- Reviewable:end -->
This commit is contained in:
commit
788c293aee
@ -544,6 +544,16 @@ def ReplaceChunk_NewlineChunk_test():
|
|||||||
'second line' ], result_buffer )
|
'second line' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
|
def ReplaceChunk_BeyondEndOfFile_test():
|
||||||
|
result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
|
||||||
|
'second line' ] )
|
||||||
|
|
||||||
|
start, end = _BuildLocations( 1, 11, 3, 1 )
|
||||||
|
vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
|
||||||
|
|
||||||
|
AssertBuffersAreEqualAsBytes( [ 'first line' ], result_buffer )
|
||||||
|
|
||||||
|
|
||||||
def _BuildLocations( start_line, start_column, end_line, end_column ):
|
def _BuildLocations( start_line, start_column, end_line, end_column ):
|
||||||
return {
|
return {
|
||||||
'line_num' : start_line,
|
'line_num' : start_line,
|
||||||
|
@ -899,6 +899,17 @@ def ReplaceChunk( start, end, replacement_text, vim_buffer ):
|
|||||||
start_column = start[ 'column_num' ] - 1
|
start_column = start[ 'column_num' ] - 1
|
||||||
end_column = end[ 'column_num' ] - 1
|
end_column = end[ 'column_num' ] - 1
|
||||||
|
|
||||||
|
# When sending a request to the server, a newline is added to the buffer
|
||||||
|
# contents to match what gets saved to disk. If the server generates a chunk
|
||||||
|
# containing that newline, this chunk goes past the Vim buffer contents since
|
||||||
|
# there is actually no new line. When this happens, recompute the end position
|
||||||
|
# of where the chunk is applied and remove all trailing characters in the
|
||||||
|
# chunk.
|
||||||
|
if end_line >= len( vim_buffer ):
|
||||||
|
end_column = len( ToBytes( vim_buffer[ -1 ] ) )
|
||||||
|
end_line = len( vim_buffer ) - 1
|
||||||
|
replacement_text = replacement_text.rstrip()
|
||||||
|
|
||||||
# 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 = SplitLines( ToBytes( replacement_text ) )
|
replacement_lines = SplitLines( ToBytes( replacement_text ) )
|
||||||
|
Loading…
Reference in New Issue
Block a user