a library to create language servers
Project description
lsp-tree-sitter
A core library to support language servers.
I write many language servers and they share some same code so I extract the shared code to this library.
I've had enough of writing many DSLs in my editor without any LSP support (completion, hover, ...). So I decide to sacrifice my time to do this work.
Language servers
- termux-language-server: for some specific bash scripts:
- mutt-language-server: for (neo)mutt's (neo)muttrc
- More
Usage
Schema
A Trie
to convert a file to a json, then you can use json schema to validate
it to get diagnostics.
Take termux-language-server as an example.
PKGBUILD
:
pkgname=hello
pkgver=0.0.1
pkgrel=1
pkgdesc="hello"
arch=(wrong_arch)
license=(GPL3)
build() {
cat <<EOF > hello
#!/usr/bin/env sh
echo hello
EOF
}
package() {
install -D hello -t $pkgdir/usr/bin
}
termux-language-server --convert PKGBUILD
{
"pkgname": "hello",
"pkgver": "0.0.1",
"pkgrel": "1",
"pkgdesc": "hello",
"arch": [
"wrong_arch"
],
"license": [
"GPL3"
],
"build": 0,
"package": 0
}
So, we can validate the json by a json schema:
$ termux-language-server --check PKGBUILD
PKGBUILD:5:7-5:17:error: 'wrong_arch' is not one of ['any', 'pentium4', 'i486', 'i686', 'x86_64', 'x86_64_v3', 'arm', 'armv6h', 'armv7h', 'armv8', 'aarch64']
Sometimes it will be more complicated:
neomuttrc
:
set allow_ansi=yes sleep_time = no ispell = aspell
set query_command = 'mutt_ldap_query.pl %s'
mutt-language-server --convert neomuttrc
{
"set": {
"allow_ansi": "yes",
"sleep_time": "no",
"ispell": "aspell",
"query_command": "mutt_ldap_query.pl %s"
}
}
$ mutt-language-server --check neomuttrc
neomuttrc:1:33-1:35:error: 'no' is not of type 'number'
We put the result to the json's .set
not .
just in order to reserve the
other keys for other usages.
Finders
Some finders to find the required node in tree-sitter's AST. Such as, if you want to get the node under the cursor:
@self.feature(TEXT_DOCUMENT_COMPLETION)
def completions(params: CompletionParams) -> CompletionList:
document = self.workspace.get_document(params.text_document.uri)
uni = PositionFinder(params.position, right_equal=True).find(
document.uri, self.trees[document.uri]
)
# ...
UNI (Universal Node Identifier) is URI + node.
Utilities
This library also provides many utility functions. Such as converting man page to markdown and tokenizing it in order to generate the json schema.
mutt-language-server --generate-schema neomuttrc
{
"$id": "https://github.com/neomutt/mutt-language-server/blob/main/src/termux_language_server/assets/json/neomuttrc.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"$comment": "Don't edit this file directly! It is generated by `mutt-language-server --generate-schema=neomuttrc`.",
"type": "object",
"properties": {
"account-hook": {
"description": "```neomuttrc\naccount-hook regex command\n```\nThis hook is executed whenever you access a remote mailbox. Useful to adjust configuration settings to different IMAP or POP servers."
},
"$comment": "..."
}
}
Template
This project provides a template for copier.
For example, you want to create a language server for a filetype named
zathurarc
. Please follow
the following steps:
Create a tree-sitter parser
- Create a tree-sitter-parser from template.
- Publish it to PYPI
You can see if py-tree-sitter-languages supports the language where you want to create a language server.
Copy a template
$ copier copy -rHEAD gh:neomutt/lsp-tree-sitter /path/to/your/XXX-language-server
๐ค What is your language name?
zathurarc
๐ค What is your file patterns? split by " "
*.zathurarc zathurarc
๐ค What is your project name?
zathura-language-server
๐ค What is your Python module name?
zathura_language_server
๐ค What is your Python class name?
ZathuraLanguageServer
๐ค What is your tree-sitter parser name?
tree-sitter-zathurarc
๐ค What is your user name?
wzy
๐ค What is your email?
32936898+Freed-Wu@users.noreply.github.com
Copying from template version None
create .
...
$ cd /path/to/your/XXX-language-server
$ tree .
๎ฟ .
โโโ ๎ฟ docs # documents
โ โโโ ๎ฟ api
โ โ โโโ ๏ zathura-language-server.md
โ โโโ ๎ conf.py
โ โโโ ๏ index.md
โ โโโ ๎ requirements.txt
โ โโโ ๎ฟ resources
โ โโโ ๏ configure.md
โ โโโ ๏ install.md
โ โโโ ๏ requirements.md
โโโ ๏ญ LICENSE
โโโ ๎ pyproject.toml
โโโ ๏ README.md
โโโ ๎ฟ requirements # optional dependencies
โ โโโ ๏
colorize.txt
โ โโโ ๏
dev.txt
โ โโโ ๏
misc.txt
โโโ ๎ requirements.txt
โโโ ๎ฟ src
โ โโโ ๎ฟ zathura_language_server
โ โโโ ๎ __init__.py
โ โโโ ๎ __main__.py
โ โโโ ๎ _shtab.py
โ โโโ ๎ฟ assets
โ โ โโโ ๎ฟ json # json schemas generated by misc/XXX.py
โ โ โ โโโ ๎ zathurarc.json
โ โ โโโ ๎ฟ queries # tree-sitter queries
โ โ โโโ ๏
import.scm
โ โโโ ๎ finders.py # project specific finders
โ โโโ ๎ฟ misc
โ โ โโโ ๎ __init__.py
โ โ โโโ ๎ zathurarc.py
โ โโโ ๏
py.typed
โ โโโ ๎ schema.py # project specific schemas
โ โโโ ๎ server.py # main file for server
โ โโโ ๎ utils.py
โโโ ๎ฟ templates
โ โโโ ๏
class.txt
โ โโโ ๏
def.txt
โ โโโ ๏
metainfo.py.j2
โ โโโ ๏
noarg.txt
โโโ ๎ฟ tests
โโโ ๎ test_utils.py
- Edit
schema.py
to convert a tree-sitter's tree to a json, which is the core function ofXXX-langauge-server --convert
- Edit a
misc/XXX.py
to generate json schemas, which is the core function ofXXX-languageserver --generate-schema
- Edit
server.py
to make sure the LSP features can work for specific tree-sitter parsers. - Edit
queries/XXX.scm
to make sure the LSP features can work for specific tree-sitter parsers if you use them. - Edit
finders.py
to add the language specific finders forXXX-languageserver --check
andXXX-languageserver --format
Test if it can work
$ git init
$ pip install -e .
$ which zathura-language-server
~/.local/bin/zathura-language-server
- Refer
docs/resources/configure.md
to configure your language server for your editor. - Refer
README.md
to see the LSP features provided by your language server.
vi /path/to/zathurarc
You can test the LSP features.
Refer https://docs.readthedocs.io to see how to publish the documents.
References
These following language servers can be a good example for beginners:
zathura-language-server
zathurarc
's syntax only has 4 directives:
set option value
include /the/path
map key function
unmap key
Very few directives make creating
tree-sitter-zathurarc and
editing schema.py
very easy. So I am highly recommended starting from it.
tmux-language-server
tmux.conf
is more complex than zathurarc
. It has not only
set option = value
and source /the/path
, but also 170+ other directives.
mutt-language-server
muttrc
or neomuttrc
has the following directives:
set option = value
source /the/path
- 80+ other directives
However, its set
syntax is very flexible. The following syntaxes are legal:
set option2 = value1 option2 = value2 ...
set option
: a shortcut forset option = yes
set nooption
: a shortcut forset option = no
set invoption
set nooption1 invoption2 option3 ...
- ...
So, in fact it is harder than tmux.conf
, IMO.
termux-language-server
build.sh
, PKGBUILD
, *.ebuild
use same syntax of bash. However, they use
different json schemas. If the language where you want to create a language
server, you can refer it to know how to handle this situation.
Other references
Some useful URLs for beginners who want to develop language servers:
- some Chinese blogs about how I write these language servers
- tree-sitter
- language server protocol
- json schema
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file lsp-tree-sitter-0.0.15.tar.gz
.
File metadata
- Download URL: lsp-tree-sitter-0.0.15.tar.gz
- Upload date:
- Size: 66.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | db37fe49827e216742425606ba6e98bf6cf653446986c588155e908fecf279aa |
|
MD5 | 3038659aec90c0e88ae37476db2922b5 |
|
BLAKE2b-256 | 920ad52fedd27f43b3c0f4c8f524a0909d6525e698d24976a87b329642c06084 |
File details
Details for the file lsp_tree_sitter-0.0.15-py3-none-any.whl
.
File metadata
- Download URL: lsp_tree_sitter-0.0.15-py3-none-any.whl
- Upload date:
- Size: 32.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 85e5c8ad78eda074cc0764f35de13112d84929317ca516874ce681e67fdac209 |
|
MD5 | fbda8425f725f3b2542a5acc0e7311f8 |
|
BLAKE2b-256 | b30dcf74fe7740c500fa308908cf76c6f624b4b9c3c2e40361af8f3c915cd19a |