Need support? Wanna help out? Join our Discord server!
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.
Installation starts with downloading an official release from the Releases page.
Up to date builds from master branch are also available in the latest successful CI run, contained in the builds
artifact.
See Downloading and Building ZLS on the Wiki, or the page about using ZLS with Visual Studio Code for a guide to help get zls
running in your editor.
You can install the latest release into $HOME/zls
using e.g.:
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
You can install the latest release into $HOME/zls
using e.g.:
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 .
Building zls
is very easy. You will need a build of Zig master to build zls.
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.
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. |
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.
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)
- In the global configuration folder of your OS (as provided by known-folders)
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. |
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
is defined as follows:
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
.
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:
Install the zls-vscode
extension from here or via the extensions menu.
It will install zls
if it is not found in your PATH
- Install the
LSP
package from here or via Package Control. - Add this snippet to
LSP's
user settings:
{
"clients": {
"zig": {
"command": ["zls"],
"enabled": true,
"languageId": "zig",
"scopes": ["source.zig"],
"syntaxes": ["Packages/Zig Language/Syntaxes/Zig.tmLanguage"]
}
}
}
{
"clients": {
"zig": {
"command": ["zls"],
"enabled": true,
"selector": "source.zig"
}
}
}
- Install language support for Zig from here
- 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 inLSP client's
GUI settings)
{
"servers": {
"zig": {
"command": ["zls"],
"url": "https://github.com/zigtools/zls",
"highlightingModeRegex": "^Zig$"
}
}
}
- Install the CoC engine from here.
Then choose one of the following two ways
-
Use extension
Run
:CocInstall coc-zls
to install coc-zls, this extension supports the same functionality as the VS Code extension -
Manually register
{ "languageserver": { "zls" : { "command": "command_or_path_to_zls", "filetypes": ["zig"] } } }
- Install YouCompleteMeFrom here.
- Add these lines to your vimrc:
"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' ]
\ }
\ ]
Requires Nvim 0.5 (HEAD)!
nvim-lspconfig already ships a configuration for zls. A simple init.vim
might look like this:
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
- Install the LanguageClient-neovim from here
- Edit your neovim configuration and add
zls
for zig filetypes:
let g:LanguageClient_serverCommands = {
\ 'zig': ['~/code/zls/zig-out/bin/zls'],
\ }
;; 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 "<path to zls>")
- Enable the
lsp
module - Install the zig-mode package (add
(package! zig-mode)
to yourpackages.el
file - Add the following to your
config.el
:
(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 "<path to zls>")
:major-modes '(zig-mode)
:server-id 'zls))))
- Add
lsp
andzig
todotspacemacs-configuration-layers
in your.spacemacs
file. - If you don't have
zls
in yourPATH
, add the following todotspacemacs/user-config
in your.spacemacs
file:
(setq lsp-zig-zls-executable "<path to zls>")
- Just add
zls
to yourPATH
. - run
hx --health
to check if helix foundzls
.
sublime-zig-language
by @prime31- Supports basic language features
- Uses data provided by
src/data
to perform builtin autocompletion
zig-lsp
by @xackus- Inspiration for
zls
- Inspiration for
known-folders
by @ziglibs- Provides API to access known folders on Linux, Windows and Mac OS
MIT