Skip to content

Commit

Permalink
lsp: Return completion suggestions from Sphinx
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed Jan 1, 2024
1 parent c32b90d commit 9c861d1
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/esbonio/esbonio/server/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def main(argv: Optional[Sequence[str]] = None):
"esbonio.server.features.directives",
"esbonio.server.features.sphinx_support.diagnostics",
"esbonio.server.features.sphinx_support.symbols",
"esbonio.server.features.sphinx_support.directives",
]

for mod in args.included_modules:
Expand Down
4 changes: 4 additions & 0 deletions lib/esbonio/esbonio/server/features/sphinx_manager/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ async def get_diagnostics(self) -> Dict[Uri, List[Dict[str, Any]]]:
"""Get the diagnostics for the project."""
...

async def get_directives(self) -> List[Tuple[str, Optional[str]]]:
"""Get all the directives known to Sphinx."""
...

async def get_document_symbols(self, src_uri: Uri) -> List[types.Symbol]:
"""Get the symbols for the given file."""
...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,15 @@ async def get_build_path(self, src_uri: Uri) -> Optional[str]:

return result[0]

async def get_directives(self) -> List[Tuple[str, Optional[str]]]:
"""Get the directives known to Sphinx."""
if self.db is None:
return []

query = "SELECT name, implementation FROM directives"
cursor = await self.db.execute(query)
return await cursor.fetchall() # type: ignore[return-value]

async def get_document_symbols(self, src_uri: Uri) -> List[types.Symbol]:
"""Get the symbols for the given file."""
if self.db is None:
Expand Down
37 changes: 37 additions & 0 deletions lib/esbonio/esbonio/server/features/sphinx_support/directives.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from typing import List
from typing import Optional

from esbonio import server
from esbonio.server.features import directives
from esbonio.server.features.sphinx_manager import SphinxManager


class SphinxDirectives(directives.DirectiveProvider):
"""Support for directives in a sphinx project."""

def __init__(self, manager: SphinxManager):
self.manager = manager

async def suggest_directives(
self, context: server.CompletionContext
) -> Optional[List[directives.Directive]]:
"""Given a completion context, suggest directives that may be used."""

if (client := await self.manager.get_client(context.uri)) is None:
return None

result: List[directives.Directive] = []
for name, implementation in await client.get_directives():
result.append(
directives.Directive(name=name, implementation=implementation)
)

return result


def esbonio_setup(
sphinx_manager: SphinxManager,
directive_feature: directives.DirectiveFeature,
):
provider = SphinxDirectives(sphinx_manager)
directive_feature.add_provider(provider)
21 changes: 21 additions & 0 deletions lib/esbonio/tests/workspaces/demo/rst/directives.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Directives
==========

The language server has extensive support for directives.

Completion
----------

The most obvious feature is the completion suggestions, try inserting a ``.. note::`` directive on the next line

.. Add your note here...
Notice how VSCode automatically presented you with a list of all the directives you can use in this Sphinx project?

Goto ...
--------

The language server also provides a number of "Goto" navigation commands.
On the ``.. note::`` directive you inserted above, try each of the following commands

- ``Implementation`` goto the source code that implements the selected directive

0 comments on commit 9c861d1

Please sign in to comment.