-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lsp: Split directive support into multiple features
Rather than try and have a single `Directives` language feature that does all the work of discovering directives, suggesting completions AND making it all work for both rst and myst, this commit breaks the work up between multiple `LanguageFeatures`. There is a backend `Directives` feature, that will provide an API that the various frontend features can use. Then there is the `RstDirectives` and `MystDirectives` features that build on the backend to surface the relevant features for their respective syntax. At the moment they are nearly identical however, they are now free to diverge to better support their associated syntax.
- Loading branch information
Showing
7 changed files
with
509 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
from __future__ import annotations | ||
|
||
import typing | ||
|
||
from lsprotocol import types | ||
|
||
from esbonio import server | ||
from esbonio.server.features.directives import DirectiveFeature | ||
from esbonio.server.features.directives import completion | ||
from esbonio.sphinx_agent.types import MYST_DIRECTIVE | ||
|
||
if typing.TYPE_CHECKING: | ||
from typing import List | ||
from typing import Optional | ||
|
||
|
||
class MystDirectives(server.LanguageFeature): | ||
"""A frontend to directives for MyST syntax.""" | ||
|
||
def __init__(self, directives: DirectiveFeature, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
|
||
self.directives = directives | ||
self._insert_behavior = "replace" | ||
|
||
completion_triggers = [MYST_DIRECTIVE] | ||
|
||
def initialized(self, params: types.InitializedParams): | ||
"""Called once the initial handshake between client and server has finished.""" | ||
self.configuration.subscribe( | ||
"esbonio.server.completion", | ||
server.CompletionConfig, | ||
self.update_configuration, | ||
) | ||
|
||
def update_configuration( | ||
self, event: server.ConfigChangeEvent[server.CompletionConfig] | ||
): | ||
"""Called when the user's configuration is updated.""" | ||
self._insert_behavior = event.value.preferred_insert_behavior | ||
|
||
async def completion( | ||
self, context: server.CompletionContext | ||
) -> Optional[List[types.CompletionItem]]: | ||
"""Provide completion suggestions for directives.""" | ||
|
||
groups = context.match.groupdict() | ||
|
||
# Are we completing a directive's options? | ||
if "directive" not in groups: | ||
return await self.complete_options(context) | ||
|
||
# Don't offer completions for targets | ||
if (groups["name"] or "").startswith("_"): | ||
return None | ||
|
||
# Are we completing the directive's argument? | ||
directive_end = context.match.span()[0] + len(groups["directive"]) | ||
complete_directive = groups["directive"].endswith("}") | ||
|
||
if complete_directive and directive_end < context.position.character: | ||
return await self.complete_arguments(context) | ||
|
||
return await self.complete_directives(context) | ||
|
||
async def complete_options(self, context: server.CompletionContext): | ||
return None | ||
|
||
async def complete_arguments(self, context: server.CompletionContext): | ||
return None | ||
|
||
async def complete_directives( | ||
self, context: server.CompletionContext | ||
) -> Optional[List[types.CompletionItem]]: | ||
"""Return completion suggestions for the available directives.""" | ||
|
||
language = self.server.get_language_at(context.doc, context.position) | ||
render_func = completion.get_directive_renderer(language, self._insert_behavior) | ||
if render_func is None: | ||
return None | ||
|
||
items = [] | ||
for directive in await self.directives.suggest_directives(context): | ||
if (item := render_func(context, directive)) is not None: | ||
items.append(item) | ||
|
||
if len(items) > 0: | ||
return items | ||
|
||
return None | ||
|
||
|
||
def esbonio_setup(esbonio: server.EsbonioLanguageServer, directives: DirectiveFeature): | ||
myst_directives = MystDirectives(directives, esbonio) | ||
esbonio.add_feature(myst_directives) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
|
Oops, something went wrong.