-
Notifications
You must be signed in to change notification settings - Fork 182
/
edit.py
60 lines (48 loc) · 2.46 KB
/
edit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from .logging import debug
from .open import open_file
from .promise import Promise
from .protocol import UINT_MAX, TextEdit as LspTextEdit, Position
from .typing import List, Dict, Any, Optional, Tuple
from functools import partial
import sublime
# tuple of start, end, newText, version
TextEditTuple = Tuple[Tuple[int, int], Tuple[int, int], str, Optional[int]]
def parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEditTuple]]:
changes = {} # type: Dict[str, List[TextEditTuple]]
document_changes = workspace_edit.get('documentChanges')
if isinstance(document_changes, list):
for document_change in document_changes:
if 'kind' in document_change:
# TODO: Support resource operations (create/rename/remove)
debug('Ignoring unsupported "resourceOperations" edit type')
continue
text_document = document_change["textDocument"]
uri = text_document['uri']
version = text_document.get('version')
text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))
changes.setdefault(uri, []).extend(text_edit)
else:
raw_changes = workspace_edit.get('changes')
if isinstance(raw_changes, dict):
for uri, uri_changes in raw_changes.items():
changes[uri] = list(parse_text_edit(change) for change in uri_changes)
return changes
def parse_range(range: Position) -> Tuple[int, int]:
return range['line'], min(UINT_MAX, range['character'])
def parse_text_edit(text_edit: LspTextEdit, version: int = None) -> TextEditTuple:
return (
parse_range(text_edit['range']['start']),
parse_range(text_edit['range']['end']),
# Strip away carriage returns -- SublimeText takes care of that.
text_edit.get('newText', '').replace("\r", ""),
version
)
def apply_workspace_edit(window: sublime.Window, changes: Dict[str, List[TextEditTuple]]) -> Promise:
"""
DEPRECATED: Use session.apply_workspace_edit_async instead.
"""
return Promise.all([open_file(window, uri).then(partial(apply_edits, edits)) for uri, edits in changes.items()])
def apply_edits(edits: List[TextEditTuple], view: Optional[sublime.View]) -> None:
if view and view.is_valid():
# Text commands run blocking. After this call has returned the changes are applied.
view.run_command("lsp_apply_document_edit", {"changes": edits})