Skip to content

Commit

Permalink
Introduce YANG LSP support (#4390)
Browse files Browse the repository at this point in the history
  • Loading branch information
esmasth committed Apr 1, 2024
1 parent d3173ad commit 4e37c36
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.org
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
* Add Cucumber support.
* Add COBOL support.
* Add Common Lisp support.
* Add YANG support using TypeFox/yang-lsp Server.

** Release 8.0.0
* Add ~lsp-clients-angular-node-get-prefix-command~ to get the Angular server from another location which is still has ~/lib/node_modules~ in it.
Expand Down
122 changes: 122 additions & 0 deletions clients/lsp-yang.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
;;; lsp-yang.el --- YANG Client settings -*- lexical-binding: t; -*-

;; Copyright (C) 2024 Siddharth Sharma

;; Author: Siddharth Sharma <siddharth.sharma@ericsson.com>
;; Keywords: languages, yang, lsp

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; LSP support for YANG using using an external language server. Currently
;; the supported server is:
;;
;; yang-lsp (yls).
;; See https://github.com/TypeFox/yang-lsp/blob/master/docs/Settings.md
;; for setting up the user/project/workspace files.

;;; Code:

(require 'lsp-mode)

(defgroup lsp-yang nil
"LSP support for the YANG data modeling language using yang-lsp server."
:group 'lsp-yang
:link '(url-link "https://github.com/TypeFox/yang-lsp"))

(defcustom lsp-yang-yls-version "0.7.6"
"yang-lsp server version to download.
It has to be set before `lsp-yang.el' is loaded and it has to
be available here: https://github.com/TypeFox/yang-lsp/releases/"
:type 'string
:group 'lsp-yang
:package-version '(lsp-mode . "8.0.1"))

(add-to-list 'auto-mode-alist '("^yang\\.settings$" . jsonc-mode))

(defcustom lsp-yang-yls-settings-schema-url
(format "https://raw.githubusercontent.com/TypeFox/yang-lsp/v%s/schema/yang-lsp-settings-schema.json"
lsp-yang-yls-version)
"URL for yang-lsp server settings schema"
:type 'string
:group 'lsp-yang
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-yang-yls-executable "yang-language-server"
"The yang-lsp server executable to use.
Leave as just the executable name to use the default behavior of finding the
executable with variable `exec-path'."
:group 'lsp-yang
:type 'string)

(defcustom lsp-yang-yls-download-url
(format "https://github.com/TypeFox/yang-lsp/releases/download/v%s/yang-language-server_%s.zip"
lsp-yang-yls-version
lsp-yang-yls-version)
"Automatic download url for yang-lsp server"
:type 'string
:group 'lsp-yang
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-yang-yls-store-path
(f-join lsp-server-install-dir "yang-lsp" "yang-lsp")
"The path to the file in which `yang-language-server' will be stored."
:type 'file
:group 'lsp-yang
:package-version '(lsp-mode . "8.0.1"))

(defcustom lsp-yang-yls-binary-path
(f-join lsp-server-install-dir (format "yang-lsp/yang-language-server-%s/bin"
lsp-yang-yls-version)
(pcase system-type
('windows-nt "yang-language-server.bat")
(_ "yang-language-server")))
"The path to `yang-language-server' binary."
:type 'file
:group 'lsp-yang
:package-version '(lsp-mode . "8.0.1"))

(defun lsp-yang--stored-yls-executable ()
"Return the stored yang-lsp server executable."
(executable-find lsp-yang-yls-binary-path))

(lsp-dependency
'yang-lsp
`(:download :url lsp-yang-yls-download-url
:decompress :zip
:store-path lsp-yang-yls-store-path
:binary-path lsp-yang-yls-binary-path
:set-exectutable? t))

(lsp-register-client
(make-lsp-client
:new-connection (lsp-stdio-connection
(lambda () (or (executable-find lsp-yang-yls-executable)
(lsp-yang--stored-yls-executable)))
(lambda () (or (executable-find lsp-yang-yls-executable)
(file-executable-p (lsp-yang--stored-yls-executable)))))
:major-modes '(yang-mode)
:language-id "YANG"
:priority -1
:server-id 'yls
:download-server-fn (lambda (_client callback error-callback _update?)
(lsp-package-ensure 'yang-lsp callback error-callback))))

(lsp-consistency-check lsp-yang)

(provide 'lsp-yang)
;;; lsp-yang.el ends here
8 changes: 8 additions & 0 deletions docs/lsp-clients.json
Original file line number Diff line number Diff line change
Expand Up @@ -1203,6 +1203,14 @@
"lsp-install-server": "yamlls",
"debugger": "Not available"
},
{
"name": "yang",
"full-name": "YANG",
"server-name": "yang-lsp",
"server-url": "https://github.com/TypeFox/yang-lsp",
"installation-url": "https://github.com/TypeFox/yang-lsp/releases",
"debugger": "Not available"
},
{
"name": "zig",
"full-name": "Zig",
Expand Down
49 changes: 49 additions & 0 deletions docs/manual-language-docs/lsp-yang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
author: esmasth
root_file: docs/manual-language-docs/lsp-yang.md
---
# YANG (yang-lsp)

`lsp-mode` provides YANG language support via the [TypeFox/yang-lsp][1] Server.
The server identifier is `yls` as an abbreviation of the released binary called
`yang-language-server`.

## Configuration

Add following configuration in `.emacs` or `init.el` to hook lsp on YANG files,
since [`yang-mode`][2] is the supported major mode.

```lisp
(add-hook 'yang-mode-hook 'lsp)
```

It recommended to add following configuration for the `yang.settings` file,
which resides at the user/project/workspace root, to be validated via
[`lsp-json`][5]. This may be automated by `lsp-yang` in later stages.

```lisp
(setq lsp-json-schemas
`[(:fileMatch ["yang.settings"] :url lsp-yang-yls-settings-schema-url)])
```

To automatically trigger the [`lsp-json`][5] based validation, following
configuration is recommended.

```lisp
(add-hook 'jsonc-mode-hook 'lsp)
```

## Known Issues

* Files in the project need to be opened in buffer to be known by LSP server
* `yang.settings` is not associated with its [JSON schema][3]
[`yang-lsp-settings-schema.json`][4] yet
* yang-lsp settings file `yang.settings` is not respected
* `lsp-format-buffer` does not follow `yang-mode` or `yang.settings`
* Snippets have a bad format with extraneous characters

[1]: https://github.com/TypeFox/yang-lsp
[2]: https://github.com/mbj4668/yang-mode
[3]: https://json-schema.org/
[4]: https://raw.githubusercontent.com/TypeFox/yang-lsp/v0.7.6/schema/yang-lsp-settings-schema.json
[5]: https://emacs-lsp.github.io/lsp-mode/page/lsp-json/
43 changes: 24 additions & 19 deletions lsp-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -174,23 +174,25 @@ As defined by the Language Server Protocol 3.16."
:package-version '(lsp-mode . "6.1"))

(defcustom lsp-client-packages
'( ccls lsp-actionscript lsp-ada lsp-angular lsp-ansible lsp-autotools lsp-awk
lsp-asm lsp-astro lsp-bash lsp-beancount lsp-bufls lsp-clangd lsp-clojure
lsp-cmake lsp-cobol lsp-credo lsp-crystal lsp-csharp lsp-css lsp-cucumber
lsp-cypher lsp-d lsp-dart lsp-dhall lsp-docker lsp-dockerfile lsp-elm lsp-elixir
lsp-emmet lsp-erlang lsp-eslint lsp-fortran lsp-fsharp lsp-gdscript lsp-go
lsp-golangci-lint lsp-gleam lsp-glsl lsp-graphql lsp-hack lsp-grammarly
lsp-groovy lsp-haskell lsp-haxe lsp-idris lsp-java lsp-javascript lsp-json
lsp-kotlin lsp-latex lsp-lisp lsp-ltex lsp-lua lsp-markdown lsp-marksman lsp-mdx
lsp-mint lsp-move lsp-nginx lsp-nim lsp-nix lsp-magik lsp-mojo lsp-metals
lsp-mssql lsp-nushell lsp-ocaml lsp-openscad lsp-pascal lsp-perl lsp-perlnavigator
lsp-pls lsp-php lsp-pwsh lsp-pyls lsp-pylsp lsp-pyright lsp-python-ms
lsp-purescript lsp-qml lsp-r lsp-racket lsp-remark lsp-ruff-lsp lsp-rf lsp-rubocop
lsp-rust lsp-semgrep lsp-shader lsp-solargraph lsp-sorbet lsp-sourcekit
lsp-sonarlint lsp-tailwindcss lsp-tex lsp-terraform lsp-toml lsp-ttcn3
lsp-typeprof lsp-v lsp-vala lsp-verilog lsp-vetur lsp-volar lsp-vhdl
lsp-vimscript lsp-wgsl lsp-xml lsp-yaml lsp-ruby-lsp lsp-ruby-syntax-tree
lsp-solidity lsp-sqls lsp-svelte lsp-steep lsp-tilt lsp-trunk lsp-zig lsp-jq)
'( ccls lsp-actionscript lsp-ada lsp-angular lsp-ansible lsp-asm lsp-astro
lsp-autotools lsp-awk lsp-bash lsp-beancount lsp-bufls lsp-clangd
lsp-clojure lsp-cmake lsp-cobol lsp-credo lsp-crystal lsp-csharp lsp-css
lsp-cucumber lsp-cypher lsp-d lsp-dart lsp-dhall lsp-docker lsp-dockerfile
lsp-elixir lsp-elm lsp-emmet lsp-erlang lsp-eslint lsp-fortran lsp-fsharp
lsp-gdscript lsp-gleam lsp-glsl lsp-go lsp-golangci-lint lsp-grammarly
lsp-graphql lsp-groovy lsp-hack lsp-haskell lsp-haxe lsp-idris lsp-java
lsp-javascript lsp-jq lsp-json lsp-kotlin lsp-latex lsp-lisp lsp-ltex
lsp-lua lsp-magik lsp-markdown lsp-marksman lsp-mdx lsp-metals lsp-mint
lsp-mojo lsp-move lsp-mssql lsp-nginx lsp-nim lsp-nix lsp-nushell lsp-ocaml
lsp-openscad lsp-pascal lsp-perl lsp-perlnavigator lsp-php lsp-pls
lsp-purescript lsp-pwsh lsp-pyls lsp-pylsp lsp-pyright lsp-python-ms
lsp-qml lsp-r lsp-racket lsp-remark lsp-rf lsp-rubocop lsp-ruby-lsp
lsp-ruby-syntax-tree lsp-ruff-lsp lsp-rust lsp-semgrep lsp-shader
lsp-solargraph lsp-solidity lsp-sonarlint lsp-sorbet lsp-sourcekit lsp-sqls
lsp-steep lsp-svelte lsp-tailwindcss lsp-terraform lsp-tex lsp-tilt
lsp-toml lsp-trunk lsp-ttcn3 lsp-typeprof lsp-v lsp-vala lsp-verilog
lsp-vetur lsp-vhdl lsp-vimscript lsp-volar lsp-wgsl lsp-xml lsp-yaml
lsp-yang lsp-zig)
"List of the clients to be automatically required."
:group 'lsp-mode
:type '(repeat symbol))
Expand Down Expand Up @@ -795,7 +797,8 @@ Changes take effect only when a new session is started."
("\\ya?ml$" . "yaml")
("^PKGBUILD$" . "shellscript")
("^go\\.mod\\'" . "go.mod")
("^settings.json$" . "jsonc")
("^settings\\.json$" . "jsonc")
("^yang\\.settings$" . "jsonc")
(ada-mode . "ada")
(ada-ts-mode . "ada")
(awk-mode . "awk")
Expand Down Expand Up @@ -958,7 +961,8 @@ Changes take effect only when a new session is started."
(jq-ts-mode . "jq")
(protobuf-mode . "protobuf")
(nushell-mode . "nushell")
(nushell-ts-mode . "nushell"))
(nushell-ts-mode . "nushell")
(yang-mode . "yang"))
"Language id configuration.")

(defvar lsp--last-active-workspaces nil
Expand Down Expand Up @@ -6036,6 +6040,7 @@ Request codeAction/resolve for more info if server supports."
(typescript-mode . typescript-indent-level) ; Typescript
(typescript-ts-mode . typescript-ts-mode-indent-offset) ; Typescript (tree-sitter, Emacs29)
(yaml-mode . yaml-indent-offset) ; YAML
(yang-mode . c-basic-offset) ; YANG (yang-mode)

(default . standard-indent)) ; default fallback
"A mapping from `major-mode' to its indent variable.")
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ nav:
- wgsl: page/lsp-wgsl.md
- XML: page/lsp-xml.md
- YAML: page/lsp-yaml.md
- YANG: page/lsp-yang.md
- Zig: page/lsp-zig.md
- Debugging:
- https://emacs-lsp.github.io/dap-mode
Expand Down

0 comments on commit 4e37c36

Please sign in to comment.