Update zinput, known-folders and enable global configuration (#277)
This commit is contained in:
		
							parent
							
								
									5e8e14fc08
								
							
						
					
					
						commit
						df22d2490b
					
				| @ -1 +1 @@ | |||||||
| Subproject commit e1193f9ef5b3aad7a6071e9f5721934fe04a020e | Subproject commit e1794360c0bdd11cc3b7a8b7aaa6cea5a0d61bde | ||||||
							
								
								
									
										24
									
								
								src/main.zig
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								src/main.zig
									
									
									
									
									
								
							| @ -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 | ||||||
|  | |||||||
							
								
								
									
										175
									
								
								src/setup.zig
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								src/setup.zig
									
									
									
									
									
								
							| @ -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 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user