From 4a5785d559314c5ecfec32a0c9be36e2dd3b9213 Mon Sep 17 00:00:00 2001 From: Raoul Wols Date: Sun, 16 May 2021 23:17:29 +0200 Subject: [PATCH] Account for out-of-bounds columnn offsets of text edits This fixes an issue for import edits for the FsAutoComplete server. See: https://github.com/fsharp/FsAutoComplete/commit/48129a5ccbf1c76fe29a5ac26eeb5d1d34975a89 Co-authored-by: chendesheng --- plugin/edit.py | 9 ++++++--- tests/test_single_document.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugin/edit.py b/plugin/edit.py index 47a3d4cc3..eb35ce2d6 100644 --- a/plugin/edit.py +++ b/plugin/edit.py @@ -28,17 +28,20 @@ def run(self, edit: Any, changes: Optional[List[TextEditTuple]] = None) -> None: return with temporary_setting(self.view.settings(), "translate_tabs_to_spaces", False): view_version = self.view.change_count() - last_row, last_col = self.view.rowcol_utf16(self.view.size()) + last_row, _ = self.view.rowcol_utf16(self.view.size()) for start, end, replacement, version in reversed(sort_by_application_order(changes)): if version is not None and version != view_version: debug('ignoring edit due to non-matching document version') continue - region = sublime.Region(self.view.text_point_utf16(*start), self.view.text_point_utf16(*end)) + region = sublime.Region( + self.view.text_point_utf16(*start, clamp_column=True), + self.view.text_point_utf16(*end, clamp_column=True) + ) if start[0] > last_row and replacement[0] != '\n': # Handle when a language server (eg gopls) inserts at a row beyond the document # some editors create the line automatically, sublime needs to have the newline prepended. self.apply_change(region, '\n' + replacement, edit) - last_row, last_col = self.view.rowcol(self.view.size()) + last_row, _ = self.view.rowcol(self.view.size()) else: self.apply_change(region, replacement, edit) diff --git a/tests/test_single_document.py b/tests/test_single_document.py index eff753a63..ea7e942f5 100644 --- a/tests/test_single_document.py +++ b/tests/test_single_document.py @@ -1,6 +1,7 @@ from copy import deepcopy from LSP.plugin import Request from LSP.plugin.core.url import filename_to_uri +from LSP.plugin.core.views import entire_content from LSP.plugin.hover import _test_contents from setup import TextDocumentTestCase from setup import TIMEOUT_TIME @@ -51,6 +52,18 @@ def test_did_open(self) -> 'Generator': # -> "shutdown" -> client shut down pass + def test_out_of_bounds_column_for_text_document_edit(self) -> 'Generator': + self.insert_characters("a\nb\nc\n") + self.view.run_command("lsp_apply_document_edit", {"changes": [ + ( + (1, 0), # start row-col + (1, 10000), # end row-col (the col offset is out of bounds intentionally) + "hello there", # new text + None # version + ) + ]}) + self.assertEqual(entire_content(self.view), "a\nhello there\nc\n") + def test_did_close(self) -> 'Generator': self.assertTrue(self.view) self.assertTrue(self.view.is_valid())