Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
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.
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.
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.
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": "..."
}
}
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:
You can see if py-tree-sitter-languages supports the language where you want to create a language server.
$ 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
schema.py
to convert a tree-sitter's tree to a json, which is the
core function of XXX-langauge-server --convert
misc/XXX.py
to generate json schemas, which is the core function of
XXX-languageserver --generate-schema
server.py
to make sure the LSP features can work for specific
tree-sitter parsers.queries/XXX.scm
to make sure the LSP features can work for specific
tree-sitter parsers if you use them.finders.py
to add the language specific finders for
XXX-languageserver --check
and XXX-languageserver --format
$ git init
$ pip install -e .
$ which zathura-language-server
~/.local/bin/zathura-language-server
docs/resources/configure.md
to configure your language server for
your editor.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.
These following language servers can be a good example for beginners:
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.conf
is more complex than zathurarc
. It has not only
set option = value
and source /the/path
, but also 170+ other directives.
muttrc
or neomuttrc
has the following directives:
set option = value
source /the/path
However, its set
syntax is very flexible. The following syntaxes are legal:
set option2 = value1 option2 = value2 ...
set option
: a shortcut for set option = yes
set nooption
: a shortcut for set option = no
set invoption
set nooption1 invoption2 option3 ...
So, in fact it is harder than tmux.conf
, IMO.
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.
Some useful URLs for beginners who want to develop language servers:
FAQs
a library to create language servers
We found that lsp-tree-sitter demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.