![Zig Language Server](./.github/assets/zls.svg) [![CI](https://github.com/zigtools/zls/workflows/CI/badge.svg)](https://github.com/zigtools/zls/actions) ![Zig Tools](./.github/assets/zigtools.svg) **Need support? Wanna help out? Join our [Discord server](https://discord.gg/5m5U3qpUhk)!** Zig Language Server, or `zls`, is a language server for Zig. The Zig wiki states that "The Zig community is decentralized" and "There is no concept of 'official' or 'unofficial'", so instead of calling `zls` unofficial, and I'm going to call it a cool option, one of [many](https://github.com/search?q=zig+language+server). ## Table Of Contents - [Installation](#installation) - [Installing binaries](#installing-binaries) - [MacOS](#macos) - [Linux](#linux) - [From Source](#from-source) - [Build Options](#build-options) - [Updating Data Files](#updating-data-files) - [Configuration Options](#configuration-options) - [Per-build Configuration Options](#per-build-configuration-options) - [`BuildOption`](#buildoption) - [Features](#features) - [VS Code](#vs-code) - [Sublime Text](#sublime-text) - [Sublime Text 3](#sublime-text-3) - [Sublime Text 4](#sublime-text-4) - [Kate](#kate) - [Neovim/Vim8](#neovimvim8) - [CoC](#coc) - [YouCompleteMe](#youcompleteme) - [nvim-lspconfig](#nvim-lspconfig) - [LanguageClient-neovim](#languageclient-neovim) - [Emacs](#emacs) - [Doom Emacs](#doom-emacs) - [Spacemacs](#spacemacs) - [Helix](#helix) - [Related Projects](#related-projects) - [License](#license) ## Installation Installation starts with downloading an official release from the [Releases page](https://github.com/zigtools/zls/releases). Up to date builds from master branch are also available in the [latest successful CI run](https://github.com/zigtools/zls/actions), contained in the `builds` artifact. See [Downloading and Building ZLS](https://github.com/zigtools/zls/wiki/Downloading-and-Building-ZLS) on the Wiki, or the page about [using ZLS with Visual Studio Code](https://github.com/zigtools/zls/wiki/Installing-for-Visual-Studio-Code) for a guide to help get `zls` running in your editor. ### Installing binaries #### MacOS You can install the latest release into `$HOME/zls` using e.g.: ```sh brew install xz mkdir $HOME/zls && cd $HOME/zls && curl -L https://github.com/zigtools/zls/releases/download/0.9.0/x86_64-macos.tar.xz | tar -xJ --strip-components=1 -C . && chmod +x zls ``` #### Linux You can install the latest release into `$HOME/zls` using e.g.: ```bash sudo apt install xz-utils mkdir $HOME/zls && cd $HOME/zls && curl -L https://github.com/zigtools/zls/releases/download/0.9.0/x86_64-linux.tar.xz | tar -xJ --strip-components=1 -C . ``` ### From Source Building `zls` is very easy. You will need [a build of Zig master](https://ziglang.org/download/) to build zls. ```bash git clone --recurse-submodules https://github.com/zigtools/zls cd zls zig build -Drelease-safe ./zig-out/bin/zls --config # Configure ZLS ``` *For detailed building instructions, see the Wiki page about [Cloning With Git](https://github.com/zigtools/zls/wiki/Downloading-and-Building-ZLS#cloning-with-git).* #### Build Options | Option | Type | Default Value | What it Does | | --- | --- | --- | --- | | `-Ddata_version` | `string` (like 0.7.1 or 0.9.0) | master | The data file version. This selects the files in the `src/data` folder that correspond to the Zig version being served.| #### Updating Data Files There is a `generate-data.py` in the `src/data` folder, run this file to update data files. It writes to stdout and you can redirect output to a zig file like `master.zig`. By default it generates data file for `master`, but can be configured to generate for a different version by modifying the `zig_version` variable. Files generated by this tool **contains** formatting information. There is also a `generate-data.js` in the `src/data` folder, you'll need to run this inside a Chrome DevTools console and copy the output. Files generated by this tool **does not contain** formatting information. ### Configuration Options You can configure zls by running `zls --config` or manually creating your own `zls.json` configuration file. zls will look for a zls.json configuration file in multiple locations with the following priority: - In the local configuration folder of your OS (as provided by [known-folders](https://github.com/ziglibs/known-folders/blob/master/RESOURCES.md#folder-list)) - In the global configuration folder of your OS (as provided by [known-folders](https://github.com/ziglibs/known-folders/blob/master/RESOURCES.md#folder-list)) The following options are currently available. | Option | Type | Default value | What it Does | | --- | --- | --- | --- | | `enable_snippets` | `bool` | `false` | Enables snippet completions when the client also supports them. | | `enable_ast_check_diagnostics` | `bool` | `true`| Whether to enable ast-check diagnostics | | `enable_autofix` | `bool` | `false`| Whether to automatically fix errors on save. Currently supports adding and removing discards. | | `enable_import_embedfile_argument_completions` | `bool` | `false` | Whether to enable import/embedFile argument completions | | `zig_lib_path` | `?[]const u8` | `null` | zig library path, e.g. `/path/to/zig/lib/zig`, used to analyze std library imports. | | `zig_exe_path` | `?[]const u8` | `null` | zig executable path, e.g. `/path/to/zig/zig`, used to run the custom build runner. If `null`, zig is looked up in `PATH`. Will be used to infer the zig standard library path if none is provided. | | `warn_style` | `bool` | `false` | Enables warnings for style *guideline* mismatches | | `build_runner_path` | `?[]const u8` | `null` | Path to the build_runner.zig file provided by zls. `null` is equivalent to `${executable_directory}/build_runner.zig` | | `global_cache_path` | `?[]const u8` | `null` | Path to a directroy that will be used as zig's cache. `null` is equivalent to `${KnownFloders.Cache}/zls` | | `enable_semantic_tokens` | `bool` | `true` | Enables semantic token support when the client also supports it. | | `enable_inlay_hints` | `bool` | `false` | Enables inlay hint support when the client also supports it. | | `inlay_hints_show_builtin` | `bool` | `true` | Enable inlay hints for builtin functions | | `inlay_hints_exclude_single_argument` | `bool` | `true`| Don't show inlay hints for single argument calls | | `inlay_hints_hide_redundant_param_names` | `bool` | `false`| Hides inlay hints when parameter name matches the identifier (e.g. foo: foo) | | `inlay_hints_hide_redundant_param_names_last_token` | `bool` | `false`| Hides inlay hints when parameter name matches the last token of a parameter node (e.g. foo: bar.foo, foo: &foo) | | `operator_completions` | `bool` | `true` | Enables `*` and `?` operators in completion lists. | |`include_at_in_builtins`|`bool`|`false`| Whether the @ sign should be part of the completion of builtins. |`max_detail_length`|`usize`|`1024 * 1024`| The detail field of completions is truncated to be no longer than this (in bytes). | `skip_std_references` | `bool` | `false` | When true, skips searching for references in std. Improves lookup speed for functions in user's code. Renaming and go-to-definition will continue to work as is. | `highlight_global_var_declarations` | `bool` | `false` | Whether to highlight global var declarations. ### Per-build Configuration Options The following options can be set on a per-project basis by placing `zls.build.json` in the project root directory next to `build.zig`. | Option | Type | Default value | What it Does | | --- | --- | --- | --- | | `relative_builtin_path` | `?[]const u8` | `null` | If present, this path is used to resolve `@import("builtin")` | | `build_options` | `?[]BuildOption` | `null` | If present, this contains a list of user options to pass to the build. This is useful when options are used to conditionally add packages in `build.zig`. | #### `BuildOption` `BuildOption` is defined as follows: ```zig const BuildOption = struct { name: []const u8, value: ?[]const u8 = null, }; ``` When `value` is present, the option will be passed the same as in `zig build -Dname=value`. When `value` is `null`, the option will be passed as a flag instead as in `zig build -Dflag`. ## Features `zls` supports most language features, including simple type function support, using namespace, payload capture type resolution, custom packages, `cImport` and others. Currently there is no support for compile time evaluation. The following LSP features are supported: - Completions - Hover - Goto definition/declaration - Document symbols - Find references - Rename symbol - Formatting using `zig fmt` - Semantic token highlighting (implemented by a few clients including VS Code, kak and emacs lsp-mode) - Inlay hints (implemented by VS Code) You can install `zls` using the instuctions for your text editor below: ### VS Code Install the `zls-vscode` extension from [here](https://github.com/zigtools/zls-vscode/releases) or via the extensions menu. It will install `zls` if it is not found in your `PATH` ### Sublime Text - Install the `LSP` package from [here](https://github.com/sublimelsp/LSP/releases) or via Package Control. - Add this snippet to `LSP's` user settings: #### Sublime Text 3 ```json { "clients": { "zig": { "command": ["zls"], "enabled": true, "languageId": "zig", "scopes": ["source.zig"], "syntaxes": ["Packages/Zig Language/Syntaxes/Zig.tmLanguage"] } } } ``` #### Sublime Text 4 ```json { "clients": { "zig": { "command": ["zls"], "enabled": true, "selector": "source.zig" } } } ``` ### Kate - Install language support for Zig from [here](https://github.com/ziglang/kde-syntax-highlighting) - Enable `LSP client` plugin in Kate settings. - Add this snippet to `LSP client's` user settings (e.g. /$HOME/.config/kate/lspclient) (or paste it in `LSP client's` GUI settings) ```json { "servers": { "zig": { "command": ["zls"], "url": "https://github.com/zigtools/zls", "highlightingModeRegex": "^Zig$" } } } ``` ### Neovim/Vim8 #### CoC - Install the CoC engine from [here](https://github.com/neoclide/coc.nvim). Then choose one of the following two ways 1. Use extension Run `:CocInstall coc-zls` to install [coc-zls](https://github.com/xiyaowong/coc-zls), this extension supports the same functionality as the VS Code extension 2. Manually register ```json { "languageserver": { "zls" : { "command": "command_or_path_to_zls", "filetypes": ["zig"] } } } ``` #### YouCompleteMe - Install YouCompleteMeFrom [here](https://github.com/ycm-core/YouCompleteMe.git). - Add these lines to your vimrc: ```vim "ensure zig is a recognized filetype autocmd BufNewFile,BufRead *.zig set filetype=zig let g:ycm_language_server = \ [ \{ \ 'name': 'zls', \ 'filetypes': [ 'zig' ], \ 'cmdline': [ '/path/to/zls_executable' ] \ } \ ] ``` #### nvim-lspconfig Requires Nvim 0.5 (HEAD)! - Install nvim-lspconfig from [here](https://github.com/neovim/nvim-lspconfig). - Install zig.vim from [here](https://github.com/ziglang/zig.vim). nvim-lspconfig already ships a configuration for zls. A simple `init.vim` might look like this: ```vim call plug#begin('~/.config/nvim/plugged') Plug 'neovim/nvim-lspconfig' Plug 'nvim-lua/completion-nvim' Plug 'ziglang/zig.vim' call plug#end() :lua << EOF local lspconfig = require('lspconfig') local on_attach = function(_, bufnr) vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') require('completion').on_attach() end local servers = {'zls'} for _, lsp in ipairs(servers) do lspconfig[lsp].setup { on_attach = on_attach, } end EOF " Set completeopt to have a better completion experience set completeopt=menuone,noinsert,noselect " Enable completions as you type let g:completion_enable_auto_popup = 1 ``` #### LanguageClient-neovim - Install the LanguageClient-neovim from [here](https://github.com/autozimu/LanguageClient-neovim) - Edit your neovim configuration and add `zls` for zig filetypes: ```vim let g:LanguageClient_serverCommands = { \ 'zig': ['~/code/zls/zig-out/bin/zls'], \ } ``` ### Emacs - Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) from melpa - [zig mode](https://github.com/ziglang/zig-mode) is also useful ```elisp ;; Setup lsp-mode as desired. ;; See https://emacs-lsp.github.io/lsp-mode/page/installation/ for more information. (require 'lsp-mode) ;; Either place zls in your PATH or add the following: (setq lsp-zig-zls-executable "") ``` ### Doom Emacs - Enable the `lsp` module - Install the [zig-mode](https://github.com/ziglang/zig-mode) package (add `(package! zig-mode)` to your `packages.el` file - Add the following to your `config.el`: ```elisp (use-package! zig-mode :hook ((zig-mode . lsp-deferred)) :custom (zig-format-on-save nil) :config (after! lsp-mode (add-to-list 'lsp-language-id-configuration '(zig-mode . "zig")) (lsp-register-client (make-lsp-client :new-connection (lsp-stdio-connection "") :major-modes '(zig-mode) :server-id 'zls)))) ``` ### Spacemacs - Add `lsp` and `zig` to `dotspacemacs-configuration-layers` in your `.spacemacs` file. - If you don't have `zls` in your `PATH`, add the following to `dotspacemacs/user-config` in your `.spacemacs` file: ```elisp (setq lsp-zig-zls-executable "") ``` ### Helix - Just add `zls` to your `PATH`. - run `hx --health` to check if helix found `zls`. ## Related Projects - [`sublime-zig-language` by @prime31](https://github.com/prime31/sublime-zig-language) - Supports basic language features - Uses data provided by `src/data` to perform builtin autocompletion - [`zig-lsp` by @xackus](https://github.com/xackus/zig-lsp) - Inspiration for `zls` - [`known-folders` by @ziglibs](https://github.com/ziglibs/known-folders) - Provides API to access known folders on Linux, Windows and Mac OS ## License MIT