Skip to content

Commit

Permalink
doc: include the example servers in the documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
alcarney committed May 29, 2024
1 parent 0ca9186 commit 2847d5a
Show file tree
Hide file tree
Showing 15 changed files with 335 additions and 7 deletions.
14 changes: 11 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
import sys
sys.path.insert(0, os.path.abspath('./ext'))

import importlib.metadata
import pathlib
import re
from docutils import nodes

Expand Down Expand Up @@ -45,17 +47,23 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
# Built-in extensions
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
# 3rd party extensions
"myst_parser",
"sphinx_design",
# Local extensions
"examples",
]

autodoc_member_order = "groupwise"
autodoc_typehints = "description"
autodoc_typehints_description_target = "all"

example_server_dir = pathlib.Path(__file__).parent.parent.parent / "examples" / "servers"

intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
}
Expand Down
6 changes: 6 additions & 0 deletions docs/source/examples/code-actions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Code Actions
============

.. example-server:: code_actions.py
:start-at: import re

7 changes: 7 additions & 0 deletions docs/source/examples/code-lens.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Code Lens
=========

.. example-server:: code_lens.py
:start-at: import logging


9 changes: 9 additions & 0 deletions docs/source/examples/colors.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Document Color
==============

.. example-server:: colors.py
:start-at: import logging




10 changes: 10 additions & 0 deletions docs/source/examples/formatting.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Document Formatting
===================

.. example-server:: formatting.py
:start-at: import logging





12 changes: 12 additions & 0 deletions docs/source/examples/goto.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Goto "X"
========

.. example-server:: goto.py
:start-at: import logging







12 changes: 12 additions & 0 deletions docs/source/examples/hover.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Hover
=====

.. example-server:: hover.py
:start-at: import logging







13 changes: 13 additions & 0 deletions docs/source/examples/inlay-hints.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Inlay Hints
===========

.. example-server:: inlay_hints.py
:start-at: import re








13 changes: 13 additions & 0 deletions docs/source/examples/json-server.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
JSON Server
===========

.. example-server:: json_server.py
:start-at: import argparse








13 changes: 13 additions & 0 deletions docs/source/examples/publish-diagnostics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Publish Diagnostics
===================

.. example-server:: publish_diagnostics.py
:start-at: import logging








13 changes: 13 additions & 0 deletions docs/source/examples/pull-diagnostics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Pull Diagnostics
================

.. example-server:: pull_diagnostics.py
:start-at: import logging








13 changes: 13 additions & 0 deletions docs/source/examples/rename.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Rename
======

.. example-server:: rename.py
:start-at: import logging








86 changes: 86 additions & 0 deletions docs/source/ext/examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""Documentation for the example servers"""
from __future__ import annotations

import os
import pathlib
import typing
import importlib.util as imutil

from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.util.docutils import SphinxDirective
from sphinx.util.logging import getLogger

if typing.TYPE_CHECKING:
from sphinx.application import Sphinx

logger = getLogger(__name__)

class ExampleServerDirective(SphinxDirective):
"""Automate the process of documenting example servers.
Currently, this doesn't do *that* much, it
- Inserts the code using a ``.. literalinclude::`` directive.
- Extracts the server module's docstring and inserts it into the page as nicely
rendered text.
But perhaps we can do something more interesting in the future!
"""

required_arguments = 1
option_spec = {
"start-at": directives.unchanged,
}

def get_docstring(self, filename: pathlib.Path):
"""Given the filepath to a module, return its docstring."""

base = filename.stem
spec = imutil.spec_from_file_location(f"examples.{base}", filename)

try:
module = imutil.module_from_spec(spec)
spec.loader.exec_module(module)
except Exception:
logger.exception("Unable to import example server")
return []

if (docstring := module.__doc__) is not None:
return docstring.splitlines()

return []

def run(self):
server_dir = self.config.example_server_dir
name = self.arguments[0]

if not (filename := pathlib.Path(server_dir, name)).exists():
raise RuntimeError(f"Unable to find example server: {filename}")

# Tell Sphinx to rebuild a document if this file changes
self.env.note_dependency(str(filename))

# An "absolute" path given to `literalinclude` is actually relative to the
# projects srcdir
relpath = os.path.relpath(str(filename), start=str(self.env.app.srcdir))
content = [
f".. literalinclude:: /{relpath}",
" :language: python",
]

if (start_at := self.options.get("start-at")) is not None:
content.append(f" :start-at: {start_at}")

# Confusingly, these are processed in reverse order...
self.state_machine.insert_input(content, "<examples>")
self.state_machine.insert_input(
self.get_docstring(filename), str(filename)
)

return []


def setup(app: Sphinx):
app.add_config_value("example_server_dir", "", rebuild='env')
app.add_directive("example-server", ExampleServerDirective)
113 changes: 113 additions & 0 deletions docs/source/getting-started.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
Getting Started
===============

.. _example-servers:

Example Servers
---------------

.. toctree::
:hidden:
:glob:

examples/*

.. tip::

If you use VSCode, we recommend you try these servers out in the :ref:`pygls-playground <howto-use-pygls-playground>` extension

Each of the following example servers are focused on implementing a particular subset of the Language Server Protocol.

.. grid:: 1 2 2 4
:gutter: 2

.. grid-item-card:: Code Actions
:link: /examples/code-actions
:link-type: doc
:text-align: center

:octicon:`light-bulb`

.. grid-item-card:: Code Lens
:link: /examples/code-lens
:link-type: doc
:text-align: center

:octicon:`eye`

.. grid-item-card:: Colors
:link: /examples/colors
:link-type: doc
:text-align: center

:octicon:`paintbrush`

.. grid-item-card:: Formatting
:link: /examples/formatting
:link-type: doc
:text-align: center

:octicon:`typography`

.. grid-item-card:: Goto "X"
:link: /examples/goto
:link-type: doc
:text-align: center

:octicon:`search`

.. grid-item-card:: Hover
:link: /examples/hover
:link-type: doc
:text-align: center

:octicon:`book`

.. grid-item-card:: Inlay Hints
:link: /examples/inlay-hints
:link-type: doc
:text-align: center

:octicon:`info`

.. grid-item-card:: Publish Diagnostics
:link: /examples/publish-diagnostics
:link-type: doc
:text-align: center

:octicon:`alert`

.. grid-item-card:: Pull Diagnostics
:link: /examples/pull-diagnostics
:link-type: doc
:text-align: center

:octicon:`alert`

.. grid-item-card:: Rename
:link: /examples/rename
:link-type: doc
:text-align: center

:octicon:`pencil`

These servers are dedicated to demonstrating features of *pygls* itself

.. grid:: 1 2 2 4
:gutter: 2

.. grid-item-card:: JSON Server
:link: /examples/json-server
:link-type: doc
:text-align: center

:octicon:`code`


Tutorial
--------

.. note::

Coming soon\ :sup:`TM`

8 changes: 4 additions & 4 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ allows you to write your own `language server`_ in just a few lines of code
:hidden:
:caption: User Guide

tutorial
getting-started
user-guide
How To <howto>
reference
Expand All @@ -40,12 +40,12 @@ The documentation is divided up into the following sections
.. grid:: 1 2 2 2
:gutter: 2

.. grid-item-card:: Tutorial
:link: /tutorial
.. grid-item-card:: Getting Started
:link: /getting-started
:link-type: doc
:text-align: center

Step-by-step guides on writing your first language server with *pygls*.
First steps with *pygls*.

.. grid-item-card:: How To Guides
:link: /howto
Expand Down

0 comments on commit 2847d5a

Please sign in to comment.