|
4 | 4 | import sys |
5 | 5 | import json |
6 | 6 | import traceback |
| 7 | +import platform |
7 | 8 |
|
8 | 9 | WORD_RE = re.compile(r'\w') |
9 | 10 | jediPreview = False |
@@ -20,6 +21,17 @@ class JediCompletion(object): |
20 | 21 | def __init__(self): |
21 | 22 | self.default_sys_path = sys.path |
22 | 23 | self._input = io.open(sys.stdin.fileno(), encoding='utf-8') |
| 24 | + if (os.path.sep == '/') and (platform.uname()[2].find('Microsoft') > -1): |
| 25 | + # WSL; does not support UNC paths |
| 26 | + self.drive_mount = '/mnt/' |
| 27 | + elif sys.platform == 'cygwin': |
| 28 | + # cygwin |
| 29 | + self.drive_mount = '/cygdrive/' |
| 30 | + else: |
| 31 | + # Do no normalization, e.g. Windows build of Python. |
| 32 | + # Could add additional test: ((os.path.sep == '/') and os.path.isdir('/mnt/c')) |
| 33 | + # However, this may have more false positives trying to identify Windows/*nix hybrids |
| 34 | + self.drive_mount = '' |
23 | 35 |
|
24 | 36 | def _get_definition_type(self, definition): |
25 | 37 | is_built_in = definition.in_builtin_module |
@@ -520,13 +532,33 @@ def _set_request_config(self, config): |
520 | 532 | if path and path not in sys.path: |
521 | 533 | sys.path.insert(0, path) |
522 | 534 |
|
| 535 | + def _normalize_request_path(self, request): |
| 536 | + """Normalize any Windows paths received by a *nix build of |
| 537 | + Python. Does not alter the reverse os.path.sep=='\\', |
| 538 | + i.e. *nix paths received by a Windows build of Python. |
| 539 | + """ |
| 540 | + if 'path' in request: |
| 541 | + if not self.drive_mount: |
| 542 | + return |
| 543 | + newPath = request['path'].replace('\\', '/') |
| 544 | + if newPath[0:1] == '/': |
| 545 | + # is absolute path with no drive letter |
| 546 | + request['path'] = newPath |
| 547 | + elif newPath[1:2] == ':': |
| 548 | + # is path with drive letter, only absolute can be mapped |
| 549 | + request['path'] = self.drive_mount + newPath[0:1].lower() + newPath[2:] |
| 550 | + else: |
| 551 | + # is relative path |
| 552 | + request['path'] = newPath |
| 553 | + |
523 | 554 | def _process_request(self, request): |
524 | 555 | """Accept serialized request from VSCode and write response. |
525 | 556 | """ |
526 | 557 | request = self._deserialize(request) |
527 | 558 |
|
528 | 559 | self._set_request_config(request.get('config', {})) |
529 | 560 |
|
| 561 | + self._normalize_request_path(request) |
530 | 562 | path = self._get_top_level_module(request.get('path', '')) |
531 | 563 | if path not in sys.path: |
532 | 564 | sys.path.insert(0, path) |
|