From e5b6936d2d684ffce3e616ca95153be9ab5e9f89 Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 6 Jul 2026 10:40:46 -0700 Subject: [PATCH 1/6] refactor(nvim): merge pd buffer deletion into pb and add test coverage Signed-off-by: Kevin Oberlies --- justfile | 6 +- .../nvim/files/lua/plugins/telescope/init.lua | 5 +- .../nvim/files/tests/spec/telescope_spec.lua | 76 +++++++++++++++++++ 3 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 roles/nvim/files/tests/spec/telescope_spec.lua diff --git a/justfile b/justfile index 8bb9895..92e79d9 100644 --- a/justfile +++ b/justfile @@ -22,8 +22,7 @@ test: # Run the code linters: YAML (yamllint) + Ansible (ansible-lint) + Lua # (lua-language-server + selene). Orthogonal to `check` (prek format/syntax # hooks); CI runs both. -lint: lint-yaml lint-ansible - just nvim lint +lint: lint-yaml lint-ansible lint-vim # Lint YAML with yamllint (config: .yamllint). lint-yaml DIR=".": @@ -33,6 +32,9 @@ lint-yaml DIR=".": lint-ansible: uvx ansible-lint +lint-vim: + just nvim lint + # Run a dry run of the Ansible playbook to see what changes would be made dry-run *ARGS: ansible-playbook -i hosts dotfiles.yml -v --check --diff {{ ARGS }} diff --git a/roles/nvim/files/lua/plugins/telescope/init.lua b/roles/nvim/files/lua/plugins/telescope/init.lua index b26906d..ab0e809 100644 --- a/roles/nvim/files/lua/plugins/telescope/init.lua +++ b/roles/nvim/files/lua/plugins/telescope/init.lua @@ -117,8 +117,7 @@ end, { desc = "Telescope find files (selected text)" }) vim.keymap.set("n", "pp", function() builtin.find_files({ hidden = true, no_ignore = true }) end, { desc = "Telescope find hidden files" }) -vim.keymap.set("n", "pb", builtin.buffers, { desc = "Telescope buffers" }) -vim.keymap.set("n", "pd", function() +vim.keymap.set("n", "pb", function() builtin.buffers({ attach_mappings = function(prompt_bufnr, map) -- multi-selects; this deletes the selection (or the entry under the cursor) @@ -131,7 +130,7 @@ vim.keymap.set("n", "pd", function() return true end, }) -end, { desc = "Telescope delete buffers" }) +end, { desc = "Telescope buffers" }) vim.keymap.set("n", "po", builtin.oldfiles, { desc = "Telescope oldfiles" }) vim.keymap.set("n", "pe", require("telescope").extensions.projects.projects, { desc = "Telescope projects" }) vim.keymap.set("n", "p.", function() diff --git a/roles/nvim/files/tests/spec/telescope_spec.lua b/roles/nvim/files/tests/spec/telescope_spec.lua new file mode 100644 index 0000000..f272ad6 --- /dev/null +++ b/roles/nvim/files/tests/spec/telescope_spec.lua @@ -0,0 +1,76 @@ +-- tests/spec/telescope_spec.lua + +describe("Telescope buffer mappings", function() + -- Load telescope so its mappings are registered + require("lazy").load({ plugins = { "telescope.nvim" } }) + + it("maps pb to telescope buffers", function() + local map_pb = vim.fn.maparg("pb", "n", false, true) + assert.is_not_nil(map_pb) + assert.is_truthy(map_pb.callback or map_pb.rhs) + assert.are.equal("Telescope buffers", map_pb.desc) + end) + + it("allows deleting buffers from pb with normal and insert commands", function() + local map_pb = vim.fn.maparg("pb", "n", false, true) + local cb = map_pb.callback + assert.is_function(cb) + + -- Mock builtin.buffers + local builtin = require("telescope.builtin") + local original_buffers = builtin.buffers + local captured_opts = nil + builtin.buffers = function(opts) + captured_opts = opts + end + + -- Run the callback to capture the options passed to builtin.buffers + cb() + + -- Restore original + builtin.buffers = original_buffers + + -- Assert and guard on captured options + assert.is_table(captured_opts) + if not captured_opts then + error("captured_opts is nil") + end + assert.is_function(captured_opts["attach_mappings"]) + + -- Mock map function and actions.delete_buffer via its metatable __call + local mapped = {} + local map_fn = function(mode, key, fn) + mapped[mode .. "_" .. key] = fn + end + + local actions = require("telescope.actions") + local delete_action = actions.delete_buffer + local mt = getmetatable(delete_action) + local original_call = mt.__call + local deleted_bufnr = nil + mt.__call = function(_, bufnr) + deleted_bufnr = bufnr + end + + -- Call attach_mappings with a mock prompt_bufnr (e.g., 42) + local mock_prompt_bufnr = 42 + local attach_mappings_fn = captured_opts["attach_mappings"] + if not attach_mappings_fn then + error("attach_mappings is nil") + end + local res = attach_mappings_fn(mock_prompt_bufnr, map_fn) + assert.is_true(res) + + -- Check mapped keys + assert.is_function(mapped["i_"]) + assert.is_function(mapped["n_"]) + assert.is_function(mapped["n_d"]) + + -- Verify that calling mapped functions triggers actions.delete_buffer with correct bufnr + mapped["n_d"]() + assert.are.equal(mock_prompt_bufnr, deleted_bufnr) + + -- Restore metatable + mt.__call = original_call + end) +end) From 8a6bb6a44237950308c096473e415af577d74058 Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 20 Jul 2026 12:52:32 -0700 Subject: [PATCH 2/6] feat(nvim): add Mermaid fallback for Zellij Signed-off-by: Kevin Oberlies --- roles/nvim/files/ftplugin/markdown.lua | 81 +++++++++++++++++++ roles/nvim/files/lua/plugins/spec/diagram.lua | 17 ++-- .../tests/spec/mermaid_fallback_spec.lua | 24 ++++++ 3 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 roles/nvim/files/tests/spec/mermaid_fallback_spec.lua diff --git a/roles/nvim/files/ftplugin/markdown.lua b/roles/nvim/files/ftplugin/markdown.lua index 69e0f84..c5663eb 100644 --- a/roles/nvim/files/ftplugin/markdown.lua +++ b/roles/nvim/files/ftplugin/markdown.lua @@ -1 +1,82 @@ vim.wo.conceallevel = (vim.bo.readonly or vim.bo.buftype == "nofile") and 2 or 0 + +if vim.env.ZELLIJ == nil or vim.b.mermaid_external_viewer_configured then return end + +vim.b.mermaid_external_viewer_configured = true + +local function mermaid_source_at_cursor() + local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false) + local cursor_row = vim.api.nvim_win_get_cursor(0)[1] + local opening_row + + for row = cursor_row, 1, -1 do + local line = lines[row] + if line:match("^%s*```") then + if line:match("^%s*```%s*mermaid%s*$") then + opening_row = row + break + end + return nil + end + end + + if not opening_row then return nil end + + local source = {} + for row = opening_row + 1, #lines do + local line = lines[row] + if line:match("^%s*```%s*$") then return table.concat(source, "\n") end + table.insert(source, line) + end +end + +local function open_mermaid_at_cursor() + local source = mermaid_source_at_cursor() + if not source then + vim.notify("Place the cursor inside a Mermaid code fence", vim.log.levels.WARN, { title = "Mermaid" }) + return + end + + if vim.fn.executable("mmdc") == 0 then + vim.notify("mmdc is required to render Mermaid diagrams", vim.log.levels.ERROR, { title = "Mermaid" }) + return + end + + local cache_dir = vim.fn.stdpath("cache") .. "/mermaid" + vim.fn.mkdir(cache_dir, "p") + + local input_path = vim.fn.tempname() + local output_path = cache_dir .. "/" .. vim.fn.sha256(source) .. ".png" + vim.fn.writefile(vim.split(source, "\n"), input_path) + + local stderr = {} + vim.fn.jobstart({ "mmdc", "-i", input_path, "-o", output_path, "-t", "dark" }, { + on_stderr = function(_, data) + for _, line in ipairs(data) do + if line ~= "" then + table.insert(stderr, line) + end + end + end, + on_exit = function(_, exit_code) + vim.schedule(function() + vim.fn.delete(input_path) + if exit_code ~= 0 or vim.fn.filereadable(output_path) == 0 then + local message = #stderr > 0 and table.concat(stderr, "\n") or "mmdc exited with code " .. exit_code + vim.notify(message, vim.log.levels.ERROR, { title = "Mermaid render failed" }) + return + end + vim.ui.open(output_path) + end) + end, + }) +end + +vim.api.nvim_buf_create_user_command(0, "MermaidOpen", open_mermaid_at_cursor, { + desc = "Render Mermaid fence at cursor", +}) + +vim.keymap.set("n", "mo", "MermaidOpen", { + buffer = true, + desc = "Open Mermaid diagram", +}) diff --git a/roles/nvim/files/lua/plugins/spec/diagram.lua b/roles/nvim/files/lua/plugins/spec/diagram.lua index 6858d50..0ef974d 100644 --- a/roles/nvim/files/lua/plugins/spec/diagram.lua +++ b/roles/nvim/files/lua/plugins/spec/diagram.lua @@ -1,11 +1,13 @@ --- Inline rendering of mermaid (and other) diagrams directly in the buffer via --- the kitty graphics protocol. Requires a graphics-capable terminal (kitty), --- the `mmdc` CLI (@mermaid-js/mermaid-cli) to render mermaid, and ImageMagick --- (`magick`) to process the images -- both installed by the packages role. +-- Inline diagram rendering relies on the Kitty graphics protocol. Zellij does +-- not forward that protocol, and Ueberzug++ overlays cannot track its panes or +-- tabs, so Markdown uses its external-viewer fallback there instead. return { { "3rd/image.nvim", event = "VeryLazy", + cond = function() + return vim.env.ZELLIJ == nil + end, opts = { backend = "kitty", -- Use the ImageMagick CLI rather than the `magick` luarock, so there is @@ -21,6 +23,9 @@ return { "3rd/diagram.nvim", dependencies = { "3rd/image.nvim" }, ft = { "markdown" }, + cond = function() + return vim.env.ZELLIJ == nil + end, -- opts is a function so the integration module is required only after the -- plugin is on the runtimepath. opts = function() @@ -32,9 +37,7 @@ return { mermaid = { theme = "dark", -- mmdc drives Chromium via puppeteer; on Ubuntu 23.10+ AppArmor - cli_args = vim.env.DOTFILES_TRUSTED_MERMAID == "1" - and { "--puppeteerConfigFile", vim.fn.stdpath("config") .. "/puppeteer-config.json" } - or {}, + cli_args = {}, }, }, } diff --git a/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua new file mode 100644 index 0000000..0bf98dc --- /dev/null +++ b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua @@ -0,0 +1,24 @@ +describe("Zellij Mermaid fallback", function() + local original_zellij = vim.env.ZELLIJ + + before_each(function() + vim.env.ZELLIJ = "0" + vim.cmd("enew!") + vim.cmd("setfiletype markdown") + end) + + after_each(function() + vim.env.ZELLIJ = original_zellij + vim.cmd("bwipeout!") + end) + + it("registers an external viewer command for Markdown buffers", function() + assert.equals(2, vim.fn.exists(":MermaidOpen")) + end) + + it("maps leader mo to the external viewer command", function() + local mapping = vim.fn.maparg("mo", "n", false, true) + assert.equals("MermaidOpen", mapping.rhs) + end) + +end) From 54968c72a0bd3d2059f809091e101c46c916a232 Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 20 Jul 2026 14:18:51 -0700 Subject: [PATCH 3/6] feat(nvim): select terminal image backend Signed-off-by: Kevin Oberlies --- roles/nvim/files/ftplugin/markdown.lua | 4 +- .../nvim/files/lua/config/diagram_backend.lua | 14 ++++++ roles/nvim/files/lua/plugins/spec/diagram.lua | 33 +++++++------- .../files/tests/spec/diagram_backend_spec.lua | 43 +++++++++++++++++++ .../tests/spec/mermaid_fallback_spec.lua | 15 +++++++ 5 files changed, 93 insertions(+), 16 deletions(-) create mode 100644 roles/nvim/files/lua/config/diagram_backend.lua create mode 100644 roles/nvim/files/tests/spec/diagram_backend_spec.lua diff --git a/roles/nvim/files/ftplugin/markdown.lua b/roles/nvim/files/ftplugin/markdown.lua index c5663eb..a727e44 100644 --- a/roles/nvim/files/ftplugin/markdown.lua +++ b/roles/nvim/files/ftplugin/markdown.lua @@ -1,6 +1,8 @@ vim.wo.conceallevel = (vim.bo.readonly or vim.bo.buftype == "nofile") and 2 or 0 -if vim.env.ZELLIJ == nil or vim.b.mermaid_external_viewer_configured then return end +local diagram_backend = require("config.diagram_backend") + +if vim.env.ZELLIJ == nil or diagram_backend.get() ~= nil or vim.b.mermaid_external_viewer_configured then return end vim.b.mermaid_external_viewer_configured = true diff --git a/roles/nvim/files/lua/config/diagram_backend.lua b/roles/nvim/files/lua/config/diagram_backend.lua new file mode 100644 index 0000000..0bdcd3c --- /dev/null +++ b/roles/nvim/files/lua/config/diagram_backend.lua @@ -0,0 +1,14 @@ +local M = {} + +function M.get() + if vim.env.WEZTERM_PANE ~= nil then + return "sixel" + end + + local is_kitty = vim.env.KITTY_PID ~= nil or vim.env.TERM == "xterm-kitty" + if vim.env.ZELLIJ == nil and is_kitty then + return "kitty" + end +end + +return M diff --git a/roles/nvim/files/lua/plugins/spec/diagram.lua b/roles/nvim/files/lua/plugins/spec/diagram.lua index 0ef974d..a3a52ed 100644 --- a/roles/nvim/files/lua/plugins/spec/diagram.lua +++ b/roles/nvim/files/lua/plugins/spec/diagram.lua @@ -1,30 +1,33 @@ --- Inline diagram rendering relies on the Kitty graphics protocol. Zellij does --- not forward that protocol, and Ueberzug++ overlays cannot track its panes or --- tabs, so Markdown uses its external-viewer fallback there instead. +local diagram_backend = require("config.diagram_backend") + +-- WezTerm supports Sixel, which also survives Zellij. Kitty graphics do not, +-- so use that backend only in direct Kitty sessions. return { { "3rd/image.nvim", event = "VeryLazy", cond = function() - return vim.env.ZELLIJ == nil + return diagram_backend.get() ~= nil + end, + opts = function() + return { + backend = diagram_backend.get(), + -- Use the ImageMagick CLI rather than the `magick` luarock, so there is + -- no luarocks build step to maintain. + processor = "magick_cli", + -- diagram.nvim drives the rendering; don't also auto-render markdown images. + integrations = {}, + max_width_window_percentage = 80, + max_height_window_percentage = 80, + } end, - opts = { - backend = "kitty", - -- Use the ImageMagick CLI rather than the `magick` luarock, so there is - -- no luarocks build step to maintain. - processor = "magick_cli", - -- diagram.nvim drives the rendering; don't also auto-render markdown images. - integrations = {}, - max_width_window_percentage = 80, - max_height_window_percentage = 80, - }, }, { "3rd/diagram.nvim", dependencies = { "3rd/image.nvim" }, ft = { "markdown" }, cond = function() - return vim.env.ZELLIJ == nil + return diagram_backend.get() ~= nil end, -- opts is a function so the integration module is required only after the -- plugin is on the runtimepath. diff --git a/roles/nvim/files/tests/spec/diagram_backend_spec.lua b/roles/nvim/files/tests/spec/diagram_backend_spec.lua new file mode 100644 index 0000000..9bac61f --- /dev/null +++ b/roles/nvim/files/tests/spec/diagram_backend_spec.lua @@ -0,0 +1,43 @@ +describe("Markdown diagram backends", function() + local environment = { "WEZTERM_PANE", "TERM", "KITTY_PID", "ZELLIJ" } + local original_environment = {} + + local function set_environment(values) + for _, name in ipairs(environment) do + vim.env[name] = values[name] + end + end + + before_each(function() + for _, name in ipairs(environment) do + original_environment[name] = vim.env[name] + end + set_environment({}) + end) + + after_each(function() + set_environment(original_environment) + end) + + it("uses Sixel for WezTerm, including inside Zellij", function() + set_environment({ WEZTERM_PANE = "123", ZELLIJ = "0" }) + + local plugins = require("plugins.spec.diagram") + assert.is_true(plugins[1].cond()) + assert.is_true(plugins[2].cond()) + assert.equals("sixel", plugins[1].opts().backend) + end) + + it("uses Kitty only outside Zellij", function() + set_environment({ TERM = "xterm-kitty" }) + + local plugins = require("plugins.spec.diagram") + assert.is_true(plugins[1].cond()) + assert.equals("kitty", plugins[1].opts().backend) + + set_environment({ TERM = "xterm-kitty", ZELLIJ = "0" }) + assert.is_false(plugins[1].cond()) + assert.is_false(plugins[2].cond()) + end) + +end) diff --git a/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua index 0bf98dc..d2f3782 100644 --- a/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua +++ b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua @@ -1,14 +1,20 @@ describe("Zellij Mermaid fallback", function() local original_zellij = vim.env.ZELLIJ + local original_wezterm_pane = vim.env.WEZTERM_PANE + local original_kitty_pid = vim.env.KITTY_PID before_each(function() vim.env.ZELLIJ = "0" + vim.env.WEZTERM_PANE = nil + vim.env.KITTY_PID = nil vim.cmd("enew!") vim.cmd("setfiletype markdown") end) after_each(function() vim.env.ZELLIJ = original_zellij + vim.env.WEZTERM_PANE = original_wezterm_pane + vim.env.KITTY_PID = original_kitty_pid vim.cmd("bwipeout!") end) @@ -21,4 +27,13 @@ describe("Zellij Mermaid fallback", function() assert.equals("MermaidOpen", mapping.rhs) end) + it("does not register the fallback when WezTerm can render through Sixel", function() + vim.cmd("bwipeout!") + vim.env.WEZTERM_PANE = "123" + vim.cmd("enew!") + vim.cmd("setfiletype markdown") + + assert.equals(0, vim.fn.exists(":MermaidOpen")) + end) + end) From b95123766b9fecc8cef737c1c53b2a0b5d944c6d Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 20 Jul 2026 15:22:35 -0700 Subject: [PATCH 4/6] fix(nvim): rerender diagrams on pane switch Signed-off-by: Kevin Oberlies --- roles/nvim/files/lua/plugins/spec/diagram.lua | 6 ++++++ roles/nvim/files/tests/spec/diagram_backend_spec.lua | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/roles/nvim/files/lua/plugins/spec/diagram.lua b/roles/nvim/files/lua/plugins/spec/diagram.lua index a3a52ed..12275e8 100644 --- a/roles/nvim/files/lua/plugins/spec/diagram.lua +++ b/roles/nvim/files/lua/plugins/spec/diagram.lua @@ -33,6 +33,12 @@ return { -- plugin is on the runtimepath. opts = function() return { + events = { + -- diagram.nvim clears diagrams on BufLeave. A buffer already shown + -- in another split does not emit BufWinEnter when focus returns, so + -- redraw it explicitly for the Sixel backend. + render_buffer = { "InsertLeave", "BufWinEnter", "TextChanged", "WinEnter" }, + }, integrations = { require("diagram.integrations.markdown"), }, diff --git a/roles/nvim/files/tests/spec/diagram_backend_spec.lua b/roles/nvim/files/tests/spec/diagram_backend_spec.lua index 9bac61f..53bc550 100644 --- a/roles/nvim/files/tests/spec/diagram_backend_spec.lua +++ b/roles/nvim/files/tests/spec/diagram_backend_spec.lua @@ -40,4 +40,16 @@ describe("Markdown diagram backends", function() assert.is_false(plugins[2].cond()) end) + it("rerenders a focused Markdown split after its image was cleared", function() + local integration_module = "diagram.integrations.markdown" + local original_integration = package.loaded[integration_module] + package.loaded[integration_module] = {} + + local plugins = require("plugins.spec.diagram") + local options = plugins[2].opts() + + package.loaded[integration_module] = original_integration + assert.same({ "InsertLeave", "BufWinEnter", "TextChanged", "WinEnter" }, options.events.render_buffer) + end) + end) From b686d53ab8b0a2ecb5474627efa8fb8186959aeb Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 20 Jul 2026 15:22:08 -0700 Subject: [PATCH 5/6] feat: add WezTerm and Neovim database UI Signed-off-by: Kevin Oberlies --- dotfiles.yml | 3 +++ roles/nvim/files/lazy-lock.json | 15 ++++++----- roles/nvim/files/lua/config/options.lua | 2 +- roles/nvim/files/lua/plugins/spec/editor.lua | 24 +++++++++++++++-- roles/nvim/files/puppeteer-config.json | 2 +- roles/wezterm/files/wezterm.lua | 14 ++++++++++ roles/wezterm/tasks/arch.yml | 6 +++++ roles/wezterm/tasks/debian.yml | 28 ++++++++++++++++++++ roles/wezterm/tasks/main.yml | 11 ++++++++ 9 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 roles/wezterm/files/wezterm.lua create mode 100644 roles/wezterm/tasks/arch.yml create mode 100644 roles/wezterm/tasks/debian.yml create mode 100644 roles/wezterm/tasks/main.yml diff --git a/dotfiles.yml b/dotfiles.yml index aa66638..5707733 100644 --- a/dotfiles.yml +++ b/dotfiles.yml @@ -44,6 +44,9 @@ - role: zellij tags: - "zellij" + - role: wezterm + tags: + - "wezterm" - role: nvim tags: - "nvim" diff --git a/roles/nvim/files/lazy-lock.json b/roles/nvim/files/lazy-lock.json index 6072ee4..2785854 100644 --- a/roles/nvim/files/lazy-lock.json +++ b/roles/nvim/files/lazy-lock.json @@ -1,7 +1,7 @@ { "FixCursorHold.nvim": { "branch": "master", "commit": "1900f89dc17c603eec29960f57c00bd9ae696495" }, "HowMuch": { "branch": "master", "commit": "787ead49e6311dc77b8e07a3aca79cbd6feab34c" }, - "LuaSnip": { "branch": "master", "commit": "458560534a73f7f8d7a11a146c801db00b081df0" }, + "LuaSnip": { "branch": "master", "commit": "642b0c595e11608b4c18219e93b88d7637af27bc" }, "actions-preview.nvim": { "branch": "master", "commit": "0ac9c2aa3cfc8c885321c0862b50b6b1c3392405" }, "ansi.nvim": { "branch": "main", "commit": "195b64c3da1c22c2e95648dcbdc6ed075d507064" }, "baleia.nvim": { "branch": "main", "commit": "710537ff5cd669c5a76c5f5b6a9169fd9b913d18" }, @@ -11,8 +11,8 @@ "blink.lib": { "branch": "main", "commit": "5876dd95deeb70aadbe9f1c0b7117a135061cdac" }, "cmp-digraphs": { "branch": "master", "commit": "5efc1f0078d7c5f3ea1c8e3aad04da3fd6e081a9" }, "codecompanion-history.nvim": { "branch": "main", "commit": "bc1b4fe06eaaf0aa2399be742e843c22f7f1652a" }, - "codecompanion.nvim": { "branch": "main", "commit": "c8bd2d0ff58b75d9a76f0a17115581754824b725" }, - "copilot.lua": { "branch": "master", "commit": "760912b5992e1d6437378a9c7f2b0cb950966cf5" }, + "codecompanion.nvim": { "branch": "main", "commit": "4fb6e67d537d88d1a642c623efcbbee80d7d231c" }, + "copilot.lua": { "branch": "master", "commit": "d521d3959f81f4fa58870ed329754f1dd5057511" }, "crates.nvim": { "branch": "main", "commit": "694357861ec9ebf12475ddcdd04ea45a0923c32d" }, "diagram.nvim": { "branch": "master", "commit": "a221810b17cdda2d5fdddba9bab3eba6fab8fabc" }, "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, @@ -23,14 +23,13 @@ "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, "git-worktree.nvim": { "branch": "main", "commit": "3ad8c17a3d178ac19be925284389c14114638ebb" }, "gitsigns.nvim": { "branch": "main", "commit": "eb60cc7b94c46005237fd34170d76f3a089a90aa" }, - "hererocks": { "branch": "master", "commit": "3db37265c3839cbd4d27fc73f92fa7b58bc3a76f" }, "hunk.nvim": { "branch": "master", "commit": "c8a8e7b6973576f63e5bf39aa8338d7f37f4dc53" }, "hydra.nvim": { "branch": "main", "commit": "8c4a9f621ec7cdc30411a1f3b6d5eebb12b469dc" }, "image.nvim": { "branch": "master", "commit": "88351f1f7d9dbae286e671ce3690a49660dd8a5c" }, "iron.nvim": { "branch": "master", "commit": "88cd340407b959f1168af2a6ae5a3d180e6df32c" }, "jj-diffconflicts": { "branch": "main", "commit": "a2aa9a247b56d2c1a6f6be81bcf41c5450cc82ff" }, "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, - "lean.nvim": { "branch": "main", "commit": "32fb8aa2edf3f172c307957dc7083e6c7f6caa7e" }, + "lean.nvim": { "branch": "main", "commit": "f5771e07ec026aeff2915c338a4cb8e7eb7247a2" }, "lsp-format.nvim": { "branch": "master", "commit": "e2b4ae87545c1aadebcf1dfc1b5dffe28dcf2ffb" }, "lsp_signature.nvim": { "branch": "master", "commit": "b7ace9ddb1640ce266012a45a672dfdaedfa5ec6" }, "mason-lspconfig.nvim": { "branch": "main", "commit": "47059d71b42d74b0a1e9f61c1d99d301039c3b5b" }, @@ -40,7 +39,7 @@ "mdx.nvim": { "branch": "main", "commit": "6c3dc7c4a4b58b5d86404c21a9b4655282ca08c5" }, "multicursors.nvim": { "branch": "main", "commit": "72225ea9e4443c3f4b9df91d0193e07c4ee8d382" }, "neodev.nvim": { "branch": "main", "commit": "46aa467dca16cf3dfe27098042402066d2ae242d" }, - "neogit": { "branch": "master", "commit": "43ea1a0854052e583f647e0b35879f0158a70a78" }, + "neogit": { "branch": "master", "commit": "6fc2fa890bd2031ed999c074daab0fb4feff20a5" }, "neotest": { "branch": "master", "commit": "fb84d87285698f7055f618083c351984449119b8" }, "neotest-plenary": { "branch": "master", "commit": "3523adcf9ffaad1911960c5813b0136c1b63a2ec" }, "neotest-python": { "branch": "master", "commit": "51c453d57f8d5156671b42ea57fafa2e1c9fb641" }, @@ -65,7 +64,7 @@ "pomo.nvim": { "branch": "main", "commit": "7e06e5221d8d1e596a0ab29dd4d7fcee5f3cd05a" }, "popup.nvim": { "branch": "master", "commit": "b7404d35d5d3548a82149238289fa71f7f6de4ac" }, "project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" }, - "schemastore.nvim": { "branch": "main", "commit": "6ff1f21b2e2b77ec59f7433ce2d9fbc052d908ac" }, + "schemastore.nvim": { "branch": "main", "commit": "e954496f8ef22904e8a84f5078f4a110fdc7a0d3" }, "suda.vim": { "branch": "master", "commit": "c492741b4679b3cdd4d9e34138209784e061d916" }, "tcomment_vim": { "branch": "master", "commit": "48ab639a461d9b8344f7fee06cb69b4374863b13" }, "telescope-fzf-native.nvim": { "branch": "main", "commit": "b25b749b9db64d375d782094e2b9dce53ad53a40" }, @@ -82,6 +81,8 @@ "unison": { "branch": "trunk", "commit": "e1870038739ffcb27b4e3b483dafd2c21f6541b2" }, "vim-autoclose": { "branch": "master", "commit": "a9a3b7384657bc1f60a963fd6c08c63fc48d61c3" }, "vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" }, + "vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" }, + "vim-dadbod-ui": { "branch": "master", "commit": "afd07819d8efcefc3317205b855ad4e3513b0011" }, "vim-dispatch": { "branch": "master", "commit": "a2ff28abdb2d89725192db5b8562977d392a4d3f" }, "vim-endwise": { "branch": "master", "commit": "4994afb0cdf956d9a665a14b9c834869e602c396" }, "vim-matchup": { "branch": "master", "commit": "055881643e1b37038a572c883de7b1969716db77" }, diff --git a/roles/nvim/files/lua/config/options.lua b/roles/nvim/files/lua/config/options.lua index c183831..4dac31b 100644 --- a/roles/nvim/files/lua/config/options.lua +++ b/roles/nvim/files/lua/config/options.lua @@ -1,6 +1,6 @@ local options = { -- clipboard = "unnamed,unnamedplus", --- Copy-paste between vim and everything else - cmdheight = 0, --- Give more space for displaying messages + cmdheight = 1, --- Give more space for displaying messages completeopt = "menu,menuone,noselect", --- Better autocompletion cursorline = true, --- Highlight of current line emoji = false, --- Fix emoji display diff --git a/roles/nvim/files/lua/plugins/spec/editor.lua b/roles/nvim/files/lua/plugins/spec/editor.lua index 228c20f..dab4c4a 100644 --- a/roles/nvim/files/lua/plugins/spec/editor.lua +++ b/roles/nvim/files/lua/plugins/spec/editor.lua @@ -117,8 +117,28 @@ return { event = "VeryLazy", }, { - "tpope/vim-dadbod", - cmd = "DB", + 'kristijanhusak/vim-dadbod-ui', + dependencies = { + { + 'tpope/vim-dadbod', + lazy = true + }, + { + 'kristijanhusak/vim-dadbod-completion', + ft = { 'sql', 'mysql', 'plsql' }, + lazy = true + }, -- Optional + }, + cmd = { + 'DBUI', + 'DBUIToggle', + 'DBUIAddConnection', + 'DBUIFindBuffer', + }, + init = function() + -- Your DBUI configuration + vim.g.db_ui_use_nerd_fonts = 1 + end, }, { "tpope/vim-dispatch", diff --git a/roles/nvim/files/puppeteer-config.json b/roles/nvim/files/puppeteer-config.json index 3201af7..21a41b3 100644 --- a/roles/nvim/files/puppeteer-config.json +++ b/roles/nvim/files/puppeteer-config.json @@ -1,3 +1,3 @@ { - "args": ["--no-sandbox"] + "args": [] } diff --git a/roles/wezterm/files/wezterm.lua b/roles/wezterm/files/wezterm.lua new file mode 100644 index 0000000..b364d3a --- /dev/null +++ b/roles/wezterm/files/wezterm.lua @@ -0,0 +1,14 @@ +local wezterm = require 'wezterm' +local config = wezterm.config_builder() + +config.keys = { + { + key = 'r', + mods = 'CTRL|SHIFT', + action = wezterm.action.ReloadConfiguration, + }, +} +config.enable_tab_bar = false +config.adjust_window_size_when_changing_font_size = false + +return config diff --git a/roles/wezterm/tasks/arch.yml b/roles/wezterm/tasks/arch.yml new file mode 100644 index 0000000..443c8a8 --- /dev/null +++ b/roles/wezterm/tasks/arch.yml @@ -0,0 +1,6 @@ +- name: Install WezTerm + community.general.pacman: + name: wezterm + state: present + become: true + become_method: sudo diff --git a/roles/wezterm/tasks/debian.yml b/roles/wezterm/tasks/debian.yml new file mode 100644 index 0000000..b082aed --- /dev/null +++ b/roles/wezterm/tasks/debian.yml @@ -0,0 +1,28 @@ +- name: Download WezTerm APT repository key + get_url: + url: https://apt.fury.io/wez/gpg.key + dest: /usr/share/keyrings/wezterm-fury.asc + mode: "0644" + become: true + become_method: sudo + +- name: Add WezTerm APT repository + apt_repository: + repo: "deb [signed-by=/usr/share/keyrings/wezterm-fury.asc] https://apt.fury.io/wez/ * *" + state: present + filename: wezterm + become: true + become_method: sudo + +- name: Update APT cache after adding WezTerm repository + apt: + update_cache: true + become: true + become_method: sudo + +- name: Install WezTerm + apt: + name: wezterm + state: present + become: true + become_method: sudo diff --git a/roles/wezterm/tasks/main.yml b/roles/wezterm/tasks/main.yml new file mode 100644 index 0000000..2224655 --- /dev/null +++ b/roles/wezterm/tasks/main.yml @@ -0,0 +1,11 @@ +- include_tasks: debian.yml + when: ansible_facts.os_family == "Debian" +- include_tasks: arch.yml + when: ansible_facts.os_family == "Archlinux" + +- name: Hard link WezTerm config + file: + src: "{{ dotfiles_home }}/roles/wezterm/files/wezterm.lua" + dest: "{{ dotfiles_user_home }}/.wezterm.lua" + state: hard + force: true From 53e669053838cb31867b7b20a5d8328aaaf9d228 Mon Sep 17 00:00:00 2001 From: Kevin Oberlies Date: Mon, 20 Jul 2026 15:58:40 -0700 Subject: [PATCH 6/6] style: format Signed-off-by: Kevin Oberlies --- roles/nvim/files/ftplugin/markdown.lua | 12 +- .../nvim/files/lua/config/diagram_backend.lua | 14 +-- roles/nvim/files/lua/plugins/spec/editor.lua | 22 ++-- .../files/tests/spec/diagram_backend_spec.lua | 105 +++++++++--------- .../tests/spec/mermaid_fallback_spec.lua | 1 - roles/wezterm/files/wezterm.lua | 6 +- 6 files changed, 82 insertions(+), 78 deletions(-) diff --git a/roles/nvim/files/ftplugin/markdown.lua b/roles/nvim/files/ftplugin/markdown.lua index a727e44..193e0f8 100644 --- a/roles/nvim/files/ftplugin/markdown.lua +++ b/roles/nvim/files/ftplugin/markdown.lua @@ -2,7 +2,9 @@ vim.wo.conceallevel = (vim.bo.readonly or vim.bo.buftype == "nofile") and 2 or 0 local diagram_backend = require("config.diagram_backend") -if vim.env.ZELLIJ == nil or diagram_backend.get() ~= nil or vim.b.mermaid_external_viewer_configured then return end +if vim.env.ZELLIJ == nil or diagram_backend.get() ~= nil or vim.b.mermaid_external_viewer_configured then + return +end vim.b.mermaid_external_viewer_configured = true @@ -22,12 +24,16 @@ local function mermaid_source_at_cursor() end end - if not opening_row then return nil end + if not opening_row then + return nil + end local source = {} for row = opening_row + 1, #lines do local line = lines[row] - if line:match("^%s*```%s*$") then return table.concat(source, "\n") end + if line:match("^%s*```%s*$") then + return table.concat(source, "\n") + end table.insert(source, line) end end diff --git a/roles/nvim/files/lua/config/diagram_backend.lua b/roles/nvim/files/lua/config/diagram_backend.lua index 0bdcd3c..1e4aded 100644 --- a/roles/nvim/files/lua/config/diagram_backend.lua +++ b/roles/nvim/files/lua/config/diagram_backend.lua @@ -1,14 +1,14 @@ local M = {} function M.get() - if vim.env.WEZTERM_PANE ~= nil then - return "sixel" - end + if vim.env.WEZTERM_PANE ~= nil then + return "sixel" + end - local is_kitty = vim.env.KITTY_PID ~= nil or vim.env.TERM == "xterm-kitty" - if vim.env.ZELLIJ == nil and is_kitty then - return "kitty" - end + local is_kitty = vim.env.KITTY_PID ~= nil or vim.env.TERM == "xterm-kitty" + if vim.env.ZELLIJ == nil and is_kitty then + return "kitty" + end end return M diff --git a/roles/nvim/files/lua/plugins/spec/editor.lua b/roles/nvim/files/lua/plugins/spec/editor.lua index dab4c4a..eff3a5c 100644 --- a/roles/nvim/files/lua/plugins/spec/editor.lua +++ b/roles/nvim/files/lua/plugins/spec/editor.lua @@ -117,23 +117,23 @@ return { event = "VeryLazy", }, { - 'kristijanhusak/vim-dadbod-ui', + "kristijanhusak/vim-dadbod-ui", dependencies = { { - 'tpope/vim-dadbod', - lazy = true + "tpope/vim-dadbod", + lazy = true, }, { - 'kristijanhusak/vim-dadbod-completion', - ft = { 'sql', 'mysql', 'plsql' }, - lazy = true - }, -- Optional + "kristijanhusak/vim-dadbod-completion", + ft = { "sql", "mysql", "plsql" }, + lazy = true, + }, -- Optional }, cmd = { - 'DBUI', - 'DBUIToggle', - 'DBUIAddConnection', - 'DBUIFindBuffer', + "DBUI", + "DBUIToggle", + "DBUIAddConnection", + "DBUIFindBuffer", }, init = function() -- Your DBUI configuration diff --git a/roles/nvim/files/tests/spec/diagram_backend_spec.lua b/roles/nvim/files/tests/spec/diagram_backend_spec.lua index 53bc550..436d7b7 100644 --- a/roles/nvim/files/tests/spec/diagram_backend_spec.lua +++ b/roles/nvim/files/tests/spec/diagram_backend_spec.lua @@ -1,55 +1,54 @@ describe("Markdown diagram backends", function() - local environment = { "WEZTERM_PANE", "TERM", "KITTY_PID", "ZELLIJ" } - local original_environment = {} - - local function set_environment(values) - for _, name in ipairs(environment) do - vim.env[name] = values[name] - end - end - - before_each(function() - for _, name in ipairs(environment) do - original_environment[name] = vim.env[name] - end - set_environment({}) - end) - - after_each(function() - set_environment(original_environment) - end) - - it("uses Sixel for WezTerm, including inside Zellij", function() - set_environment({ WEZTERM_PANE = "123", ZELLIJ = "0" }) - - local plugins = require("plugins.spec.diagram") - assert.is_true(plugins[1].cond()) - assert.is_true(plugins[2].cond()) - assert.equals("sixel", plugins[1].opts().backend) - end) - - it("uses Kitty only outside Zellij", function() - set_environment({ TERM = "xterm-kitty" }) - - local plugins = require("plugins.spec.diagram") - assert.is_true(plugins[1].cond()) - assert.equals("kitty", plugins[1].opts().backend) - - set_environment({ TERM = "xterm-kitty", ZELLIJ = "0" }) - assert.is_false(plugins[1].cond()) - assert.is_false(plugins[2].cond()) - end) - - it("rerenders a focused Markdown split after its image was cleared", function() - local integration_module = "diagram.integrations.markdown" - local original_integration = package.loaded[integration_module] - package.loaded[integration_module] = {} - - local plugins = require("plugins.spec.diagram") - local options = plugins[2].opts() - - package.loaded[integration_module] = original_integration - assert.same({ "InsertLeave", "BufWinEnter", "TextChanged", "WinEnter" }, options.events.render_buffer) - end) - + local environment = { "WEZTERM_PANE", "TERM", "KITTY_PID", "ZELLIJ" } + local original_environment = {} + + local function set_environment(values) + for _, name in ipairs(environment) do + vim.env[name] = values[name] + end + end + + before_each(function() + for _, name in ipairs(environment) do + original_environment[name] = vim.env[name] + end + set_environment({}) + end) + + after_each(function() + set_environment(original_environment) + end) + + it("uses Sixel for WezTerm, including inside Zellij", function() + set_environment({ WEZTERM_PANE = "123", ZELLIJ = "0" }) + + local plugins = require("plugins.spec.diagram") + assert.is_true(plugins[1].cond()) + assert.is_true(plugins[2].cond()) + assert.equals("sixel", plugins[1].opts().backend) + end) + + it("uses Kitty only outside Zellij", function() + set_environment({ TERM = "xterm-kitty" }) + + local plugins = require("plugins.spec.diagram") + assert.is_true(plugins[1].cond()) + assert.equals("kitty", plugins[1].opts().backend) + + set_environment({ TERM = "xterm-kitty", ZELLIJ = "0" }) + assert.is_false(plugins[1].cond()) + assert.is_false(plugins[2].cond()) + end) + + it("rerenders a focused Markdown split after its image was cleared", function() + local integration_module = "diagram.integrations.markdown" + local original_integration = package.loaded[integration_module] + package.loaded[integration_module] = {} + + local plugins = require("plugins.spec.diagram") + local options = plugins[2].opts() + + package.loaded[integration_module] = original_integration + assert.same({ "InsertLeave", "BufWinEnter", "TextChanged", "WinEnter" }, options.events.render_buffer) + end) end) diff --git a/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua index d2f3782..36288ee 100644 --- a/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua +++ b/roles/nvim/files/tests/spec/mermaid_fallback_spec.lua @@ -35,5 +35,4 @@ describe("Zellij Mermaid fallback", function() assert.equals(0, vim.fn.exists(":MermaidOpen")) end) - end) diff --git a/roles/wezterm/files/wezterm.lua b/roles/wezterm/files/wezterm.lua index b364d3a..34361b7 100644 --- a/roles/wezterm/files/wezterm.lua +++ b/roles/wezterm/files/wezterm.lua @@ -1,10 +1,10 @@ -local wezterm = require 'wezterm' +local wezterm = require("wezterm") local config = wezterm.config_builder() config.keys = { { - key = 'r', - mods = 'CTRL|SHIFT', + key = "r", + mods = "CTRL|SHIFT", action = wezterm.action.ReloadConfiguration, }, }