We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
"Rename…" code action is broken
(v1.1.6) The _Rename_ code action doesn’t work correctly. I wasn’t able to use it in VSCode so I can’t tell whether it comes from the language server of the Sublime extension.

Here is a minimal example:

```elm
module Test exposing (..)

import Html exposing (Html)


view : Html msg
view =
    Html.text body


body : String
body =
    "..."
```

When renaming `body` for instance:

* if the new name has the same length, it seems to work fine
* if the new name is longer (`bodyxyz` in the example below), the last few characters are duplicated:
```elm

view : Html msg
view =
    Html.text bodyxyzxyz


bodyxyzxyz : String
bodyxyzxyz =
    "..."
```
* if the new name is shorter (`a` in this example), well…
```elm
view : Html msg
view =
    Html.text aaString
a    "..."
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugin/core/edit.py`
Content:
```
1 from .logging import debug
2 from .open import open_file
3 from .promise import Promise
4 from .typing import List, Dict, Any, Iterable, Optional, Tuple
5 from .url import uri_to_filename
6 from functools import partial
7 import operator
8 import sublime
9 
10 
11 # tuple of start, end, newText, version
12 TextEdit = Tuple[Tuple[int, int], Tuple[int, int], str, Optional[int]]
13 
14 
15 def parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEdit]]:
16     changes = {}  # type: Dict[str, List[TextEdit]]
17     raw_changes = workspace_edit.get('changes')
18     if isinstance(raw_changes, dict):
19         for uri, file_changes in raw_changes.items():
20             changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)
21     document_changes = workspace_edit.get('documentChanges')
22     if isinstance(document_changes, list):
23         for document_change in document_changes:
24             if 'kind' in document_change:
25                 debug('Ignoring unsupported "resourceOperations" edit type')
26                 continue
27             uri = document_change.get('textDocument').get('uri')
28             version = document_change.get('textDocument').get('version')
29             text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))
30             changes.setdefault(uri_to_filename(uri), []).extend(text_edit)
31     return changes
32 
33 
34 def parse_range(range: Dict[str, int]) -> Tuple[int, int]:
35     return range['line'], range['character']
36 
37 
38 def parse_text_edit(text_edit: Dict[str, Any], version: int = None) -> TextEdit:
39     return (
40         parse_range(text_edit['range']['start']),
41         parse_range(text_edit['range']['end']),
42         # Strip away carriage returns -- SublimeText takes care of that.
43         text_edit.get('newText', '').replace("\r", ""),
44         version
45     )
46 
47 
48 def sort_by_application_order(changes: Iterable[TextEdit]) -> List[TextEdit]:
49     # The spec reads:
50     # > However, it is possible that multiple edits have the same start position: multiple
51     # > inserts, or any number of inserts followed by a single remove or replace edit. If
52     # > multiple inserts have the same position, the order in the array defines the order in
53     # > which the inserted strings appear in the resulting text.
54     # So we sort by start position. But if multiple text edits start at the same position,
55     # we use the index in the array as the key.
56 
57     return list(sorted(changes, key=operator.itemgetter(0)))
58 
59 
60 def apply_workspace_edit(window: sublime.Window, changes: Dict[str, List[TextEdit]]) -> Promise:
61     """Apply workspace edits. This function must be called from the main thread!"""
62     return Promise.all([open_file(window, fn).then(partial(_apply_edits, edits)) for fn, edits in changes.items()])
63 
64 
65 def _apply_edits(edits: List[TextEdit], view: Optional[sublime.View]) -> None:
66     if view and view.is_valid():
67         # Text commands run blocking. After this call has returned the changes are applied.
68         view.run_command("lsp_apply_document_edit", {"changes": edits})
69
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugin/core/edit.py b/plugin/core/edit.py
--- a/plugin/core/edit.py
+++ b/plugin/core/edit.py
@@ -14,10 +14,6 @@
 
 def parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEdit]]:
     changes = {}  # type: Dict[str, List[TextEdit]]
-    raw_changes = workspace_edit.get('changes')
-    if isinstance(raw_changes, dict):
-        for uri, file_changes in raw_changes.items():
-            changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)
     document_changes = workspace_edit.get('documentChanges')
     if isinstance(document_changes, list):
         for document_change in document_changes:
@@ -28,6 +24,11 @@
             version = document_change.get('textDocument').get('version')
             text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))
             changes.setdefault(uri_to_filename(uri), []).extend(text_edit)
+    else:
+        raw_changes = workspace_edit.get('changes')
+        if isinstance(raw_changes, dict):
+            for uri, file_changes in raw_changes.items():
+                changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)
     return changes

{"golden_diff": "diff --git a/plugin/core/edit.py b/plugin/core/edit.py\n--- a/plugin/core/edit.py\n+++ b/plugin/core/edit.py\n@@ -14,10 +14,6 @@\n \n def parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEdit]]:\n     changes = {}  # type: Dict[str, List[TextEdit]]\n-    raw_changes = workspace_edit.get('changes')\n-    if isinstance(raw_changes, dict):\n-        for uri, file_changes in raw_changes.items():\n-            changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)\n     document_changes = workspace_edit.get('documentChanges')\n     if isinstance(document_changes, list):\n         for document_change in document_changes:\n@@ -28,6 +24,11 @@\n             version = document_change.get('textDocument').get('version')\n             text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))\n             changes.setdefault(uri_to_filename(uri), []).extend(text_edit)\n+    else:\n+        raw_changes = workspace_edit.get('changes')\n+        if isinstance(raw_changes, dict):\n+            for uri, file_changes in raw_changes.items():\n+                changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)\n     return changes\n", "issue": "\"Rename\u2026\" code action is broken\n(v1.1.6) The _Rename_ code action doesn\u2019t work correctly. I wasn\u2019t able to use it in VSCode so I can\u2019t tell whether it comes from the language server of the Sublime extension.\r\n\r\nHere is a minimal example:\r\n\r\n```elm\r\nmodule Test exposing (..)\r\n\r\nimport Html exposing (Html)\r\n\r\n\r\nview : Html msg\r\nview =\r\n    Html.text body\r\n\r\n\r\nbody : String\r\nbody =\r\n    \"...\"\r\n```\r\n\r\nWhen renaming `body` for instance:\r\n\r\n* if the new name has the same length, it seems to work fine\r\n* if the new name is longer (`bodyxyz` in the example below), the last few characters are duplicated:\r\n```elm\r\n\r\nview : Html msg\r\nview =\r\n    Html.text bodyxyzxyz\r\n\r\n\r\nbodyxyzxyz : String\r\nbodyxyzxyz =\r\n    \"...\"\r\n```\r\n* if the new name is shorter (`a` in this example), well\u2026\r\n```elm\r\nview : Html msg\r\nview =\r\n    Html.text aaString\r\na    \"...\"\r\n```\n", "before_files": [{"content": "from .logging import debug\nfrom .open import open_file\nfrom .promise import Promise\nfrom .typing import List, Dict, Any, Iterable, Optional, Tuple\nfrom .url import uri_to_filename\nfrom functools import partial\nimport operator\nimport sublime\n\n\n# tuple of start, end, newText, version\nTextEdit = Tuple[Tuple[int, int], Tuple[int, int], str, Optional[int]]\n\n\ndef parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEdit]]:\n    changes = {}  # type: Dict[str, List[TextEdit]]\n    raw_changes = workspace_edit.get('changes')\n    if isinstance(raw_changes, dict):\n        for uri, file_changes in raw_changes.items():\n            changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)\n    document_changes = workspace_edit.get('documentChanges')\n    if isinstance(document_changes, list):\n        for document_change in document_changes:\n            if 'kind' in document_change:\n                debug('Ignoring unsupported \"resourceOperations\" edit type')\n                continue\n            uri = document_change.get('textDocument').get('uri')\n            version = document_change.get('textDocument').get('version')\n            text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))\n            changes.setdefault(uri_to_filename(uri), []).extend(text_edit)\n    return changes\n\n\ndef parse_range(range: Dict[str, int]) -> Tuple[int, int]:\n    return range['line'], range['character']\n\n\ndef parse_text_edit(text_edit: Dict[str, Any], version: int = None) -> TextEdit:\n    return (\n        parse_range(text_edit['range']['start']),\n        parse_range(text_edit['range']['end']),\n        # Strip away carriage returns -- SublimeText takes care of that.\n        text_edit.get('newText', '').replace(\"\\r\", \"\"),\n        version\n    )\n\n\ndef sort_by_application_order(changes: Iterable[TextEdit]) -> List[TextEdit]:\n    # The spec reads:\n    # > However, it is possible that multiple edits have the same start position: multiple\n    # > inserts, or any number of inserts followed by a single remove or replace edit. If\n    # > multiple inserts have the same position, the order in the array defines the order in\n    # > which the inserted strings appear in the resulting text.\n    # So we sort by start position. But if multiple text edits start at the same position,\n    # we use the index in the array as the key.\n\n    return list(sorted(changes, key=operator.itemgetter(0)))\n\n\ndef apply_workspace_edit(window: sublime.Window, changes: Dict[str, List[TextEdit]]) -> Promise:\n    \"\"\"Apply workspace edits. This function must be called from the main thread!\"\"\"\n    return Promise.all([open_file(window, fn).then(partial(_apply_edits, edits)) for fn, edits in changes.items()])\n\n\ndef _apply_edits(edits: List[TextEdit], view: Optional[sublime.View]) -> None:\n    if view and view.is_valid():\n        # Text commands run blocking. After this call has returned the changes are applied.\n        view.run_command(\"lsp_apply_document_edit\", {\"changes\": edits})\n", "path": "plugin/core/edit.py"}], "after_files": [{"content": "from .logging import debug\nfrom .open import open_file\nfrom .promise import Promise\nfrom .typing import List, Dict, Any, Iterable, Optional, Tuple\nfrom .url import uri_to_filename\nfrom functools import partial\nimport operator\nimport sublime\n\n\n# tuple of start, end, newText, version\nTextEdit = Tuple[Tuple[int, int], Tuple[int, int], str, Optional[int]]\n\n\ndef parse_workspace_edit(workspace_edit: Dict[str, Any]) -> Dict[str, List[TextEdit]]:\n    changes = {}  # type: Dict[str, List[TextEdit]]\n    document_changes = workspace_edit.get('documentChanges')\n    if isinstance(document_changes, list):\n        for document_change in document_changes:\n            if 'kind' in document_change:\n                debug('Ignoring unsupported \"resourceOperations\" edit type')\n                continue\n            uri = document_change.get('textDocument').get('uri')\n            version = document_change.get('textDocument').get('version')\n            text_edit = list(parse_text_edit(change, version) for change in document_change.get('edits'))\n            changes.setdefault(uri_to_filename(uri), []).extend(text_edit)\n    else:\n        raw_changes = workspace_edit.get('changes')\n        if isinstance(raw_changes, dict):\n            for uri, file_changes in raw_changes.items():\n                changes[uri_to_filename(uri)] = list(parse_text_edit(change) for change in file_changes)\n    return changes\n\n\ndef parse_range(range: Dict[str, int]) -> Tuple[int, int]:\n    return range['line'], range['character']\n\n\ndef parse_text_edit(text_edit: Dict[str, Any], version: int = None) -> TextEdit:\n    return (\n        parse_range(text_edit['range']['start']),\n        parse_range(text_edit['range']['end']),\n        # Strip away carriage returns -- SublimeText takes care of that.\n        text_edit.get('newText', '').replace(\"\\r\", \"\"),\n        version\n    )\n\n\ndef sort_by_application_order(changes: Iterable[TextEdit]) -> List[TextEdit]:\n    # The spec reads:\n    # > However, it is possible that multiple edits have the same start position: multiple\n    # > inserts, or any number of inserts followed by a single remove or replace edit. If\n    # > multiple inserts have the same position, the order in the array defines the order in\n    # > which the inserted strings appear in the resulting text.\n    # So we sort by start position. But if multiple text edits start at the same position,\n    # we use the index in the array as the key.\n\n    return list(sorted(changes, key=operator.itemgetter(0)))\n\n\ndef apply_workspace_edit(window: sublime.Window, changes: Dict[str, List[TextEdit]]) -> Promise:\n    \"\"\"Apply workspace edits. This function must be called from the main thread!\"\"\"\n    return Promise.all([open_file(window, fn).then(partial(_apply_edits, edits)) for fn, edits in changes.items()])\n\n\ndef _apply_edits(edits: List[TextEdit], view: Optional[sublime.View]) -> None:\n    if view and view.is_valid():\n        # Text commands run blocking. After this call has returned the changes are applied.\n        view.run_command(\"lsp_apply_document_edit\", {\"changes\": edits})\n", "path": "plugin/core/edit.py"}]}