2020-05-02 17:43:26 +01:00
const std = @import ( " std " ) ;
2020-04-24 23:19:03 +01:00
const builtin = @import ( " builtin " ) ;
2020-05-25 22:12:08 +01:00
// const build_options = @import("build_options")
const zinput = @import ( " src/zinput/src/main.zig " ) ;
var builder : * std . build . Builder = undefined ;
pub fn config ( step : * std . build . Step ) anyerror ! void {
@setEvalBranchQuota ( 2500 ) ;
std . debug . warn ( " Welcome to the ZLS configuration wizard! (insert mage emoji here) \n " , . { } ) ;
2020-11-15 22:07:35 +00:00
var zig_exe_path : ? [ ] const u8 = null ;
std . debug . print ( " Looking for 'zig' in PATH... \n " , . { } ) ;
find_zig : {
const allocator = builder . allocator ;
const env_path = std . process . getEnvVarOwned ( allocator , " PATH " ) catch | err | switch ( err ) {
error . EnvironmentVariableNotFound = > {
break : find_zig ;
} ,
else = > return err ,
} ;
defer allocator . free ( env_path ) ;
const exe_extension = @as ( std . zig . CrossTarget , . { } ) . exeFileExt ( ) ;
2021-01-04 17:51:26 +00:00
const zig_exe = try std . fmt . allocPrint ( allocator , " zig{s} " , . { exe_extension } ) ;
2020-11-15 22:07:35 +00:00
defer allocator . free ( zig_exe ) ;
var it = std . mem . tokenize ( env_path , & [ _ ] u8 { std . fs . path . delimiter } ) ;
while ( it . next ( ) ) | path | {
2021-03-14 04:06:41 +00:00
const resolved_path = try std . fs . path . resolve ( allocator , & [ _ ] [ ] const u8 { path } ) ;
defer allocator . free ( resolved_path ) ;
2020-11-15 22:07:35 +00:00
const full_path = try std . fs . path . join ( allocator , & [ _ ] [ ] const u8 {
2021-03-14 04:06:41 +00:00
resolved_path ,
2020-11-15 22:07:35 +00:00
zig_exe ,
2020-11-24 04:20:22 +00:00
} ) ;
2020-11-15 22:07:35 +00:00
defer allocator . free ( full_path ) ;
2020-11-24 04:20:22 +00:00
2020-12-20 02:24:42 +00:00
if ( ! std . fs . path . isAbsolute ( full_path ) ) continue ;
2020-11-24 04:14:50 +00:00
// Skip folders named zig
const file = std . fs . openFileAbsolute ( full_path , . { } ) catch continue ;
const stat = file . stat ( ) catch continue ;
2020-11-24 04:20:22 +00:00
const is_dir = stat . kind = = . Directory ;
if ( is_dir ) continue ;
2020-11-15 22:07:35 +00:00
var buf : [ std . fs . MAX_PATH_BYTES ] u8 = undefined ;
2020-11-24 04:20:22 +00:00
zig_exe_path = try std . mem . dupe ( allocator , u8 , std . os . realpath ( full_path , & buf ) catch continue ) ;
2020-11-15 22:07:35 +00:00
break : find_zig ;
}
}
if ( zig_exe_path = = null ) {
std . debug . print ( " Could not find 'zig' in PATH \n " , . { } ) ;
zig_exe_path = try zinput . askString ( builder . allocator , " What is the path to the 'zig' executable you would like to use? " , 512 ) ;
} else {
2021-01-04 17:51:26 +00:00
std . debug . print ( " Found zig executable '{s}' \n " , . { zig_exe_path . ? } ) ;
2020-11-15 22:07:35 +00:00
}
2021-03-26 09:20:20 +00:00
const editor = try zinput . askSelectOne ( " Which code editor do you use? " , enum { VSCode , Sublime , Kate , Neovim , Vim8 , Emacs , Doom , Other } ) ;
2020-05-25 22:12:08 +01:00
const snippets = try zinput . askBool ( " Do you want to enable snippets? " ) ;
const style = try zinput . askBool ( " Do you want to enable style warnings? " ) ;
2020-07-04 16:04:36 +01:00
const semantic_tokens = try zinput . askBool ( " Do you want to enable semantic highlighting? " ) ;
2021-03-26 09:20:20 +00:00
const operator_completions = try zinput . askBool ( " Do you want to enable .* and .? completions? " ) ;
const include_at_in_builtins = switch ( editor ) {
. Sublime = >
true ,
. VSCode ,
. Kate ,
. Neovim ,
. Vim8 ,
. Emacs ,
. Doom = >
false ,
else = >
try zinput . askBool ( " Should the @ sign be included in completions of builtin functions? \n Change this later if `@inc` completes to `include` or `@@include` " )
} ;
2021-03-27 19:37:51 +00:00
const max_detail_length : usize = switch ( editor ) {
. Sublime = >
256 ,
else = >
1024 * 1024
} ;
2021-03-26 09:20:20 +00:00
2020-05-25 22:12:08 +01:00
var dir = try std . fs . cwd ( ) . openDir ( builder . exe_dir , . { } ) ;
defer dir . close ( ) ;
2020-05-28 02:14:27 +01:00
var file = try dir . createFile ( " zls.json " , . { } ) ;
2020-05-25 22:12:08 +01:00
defer file . close ( ) ;
2021-01-10 15:57:24 +00:00
const out = file . writer ( ) ;
2020-05-25 22:12:08 +01:00
std . debug . warn ( " Writing to config... \n " , . { } ) ;
2020-05-27 08:48:22 +01:00
const content = std . json . stringify ( . {
2020-11-15 22:07:35 +00:00
. zig_exe_path = zig_exe_path ,
2020-05-25 22:12:08 +01:00
. enable_snippets = snippets ,
2020-05-27 08:48:22 +01:00
. warn_style = style ,
2020-07-04 16:04:36 +01:00
. enable_semantic_tokens = semantic_tokens ,
2020-11-15 22:07:35 +00:00
. operator_completions = operator_completions ,
2021-03-26 09:20:20 +00:00
. include_at_in_builtins = include_at_in_builtins ,
2021-03-27 19:37:51 +00:00
. max_detail_length = max_detail_length ,
2020-05-25 22:12:08 +01:00
} , std . json . StringifyOptions { } , out ) ;
std . debug . warn ( " Successfully saved configuration options! \n " , . { } ) ;
std . debug . warn ( " \n " , . { } ) ;
switch ( editor ) {
. VSCode = > {
std . debug . warn (
\\To use ZLS in Visual Studio Code, install the 'ZLS for VSCode' extension.
\\Then, open VSCode's 'settings.json' file, and add `"zigLanguageClient.path": "[command_or_path_to_zls]"`.
, . { } ) ;
} ,
. Sublime = > {
std . debug . warn (
\\To use ZLS in Sublime, install the `LSP` package from `https://github.com/sublimelsp/LSP/releases` or via Package Control.
\\Then, add the following snippet to `LSP`'s user settings:
\\
\\{{
\\ "clients": {{
\\ "zig": {{
\\ "command": ["zls"],
\\ "enabled": true,
\\ "languageId": "zig",
2020-05-26 11:06:13 +01:00
\\ "scopes": ["source.zig"],
2020-05-25 22:12:08 +01:00
\\ "syntaxes": ["Packages/Zig/Syntaxes/Zig.tmLanguage"]
\\ }}
\\ }}
\\}}
, . { } ) ;
} ,
2020-05-27 08:48:22 +01:00
. Kate = > {
std . debug . warn (
\\To use ZLS in Kate, enable `LSP client` plugin in Kate settings.
\\Then, add the following snippet to `LSP client's` user settings:
\\(or paste it in `LSP client's` GUI settings)
2020-06-08 23:18:12 +01:00
\\
2020-05-27 08:48:22 +01:00
\\{{
\\ "servers": {{
\\ "zig": {{
\\ "command": ["zls"],
\\ "url": "https://github.com/zigtools/zls",
\\ "highlightingModeRegex": "^Zig$"
\\ }}
\\ }}
\\}}
, . { } ) ;
} ,
2020-05-28 17:55:16 +01:00
. Neovim , . Vim8 = > {
std . debug . warn (
\\To use ZLS in Neovim/Vim8, we recommend using CoC engine. You can get it from 'https://github.com/neoclide/coc.nvim'.
\\Then, simply issue cmd from Neovim/Vim8 `:CocConfig`, and add this to your CoC config:
2020-06-08 23:18:12 +01:00
\\
2020-05-28 17:55:16 +01:00
\\{{
2020-06-08 23:18:12 +01:00
\\ "languageserver": {{
2020-05-28 17:55:16 +01:00
\\ "zls" : {{
\\ "command": "command_or_path_to_zls",
\\ "filetypes": ["zig"]
\\ }}
\\ }}
\\}}
, . { } ) ;
} ,
2020-06-08 23:18:12 +01:00
. Emacs = > {
std . debug . warn (
\\To use ZLS in Emacs, install lsp-mode (https://github.com/emacs-lsp/lsp-mode) from melpa.
\\Zig mode (https://github.com/ziglang/zig-mode) is also useful!
\\Then, add the following to your emacs config:
\\
2021-03-21 09:28:32 +00:00
\\(require 'lsp-mode)
\\(setq lsp-zig-zls-executable "<path to zls>")
2020-06-08 23:18:12 +01:00
, . { } ) ;
} ,
2021-03-18 10:44:24 +00:00
. Doom = > {
std . debug . warn (
\\To use ZLS in Doom Emacs, enable the lsp module
2021-03-21 09:28:32 +00:00
\\And install the `zig-mode` (https://github.com/ziglang/zig-mode) package by adding `(package! zig-mode)` to your packages.el file.
2021-03-18 10:44:24 +00:00
\\
\\(use-package! zig-mode
2021-03-21 09:28:32 +00:00
\\ :hook ((zig-mode . lsp-deferred))
2021-03-18 10:44:24 +00:00
\\ :custom (zig-format-on-save nil)
2021-03-21 09:28:32 +00:00
\\ :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))))
2021-03-18 10:44:24 +00:00
, . { } ) ;
} ,
2020-05-25 22:12:08 +01:00
. Other = > {
std . debug . warn (
\\We might not *officially* support your editor, but you can definitely still use ZLS!
\\Simply configure your editor for use with language servers and point it to the ZLS executable!
, . { } ) ;
2020-05-27 08:48:22 +01:00
} ,
2020-05-25 22:12:08 +01:00
}
std . debug . warn ( " \n You can find the ZLS executable in the \" zig-cache/bin \" by default. \n NOTE: Make sure that if you move the ZLS executable, you move the `zls.json` config file with it as well! \n \n And finally: Thanks for choosing ZLS! \n \n " , . { } ) ;
}
2020-04-24 23:19:03 +01:00
2020-05-07 16:29:40 +01:00
pub fn build ( b : * std . build . Builder ) ! void {
2020-05-25 22:12:08 +01:00
builder = b ;
2020-04-24 23:19:03 +01:00
// Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options
// for restricting supported target set are available.
const target = b . standardTargetOptions ( . { } ) ;
const mode = b . standardReleaseOptions ( ) ;
const exe = b . addExecutable ( " zls " , " src/main.zig " ) ;
2020-11-08 16:01:07 +00:00
2020-05-07 16:29:40 +01:00
exe . addBuildOption (
[ ] const u8 ,
" data_version " ,
2020-11-15 11:01:33 +00:00
b . option ( [ ] const u8 , " data_version " , " The data version - either 0.7.0 or master. " ) orelse " master " ,
2020-05-07 16:29:40 +01:00
) ;
2020-05-02 17:43:26 +01:00
2020-05-25 01:22:39 +01:00
exe . addPackage ( . { . name = " known-folders " , . path = " src/known-folders/known-folders.zig " } ) ;
2020-04-24 23:19:03 +01:00
exe . setTarget ( target ) ;
exe . setBuildMode ( mode ) ;
exe . install ( ) ;
2020-05-25 01:22:39 +01:00
b . installFile ( " src/special/build_runner.zig " , " bin/build_runner.zig " ) ;
2020-04-24 23:19:03 +01:00
const run_cmd = exe . run ( ) ;
run_cmd . step . dependOn ( b . getInstallStep ( ) ) ;
const run_step = b . step ( " run " , " Run the app " ) ;
run_step . dependOn ( & run_cmd . step ) ;
2020-05-25 22:12:08 +01:00
const configure_step = b . step ( " config " , " Configure zls " ) ;
configure_step . makeFn = config ;
2020-05-27 19:58:35 +01:00
const test_step = b . step ( " test " , " Run all the tests " ) ;
2020-07-03 12:21:32 +01:00
test_step . dependOn ( builder . getInstallStep ( ) ) ;
2020-05-27 19:58:35 +01:00
2021-03-29 13:02:52 +01:00
var unit_tests = b . addTest ( " src/unit_tests.zig " ) ;
2020-05-27 19:58:35 +01:00
unit_tests . setBuildMode ( . Debug ) ;
2021-03-29 13:02:52 +01:00
test_step . dependOn ( & unit_tests . step ) ;
2020-06-30 13:46:43 +01:00
var session_tests = b . addTest ( " tests/sessions.zig " ) ;
session_tests . addPackage ( . { . name = " header " , . path = " src/header.zig " } ) ;
session_tests . setBuildMode ( . Debug ) ;
test_step . dependOn ( & session_tests . step ) ;
2020-04-24 23:19:03 +01:00
}