diff --git a/plugin/deoplete-rust.vim b/plugin/deoplete-rust.vim index 2610972..62e137d 100644 --- a/plugin/deoplete-rust.vim +++ b/plugin/deoplete-rust.vim @@ -35,7 +35,7 @@ function! s:jumpTo(mode, filename, line_nr, column_nr) " FIXME(SK): Throws error if buffer has been modified but changes " have not been written to disk yet - exec 'edit '.a:filename + exec 'keepjumps edit '.fnameescape(a:filename) call cursor(a:line_nr, a:column_nr) normal! zz @@ -114,8 +114,8 @@ function! s:DeopleteRustShowDocumentation() let l:line_nr = line('.') let l:column_nr = col('.') - let l:path = expand('%:p') - let l:buf = tempname() + let l:path = s:GetFilename() + let l:buf = s:GetTempName() call writefile(getline(1, '$'), l:buf) @@ -152,8 +152,8 @@ function! s:DeopleteRustGoToDefinition(mode) let l:line_nr = line('.') let l:column_nr = col('.') - let l:path = expand('%:p') - let l:buf = tempname() + let l:path = s:GetFilename() + let l:buf = s:GetTempName() call writefile(getline(1, '$'), l:buf) @@ -183,6 +183,23 @@ function! s:DeopleteRustGoToDefinition(mode) endfor endfunction +function! s:GetFilename() + return s:CygwinConvertPath(expand('%:p')) +endfunction + +function! s:GetTempName() + return s:CygwinConvertPath(tempname()) +endfunction + +" Returns the filename. Handles cygwin as a special case. +function! s:CygwinConvertPath(str) + if has('win32unix') + let res = system("cygpath --windows ".a:str) + return fnameescape(substitute(res, '\n\+$', '', '')) + endif + return a:str +endfunction + function! s:warn(message) echohl WarningMsg | echomsg a:message | echohl NONE endfunction diff --git a/rplugin/python3/deoplete/sources/rust.py b/rplugin/python3/deoplete/sources/rust.py index 5664f3d..8c5db2b 100644 --- a/rplugin/python3/deoplete/sources/rust.py +++ b/rplugin/python3/deoplete/sources/rust.py @@ -4,6 +4,7 @@ import re import subprocess import tempfile +import platform from .base import Base from deoplete.logger import getLogger @@ -14,7 +15,6 @@ VAR_RUST_SOURCE = 'deoplete#sources#rust#rust_source_path' VAR_DUPLICATION = 'deoplete#sources#rust#show_duplicates' - class Source(Base): """Deoplete Rust source""" def __init__(self, vim): @@ -81,20 +81,48 @@ def __retrieve(self): 'complete', str(line), str(column), - content.name, - buf.name + self.__escape_path(content.name), + self.__escape_path(buf.name) ] results = [] try: - results = subprocess.check_output(args) \ + # NOTE: needs to avoid the list form of calling 'check_output' + # because quotes was NOT preserved. See StackOverlow post. + # https://stackoverflow.com/a/39096422/3325787 + cmd = " ".join(args) + results = subprocess.check_output(cmd, shell=True) \ .decode(self.__encoding).splitlines() except Exception: pass return results + def __escape_path(self, path): + """ + Handles Cygwin case. + + path(String): path to escape. + Returns: string of new path to use. + """ + if "cygwin" not in platform.system().lower(): + return path + args = [ + "cygpath", "--windows", path + ] + try: + results = subprocess.check_output(args) \ + .decode(self.__encoding).splitlines() + except Exception: + pass + # In the error path, best-effort is to try 'path'. + if results is None or len(results) == 0: + return path + # TODO: find something like vim's fnameescape instead of just + # surrounding with quotes. + return '"' + results[0] + '"' + def __check_binary(self): """Missing""" return os.path.isfile(self.__racer) and os.environ.get('RUST_SRC_PATH')