We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Go to definition in the Editor stopped working after the introspection services migration to use the LSP
## Problem Description

Go to definition (Ctrl-G) in the Editor stopped working after PR #4751 was merged.

A minor comment first: the `lsp_client_python.log` file is taking forever to build and if something introspection related is done while the file is being built, everything seems to break (help, go to definition and code style warnings).

I think the reason that go to definition has stopped working is that there is an error in the path of the file that the language server is returning to Spyder in [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956). An extra `/` is added at the beginning and the disk name is not capitalized.

For example, let's say that I Ctrl-G [GoToLineDialog](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L1682) on line 1682 of the file `codeeditor.py`. This file is located on my computer at `C:\Users\User\spyder\spyder\widgets\sourcecode\codeeditor.py`.

The `position['params']` that is returned to [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956) is:

```python
{'uri': 'file:///c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py', 
 'range': {'start': {'line': 102, 'character': 6}, 'end': {'line': 102, 'character': 20}},
 'file': '/c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py'
}
```
So as you can see, the value stored for the file is `'/c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py'` instead of `C:\Users\User\spyder\spyder\widgets\sourcecode\codeeditor.py`, the value that is stored in `CodeEditor.filename`.

If I replace [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956) by:

```python
    @handles(LSPRequestTypes.DOCUMENT_DEFINITION)
    def handle_go_to_definition(self, position):
        position = position['params']
        if position is not None:
            def_range = position['range']
            start = def_range['start']
            position_file = osp.normpath(position['file'][1:])
            if osp.normpath(self.filename) == position_file:
                self.go_to_line(start['line'] + 1, start['character'],
                                None, word=None)
            else:
                self.go_to_definition.emit(position_file, start['line'] + 1,
                                           start['character'])
```

to remove the extra `\` and normalize the paths before comparing them, then the go to definition feature is working again as expected.


## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: Spyder 4.0.0.dev0
* Python version: Python 3.6.5 64bits
* Qt version: Qt 5.9.3
* PyQt version: PyQt5 5.9.2
* Operating System name/version: Windows 

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
pyflakes >=0.6.0  :  1.6.0 (OK)
pycodestyle >=2.3 :  2.3.1 (OK)
pygments >=2.0    :  2.2.0 (OK)
sphinx >=0.6.6    :  1.7.1 (OK)
rope >=0.9.4      :  0.10.7 (OK)
jedi >=0.11.0     :  0.12.1 (OK)
nbconvert >=4.0   :  5.3.1 (OK)
pandas >=0.13.1   :  0.22.0 (OK)
numpy >=1.7       :  1.13.0 (OK)
sympy >=0.7.3     :  1.1.1 (OK)
cython >=0.21     :  0.27.3 (OK)
qtconsole >=4.2.0 :  4.4.0.dev (OK)
IPython >=4.0     :  6.2.1 (OK)
matplotlib >=2.0.0:  2.2.0 (OK)
pylint >=0.25     :  1.8.3 (OK)
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `spyder/plugins/editor/lsp/providers/document.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Copyright © Spyder Project Contributors
4 # Licensed under the terms of the MIT License
5 # (see spyder/__init__.py for details)
6 
7 """Spyder Language Server Protocol Client document handler routines."""
8 
9 import os.path as osp
10 
11 from spyder.py3compat import PY2
12 from spyder.config.base import debug_print
13 from spyder.plugins.editor.lsp import (
14     LSPRequestTypes, InsertTextFormat, CompletionItemKind,
15     ClientConstants)
16 from spyder.plugins.editor.lsp.decorators import handles, send_request
17 
18 if PY2:
19     import pathlib2 as pathlib
20     from urlparse import urlparse
21 else:
22     import pathlib
23     from urllib.parse import urlparse
24 
25 
26 def path_as_uri(path):
27     return pathlib.Path(osp.abspath(path)).as_uri()
28 
29 
30 class DocumentProvider:
31     def register_file(self, filename, signal):
32         filename = path_as_uri(filename)
33         if filename not in self.watched_files:
34             self.watched_files[filename] = []
35         self.watched_files[filename].append(signal)
36 
37     @handles(LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS)
38     def process_document_diagnostics(self, response, *args):
39         uri = response['uri']
40         diagnostics = response['diagnostics']
41         callbacks = self.watched_files[uri]
42         for callback in callbacks:
43             callback.emit(
44                 LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS,
45                 {'params': diagnostics})
46 
47     @send_request(
48         method=LSPRequestTypes.DOCUMENT_DID_CHANGE, requires_response=False)
49     def document_changed(self, params):
50         params = {
51             'textDocument': {
52                 'uri': path_as_uri(params['file']),
53                 'version': params['version']
54             },
55             'contentChanges': [{
56                 'text': params['text']
57             }]
58         }
59         return params
60 
61     @send_request(
62         method=LSPRequestTypes.DOCUMENT_DID_OPEN, requires_response=False)
63     def document_open(self, editor_params):
64         uri = path_as_uri(editor_params['file'])
65         if uri not in self.watched_files:
66             self.register_file(editor_params['file'], editor_params['signal'])
67         params = {
68             'textDocument': {
69                 'uri': uri,
70                 'languageId': editor_params['language'],
71                 'version': editor_params['version'],
72                 'text': editor_params['text']
73             }
74         }
75 
76         return params
77 
78     @send_request(method=LSPRequestTypes.DOCUMENT_COMPLETION)
79     def document_completion_request(self, params):
80         params = {
81             'textDocument': {
82                 'uri': path_as_uri(params['file'])
83             },
84             'position': {
85                 'line': params['line'],
86                 'character': params['column']
87             }
88         }
89 
90         return params
91 
92     @handles(LSPRequestTypes.DOCUMENT_COMPLETION)
93     def process_document_completion(self, response, req_id):
94         if isinstance(response, dict):
95             response = response['items']
96         for item in response:
97             item['kind'] = item.get('kind', CompletionItemKind.TEXT)
98             item['detail'] = item.get('detail', '')
99             item['documentation'] = item.get('documentation', '')
100             item['sortText'] = item.get('sortText', item['label'])
101             item['filterText'] = item.get('filterText', item['label'])
102             item['insertTextFormat'] = item.get(
103                 'insertTextFormat', InsertTextFormat.PLAIN_TEXT)
104             item['insertText'] = item.get('insertText', item['label'])
105 
106         if req_id in self.req_reply:
107             self.req_reply[req_id].emit(
108                 LSPRequestTypes.DOCUMENT_COMPLETION, {'params': response})
109 
110     @send_request(method=LSPRequestTypes.DOCUMENT_SIGNATURE)
111     def signature_help_request(self, params):
112         params = {
113             'textDocument': {
114                 'uri': path_as_uri(params['file'])
115             },
116             'position': {
117                 'line': params['line'],
118                 'character': params['column']
119             }
120         }
121 
122         return params
123 
124     @handles(LSPRequestTypes.DOCUMENT_SIGNATURE)
125     def process_signature_completion(self, response, req_id):
126         if len(response['signatures']) > 0:
127             response['signatures'] = response['signatures'][
128                 response['activeSignature']]
129         else:
130             response = None
131         if req_id in self.req_reply:
132             self.req_reply[req_id].emit(
133                 LSPRequestTypes.DOCUMENT_SIGNATURE,
134                 {'params': response})
135 
136     @send_request(method=LSPRequestTypes.DOCUMENT_HOVER)
137     def hover_request(self, params):
138         params = {
139             'textDocument': {
140                 'uri': path_as_uri(params['file'])
141             },
142             'position': {
143                 'line': params['line'],
144                 'character': params['column']
145             }
146         }
147 
148         return params
149 
150     @handles(LSPRequestTypes.DOCUMENT_HOVER)
151     def process_hover_result(self, result, req_id):
152         contents = result['contents']
153         if isinstance(contents, list):
154             contents = contents[0]
155         if isinstance(contents, dict):
156             contents = contents['value']
157         if req_id in self.req_reply:
158             self.req_reply[req_id].emit(
159                 LSPRequestTypes.DOCUMENT_HOVER,
160                 {'params': contents})
161 
162     @send_request(method=LSPRequestTypes.DOCUMENT_DEFINITION)
163     def go_to_definition_request(self, params):
164         params = {
165             'textDocument': {
166                 'uri': path_as_uri(params['file'])
167             },
168             'position': {
169                 'line': params['line'],
170                 'character': params['column']
171             }
172         }
173 
174         return params
175 
176     @handles(LSPRequestTypes.DOCUMENT_DEFINITION)
177     def process_go_to_definition(self, result, req_id):
178         if isinstance(result, list):
179             if len(result) > 0:
180                 result = result[0]
181                 uri = urlparse(result['uri'])
182                 result['file'] = osp.join(uri.netloc, uri.path)
183             else:
184                 result = None
185         if req_id in self.req_reply:
186             self.req_reply[req_id].emit(
187                 LSPRequestTypes.DOCUMENT_DEFINITION,
188                 {'params': result})
189 
190     @send_request(method=LSPRequestTypes.DOCUMENT_WILL_SAVE,
191                   requires_response=False)
192     def document_will_save_notification(self, params):
193         params = {
194             'textDocument': {
195                 'uri': path_as_uri(params['file'])
196             },
197             'reason': params['reason']
198         }
199         return params
200 
201     @send_request(method=LSPRequestTypes.DOCUMENT_DID_CLOSE,
202                   requires_response=False)
203     def document_did_close(self, params):
204         file_signal = params['signal']
205         debug_print('[{0}] File: {1}'.format(
206             LSPRequestTypes.DOCUMENT_DID_CLOSE, params['file']))
207         filename = path_as_uri(params['file'])
208 
209         params = {
210             'textDocument': {
211                 'uri': filename
212             }
213         }
214         if filename not in self.watched_files:
215             params[ClientConstants.CANCEL] = True
216         else:
217             signals = self.watched_files[filename]
218             idx = -1
219             for i, signal in enumerate(signals):
220                 if id(file_signal) == id(signal):
221                     idx = i
222                     break
223             if idx > 0:
224                 signals.pop(idx)
225 
226             if len(signals) == 0:
227                 self.watched_files.pop(filename)
228         return params
229
```
--- 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/spyder/plugins/editor/lsp/providers/document.py b/spyder/plugins/editor/lsp/providers/document.py
--- a/spyder/plugins/editor/lsp/providers/document.py
+++ b/spyder/plugins/editor/lsp/providers/document.py
@@ -18,9 +18,11 @@
 if PY2:
     import pathlib2 as pathlib
     from urlparse import urlparse
+    from urllib import url2pathname
 else:
     import pathlib
     from urllib.parse import urlparse
+    from urllib.request import url2pathname
 
 
 def path_as_uri(path):
@@ -179,7 +181,10 @@
             if len(result) > 0:
                 result = result[0]
                 uri = urlparse(result['uri'])
-                result['file'] = osp.join(uri.netloc, uri.path)
+                netloc, path = uri.netloc, uri.path
+                # Prepend UNC share notation if we have a UNC path.
+                netloc = '\\\\' + netloc if netloc else netloc
+                result['file'] = url2pathname(netloc + path)
             else:
                 result = None
         if req_id in self.req_reply:

{"golden_diff": "diff --git a/spyder/plugins/editor/lsp/providers/document.py b/spyder/plugins/editor/lsp/providers/document.py\n--- a/spyder/plugins/editor/lsp/providers/document.py\n+++ b/spyder/plugins/editor/lsp/providers/document.py\n@@ -18,9 +18,11 @@\n if PY2:\n     import pathlib2 as pathlib\n     from urlparse import urlparse\n+    from urllib import url2pathname\n else:\n     import pathlib\n     from urllib.parse import urlparse\n+    from urllib.request import url2pathname\n \n \n def path_as_uri(path):\n@@ -179,7 +181,10 @@\n             if len(result) > 0:\n                 result = result[0]\n                 uri = urlparse(result['uri'])\n-                result['file'] = osp.join(uri.netloc, uri.path)\n+                netloc, path = uri.netloc, uri.path\n+                # Prepend UNC share notation if we have a UNC path.\n+                netloc = '\\\\\\\\' + netloc if netloc else netloc\n+                result['file'] = url2pathname(netloc + path)\n             else:\n                 result = None\n         if req_id in self.req_reply:\n", "issue": "Go to definition in the Editor stopped working after the introspection services migration to use the LSP\n## Problem Description\r\n\r\nGo to definition (Ctrl-G) in the Editor stopped working after PR #4751 was merged.\r\n\r\nA minor comment first: the `lsp_client_python.log` file is taking forever to build and if something introspection related is done while the file is being built, everything seems to break (help, go to definition and code style warnings).\r\n\r\nI think the reason that go to definition has stopped working is that there is an error in the path of the file that the language server is returning to Spyder in [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956). An extra `/` is added at the beginning and the disk name is not capitalized.\r\n\r\nFor example, let's say that I Ctrl-G [GoToLineDialog](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L1682) on line 1682 of the file `codeeditor.py`. This file is located on my computer at `C:\\Users\\User\\spyder\\spyder\\widgets\\sourcecode\\codeeditor.py`.\r\n\r\nThe `position['params']` that is returned to [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956) is:\r\n\r\n```python\r\n{'uri': 'file:///c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py', \r\n 'range': {'start': {'line': 102, 'character': 6}, 'end': {'line': 102, 'character': 20}},\r\n 'file': '/c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py'\r\n}\r\n```\r\nSo as you can see, the value stored for the file is `'/c:/Users/User/spyder/spyder/widgets/sourcecode/codeeditor.py'` instead of `C:\\Users\\User\\spyder\\spyder\\widgets\\sourcecode\\codeeditor.py`, the value that is stored in `CodeEditor.filename`.\r\n\r\nIf I replace [handle_go_to_definition](https://github.com/spyder-ide/spyder/blob/master/spyder/widgets/sourcecode/codeeditor.py#L956) by:\r\n\r\n```python\r\n    @handles(LSPRequestTypes.DOCUMENT_DEFINITION)\r\n    def handle_go_to_definition(self, position):\r\n        position = position['params']\r\n        if position is not None:\r\n            def_range = position['range']\r\n            start = def_range['start']\r\n            position_file = osp.normpath(position['file'][1:])\r\n            if osp.normpath(self.filename) == position_file:\r\n                self.go_to_line(start['line'] + 1, start['character'],\r\n                                None, word=None)\r\n            else:\r\n                self.go_to_definition.emit(position_file, start['line'] + 1,\r\n                                           start['character'])\r\n```\r\n\r\nto remove the extra `\\` and normalize the paths before comparing them, then the go to definition feature is working again as expected.\r\n\r\n\r\n## Versions\r\n<!--- You can get this information from Help > About Spyder...\r\nor (if Spyder won't launch) the \"conda list\" command\r\nfrom the Anaconda Prompt/Terminal/command line. --->\r\n\r\n* Spyder version: Spyder 4.0.0.dev0\r\n* Python version: Python 3.6.5 64bits\r\n* Qt version: Qt 5.9.3\r\n* PyQt version: PyQt5 5.9.2\r\n* Operating System name/version: Windows \r\n\r\n### Dependencies\r\n<!--- Please go to the menu entry Help > Dependencies,\r\npress the Copy to clipboard button and paste below --->\r\n\r\n```\r\npyflakes >=0.6.0  :  1.6.0 (OK)\r\npycodestyle >=2.3 :  2.3.1 (OK)\r\npygments >=2.0    :  2.2.0 (OK)\r\nsphinx >=0.6.6    :  1.7.1 (OK)\r\nrope >=0.9.4      :  0.10.7 (OK)\r\njedi >=0.11.0     :  0.12.1 (OK)\r\nnbconvert >=4.0   :  5.3.1 (OK)\r\npandas >=0.13.1   :  0.22.0 (OK)\r\nnumpy >=1.7       :  1.13.0 (OK)\r\nsympy >=0.7.3     :  1.1.1 (OK)\r\ncython >=0.21     :  0.27.3 (OK)\r\nqtconsole >=4.2.0 :  4.4.0.dev (OK)\r\nIPython >=4.0     :  6.2.1 (OK)\r\nmatplotlib >=2.0.0:  2.2.0 (OK)\r\npylint >=0.25     :  1.8.3 (OK)\r\n```\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 Spyder Project Contributors\n# Licensed under the terms of the MIT License\n# (see spyder/__init__.py for details)\n\n\"\"\"Spyder Language Server Protocol Client document handler routines.\"\"\"\n\nimport os.path as osp\n\nfrom spyder.py3compat import PY2\nfrom spyder.config.base import debug_print\nfrom spyder.plugins.editor.lsp import (\n    LSPRequestTypes, InsertTextFormat, CompletionItemKind,\n    ClientConstants)\nfrom spyder.plugins.editor.lsp.decorators import handles, send_request\n\nif PY2:\n    import pathlib2 as pathlib\n    from urlparse import urlparse\nelse:\n    import pathlib\n    from urllib.parse import urlparse\n\n\ndef path_as_uri(path):\n    return pathlib.Path(osp.abspath(path)).as_uri()\n\n\nclass DocumentProvider:\n    def register_file(self, filename, signal):\n        filename = path_as_uri(filename)\n        if filename not in self.watched_files:\n            self.watched_files[filename] = []\n        self.watched_files[filename].append(signal)\n\n    @handles(LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS)\n    def process_document_diagnostics(self, response, *args):\n        uri = response['uri']\n        diagnostics = response['diagnostics']\n        callbacks = self.watched_files[uri]\n        for callback in callbacks:\n            callback.emit(\n                LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS,\n                {'params': diagnostics})\n\n    @send_request(\n        method=LSPRequestTypes.DOCUMENT_DID_CHANGE, requires_response=False)\n    def document_changed(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file']),\n                'version': params['version']\n            },\n            'contentChanges': [{\n                'text': params['text']\n            }]\n        }\n        return params\n\n    @send_request(\n        method=LSPRequestTypes.DOCUMENT_DID_OPEN, requires_response=False)\n    def document_open(self, editor_params):\n        uri = path_as_uri(editor_params['file'])\n        if uri not in self.watched_files:\n            self.register_file(editor_params['file'], editor_params['signal'])\n        params = {\n            'textDocument': {\n                'uri': uri,\n                'languageId': editor_params['language'],\n                'version': editor_params['version'],\n                'text': editor_params['text']\n            }\n        }\n\n        return params\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_COMPLETION)\n    def document_completion_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_COMPLETION)\n    def process_document_completion(self, response, req_id):\n        if isinstance(response, dict):\n            response = response['items']\n        for item in response:\n            item['kind'] = item.get('kind', CompletionItemKind.TEXT)\n            item['detail'] = item.get('detail', '')\n            item['documentation'] = item.get('documentation', '')\n            item['sortText'] = item.get('sortText', item['label'])\n            item['filterText'] = item.get('filterText', item['label'])\n            item['insertTextFormat'] = item.get(\n                'insertTextFormat', InsertTextFormat.PLAIN_TEXT)\n            item['insertText'] = item.get('insertText', item['label'])\n\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_COMPLETION, {'params': response})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_SIGNATURE)\n    def signature_help_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_SIGNATURE)\n    def process_signature_completion(self, response, req_id):\n        if len(response['signatures']) > 0:\n            response['signatures'] = response['signatures'][\n                response['activeSignature']]\n        else:\n            response = None\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_SIGNATURE,\n                {'params': response})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_HOVER)\n    def hover_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_HOVER)\n    def process_hover_result(self, result, req_id):\n        contents = result['contents']\n        if isinstance(contents, list):\n            contents = contents[0]\n        if isinstance(contents, dict):\n            contents = contents['value']\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_HOVER,\n                {'params': contents})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_DEFINITION)\n    def go_to_definition_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_DEFINITION)\n    def process_go_to_definition(self, result, req_id):\n        if isinstance(result, list):\n            if len(result) > 0:\n                result = result[0]\n                uri = urlparse(result['uri'])\n                result['file'] = osp.join(uri.netloc, uri.path)\n            else:\n                result = None\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_DEFINITION,\n                {'params': result})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_WILL_SAVE,\n                  requires_response=False)\n    def document_will_save_notification(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'reason': params['reason']\n        }\n        return params\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_DID_CLOSE,\n                  requires_response=False)\n    def document_did_close(self, params):\n        file_signal = params['signal']\n        debug_print('[{0}] File: {1}'.format(\n            LSPRequestTypes.DOCUMENT_DID_CLOSE, params['file']))\n        filename = path_as_uri(params['file'])\n\n        params = {\n            'textDocument': {\n                'uri': filename\n            }\n        }\n        if filename not in self.watched_files:\n            params[ClientConstants.CANCEL] = True\n        else:\n            signals = self.watched_files[filename]\n            idx = -1\n            for i, signal in enumerate(signals):\n                if id(file_signal) == id(signal):\n                    idx = i\n                    break\n            if idx > 0:\n                signals.pop(idx)\n\n            if len(signals) == 0:\n                self.watched_files.pop(filename)\n        return params\n", "path": "spyder/plugins/editor/lsp/providers/document.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 Spyder Project Contributors\n# Licensed under the terms of the MIT License\n# (see spyder/__init__.py for details)\n\n\"\"\"Spyder Language Server Protocol Client document handler routines.\"\"\"\n\nimport os.path as osp\n\nfrom spyder.py3compat import PY2\nfrom spyder.config.base import debug_print\nfrom spyder.plugins.editor.lsp import (\n    LSPRequestTypes, InsertTextFormat, CompletionItemKind,\n    ClientConstants)\nfrom spyder.plugins.editor.lsp.decorators import handles, send_request\n\nif PY2:\n    import pathlib2 as pathlib\n    from urlparse import urlparse\n    from urllib import url2pathname\nelse:\n    import pathlib\n    from urllib.parse import urlparse\n    from urllib.request import url2pathname\n\n\ndef path_as_uri(path):\n    return pathlib.Path(osp.abspath(path)).as_uri()\n\n\nclass DocumentProvider:\n    def register_file(self, filename, signal):\n        filename = path_as_uri(filename)\n        if filename not in self.watched_files:\n            self.watched_files[filename] = []\n        self.watched_files[filename].append(signal)\n\n    @handles(LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS)\n    def process_document_diagnostics(self, response, *args):\n        uri = response['uri']\n        diagnostics = response['diagnostics']\n        callbacks = self.watched_files[uri]\n        for callback in callbacks:\n            callback.emit(\n                LSPRequestTypes.DOCUMENT_PUBLISH_DIAGNOSTICS,\n                {'params': diagnostics})\n\n    @send_request(\n        method=LSPRequestTypes.DOCUMENT_DID_CHANGE, requires_response=False)\n    def document_changed(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file']),\n                'version': params['version']\n            },\n            'contentChanges': [{\n                'text': params['text']\n            }]\n        }\n        return params\n\n    @send_request(\n        method=LSPRequestTypes.DOCUMENT_DID_OPEN, requires_response=False)\n    def document_open(self, editor_params):\n        uri = path_as_uri(editor_params['file'])\n        if uri not in self.watched_files:\n            self.register_file(editor_params['file'], editor_params['signal'])\n        params = {\n            'textDocument': {\n                'uri': uri,\n                'languageId': editor_params['language'],\n                'version': editor_params['version'],\n                'text': editor_params['text']\n            }\n        }\n\n        return params\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_COMPLETION)\n    def document_completion_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_COMPLETION)\n    def process_document_completion(self, response, req_id):\n        if isinstance(response, dict):\n            response = response['items']\n        for item in response:\n            item['kind'] = item.get('kind', CompletionItemKind.TEXT)\n            item['detail'] = item.get('detail', '')\n            item['documentation'] = item.get('documentation', '')\n            item['sortText'] = item.get('sortText', item['label'])\n            item['filterText'] = item.get('filterText', item['label'])\n            item['insertTextFormat'] = item.get(\n                'insertTextFormat', InsertTextFormat.PLAIN_TEXT)\n            item['insertText'] = item.get('insertText', item['label'])\n\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_COMPLETION, {'params': response})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_SIGNATURE)\n    def signature_help_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_SIGNATURE)\n    def process_signature_completion(self, response, req_id):\n        if len(response['signatures']) > 0:\n            response['signatures'] = response['signatures'][\n                response['activeSignature']]\n        else:\n            response = None\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_SIGNATURE,\n                {'params': response})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_HOVER)\n    def hover_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_HOVER)\n    def process_hover_result(self, result, req_id):\n        contents = result['contents']\n        if isinstance(contents, list):\n            contents = contents[0]\n        if isinstance(contents, dict):\n            contents = contents['value']\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_HOVER,\n                {'params': contents})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_DEFINITION)\n    def go_to_definition_request(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'position': {\n                'line': params['line'],\n                'character': params['column']\n            }\n        }\n\n        return params\n\n    @handles(LSPRequestTypes.DOCUMENT_DEFINITION)\n    def process_go_to_definition(self, result, req_id):\n        if isinstance(result, list):\n            if len(result) > 0:\n                result = result[0]\n                uri = urlparse(result['uri'])\n                netloc, path = uri.netloc, uri.path\n                # Prepend UNC share notation if we have a UNC path.\n                netloc = '\\\\\\\\' + netloc if netloc else netloc\n                result['file'] = url2pathname(netloc + path)\n            else:\n                result = None\n        if req_id in self.req_reply:\n            self.req_reply[req_id].emit(\n                LSPRequestTypes.DOCUMENT_DEFINITION,\n                {'params': result})\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_WILL_SAVE,\n                  requires_response=False)\n    def document_will_save_notification(self, params):\n        params = {\n            'textDocument': {\n                'uri': path_as_uri(params['file'])\n            },\n            'reason': params['reason']\n        }\n        return params\n\n    @send_request(method=LSPRequestTypes.DOCUMENT_DID_CLOSE,\n                  requires_response=False)\n    def document_did_close(self, params):\n        file_signal = params['signal']\n        debug_print('[{0}] File: {1}'.format(\n            LSPRequestTypes.DOCUMENT_DID_CLOSE, params['file']))\n        filename = path_as_uri(params['file'])\n\n        params = {\n            'textDocument': {\n                'uri': filename\n            }\n        }\n        if filename not in self.watched_files:\n            params[ClientConstants.CANCEL] = True\n        else:\n            signals = self.watched_files[filename]\n            idx = -1\n            for i, signal in enumerate(signals):\n                if id(file_signal) == id(signal):\n                    idx = i\n                    break\n            if idx > 0:\n                signals.pop(idx)\n\n            if len(signals) == 0:\n                self.watched_files.pop(filename)\n        return params\n", "path": "spyder/plugins/editor/lsp/providers/document.py"}]}