跳转到主要内容

创建语言服务器的库

项目描述

lsp-tree-sitter

readthedocs pre-commit.ci status github/workflow codecov DeepSource

github/downloads github/downloads/latest github/issues github/issues-closed github/issues-pr github/issues-pr-closed github/discussions github/milestones github/forks github/stars github/watchers github/contributors github/commit-activity github/last-commit github/release-date

github/license github/languages github/languages/top github/directory-file-count github/code-size github/repo-size github/v

pypi/status pypi/v pypi/downloads pypi/format pypi/implementation pypi/pyversions

支持语言服务器的核心库。

我编写了许多语言服务器,它们共享一些相同的代码,所以我将共享的代码提取到这个库中。

我在编辑器中编写了许多没有LSP支持(自动完成、悬停等)的DSL,我已经受够了。所以我决定牺牲我的时间来做这项工作。

语言服务器

使用方法

模式

将文件转换为json的Trie,然后你可以使用json模式来验证它以获取诊断。

termux-language-server为例。

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
}

因此,我们可以通过一个json模式来验证json。

$ 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']

PKGBUILD

有时可能会更复杂

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'

neomuttrc

我们将结果存入json的.set而不是.,仅仅是为了保留其他键供其他用途。

查找器

一些查找器用于在tree-sitter的AST中找到所需的节点。例如,如果您想获取光标下的节点

@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(通用节点标识符)是URI + 节点。

工具函数

这个库还提供了许多工具函数。例如,将手册页转换为markdown并对其进行标记化,以便生成json模式。

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": "https://json-schema.fullstack.org.cn/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": "..."
  }
}

hover

模板

本项目为copier提供了一个模板。

例如,您想为名为zathurarc的文件类型创建一个语言服务器。请按照以下步骤操作

创建tree-sitter解析器

  1. 模板创建tree-sitter-parser。
  2. 发布到PYPI

您可以在py-tree-sitter-languages中查看是否支持您想要创建语言服务器的语言。

复制模板

$ 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
  1. 编辑schema.py,将tree-sitter的树转换为json,这是XXX-langauge-server --convert的核心功能
  2. 编辑misc/XXX.py生成json模式,这是XXX-languageserver --generate-schema的核心功能
  3. 编辑server.py确保LSP功能可以为特定的tree-sitter解析器工作。
  4. 编辑queries/XXX.scm确保如果您使用它们,LSP功能可以为特定的tree-sitter解析器工作。
  5. 编辑finders.pyXXX-languageserver --checkXXX-languageserver --format添加语言特定的查找器

测试是否可以工作

$ git init
$ pip install -e .
$ which zathura-language-server
~/.local/bin/zathura-language-server
  1. 参考docs/resources/configure.md配置您的语言服务器以供您的编辑器使用。
  2. 参考README.md查看您的语言服务器提供的LSP功能。
vi /path/to/zathurarc

您可以测试LSP功能。

参考https://docs.readthedocs.io了解如何发布文档。

参考文献

以下语言服务器可以作为初学者的良好示例

zathura-language-server

zathurarc的语法只有4个指令

  • 设置选项值
  • 包含/路径
  • 映射键函数
  • 取消映射键

如此少的指令使得创建tree-sitter-zathurarc和编辑schema.py变得非常容易。因此,我强烈建议从这里开始。

tmux-language-server

tmux.confzathurarc更复杂。它不仅包含set option = valuesource /the/path,还有170多个其他指令。

mutt-language-server

muttrcneomuttrc有如下指令

  • 设置选项值
  • 从/路径源
  • 80多个其他指令

然而,其set语法非常灵活。以下语法是合法的

  • 设置选项2 = 值1 选项2 = 值2 ...
  • 设置选项set option = yes的快捷方式
  • 设置无选项set option = no的快捷方式
  • 设置反选项
  • 设置无选项1 反选项2 选项3 ...
  • ...

所以,我认为实际上它比tmux.conf更难。

termux-language-server

build.shPKGBUILD*.ebuild使用与bash相同的语法。但是,它们使用不同的json模式。如果您想要创建语言服务器的语言,可以参考它了解如何处理这种情况。

其他参考文献

一些对想要开发语言服务器的初学者有用的URL

项目详情


下载文件

下载适用于您平台的文件。如果您不确定该选择哪一个,请了解更多关于 安装包 的信息。

源代码发行版

lsp_tree_sitter-0.0.16.tar.gz (66.7 kB 查看哈希值)

上传时间 源代码

构建发行版

lsp_tree_sitter-0.0.16-py3-none-any.whl (32.2 kB 查看哈希值)

上传时间 Python 3

由以下支持