Update zinput, known-folders and enable global configuration (#277)

This commit is contained in:
Tau 2021-03-31 16:54:27 +02:00 committed by GitHub
parent 5e8e14fc08
commit df22d2490b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 100 deletions

@ -1 +1 @@
Subproject commit e1193f9ef5b3aad7a6071e9f5721934fe04a020e Subproject commit e1794360c0bdd11cc3b7a8b7aaa6cea5a0d61bde

View File

@ -1691,6 +1691,7 @@ pub fn main() anyerror!void {
// Check arguments. // Check arguments.
var args_it = std.process.args(); var args_it = std.process.args();
defer args_it.deinit();
const prog_name = try args_it.next(allocator) orelse unreachable; const prog_name = try args_it.next(allocator) orelse unreachable;
allocator.free(prog_name); allocator.free(prog_name);
@ -1703,14 +1704,12 @@ pub fn main() anyerror!void {
} else if (std.mem.eql(u8, arg, "config")) { } else if (std.mem.eql(u8, arg, "config")) {
keep_running = false; keep_running = false;
try setup.wizard(allocator); try setup.wizard(allocator);
args_it.deinit();
return; return;
} else { } else {
std.debug.print("Unrecognized argument {s}\n", .{arg}); std.debug.print("Unrecognized argument {s}\n", .{arg});
std.os.exit(1); std.os.exit(1);
} }
} }
args_it.deinit();
// Init global vars // Init global vars
const reader = std.io.getStdIn().reader(); const reader = std.io.getStdIn().reader();
@ -1722,22 +1721,21 @@ pub fn main() anyerror!void {
defer std.json.parseFree(Config, config, config_parse_options); defer std.json.parseFree(Config, config, config_parse_options);
config_read: { config_read: {
const res = try known_folders.getPath(allocator, .local_configuration); if (try known_folders.getPath(allocator, .local_configuration)) |path| {
defer allocator.free(path);
if (res) |local_config_path| { if (loadConfig(path)) |conf| {
defer allocator.free(local_config_path);
if (loadConfig(local_config_path)) |conf| {
config = conf; config = conf;
break :config_read; break :config_read;
} }
} }
if (try known_folders.getPath(allocator, .global_configuration)) |path| {
var exe_dir_bytes: [std.fs.MAX_PATH_BYTES]u8 = undefined; defer allocator.free(path);
const exe_dir_path = std.fs.selfExeDirPath(&exe_dir_bytes) catch break :config_read; if (loadConfig(path)) |conf| {
config = conf;
if (loadConfig(exe_dir_path)) |conf| { break :config_read;
config = conf; }
} }
logger.info("No config file zls.json found.", .{});
} }
// Find the zig executable in PATH // Find the zig executable in PATH

View File

@ -2,9 +2,19 @@ const std = @import("std");
const zinput = @import("zinput/src/main.zig"); const zinput = @import("zinput/src/main.zig");
const known_folders = @import("known-folders"); const known_folders = @import("known-folders");
fn print(comptime fmt: []const u8, args: anytype) void {
const stdout = std.io.getStdOut().writer();
stdout.print(fmt, args) catch @panic("Could not write to stdout");
}
fn write(text: []const u8) void {
const stdout = std.io.getStdOut().writer();
stdout.writeAll(text) catch @panic("Could not write to stdout");
}
pub fn wizard(allocator: *std.mem.Allocator) !void { pub fn wizard(allocator: *std.mem.Allocator) !void {
@setEvalBranchQuota(2500); @setEvalBranchQuota(2500);
std.debug.warn( write(
\\Welcome to the ZLS configuration wizard! \\Welcome to the ZLS configuration wizard!
\\ * \\ *
\\ |\ \\ |\
@ -16,15 +26,52 @@ pub fn wizard(allocator: *std.mem.Allocator) !void {
\\ \__-/ / \\ \__-/ /
\\ \\
\\ \\
, .{}); );
var local_path = known_folders.getPath(allocator, .local_configuration) catch null;
var global_path = known_folders.getPath(allocator, .global_configuration) catch null;
defer if (local_path) |d| allocator.free(d);
defer if (global_path) |d| allocator.free(d);
if (global_path == null and local_path == null) {
write("Could not open a global or local config directory.\n");
return;
}
var config_path: []const u8 = undefined;
if (try zinput.askBool("Should this configuration be system-wide?")) {
if (global_path) |p| {
config_path = p;
} else {
write("Could not find a global config directory.\n");
return;
}
} else {
if (local_path) |p| {
config_path = p;
} else {
write("Could not find a local config directory.\n");
return;
}
}
var dir = std.fs.cwd().openDir(config_path, .{}) catch |err| {
print("Could not open {s}: {}.\n", .{config_path, err});
return;
};
defer dir.close();
var file = dir.createFile("zls.json", .{}) catch |err| {
print("Could not create {s}/zls.json: {}.\n", .{config_path, err});
return;
};
defer file.close();
const out = file.writer();
var zig_exe_path = try findZig(allocator); var zig_exe_path = try findZig(allocator);
defer if (zig_exe_path) |p| allocator.free(p); defer if (zig_exe_path) |p| allocator.free(p);
if (zig_exe_path) |path| { if (zig_exe_path) |path| {
std.debug.print("Found zig executable '{s}' in PATH.\n", .{path}); print("Found zig executable '{s}' in PATH.\n", .{path});
} else { } else {
std.debug.print("Could not find 'zig' in PATH\n", .{}); write("Could not find 'zig' in PATH\n");
zig_exe_path = try zinput.askString(allocator, "What is the path to the 'zig' executable you would like to use?", std.fs.MAX_PATH_BYTES); zig_exe_path = try zinput.askString(allocator, "What is the path to the 'zig' executable you would like to use?", std.fs.MAX_PATH_BYTES);
} }
@ -43,53 +90,9 @@ pub fn wizard(allocator: *std.mem.Allocator) !void {
else => 1024 * 1024, else => 1024 * 1024,
}; };
var file: std.fs.File = undefined; std.debug.warn("Writing config to {s}/zls.json ... ", .{config_path});
var dir_path: []const u8 = &.{};
defer allocator.free(dir_path);
try_config_open: { const content = std.json.stringify(.{
if (try known_folders.getPath(allocator, .local_configuration)) |path| local_conf: {
var dir = std.fs.cwd().openDir(path, .{}) catch |err| switch (err) {
error.FileNotFound => {
break :local_conf;
},
else => |e| {
std.debug.print("Failed to open directory `{s}`. Error: {}\n", .{ path, err });
return;
},
};
defer dir.close();
file = dir.createFile("zls.json", .{}) catch |err| {
std.debug.print("Failed to create file `{s}/zls.json`. Error: {}\n", .{ path, err });
return;
};
dir_path = path;
break :try_config_open;
}
if (try known_folders.getPath(allocator, .executable_dir)) |path| exe_dir: {
var dir = std.fs.cwd().openDir(path, .{}) catch |err| switch (err) {
error.FileNotFound => {
break :exe_dir;
},
else => |e| {
std.debug.print("Failed to open directory `{s}`. Error: {}\n", .{ path, err });
return;
},
};
defer dir.close();
file = dir.createFile("zls.json", .{}) catch |err| {
std.debug.print("Failed to create file `{s}/zls.json`. Error: {}\n", .{ path, err });
return;
};
dir_path = path;
break :try_config_open;
}
std.debug.print("Could not open the local configuration directory nor the executable directory, aborting.\n", .{});
return;
}
defer file.close();
std.debug.print("Writing config to {s}/zls.json ... ", .{dir_path});
try std.json.stringify(.{
.zig_exe_path = zig_exe_path, .zig_exe_path = zig_exe_path,
.enable_snippets = snippets, .enable_snippets = snippets,
.warn_style = style, .warn_style = style,
@ -97,84 +100,86 @@ pub fn wizard(allocator: *std.mem.Allocator) !void {
.operator_completions = operator_completions, .operator_completions = operator_completions,
.include_at_in_builtins = include_at_in_builtins, .include_at_in_builtins = include_at_in_builtins,
.max_detail_length = max_detail_length, .max_detail_length = max_detail_length,
}, std.json.StringifyOptions{}, file.writer()); }, std.json.StringifyOptions{}, out);
std.debug.print("successful.\n\n\n\n", .{});
write("successful.\n\n\n\n");
// Keep synced with README.md // Keep synced with README.md
switch (editor) { switch (editor) {
.VSCode => { .VSCode => {
std.debug.warn( write(
\\To use ZLS in Visual Studio Code, install the 'ZLS for VSCode' extension from \\To use ZLS in Visual Studio Code, install the 'ZLS for VSCode' extension from
\\'https://github.com/zigtools/zls-vscode/releases' or via the extensions menu. \\'https://github.com/zigtools/zls-vscode/releases' or via the extensions menu.
\\Then, open VSCode's 'settings.json' file, and add: \\Then, open VSCode's 'settings.json' file, and add:
\\ \\
\\"zigLanguageClient.path": "[command_or_path_to_zls]" \\"zigLanguageClient.path": "[command_or_path_to_zls]"
, .{}); );
}, },
.Sublime => { .Sublime => {
std.debug.warn( write(
\\To use ZLS in Sublime, install the `LSP` package from \\To use ZLS in Sublime, install the `LSP` package from
\\https://github.com/sublimelsp/LSP/releases or via Package Control. \\https://github.com/sublimelsp/LSP/releases or via Package Control.
\\Then, add the following snippet to LSP's user settings: \\Then, add the following snippet to LSP's user settings:
\\ \\
\\{{ \\{
\\ "clients": {{ \\ "clients": {
\\ "zig": {{ \\ "zig": {
\\ "command": ["zls"], \\ "command": ["zls"],
\\ "enabled": true, \\ "enabled": true,
\\ "languageId": "zig", \\ "languageId": "zig",
\\ "scopes": ["source.zig"], \\ "scopes": ["source.zig"],
\\ "syntaxes": ["Packages/Zig/Syntaxes/Zig.tmLanguage"] \\ "syntaxes": ["Packages/Zig/Syntaxes/Zig.tmLanguage"]
\\ }} \\ }
\\ }} \\ }
\\}} \\}
, .{}); );
}, },
.Kate => { .Kate => {
std.debug.warn( write(
\\To use ZLS in Kate, enable `LSP client` plugin in Kate settings. \\To use ZLS in Kate, enable `LSP client` plugin in Kate settings.
\\Then, add the following snippet to `LSP client's` user settings: \\Then, add the following snippet to `LSP client's` user settings:
\\(or paste it in `LSP client's` GUI settings) \\(or paste it in `LSP client's` GUI settings)
\\ \\
\\{{ \\{
\\ "servers": {{ \\ "servers": {
\\ "zig": {{ \\ "zig": {
\\ "command": ["zls"], \\ "command": ["zls"],
\\ "url": "https://github.com/zigtools/zls", \\ "url": "https://github.com/zigtools/zls",
\\ "highlightingModeRegex": "^Zig$" \\ "highlightingModeRegex": "^Zig$"
\\ }} \\ }
\\ }} \\ }
\\}} \\}
, .{}); );
}, },
.Neovim, .Vim8 => { .Neovim, .Vim8 => {
std.debug.warn( write(
\\To use ZLS in Neovim/Vim8, we recommend using CoC engine. \\To use ZLS in Neovim/Vim8, we recommend using CoC engine.
\\You can get it from https://github.com/neoclide/coc.nvim. \\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: \\Then, simply issue cmd from Neovim/Vim8 `:CocConfig`, and add this to your CoC config:
\\ \\
\\{{ \\{
\\ "languageserver": {{ \\ "languageserver": {
\\ "zls" : {{ \\ "zls" : {
\\ "command": "command_or_path_to_zls", \\ "command": "command_or_path_to_zls",
\\ "filetypes": ["zig"] \\ "filetypes": ["zig"]
\\ }} \\ }
\\ }} \\ }
\\}} \\}
, .{}); );
}, },
.Emacs => { .Emacs => {
std.debug.warn( write(
\\To use ZLS in Emacs, install lsp-mode (https://github.com/emacs-lsp/lsp-mode) from melpa. \\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! \\Zig mode (https://github.com/ziglang/zig-mode) is also useful!
\\Then, add the following to your emacs config: \\Then, add the following to your emacs config:
\\ \\
\\(require 'lsp-mode) \\(require 'lsp-mode)
\\(setq lsp-zig-zls-executable "<path to zls>") \\(setq lsp-zig-zls-executable "<path to zls>")
, .{}); );
}, },
.Doom => { .Doom => {
std.debug.warn( write(
\\To use ZLS in Doom Emacs, enable the lsp module \\To use ZLS in Doom Emacs, enable the lsp module
\\And install the `zig-mode` (https://github.com/ziglang/zig-mode) \\And install the `zig-mode` (https://github.com/ziglang/zig-mode)
\\package by adding `(package! zig-mode)` to your packages.el file. \\package by adding `(package! zig-mode)` to your packages.el file.
@ -190,17 +195,17 @@ pub fn wizard(allocator: *std.mem.Allocator) !void {
\\ :new-connection (lsp-stdio-connection "<path to zls>") \\ :new-connection (lsp-stdio-connection "<path to zls>")
\\ :major-modes '(zig-mode) \\ :major-modes '(zig-mode)
\\ :server-id 'zls)))) \\ :server-id 'zls))))
, .{}); );
}, },
.Other => { .Other => {
std.debug.warn( write(
\\We might not *officially* support your editor, but you can definitely still use ZLS! \\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! \\Simply configure your editor for use with language servers and point it to the ZLS executable!
, .{}); );
}, },
} }
std.debug.warn("\n\nThank you for choosing ZLS!\n", .{}); write("\n\nThank you for choosing ZLS!\n");
} }
pub fn findZig(allocator: *std.mem.Allocator) !?[]const u8 { pub fn findZig(allocator: *std.mem.Allocator) !?[]const u8 {

@ -1 +1 @@
Subproject commit eae98b3d70078c45e3f0d7ec81bb2cf3384187ff Subproject commit 95106b1f71430f61973f81f7b255f3b319d88828