Skip to content

Commit 1741a7a

Browse files
diablodaleDonJayamanne
authored andcommitted
fix for completion (aka Intellisense) pathnames for WSL Bash and Cygwin (DonJayamanne#1049)
- detect Windows hosts with Python running in WSL or Cygwin - ignore Python running in Windows - ignore other hosts like Linux, Osx, etc. - alter absolute and relative paths - can be combined with a batch file and VSCode settings change to enable full linting and completition
1 parent 2b6c455 commit 1741a7a

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

pythonFiles/completion.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import json
66
import traceback
7+
import platform
78

89
WORD_RE = re.compile(r'\w')
910
jediPreview = False
@@ -20,6 +21,17 @@ class JediCompletion(object):
2021
def __init__(self):
2122
self.default_sys_path = sys.path
2223
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 = ''
2335

2436
def _get_definition_type(self, definition):
2537
is_built_in = definition.in_builtin_module
@@ -520,13 +532,33 @@ def _set_request_config(self, config):
520532
if path and path not in sys.path:
521533
sys.path.insert(0, path)
522534

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+
523554
def _process_request(self, request):
524555
"""Accept serialized request from VSCode and write response.
525556
"""
526557
request = self._deserialize(request)
527558

528559
self._set_request_config(request.get('config', {}))
529560

561+
self._normalize_request_path(request)
530562
path = self._get_top_level_module(request.get('path', ''))
531563
if path not in sys.path:
532564
sys.path.insert(0, path)

0 commit comments

Comments
 (0)