From 6c7f180df5935b709fc77e8a91d11f976a478b98 Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Fri, 26 Apr 2024 16:06:58 +0200 Subject: [PATCH] nvim: UI rework --- flake.lock | 6 +- .../common-zig}/src/delimited_writer.zig | 9 ++ lib/common-zig/src/main.zig | 2 + mzte-nv/build.zig | 2 + mzte-nv/conf/lua/pluginconf/p-dressing.fnl | 3 +- mzte-nv/conf/lua/pluginconf/p-line.fnl | 10 ++- mzte-nv/conf/lua/pluginconf/p-lspprogress.fnl | 9 ++ mzte-nv/conf/lua/pluginconf/p-noice.fnl | 25 ------ mzte-nv/conf/lua/plugins.fnl | 2 +- mzte-nv/conf/lua/settings.fnl | 5 +- mzte-nv/src/main.zig | 5 ++ mzte-nv/src/modules/lsp_progress.zig | 88 +++++++++++++++++++ mzte-nv/src/ser.zig | 4 +- nix/cgnix/nvim-plugins.nix | 5 +- scripts/mzteinit/src/env.zig | 2 +- 15 files changed, 134 insertions(+), 43 deletions(-) rename {scripts/mzteinit => lib/common-zig}/src/delimited_writer.zig (77%) create mode 100644 mzte-nv/conf/lua/pluginconf/p-lspprogress.fnl delete mode 100644 mzte-nv/conf/lua/pluginconf/p-noice.fnl create mode 100644 mzte-nv/src/modules/lsp_progress.zig diff --git a/flake.lock b/flake.lock index 0b3c322..0cdcf2c 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1713714899, - "narHash": "sha256-+z/XjO3QJs5rLE5UOf015gdVauVRQd2vZtsFkaXBq2Y=", + "lastModified": 1714076141, + "narHash": "sha256-Drmja/f5MRHZCskS6mvzFqxEaZMeciScCTFxWVLqWEY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6143fc5eeb9c4f00163267708e26191d1e918932", + "rev": "7bb2ccd8cdc44c91edba16c48d2c8f331fb3d856", "type": "github" }, "original": { diff --git a/scripts/mzteinit/src/delimited_writer.zig b/lib/common-zig/src/delimited_writer.zig similarity index 77% rename from scripts/mzteinit/src/delimited_writer.zig rename to lib/common-zig/src/delimited_writer.zig index 1ded1af..01c4a28 100644 --- a/scripts/mzteinit/src/delimited_writer.zig +++ b/lib/common-zig/src/delimited_writer.zig @@ -30,5 +30,14 @@ pub fn DelimitedWriter(comptime Writer: type) type { try self.writer.writeAll(str); } + + pub fn print(self: *Self, comptime fmt: []const u8, args: anytype) !void { + if (self.has_written) { + try self.writer.writeByte(self.delimeter); + } + self.has_written = true; + + try self.writer.print(fmt, args); + } }; } diff --git a/lib/common-zig/src/main.zig b/lib/common-zig/src/main.zig index a871bcb..0727bdf 100644 --- a/lib/common-zig/src/main.zig +++ b/lib/common-zig/src/main.zig @@ -1,5 +1,7 @@ const std = @import("std"); +pub usingnamespace @import("delimited_writer.zig"); + var stderr_isatty: ?bool = null; pub var log_file: ?std.fs.File = null; diff --git a/mzte-nv/build.zig b/mzte-nv/build.zig index 92058e5..c035a63 100644 --- a/mzte-nv/build.zig +++ b/mzte-nv/build.zig @@ -18,6 +18,7 @@ pub fn build(b: *std.Build) !void { }); const znvim_dep = b.dependency("znvim", .{ .target = target, .optimize = mode }); + const common_dep = b.dependency("common", .{}); const cg_opt = try common.confgenGet(struct { term_font: []u8, // TODO: this being non-const is a workaround for an std bug @@ -40,6 +41,7 @@ pub fn build(b: *std.Build) !void { lib.root_module.addImport("opts", opts.createModule()); + lib.root_module.addImport("common", common_dep.module("common")); lib.root_module.addImport("nvim", znvim_dep.module("nvim_c")); lib.root_module.addImport("znvim", znvim_dep.module("znvim")); diff --git a/mzte-nv/conf/lua/pluginconf/p-dressing.fnl b/mzte-nv/conf/lua/pluginconf/p-dressing.fnl index a6c0fa0..bbd6f61 100644 --- a/mzte-nv/conf/lua/pluginconf/p-dressing.fnl +++ b/mzte-nv/conf/lua/pluginconf/p-dressing.fnl @@ -1,4 +1,3 @@ (local dressing (require :dressing)) -(dressing.setup {;; Provided by noice - :input {:enabled false}}) +(dressing.setup {}) diff --git a/mzte-nv/conf/lua/pluginconf/p-line.fnl b/mzte-nv/conf/lua/pluginconf/p-line.fnl index 2cf0134..ee4f195 100644 --- a/mzte-nv/conf/lua/pluginconf/p-line.fnl +++ b/mzte-nv/conf/lua/pluginconf/p-line.fnl @@ -1,5 +1,6 @@ -(local (mztenv lline lightbulb) - (values (require :mzte_nv) (require :lualine) (require :nvim-lightbulb))) +(local (mztenv lline lightbulb lspprogress) + (values (require :mzte_nv) (require :lualine) (require :nvim-lightbulb) + (require :lsp-progress))) (lline.setup {:options {:theme :catppuccin} :sections {:lualine_b [:filename :diff] @@ -7,7 +8,12 @@ :tabline {:lualine_a [{1 :tabs ;; show file name :mode 1}] + :lualine_c [#(or (. (lspprogress.progress) :msg) "")] :lualine_x [:searchcount {1 #(lightbulb.get_status_text) :color {:fg mztenv.reg.catppuccin-palette.teal}}] :lualine_y [:branch]}}) + +(vim.api.nvim_create_autocmd :User + {:pattern :LspProgressStatusUpdated + :callback lline.refresh}) diff --git a/mzte-nv/conf/lua/pluginconf/p-lspprogress.fnl b/mzte-nv/conf/lua/pluginconf/p-lspprogress.fnl new file mode 100644 index 0000000..a5515b1 --- /dev/null +++ b/mzte-nv/conf/lua/pluginconf/p-lspprogress.fnl @@ -0,0 +1,9 @@ +(local lspp (require :lsp-progress)) +(local mztenv (require :mzte_nv)) + +(lspp.setup {:regular_internal_update_time 1000 + :spinner mztenv.reg.spinner + :decay 2000 + :series_format mztenv.lsp_progress.formatSeries + :client_format mztenv.lsp_progress.formatClient + :format #{:msg (table.concat $1 " ")}}) diff --git a/mzte-nv/conf/lua/pluginconf/p-noice.fnl b/mzte-nv/conf/lua/pluginconf/p-noice.fnl deleted file mode 100644 index 4bede93..0000000 --- a/mzte-nv/conf/lua/pluginconf/p-noice.fnl +++ /dev/null @@ -1,25 +0,0 @@ -(local (mztenv noice) (values (require :mzte_nv) (require :noice))) - -(local overrides [:vim.lsp.util.convert_input_to_markdown_lines - :vim.lsp.util.stylize_markdown - :cmp.entry.get_documentation]) - -(fn show-mini? [notif] - (or ;; INFO level - (= notif.level :info) (and notif.opts notif.opts.mzte_nv_mini))) - -(noice.setup {:cmdline {:view :cmdline - :format {:fnl {:pattern "^:%s*Fnl%s+" - :icon "🌜" - :lang :fennel - :title :Fennel}}} - :messages {:enabled false} - :lsp {:override (collect [_ o (ipairs overrides)] (values o true))} - :routes [;; Redirect DAP messages to mini view - {:filter {:event :notify :cond show-mini?} :view :mini}] - :presets {:lsp_doc_border true}}) - -;; Shift-Enter to redirect cmdline -(vim.keymap.set :c : #(noice.redirect (vim.fn.getcmdline)) - {:desc "Redirect Cmdline"}) -(set vim.o.cmdheight 0) diff --git a/mzte-nv/conf/lua/plugins.fnl b/mzte-nv/conf/lua/plugins.fnl index 38859d5..54350d9 100644 --- a/mzte-nv/conf/lua/plugins.fnl +++ b/mzte-nv/conf/lua/plugins.fnl @@ -16,6 +16,7 @@ :luasnip :nullls :catppuccin + :lspprogress :line :treesitter :nvimtree @@ -30,7 +31,6 @@ :dap :harpoon :recorder - :noice :tsn-actions :lightbulb :dressing diff --git a/mzte-nv/conf/lua/settings.fnl b/mzte-nv/conf/lua/settings.fnl index 99a15c0..4df42c9 100644 --- a/mzte-nv/conf/lua/settings.fnl +++ b/mzte-nv/conf/lua/settings.fnl @@ -13,7 +13,4 @@ (let [compile-path mztenv.compile.compilePath make-cmd vim.api.nvim_create_user_command] (make-cmd :CompileConfig - #(compile-path (.. (vim.fn.getenv :HOME) :/.config/nvim)) {:nargs 0}) - (make-cmd :CompilePlugins - #(compile-path (. (require :packer) :config :package_root)) - {:nargs 0})) + #(compile-path (.. (vim.fn.getenv :HOME) :/.config/nvim)) {:nargs 0})) diff --git a/mzte-nv/src/main.zig b/mzte-nv/src/main.zig index 850e1de..c67ce45 100644 --- a/mzte-nv/src/main.zig +++ b/mzte-nv/src/main.zig @@ -16,6 +16,7 @@ const modules = struct { const fennel = @import("modules/fennel.zig"); const jdtls = @import("modules/jdtls.zig"); const lsp = @import("modules/lsp.zig"); + const lsp_progress = @import("modules/lsp_progress.zig"); const telescope = @import("modules/telescope.zig"); const tsn_actions = @import("modules/tsn_actions.zig"); const utils = @import("modules/utils.zig"); @@ -93,6 +94,7 @@ export fn luaopen_mzte_nv(l_: ?*c.lua_State) c_int { .fennel = modules.fennel, .jdtls = modules.jdtls, .lsp = modules.lsp, + .lsp_progress = modules.lsp_progress, .telescope = modules.telescope, .tsn_actions = modules.tsn_actions, .utils = modules.utils, @@ -112,6 +114,9 @@ fn lOnInit(l: *c.lua_State) !c_int { } } + ser.luaPushAny(l, [_][]const u8{ "⬖", "⬘", "⬗", "⬙" }); + c.lua_setfield(l, -2, "spinner"); + std.log.info( "MZTE-NV v{s} Initialized on {s}", .{ version, nvim.longVersion }, diff --git a/mzte-nv/src/modules/lsp_progress.zig b/mzte-nv/src/modules/lsp_progress.zig new file mode 100644 index 0000000..8201d7e --- /dev/null +++ b/mzte-nv/src/modules/lsp_progress.zig @@ -0,0 +1,88 @@ +const std = @import("std"); +const c = ffi.c; +const common = @import("common"); + +const ser = @import("../ser.zig"); +const ffi = @import("../ffi.zig"); + +pub fn luaPush(l: *c.lua_State) void { + ser.luaPushAny(l, .{ + .formatSeries = ffi.luaFunc(lFormatSeries), + .formatClient = ffi.luaFunc(lFormatClient), + }); +} + +fn fmtEscapedFn( + s: []const u8, + comptime _: []const u8, + _: std.fmt.FormatOptions, + writer: anytype, +) !void { + for (s) |ch| { + if (ch == '%') + try writer.writeAll("%%") + else + try writer.writeByte(ch); + } +} + +fn fmtEscaped(s: []const u8) std.fmt.Formatter(fmtEscapedFn) { + return .{ .data = s }; +} + +fn lFormatSeries(l: *c.lua_State) !c_int { + const title = if (c.lua_isnil(l, 1)) null else ffi.luaCheckstring(l, 1); + const message = if (c.lua_isnil(l, 2)) null else ffi.luaCheckstring(l, 2); + const percentage = c.lua_tointeger(l, 3); + const done = c.lua_toboolean(l, 4) != 0; + + var buf = std.BoundedArray(u8, 1024).init(0) catch unreachable; + var del = common.delimitedWriter(buf.writer(), ' '); + + const msg_is_title = title != null and message != null and std.mem.eql(u8, title.?, message.?); + + if (title) |t| + try del.print("%#Title#{s}", .{fmtEscaped(t)}); + + if (message) |m| + if (!msg_is_title) + try del.print("%#ModeMsg#{s}", .{fmtEscaped(m)}); + + if (percentage != 0) + try del.print("%#NONE#(%#Number#{d}%%%#NONE#)", .{percentage}); + + if (done) + try del.push("- %#DiagnosticOk#󰸞"); + + try del.writer.writeAll("%#NONE#"); + + ffi.luaPushString(l, buf.slice()); + return 1; +} + +fn lFormatClient(l: *c.lua_State) !c_int { + const client_name = ffi.luaCheckstring(l, 1); + const spinner = ffi.luaCheckstring(l, 2); + // 3: array of series messages + c.luaL_checktype(l, 3, c.LUA_TTABLE); + + var buf = std.BoundedArray(u8, 1024).init(0) catch unreachable; + var del = common.delimitedWriter(buf.writer(), ' '); + + try del.print("%#Special#[{s}] %#Comment#{s}", .{ client_name, spinner }); + + const nmsgs = c.lua_objlen(l, 3); + for (1..nmsgs + 1) |i| { + _ = c.lua_rawgeti(l, 3, @intCast(i)); + defer c.lua_pop(l, 1); + + const msg = ffi.luaToString(l, -1); + try del.push(msg); + if (i != nmsgs) { + try del.writer.writeAll("%#Operator#,"); + } + } + + ffi.luaPushString(l, buf.slice()); + return 1; +} diff --git a/mzte-nv/src/ser.zig b/mzte-nv/src/ser.zig index d22c81f..f1d7f83 100644 --- a/mzte-nv/src/ser.zig +++ b/mzte-nv/src/ser.zig @@ -27,11 +27,11 @@ pub fn luaPushAny(l: *c.lua_State, x: anytype) void { if (P.child == u8) { ffi.luaPushString(l, x); } else { - c.lua_createtable(l, x.len, 0); + c.lua_createtable(l, @intCast(x.len), 0); for (x, 1..) |element, i| { luaPushAny(l, element); - c.lua_rawseti(l, -2, i); + c.lua_rawseti(l, -2, @intCast(i)); } } }, diff --git a/nix/cgnix/nvim-plugins.nix b/nix/cgnix/nvim-plugins.nix index 623e133..4898f07 100644 --- a/nix/cgnix/nvim-plugins.nix +++ b/nix/cgnix/nvim-plugins.nix @@ -42,16 +42,15 @@ let "50-neogit" = fetchGit { url = "https://git.mzte.de/nvim-plugins/neogit.git?rev=nightly"; }; "50-telescope" = plugin "telescope.nvim"; "50-toggleterm" = plugin "toggleterm.nvim"; - "50-notify" = plugin "nvim-notify"; - "50-dressing" = plugin "dressing.nvim"; # TODO: remove once noice gets support for ui.select + "50-dressing" = plugin "dressing.nvim"; "50-ufo" = plugin "nvim-ufo"; "50-aerial" = plugin "aerial.nvim"; "50-dap" = plugin "nvim-dap"; "50-dapui" = plugin "nvim-dap-ui"; "50-harpoon" = plugin "harpoon"; "50-recorder" = plugin "nvim-recorder"; - "50-noice" = plugin "noice.nvim"; "50-lightbulb" = plugin "nvim-lightbulb"; + "50-lsp-progress" = plugin "lsp-progress.nvim"; # Libraries "10-plenary" = plugin "plenary.nvim"; diff --git a/scripts/mzteinit/src/env.zig b/scripts/mzteinit/src/env.zig index f41dd01..e8a2763 100644 --- a/scripts/mzteinit/src/env.zig +++ b/scripts/mzteinit/src/env.zig @@ -7,7 +7,7 @@ const msg = @import("message.zig").msg; const log = std.log.scoped(.env); -const delimitedWriter = @import("delimited_writer.zig").delimitedWriter; +const delimitedWriter = @import("common").delimitedWriter; /// Initialize the environment. /// Returns true if the environment should be transferred to the system daemon.