1![Zig Language Server](./.github/assets/zls.svg)
2
3[![CI](https://github.com/zigtools/zls/workflows/CI/badge.svg)](https://github.com/zigtools/zls/actions)
4![Zig Tools](./.github/assets/zigtools.svg)
5
6Zig 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).
7
8<!-- omit in toc -->
9## Table Of Contents
10
11- [Installation](#installation)
12  - [Build Options](#build-options)
13  - [Configuration Options](#configuration-options)
14- [Usage](#usage)
15  - [VSCode](#vscode)
16  - [Sublime Text](#sublime-text)
17  - [Kate](#kate)
18  - [Neovim/Vim8](#neovimvim8)
19  - [Emacs](#emacs)
20  - [Doom Emacs](#doom-emacs)
21- [Related Projects](#related-projects)
22- [License](#license)
23
24## Installation
25
26Installation starts with downloading an official release from the [Releases page](https://github.com/zigtools/zls/releases).
27Up 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.
28
29See [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.
30
31### Installing binaries
32
33#### MacOS
34
35You can install the latest release into `$HOME/zls` using e.g.:
36
37```sh
38brew install xz
39mkdir $HOME/zls && cd $HOME/zls && curl -L https://github.com/zigtools/zls/releases/download/0.1.0/x86_64-macos.tar.xz | tar -xJ --strip-components=1 -C .
40```
41
42#### Linux
43
44You can install the latest release into `$HOME/zls` using e.g.:
45
46```
47sudo apt install xz-utils
48mkdir $HOME/zls && cd $HOME/zls && curl -L https://github.com/zigtools/zls/releases/download/0.1.0/x86_64-linux.tar.xz | tar -xJ --strip-components=1 -C .
49```
50
51### From Source
52
53Building `zls` is very easy. You will need [a build of Zig master](https://ziglang.org/download/) to build zls.
54
55```bash
56git clone --recurse-submodules https://github.com/zigtools/zls
57cd zls
58zig build -Drelease-safe
59./zig-out/bin/zls config # Configure ZLS
60```
61
62*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).*
63
64#### Build Options
65
66<!-- When updating this table, be sure to copy changes to the Wiki page about building from source. -->
67<!-- If this table grows too large, then delete this one and move it all over to the Wiki page about building from source. -->
68| Option | Type | Default Value | What it Does |
69| --- | --- | --- | --- |
70| `-Ddata_version` | `string` (master, 0.7.0 or 0.7.1) | master | The data file version. This selects the files in the `src/data` folder that correspond to the Zig version being served.|
71
72#### Updating Data Files
73
74There is a `generate-data.py` in the `src/data` folder, run this file to update data files.
75It 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.
76
77There 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.
78
79### Configuration Options
80
81You can configure zls by running `zls config` or manually creating your own `zls.json` configuration file.
82zls will look for a zls.json configuration file in multiple locations with the following priority:
83- 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))
84- 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))
85
86The following options are currently available.
87
88| Option | Type | Default value | What it Does |
89| --- | --- | --- | --- |
90| `enable_snippets` | `bool` | `false` | Enables snippet completions when the client also supports them. |
91| `zig_lib_path` | `?[]const u8` | `null` | zig library path, e.g. `/path/to/zig/lib/zig`, used to analyze std library imports. |
92| `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. |
93| `warn_style` | `bool` | `false` | Enables warnings for style *guideline* mismatches |
94| `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` |
95| `build_runner_cache_path` | `?[]const u8` | `null` | Path to a directroy that will be used as zig's cache when running `zig run build_runner.zig ...`. `null` is equivalent to `${KnownFloders.Cache}/zls` |
96| `enable_semantic_tokens` | `bool` | `true` | Enables semantic token support when the client also supports it. |
97| `operator_completions` | `bool` | `true` | Enables `*` and `?` operators in completion lists. |
98| `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.
99
100## Features
101
102`zls` supports most language features, including simple type function support, usingnamespace, payload capture type resolution, custom packages and others.
103Notable language features that are not currently implemented include `@cImport` as well as most forms of compile time evaluation.
104
105The following LSP features are supported:
106- Completions
107- Hover
108- Goto definition/declaration
109- Document symbols
110- Find references
111- Rename symbol
112- Formatting using `zig fmt`
113- Semantic token highlighting (LSP 3.16 proposed feature, implemented by a few clients including VSCode, kak and emacs lsp-mode)
114
115You can install `zls` using the instuctions for your text editor below:
116
117### VSCode
118
119Install the `zls-vscode` extension from [here](https://github.com/zigtools/zls-vscode/releases) and provide a path to the build `zls` executable.
120
121### Sublime Text
122
123- Install the `LSP` package from [here](https://github.com/sublimelsp/LSP/releases) or via Package Control.
124- Add this snippet to `LSP's` user settings:
125
126#### For Sublime Text 3:
127
128```json
129{
130    "clients": {
131        "zig": {
132            "command": ["zls"],
133            "enabled": true,
134            "languageId": "zig",
135            "scopes": ["source.zig"],
136            "syntaxes": ["Packages/Zig Language/Syntaxes/Zig.tmLanguage"]
137        }
138    }
139}
140```
141
142#### For Sublime Text 4:
143
144```json
145{
146    "clients": {
147        "zig": {
148            "command": ["zls"],
149            "enabled": true,
150            "selector": "source.zig"
151        }
152    }
153}
154```
155
156### Kate
157
158- Enable `LSP client` plugin in Kate settings.
159- Add this snippet to `LSP client's` user settings (e.g. /$HOME/.config/kate/lspclient)
160  (or paste it in `LSP client's` GUI settings)
161
162```json
163{
164    "servers": {
165        "zig": {
166            "command": ["zls"],
167            "url": "https://github.com/zigtools/zls",
168            "highlightingModeRegex": "^Zig$"
169        }
170    }
171}
172```
173
174### Neovim/Vim8
175#### CoC
176
177- Install the CoC engine from [here](https://github.com/neoclide/coc.nvim).
178- Issue `:CocConfig` from within your Vim editor, and the following snippet:
179
180```json
181{
182   "languageserver": {
183       "zls" : {
184           "command": "command_or_path_to_zls",
185           "filetypes": ["zig"]
186       }
187   }
188}
189```
190
191#### YouCompleteMe
192- Install YouCompleteMeFrom [here](https://github.com/ycm-core/YouCompleteMe.git).
193- Add these lines to your vimrc:
194
195```vim
196"ensure zig is a recognized filetype
197autocmd BufNewFile,BufRead *.zig set filetype=zig
198
199let g:ycm_language_server =
200  \ [
201  \{
202  \     'name': 'zls',
203  \     'filetypes': [ 'zig' ],
204  \     'cmdline': [ '/path/to/zls_executable' ]
205  \    }
206  \ ]
207```
208
209#### nvim-lspconfig
210
211Requires Nvim 0.5 (HEAD)!
212
213- Install nvim-lspconfig from [here](https://github.com/neovim/nvim-lspconfig).
214- Install zig.vim from [here](https://github.com/ziglang/zig.vim).
215
216nvim-lspconfig already ships a configuration for zls. A simple `init.vim` might look like this:
217```vim
218call plug#begin('~/.config/nvim/plugged')
219Plug 'neovim/nvim-lspconfig'
220Plug 'nvim-lua/completion-nvim'
221Plug 'ziglang/zig.vim'
222call plug#end()
223
224:lua << EOF
225    local lspconfig = require('lspconfig')
226
227    local on_attach = function(_, bufnr)
228        vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')
229        require('completion').on_attach()
230    end
231
232    local servers = {'zls'}
233    for _, lsp in ipairs(servers) do
234        lspconfig[lsp].setup {
235            on_attach = on_attach,
236        }
237    end
238EOF
239
240" Set completeopt to have a better completion experience
241set completeopt=menuone,noinsert,noselect
242
243" Enable completions as you type
244let g:completion_enable_auto_popup = 1
245```
246
247#### LanguageClient-neovim
248
249- Install the LanguageClient-neovim from [here](https://github.com/autozimu/LanguageClient-neovim)
250- Edit your neovim configuration and add `zls` for zig filetypes:
251
252```vim
253let g:LanguageClient_serverCommands = {
254       \ 'zig': ['~/code/zls/zig-out/bin/zls'],
255       \ }
256```
257
258### Emacs
259
260- Install [lsp-mode](https://github.com/emacs-lsp/lsp-mode) from melpa
261- [zig mode](https://github.com/ziglang/zig-mode) is also useful
262
263```elisp
264;; Setup lsp-mode as desired.
265;; See https://emacs-lsp.github.io/lsp-mode/page/installation/ for more information.
266(require 'lsp-mode)
267
268;; Either place zls in your PATH or add the following:
269(setq lsp-zig-zls-executable "<path to zls>")
270```
271
272### Doom Emacs
273
274- Enable the `lsp` module
275- Install the [zig-mode](https://github.com/ziglang/zig-mode) package (add `(package! zig-mode)` to your `packages.el` file
276- Add the following to your `config.el`:
277
278```elisp
279(use-package! zig-mode
280  :hook ((zig-mode . lsp-deferred))
281  :custom (zig-format-on-save nil)
282  :config
283  (after! lsp-mode
284    (add-to-list 'lsp-language-id-configuration '(zig-mode . "zig"))
285    (lsp-register-client
286      (make-lsp-client
287        :new-connection (lsp-stdio-connection "<path to zls>")
288        :major-modes '(zig-mode)
289        :server-id 'zls))))
290```
291
292## Related Projects
293
294- [`sublime-zig-language` by @prime31](https://github.com/prime31/sublime-zig-language)
295  - Supports basic language features
296  - Uses data provided by `src/data` to perform builtin autocompletion
297- [`zig-lsp` by @xackus](https://github.com/xackus/zig-lsp)
298  - Inspiration for `zls`
299- [`known-folders` by @ziglibs](https://github.com/ziglibs/known-folders)
300  - Provides API to access known folders on Linux, Windows and Mac OS
301
302## License
303
304MIT
305