Skip to content

Commit

Permalink
Merge pull request #13 from regen100/fix-vim-lsp
Browse files Browse the repository at this point in the history
Fix vim lsp
  • Loading branch information
regen100 authored Apr 29, 2020
2 parents c8c284e + e07b324 commit 48d5980
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 70 deletions.
15 changes: 10 additions & 5 deletions src/cmake_language_server/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,10 @@ def query(self) -> bool:
}''')

proc = subprocess.run([self._cmake, str(self._build)],
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stderr=subprocess.PIPE,
encoding='utf-8',
universal_newlines=True)
self.query_json.unlink()
self.query_json.parent.rmdir()
if proc.returncode != 0:
Expand Down Expand Up @@ -144,10 +145,11 @@ def _read_cmake_files(self, jsonpath: Path):
''')
p = subprocess.run(
[self._cmake, '-P', str(tmplist)],
cwd=cmake_files['paths']['source'],
universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stderr=subprocess.PIPE,
cwd=cmake_files['paths']['source'],
encoding='utf-8',
universal_newlines=True)
if p.returncode != 0:
return

Expand Down Expand Up @@ -190,6 +192,7 @@ def parse_doc(self) -> None:
def _parse_commands(self) -> None:
p = subprocess.run([self._cmake, '--help-commands'],
stdout=subprocess.PIPE,
encoding='utf-8',
universal_newlines=True)

if p.returncode != 0:
Expand All @@ -213,6 +216,7 @@ def _parse_commands(self) -> None:
def _parse_variables(self) -> None:
p = subprocess.run([self._cmake, '--help-variables'],
stdout=subprocess.PIPE,
encoding='utf-8',
universal_newlines=True)

if p.returncode != 0:
Expand Down Expand Up @@ -241,6 +245,7 @@ def _parse_variables(self) -> None:
def _parse_modules(self) -> None:
p = subprocess.run([self._cmake, '--help-modules'],
stdout=subprocess.PIPE,
encoding='utf-8',
universal_newlines=True)

if p.returncode != 0:
Expand Down
37 changes: 23 additions & 14 deletions src/cmake_language_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,26 @@ def initialize(params: InitializeParams):
self._api = API(cmake, Path(builddir))
self._api.parse_doc()

@self.feature(COMPLETION, trigger_characters=['{', '('])
trigger_characters = ['{', '(']

@self.feature(COMPLETION, trigger_characters=trigger_characters)
def completions(params: CompletionParams):
if (hasattr(params, 'context') and params.context.triggerKind ==
CompletionTriggerKind.TriggerCharacter):
token = ''
trigger = params.context.triggerCharacter
else:
word = self._cursor_word(params.textDocument.uri,
params.position, False)
token = '' if word is None else word[0]
trigger = None
line = self._cursor_line(params.textDocument.uri,
params.position)
idx = params.position.character - 1
if 0 <= idx < len(line) and line[idx] in trigger_characters:
token = ''
trigger = line[idx]
else:
word = self._cursor_word(params.textDocument.uri,
params.position, False)
token = '' if word is None else word[0]
trigger = None

items: List[CompletionItem] = []

Expand All @@ -59,21 +68,21 @@ def completions(params: CompletionParams):
items.extend(
CompletionItem(x,
CompletionItemKind.Function,
documentation=self._api.get_command_doc(x))
for x in commands)
documentation=self._api.get_command_doc(x),
insert_text=x) for x in commands)

if trigger is None or trigger == '{':
variables = self._api.search_variable(token)
items.extend(
CompletionItem(x,
CompletionItemKind.Variable,
documentation=self._api.get_variable_doc(x))
for x in variables)
documentation=self._api.get_variable_doc(x),
insert_text=x) for x in variables)

if trigger is None:
targets = self._api.search_target(token)
items.extend(
CompletionItem(x, CompletionItemKind.Class)
CompletionItem(x, CompletionItemKind.Class, insert_text=x)
for x in targets)

if trigger == '(':
Expand All @@ -87,16 +96,16 @@ def completions(params: CompletionParams):
CompletionItem(x,
CompletionItemKind.Module,
documentation=self._api.
get_module_doc(x, False))
for x in modules)
get_module_doc(x, False),
insert_text=x) for x in modules)
elif func == 'find_package':
modules = self._api.search_module(token, True)
items.extend(
CompletionItem(x,
CompletionItemKind.Module,
documentation=self._api.
get_module_doc(x, True))
for x in modules)
get_module_doc(x, True),
insert_text=x) for x in modules)

return CompletionList(False, items)

Expand Down
91 changes: 40 additions & 51 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ def _open(client: LanguageServer, path: Path, text: Optional[str] = None):
TextDocumentItem(path.as_uri(), 'cmake', 1, text)))


def _test_completion(client_server, datadir, content: str,
context: Optional[CompletionContext]):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, content)
params = CompletionParams(TextDocumentIdentifier(path.as_uri()),
Position(0, len(content)), context)
if context is None:
# some clients do not send context
del params.context
return client.lsp.send_request(COMPLETION,
params).result(timeout=CALL_TIMEOUT)


def test_initialize(client_server, datadir):
client, server = client_server

Expand All @@ -49,78 +64,52 @@ def test_initialize(client_server, datadir):


def test_completions_invoked(client_server, datadir):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, 'projec')
response = client.lsp.send_request(
COMPLETION,
CompletionParams(TextDocumentIdentifier(path.as_uri()), Position(
0, 6), CompletionContext(
CompletionTriggerKind.Invoked))).result(timeout=CALL_TIMEOUT)
response = _test_completion(
client_server, datadir, 'projec',
CompletionContext(CompletionTriggerKind.Invoked))
item = next(filter(lambda x: x.label == 'project', response.items), None)
assert item is not None
assert '<PROJECT-NAME>' in item.documentation


def test_completions_no_context(client_server, datadir):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, 'projec')
params = CompletionParams(TextDocumentIdentifier(path.as_uri()),
Position(0, 6),
CompletionContext(CompletionTriggerKind.Invoked))
# some clients do not send context
del params.context
response = client.lsp.send_request(COMPLETION,
params).result(timeout=CALL_TIMEOUT)
def test_completions_nocontext(client_server, datadir):
response = _test_completion(client_server, datadir, 'projec', None)
item = next(filter(lambda x: x.label == 'project', response.items), None)
assert item is not None
assert '<PROJECT-NAME>' in item.documentation


def test_completions_triggercharacter_variable(client_server, datadir):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, '${')
response = client.lsp.send_request(
COMPLETION,
CompletionParams(
TextDocumentIdentifier(path.as_uri()), Position(0, 2),
CompletionContext(CompletionTriggerKind.TriggerCharacter,
'{'))).result(timeout=CALL_TIMEOUT)
response = _test_completion(
client_server, datadir, '${',
CompletionContext(CompletionTriggerKind.TriggerCharacter, '{'))
assert 'PROJECT_VERSION' in [x.label for x in response.items]

response_nocontext = _test_completion(client_server, datadir, '${', None)
assert response == response_nocontext


def test_completions_triggercharacter_module(client_server, datadir):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, 'include(')
response = client.lsp.send_request(
COMPLETION,
CompletionParams(
TextDocumentIdentifier(path.as_uri()), Position(0, 8),
CompletionContext(CompletionTriggerKind.TriggerCharacter,
'('))).result(timeout=CALL_TIMEOUT)
response = _test_completion(
client_server, datadir, 'include(',
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
assert 'GoogleTest' in [x.label for x in response.items]

response_nocontext = _test_completion(client_server, datadir, 'include(',
None)
assert response == response_nocontext


def test_completions_triggercharacter_package(client_server, datadir):
client, server = client_server
_init(client, datadir)
path = datadir / 'CMakeLists.txt'
_open(client, path, 'find_package(')
response = client.lsp.send_request(
COMPLETION,
CompletionParams(
TextDocumentIdentifier(path.as_uri()), Position(0, 13),
CompletionContext(CompletionTriggerKind.TriggerCharacter,
'('))).result(timeout=CALL_TIMEOUT)
response = _test_completion(
client_server, datadir, 'find_package(',
CompletionContext(CompletionTriggerKind.TriggerCharacter, '('))
assert 'Boost' in [x.label for x in response.items]

response_nocontext = _test_completion(client_server, datadir,
'find_package(', None)
assert response == response_nocontext


def test_formatting(client_server, datadir):
client, server = client_server
Expand Down

0 comments on commit 48d5980

Please sign in to comment.