Contents Menu Expand Light mode Dark mode Auto light/dark, in light mode Auto light/dark, in dark mode Skip to content
pygls v2.1.0
pygls v2.1.0

Language Servers

  • Getting Started
    • Code Actions
    • Code Lens
    • Document Color
    • Document Formatting
    • Goto “X” and Find References
    • Hover
    • Inlay Hints
    • JSON Server
    • Document Links
    • Publish Diagnostics
    • Pull Diagnostics
    • Rename
    • Semantic Tokens
    • Document & Workspace Symbols
    • Threaded Handlers
  • How To
    • Access the Server Instance
    • Add Notebook Support
    • Customise Error Reporting
    • Get Client Configuration
    • Give User Feedback
    • Implement Workspace Commands
    • Run a Server
    • Run a Server with Pyodide
    • Work with Text Documents
  • Reference
    • Built-In Features

Language Clients

  • Coming SoonTM

The Protocol

  • How To
    • Interpret Semantic Tokens

The Library

  • How To
    • Migrate to v1
    • Migrate to v2
    • Send Custom Messages
    • Use Custom Converter
    • Use the pygls-playground
  • Reference
    • Logging
    • Message Handler Types
  • Python API
    • Clients
    • IO
    • Protocol
    • Servers
    • Types
    • URIs
    • Workspace

Contributing

  • How To
    • Run the Pyodide Tests

About

  • Implementations Based on pygls
  • Tools Based on pygls
  • History of pygls
  • Changelog
  • Pre Automation Changelog
Back to top
View this page
Edit this page

Document Links¶

This implements the textDocument/documentLink and documentLink/resolve requests.

These allow you to add support for custom link syntax to your language. In editors like VSCode, links will often be underlined and can be opened with a Ctrl+Click.

This server scans the document given to textDocument/documentLink for the syntax <LINK_TYPE:PATH> and returns a document link desribing its location. While we could easily compute the target and tooltip fields in the same method, this example demonstrates how the documentLink/resolve method can be used to defer this until it is actually necessary

import logging
import re

from lsprotocol import types

from pygls.cli import start_server
from pygls.lsp.server import LanguageServer

LINK = re.compile(r"<(\w+):([^>]+)>")
server = LanguageServer("links-server", "v1")


@server.feature(
    types.TEXT_DOCUMENT_DOCUMENT_LINK,
)
def document_links(params: types.DocumentLinkParams):
    """Return a list of links contained in the document."""
    items = []
    document_uri = params.text_document.uri
    document = server.workspace.get_text_document(document_uri)

    for linum, line in enumerate(document.lines):
        for match in LINK.finditer(line):
            start_char, end_char = match.span()
            items.append(
                types.DocumentLink(
                    range=types.Range(
                        start=types.Position(line=linum, character=start_char),
                        end=types.Position(line=linum, character=end_char),
                    ),
                    data={"type": match.group(1), "target": match.group(2)},
                ),
            )

    return items


LINK_TYPES = {
    "github": ("https://github.com/{}", "Github - {}"),
    "pypi": ("https://pypi.org/project/{}", "PyPi - {}"),
}


@server.feature(types.DOCUMENT_LINK_RESOLVE)
def document_link_resolve(link: types.DocumentLink):
    """Given a link, fill in additional information about it"""
    logging.info("resolving link: %s", link)

    link_type = link.data.get("type", "<unknown>")
    link_target = link.data.get("target", "<unknown>")

    if (link_info := LINK_TYPES.get(link_type, None)) is None:
        logging.error("Unknown link type: '%s'", link_type)
        return link

    url, tooltip = link_info
    link.target = url.format(link_target)
    link.tooltip = tooltip.format(link_target)

    return link


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format="%(message)s")
    start_server(server)
Next
Publish Diagnostics
Previous
JSON Server
Copyright © Open Law Library
Made with Sphinx and @pradyunsg's Furo