Skip to content

Commit 0d301ed

Browse files
authored
Don't require SnippetTextEdit in TextDocumentEdit to be the topmost edit (#2944)
1 parent b5d3208 commit 0d301ed

1 file changed

Lines changed: 27 additions & 30 deletions

File tree

plugin/edit.py

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -115,40 +115,37 @@ def run(
115115
return
116116
if listener := windows.listener_for_view(self.view):
117117
listener.set_change_event_action(ChangeEventAction.OTHER)
118-
topmost_edit, *other_edits = sorted(edits, key=lambda e: parse_lsp_position(e['range']['start']))
119118
with temporary_setting(self.view.settings(), 'translate_tabs_to_spaces', False):
120119
last_row = self.view.rowcol_utf16(self.view.size())[0]
121-
for text_edit in reversed(other_edits):
120+
snippet_text_edit_already_applied = False
121+
for text_edit in reversed(sorted(edits, key=lambda e: parse_lsp_position(e['range']['start']))): # noqa: C413
122122
start_row, region = self._get_region(text_edit)
123-
new_text = self._get_new_text(text_edit)
124-
if start_row > last_row and not new_text.startswith('\n'):
125-
self._apply_edit(edit, region, '\n' + new_text)
126-
last_row = self.view.rowcol_utf16(self.view.size())[0]
123+
if not snippet_text_edit_already_applied and is_snippet_text_edit(text_edit) and \
124+
self.view == sublime.active_window().active_view():
125+
new_text = self._get_new_text(text_edit, keep_placeholders=True)
126+
if start_row > last_row and not new_text.startswith('\n'):
127+
start_row = last_row
128+
new_text = '\n' + new_text
129+
# https://github.com/microsoft/language-server-protocol/pull/1892#issuecomment-1964186341
130+
# The insert_snippet command automatically adds additional indentation to each row, based on the
131+
# indentation level of the row where it gets inserted. Therefore we first have to remove that same
132+
# indentation whitespace after each line break in the snippet text from the language server.
133+
line_content = self.view.substr(self.view.line(self.view.text_point(start_row, 0)))
134+
if leading_whitespace := line_content[:-len(line_content.lstrip())]:
135+
new_text = new_text.replace('\n' + leading_whitespace, '\n')
136+
selection = self.view.sel()
137+
selection.clear()
138+
selection.add(region)
139+
self.view.show(region.a)
140+
self.view.run_command('insert_snippet', {'contents': new_text})
141+
snippet_text_edit_already_applied = True
127142
else:
128-
self._apply_edit(edit, region, new_text)
129-
start_row, region = self._get_region(topmost_edit)
130-
if is_snippet_text_edit(topmost_edit) and self.view == sublime.active_window().active_view():
131-
new_text = self._get_new_text(topmost_edit, keep_placeholders=True)
132-
if start_row > last_row and not new_text.startswith('\n'):
133-
start_row = last_row
134-
new_text = '\n' + new_text
135-
# https://github.com/microsoft/language-server-protocol/pull/1892#issuecomment-1964186341
136-
# The insert_snippet command automatically adds additional indentation to each row, based on the
137-
# indentation level of the row where it gets inserted. Therefore we first have to remove that same
138-
# indentation whitespace after each line break in the snippet text from the language server.
139-
line_content = self.view.substr(self.view.line(self.view.text_point(start_row, 0)))
140-
if leading_whitespace := line_content[:-len(line_content.lstrip())]:
141-
new_text = new_text.replace('\n' + leading_whitespace, '\n')
142-
selection = self.view.sel()
143-
selection.clear()
144-
selection.add(region)
145-
self.view.show(region.a)
146-
self.view.run_command('insert_snippet', {'contents': new_text})
147-
else:
148-
new_text = self._get_new_text(topmost_edit)
149-
if start_row > last_row and not new_text.startswith('\n'):
150-
new_text = '\n' + new_text
151-
self._apply_edit(edit, region, new_text)
143+
new_text = self._get_new_text(text_edit)
144+
if start_row > last_row and not new_text.startswith('\n'):
145+
self._apply_edit(edit, region, '\n' + new_text)
146+
last_row = self.view.rowcol_utf16(self.view.size())[0]
147+
else:
148+
self._apply_edit(edit, region, new_text)
152149

153150
def _get_region(self, edit: TextEdit | AnnotatedTextEdit | SnippetTextEdit) -> tuple[int, sublime.Region]:
154151
range_ = edit['range']

0 commit comments

Comments
 (0)