diff --git a/CHANGELOG.org b/CHANGELOG.org index c2ce9f5766e..4c8e425bc82 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -114,6 +114,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. diff --git a/clients/lsp-yang.el b/clients/lsp-yang.el new file mode 100644 index 00000000000..70f8b14f125 --- /dev/null +++ b/clients/lsp-yang.el @@ -0,0 +1,122 @@ +;;; lsp-yang.el --- YANG Client settings -*- lexical-binding: t; -*- + +;; Copyright (C) 2024 Siddharth Sharma + +;; Author: Siddharth Sharma +;; 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 . + +;;; 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 diff --git a/docs/lsp-clients.json b/docs/lsp-clients.json index f5be0b03cb4..691c2b9c4a3 100644 --- a/docs/lsp-clients.json +++ b/docs/lsp-clients.json @@ -1194,6 +1194,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", diff --git a/docs/manual-language-docs/lsp-yang.md b/docs/manual-language-docs/lsp-yang.md new file mode 100644 index 00000000000..fa5b9dc605a --- /dev/null +++ b/docs/manual-language-docs/lsp-yang.md @@ -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/ diff --git a/lsp-mode.el b/lsp-mode.el index 1737d7ff3a9..bd40e86c540 100644 --- a/lsp-mode.el +++ b/lsp-mode.el @@ -174,23 +174,24 @@ 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-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-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)) @@ -795,6 +796,7 @@ Changes take effect only when a new session is started." ("^PKGBUILD$" . "shellscript") ("^go\\.mod\\'" . "go.mod") ("^settings.json$" . "jsonc") + ("^yang\\.settings$" . "jsonc") (ada-mode . "ada") (ada-ts-mode . "ada") (awk-mode . "awk") @@ -956,7 +958,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 @@ -6033,6 +6036,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.") diff --git a/mkdocs.yml b/mkdocs.yml index 11861f1e4a3..3a8d35ddd55 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -175,6 +175,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