From ac39b0585d46ecf763105fad19f696e4e058d871 Mon Sep 17 00:00:00 2001 From: iofq Date: Fri, 18 Jul 2025 09:36:11 -0500 Subject: [PATCH] snacks + tabline changes --- flake.nix | 1 + nvim/colors/iofq.lua | 9 ++-- nvim/lua/config/init.lua | 2 + nvim/lua/plugins/completion.lua | 7 +++ nvim/lua/plugins/lib/minidiff_jj.lua | 27 +++++------ nvim/lua/plugins/lib/session_jj.lua | 2 +- nvim/lua/plugins/lib/snacks.lua | 44 +++++++++++++++--- nvim/lua/plugins/lsp.lua | 67 +++++++++++++++------------- nvim/lua/plugins/mini.lua | 24 ++++++---- nvim/lua/plugins/snacks.lua | 5 +-- nvim/lua/plugins/treesitter.lua | 2 - 11 files changed, 120 insertions(+), 70 deletions(-) diff --git a/flake.nix b/flake.nix index 984342b..b752ee4 100644 --- a/flake.nix +++ b/flake.nix @@ -49,6 +49,7 @@ stylua luajitPackages.luacheck alejandra + nvim-dev ]; shellHook = '' # symlink the .luarc.json generated in the overlay diff --git a/nvim/colors/iofq.lua b/nvim/colors/iofq.lua index 5d32f8f..cc9f2ab 100644 --- a/nvim/colors/iofq.lua +++ b/nvim/colors/iofq.lua @@ -385,10 +385,11 @@ hi(0, 'MiniDepsTitle', { link = 'Title' }) hi(0, 'MiniDepsTitleError', { bg = '#e85c51', fg = '#0f1c1e' }) hi(0, 'MiniDepsTitleSame', { link = 'DiffText' }) hi(0, 'MiniDepsTitleUpdate', { bg = '#7aa4a1', fg = '#0f1c1e' }) -hi(0, 'MiniDiffOverAdd', { link = 'DiffAdd' }) -hi(0, 'MiniDiffOverChange', { link = 'DiffText' }) -hi(0, 'MiniDiffOverContext', { link = 'DiffChange' }) -hi(0, 'MiniDiffOverDelete', { link = 'DiffDelete' }) +hi(0, 'MiniDiffOverAdd', { bg = '#31474b' }) +hi(0, 'MiniDiffOverChange', { bg = '#466066' }) +hi(0, 'MiniDiffOverChangeBuf', { bg = '#466066' }) +hi(0, 'MiniDiffOverContext', { bg = '#31474b' }) +hi(0, 'MiniDiffOverDelete', { fg = 'red' }) hi(0, 'MiniDiffSignAdd', { fg = 'green', bold = true }) hi(0, 'MiniDiffSignChange', { fg = 'green', bold = true }) hi(0, 'MiniDiffSignDelete', { fg = 'red', bold = true }) diff --git a/nvim/lua/config/init.lua b/nvim/lua/config/init.lua index a2a90d3..b5b4365 100644 --- a/nvim/lua/config/init.lua +++ b/nvim/lua/config/init.lua @@ -87,6 +87,8 @@ vim.keymap.set('n', '', vim.cmd.bnext, { noremap = true, silent = true }) vim.keymap.set('n', '', vim.cmd.bprev, { noremap = true, silent = true }) vim.keymap.set('v', '<', '', '>gv') +vim.keymap.set('v', '', ":m '>+1gv=gv", { desc = 'move selection down' }) +vim.keymap.set('v', '', ":m '<-2gv=gv", { desc = 'move selection up' }) vim.keymap.set({ 'v', 'n' }, 'q:', '') vim.keymap.set('n', 'gq', vim.cmd.bdelete, { noremap = true, silent = true, desc = 'close buffer' }) vim.keymap.set('n', 'gQ', function() diff --git a/nvim/lua/plugins/completion.lua b/nvim/lua/plugins/completion.lua index c860619..ad53094 100644 --- a/nvim/lua/plugins/completion.lua +++ b/nvim/lua/plugins/completion.lua @@ -32,6 +32,13 @@ return { snippets = { score_offset = -10, }, + path = { + opts = { + get_cwd = function(_) + return vim.fn.getcwd() + end, + }, + }, ripgrep = { module = 'blink-ripgrep', name = 'rg', diff --git a/nvim/lua/plugins/lib/minidiff_jj.lua b/nvim/lua/plugins/lib/minidiff_jj.lua index c71654f..d5b93d8 100644 --- a/nvim/lua/plugins/lib/minidiff_jj.lua +++ b/nvim/lua/plugins/lib/minidiff_jj.lua @@ -1,7 +1,6 @@ local diff = require('mini.diff') local M = { cache = {}, - jj_cache = {}, } M.get_buf_realpath = function(buf_id) @@ -20,10 +19,10 @@ M.jj_start_watching_tree_state = function(buf_id, path) local on_not_in_jj = vim.schedule_wrap(function() if not vim.api.nvim_buf_is_valid(buf_id) then M.cache[buf_id] = nil - return + return false end diff.fail_attach(buf_id) - M.jj_cache[buf_id] = {} + M.cache[buf_id] = {} end) local process, stdout_feed = nil, {} @@ -61,12 +60,11 @@ M.jj_setup_tree_state_watch = function(buf_id, jj_dir_path) timer:stop() timer:start(50, 0, buf_jj_set_ref_text) end - buf_fs_event:start(jj_dir_path, { recursive = false }, watch_tree_state) + buf_fs_event:start(jj_dir_path, { stat = true }, watch_tree_state) - M.jj_invalidate_cache(M.jj_cache[buf_id]) - M.jj_cache[buf_id] = { fs_event = buf_fs_event, timer = timer } + M.jj_invalidate_cache(M.cache[buf_id]) + M.cache[buf_id] = { fs_event = buf_fs_event, timer = timer } end - M.jj_set_ref_text = vim.schedule_wrap(function(buf_id) if not vim.api.nvim_buf_is_valid(buf_id) then return @@ -86,13 +84,13 @@ M.jj_set_ref_text = vim.schedule_wrap(function(buf_id) -- Set local stdout = vim.loop.new_pipe() local spawn_opts = { - args = { 'file', 'show', '--ignore-working-copy', '-r', '@-', './' .. basename }, + args = { 'file', 'show', '--no-pager', '--ignore-working-copy', '-r', '@-', './' .. basename }, cwd = cwd, stdio = { nil, stdout, nil }, } local process, stdout_feed = nil, {} - local on_exit = function(exit_code) + process = vim.loop.spawn('jj', spawn_opts, function(exit_code) process:close() if exit_code ~= 0 or stdout_feed[1] == nil then @@ -102,9 +100,8 @@ M.jj_set_ref_text = vim.schedule_wrap(function(buf_id) -- Set reference text accounting for possible 'crlf' end of line in index local text = table.concat(stdout_feed, ''):gsub('\r\n', '\n') buf_set_ref_text(text) - end + end) - process = vim.loop.spawn('jj', spawn_opts, on_exit) M.jj_read_stream(stdout, stdout_feed) end) @@ -132,7 +129,7 @@ end M.gen_source = function() local attach = function(buf_id) -- Try attaching to a buffer only once - if M.jj_cache[buf_id] ~= nil then + if M.cache[buf_id] ~= nil then return false end -- - Possibly resolve symlinks to get data from the original repo @@ -141,13 +138,13 @@ M.gen_source = function() return false end - M.jj_cache[buf_id] = {} + M.cache[buf_id] = {} M.jj_start_watching_tree_state(buf_id, path) end local detach = function(buf_id) - local cache = M.jj_cache[buf_id] - M.jj_cache[buf_id] = nil + local cache = M.cache[buf_id] + M.cache[buf_id] = nil M.jj_invalidate_cache(cache) end diff --git a/nvim/lua/plugins/lib/session_jj.lua b/nvim/lua/plugins/lib/session_jj.lua index ee9bf6a..9fe5cf0 100644 --- a/nvim/lua/plugins/lib/session_jj.lua +++ b/nvim/lua/plugins/lib/session_jj.lua @@ -50,7 +50,7 @@ M.load = function() -- load session (buffers, etc) as well as shada (marks) sessions.read(id) vim.cmd('rshada') - vim.notify('loaded jj session: ' .. id) + Snacks.notify('loaded jj session: ' .. id) end end) else diff --git a/nvim/lua/plugins/lib/snacks.lua b/nvim/lua/plugins/lib/snacks.lua index 8945232..d7fc22a 100644 --- a/nvim/lua/plugins/lib/snacks.lua +++ b/nvim/lua/plugins/lib/snacks.lua @@ -1,10 +1,10 @@ M = {} M.marks = function() - return { - finder = 'vim_marks', - format = 'file', + Snacks.picker.marks { ['local'] = false, - global = true, + on_show = function() + vim.cmd.delmarks { args = { '0-9' } } + end, actions = { markdel = function(picker) for _, item in ipairs(picker:selected()) do @@ -17,10 +17,42 @@ M.marks = function() end, }, win = { - list = { - keys = { ['dd'] = 'markdel' }, + input = { + keys = { [''] = 'markdel' }, }, }, } end +M.diagnostics = function(filter) + Snacks.picker.diagnostics { + filter = filter, + focus = 'list', + format = function(item, picker) + P = require('snacks.picker.format') + local ret = {} ---@type snacks.picker.Highlight[] + vim.list_extend(ret, P.filename(item, picker)) + + local diag = item.item ---@type vim.Diagnostic + if item.severity then + vim.list_extend(ret, P.severity(item, picker)) + end + + local message = diag.message + ret[#ret + 1] = { message } + Snacks.picker.highlight.markdown(ret) + ret[#ret + 1] = { ' ' } + + if diag.source then + ret[#ret + 1] = { diag.source, 'SnacksPickerDiagnosticSource' } + ret[#ret + 1] = { ' ' } + end + + if diag.code then + ret[#ret + 1] = { ('(%s)'):format(diag.code), 'SnacksPickerDiagnosticCode' } + ret[#ret + 1] = { ' ' } + end + return ret + end, + } +end return M diff --git a/nvim/lua/plugins/lsp.lua b/nvim/lua/plugins/lsp.lua index 2d3f6ea..88e4cb6 100644 --- a/nvim/lua/plugins/lsp.lua +++ b/nvim/lua/plugins/lsp.lua @@ -1,29 +1,22 @@ return { - { - 'folke/trouble.nvim', - event = 'VeryLazy', - opts = { - pinned = true, - focus = true, - follow = false, - auto_close = false, - win = { - size = 0.33, - position = 'right', - type = 'split', - }, - }, - keys = { - { - 'gre', - 'Trouble diagnostics toggle', - desc = 'Trouble diagnostics', - }, - }, - }, { 'neovim/nvim-lspconfig', event = 'VeryLazy', + dependencies = { + 'folke/trouble.nvim', + event = 'VeryLazy', + opts = { + pinned = true, + focus = true, + follow = false, + auto_close = false, + win = { + size = 0.33, + position = 'right', + type = 'split', + }, + }, + }, config = function() vim.lsp.enable { 'nil_ls', @@ -40,23 +33,35 @@ return { return end vim.keymap.set('n', 'grg', 'Trouble lsp toggle', { buffer = ev.buf, desc = 'Trouble LSP' }) - vim.keymap.set( - 'n', - 'gO', - 'Trouble lsp_document_symbols win.position=left', - { buffer = ev.buf, desc = 'Trouble LSP symbols' } - ) - vim.keymap.set('n', 'grd', function() + + vim.keymap.set('n', 'gO', function() + Snacks.picker.lsp_symbols { focus = 'list' } + end, { buffer = ev.buf, desc = 'LSP symbols' }) + vim.keymap.set('n', '', function() Snacks.picker.lsp_definitions { focus = 'list' } end, { buffer = ev.buf, desc = 'LSP definition' }) + vim.keymap.set('n', 'grt', function() + Snacks.picker.lsp_type_definitions { focus = 'list' } + end, { buffer = ev.buf, desc = 'LSP type definition' }) vim.keymap.set('n', 'grr', function() Snacks.picker.lsp_references { focus = 'list' } - end, { buffer = ev.buf, desc = 'LSP definition' }) + end, { buffer = ev.buf, desc = 'LSP refrences' }) + vim.keymap.set('n', 'gri', function() + Snacks.picker.lsp_implementations { focus = 'list' } + end, { buffer = ev.buf, desc = 'LSP implementations' }) + vim.keymap.set('n', 'grh', function() vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) end, { buffer = ev.buf, desc = 'LSP hints toggle' }) vim.keymap.set('n', 'grl', vim.lsp.codelens.run, { buffer = ev.buf, desc = 'vim.lsp.codelens.run()' }) + vim.keymap.set('n', 'gre', function() + require('plugins.lib.snacks').diagnostics { buf = true } + end, { buffer = ev.buf, desc = 'LSP buffer diagnostics' }) + vim.keymap.set('n', 'grE', function() + require('plugins.lib.snacks').diagnostics { cwd = false } + end, { buffer = ev.buf, desc = 'LSP diagnostics' }) + -- Auto-refresh code lenses if client.server_capabilities.codeLensProvider then vim.api.nvim_create_autocmd({ 'InsertLeave', 'TextChanged' }, { @@ -81,6 +86,7 @@ return { '\\f', function() vim.b.disable_autoformat = not vim.b.disable_autoformat + Snacks.notify(string.format('Buffer formatting disabled: %s', vim.b.disable_autoformat)) end, mode = { 'n', 'x' }, desc = 'toggle buffer formatting', @@ -89,6 +95,7 @@ return { '\\F', function() vim.g.disable_autoformat = not vim.g.disable_autoformat + Snacks.notify(string.format('Global formatting disabled: %s', vim.g.disable_autoformat)) end, mode = { 'n', 'x' }, desc = 'toggle global formatting', diff --git a/nvim/lua/plugins/mini.lua b/nvim/lua/plugins/mini.lua index 27066f0..5b8f301 100644 --- a/nvim/lua/plugins/mini.lua +++ b/nvim/lua/plugins/mini.lua @@ -50,6 +50,17 @@ return { require('mini.tabline').setup { tabpage_section = 'right', show_icons = false, + format = function(buf_id, label) -- show global marks in tab + local default = MiniTabline.default_format(buf_id, label) + for _, mark in ipairs(vim.fn.getmarklist()) do + if mark.pos[1] == buf_id then + if mark.mark:match("^'[A-Z]$") then + return ' [' .. mark.mark:sub(2) .. ']' .. default + end + end + end + return default + end, } require('mini.statusline').setup { content = { @@ -175,15 +186,10 @@ return { width_preview = 50, }, } - vim.keymap.set( - 'n', - 'nc', - function() - files.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir - files.reveal_cwd() - end, - { desc = 'minifiles open' } - ) + vim.keymap.set('n', 'nc', function() + files.open(vim.api.nvim_buf_get_name(0), false) -- open current buffer's dir + files.reveal_cwd() + end, { desc = 'minifiles open' }) vim.api.nvim_create_autocmd('User', { pattern = 'MiniFilesBufferCreate', callback = function(args) diff --git a/nvim/lua/plugins/snacks.lua b/nvim/lua/plugins/snacks.lua index 730a4f6..9c62be3 100644 --- a/nvim/lua/plugins/snacks.lua +++ b/nvim/lua/plugins/snacks.lua @@ -37,7 +37,7 @@ return { }, smart = { multi = { - require('plugins.lib.snacks').marks(), + 'marks', { source = 'buffers', current = false }, 'recent', { source = 'files', hidden = true }, @@ -178,8 +178,7 @@ return { { 'fm', function() - vim.cmd.delmarks { args = { '0-9' } } - Snacks.picker.pick(require('plugins.lib.snacks').marks()) + require('plugins.lib.snacks').marks() end, desc = 'pick global marks', }, diff --git a/nvim/lua/plugins/treesitter.lua b/nvim/lua/plugins/treesitter.lua index ddb5da9..51efd4d 100644 --- a/nvim/lua/plugins/treesitter.lua +++ b/nvim/lua/plugins/treesitter.lua @@ -32,12 +32,10 @@ return { goto_next_start = { [']a'] = '@parameter.inner', [']f'] = '@function.outer', - [']t'] = '@statement.outer', }, goto_previous_start = { ['[a'] = '@parameter.inner', ['[f'] = '@function.outer', - ['[t'] = '@statement.outer', }, }, swap = {