diff options
Diffstat (limited to 'nvim')
-rw-r--r-- | nvim/.config/nvim/init.lua | 2 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/plugins/dressing.lua | 24 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/commands.lua | 6 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/utils.lua | 21 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/utils/ui.lua | 209 |
5 files changed, 219 insertions, 43 deletions
diff --git a/nvim/.config/nvim/init.lua b/nvim/.config/nvim/init.lua index e741a74..d4fe74b 100644 --- a/nvim/.config/nvim/init.lua +++ b/nvim/.config/nvim/init.lua @@ -1,4 +1,6 @@ U = require("tobyvin.utils") +vim.ui.select = U.ui.select +vim.ui.input = U.ui.input require("tobyvin.options") require("tobyvin.filetype") require("tobyvin.autocmds") diff --git a/nvim/.config/nvim/lua/plugins/dressing.lua b/nvim/.config/nvim/lua/plugins/dressing.lua deleted file mode 100644 index e9fa349..0000000 --- a/nvim/.config/nvim/lua/plugins/dressing.lua +++ /dev/null @@ -1,24 +0,0 @@ ----@type LazyPluginSpec -local M = { - "stevearc/dressing.nvim", - dependencies = { - "nvim-telescope/telescope.nvim", - }, - opts = {}, -} - -function M.init() - ---@diagnostic disable-next-line: duplicate-set-field - vim.ui.select = function(...) - require("lazy").load({ plugins = { "dressing.nvim" } }) - return vim.ui.select(...) - end - - ---@diagnostic disable-next-line: duplicate-set-field - vim.ui.input = function(...) - require("lazy").load({ plugins = { "dressing.nvim" } }) - return vim.ui.input(...) - end -end - -return M diff --git a/nvim/.config/nvim/lua/tobyvin/commands.lua b/nvim/.config/nvim/lua/tobyvin/commands.lua index c6f159a..8a41e67 100644 --- a/nvim/.config/nvim/lua/tobyvin/commands.lua +++ b/nvim/.config/nvim/lua/tobyvin/commands.lua @@ -11,12 +11,14 @@ end, { nargs = "?", desc = "scratch buffer", complete = "filetype" }) vim.api.nvim_create_user_command("Runtime", function(opts) local items = vim.api.nvim_get_runtime_file(("*%s*"):format(opts.args), not opts.bang) - U.select(items, { + vim.ui.select(items, { prompt = "select runtime file", format_item = function(item) return item:gsub(vim.env.HOME, "~") end, }, function(item) - vim.cmd.edit(item) + if item then + vim.cmd.edit(item) + end end) end, { nargs = "?", bang = true, desc = "scratch buffer", complete = "filetype" }) diff --git a/nvim/.config/nvim/lua/tobyvin/utils.lua b/nvim/.config/nvim/lua/tobyvin/utils.lua index 0c2a316..ddbb5c2 100644 --- a/nvim/.config/nvim/lua/tobyvin/utils.lua +++ b/nvim/.config/nvim/lua/tobyvin/utils.lua @@ -1,10 +1,11 @@ local M = { - fs = require("tobyvin.utils.fs"), buf = require("tobyvin.utils.buf"), - dashboard = require("tobyvin.utils.dashboard"), - session = require("tobyvin.utils.session"), dap = require("tobyvin.utils.dap"), + dashboard = require("tobyvin.utils.dashboard"), + fs = require("tobyvin.utils.fs"), lsp = require("tobyvin.utils.lsp"), + session = require("tobyvin.utils.session"), + ui = require("tobyvin.utils.ui"), } function M.inspect(v) @@ -12,20 +13,6 @@ function M.inspect(v) return v end -function M.select(items, opts, on_choice) - if #items == 1 then - on_choice(items[1]) - elseif #items > 1 then - vim.ui.select(items, opts, function(item, idx) - if item ~= nil then - on_choice(item, idx) - end - end) - else - vim.print("No results found") - end -end - function M.lazy_require(modname) return setmetatable({}, { __index = function(_, k) diff --git a/nvim/.config/nvim/lua/tobyvin/utils/ui.lua b/nvim/.config/nvim/lua/tobyvin/utils/ui.lua new file mode 100644 index 0000000..1e7b173 --- /dev/null +++ b/nvim/.config/nvim/lua/tobyvin/utils/ui.lua @@ -0,0 +1,209 @@ +local M = {} + +function M.select(items, opts, on_choice) + vim.validate({ + items = { items, "table", false }, + opts = { opts, { "table", nil }, false }, + on_choice = { on_choice, "function", false }, + }) + + opts = vim.tbl_extend("keep", opts or {}, { + format_item = tostring, + }) + + local fmt_items = vim.iter(items) + :map(function(item) + local text = opts.format_item(item) + return text + end) + :totable() + + ---@type vim.api.keyset.win_config + local config = { + width = vim.iter(fmt_items):fold(vim.api.nvim_strwidth(opts.prompt), function(acc, item) + return math.max(vim.api.nvim_strwidth(item), acc) + end), + height = #items, + zindex = 200, + style = "minimal", + border = "single", + title = opts.prompt, + } + + if opts.kind == "codeaction" then + config.relative = "cursor" + config.row = 1 + config.col = 0 + config.footer = vim.lsp.get_client_by_id(items[1].ctx.client_id).name + else + config.relative = "editor" + config.col = math.floor((vim.o.columns - config.width) / 2) + config.row = math.floor((vim.o.lines - vim.o.cmdheight - config.height) / 2) + end + + local buffer = vim.api.nvim_create_buf(false, true) + local window = vim.api.nvim_open_win(buffer, true, config) + + local ns_id = vim.api.nvim_create_namespace("select") + vim.api.nvim_buf_add_highlight(buffer, ns_id, "Pmenu", 0, 0, -1) + vim.api.nvim_set_hl(ns_id, "CursorLine", { link = "PmenuSel" }) + vim.api.nvim_set_hl(ns_id, "Cursor", { cterm = nil, gui = nil, blend = 100 }) + vim.api.nvim_win_set_hl_ns(window, ns_id) + + vim.api.nvim_buf_set_lines(buffer, 0, 0, false, fmt_items) + vim.api.nvim_buf_set_lines(buffer, -2, -1, false, {}) + + vim.api.nvim_set_option_value("modifiable", false, { buf = buffer }) + vim.api.nvim_set_option_value("filetype", "select", { buf = buffer }) + vim.api.nvim_set_option_value("swapfile", false, { buf = buffer }) + vim.api.nvim_set_option_value("bufhidden", "wipe", { buf = buffer }) + vim.api.nvim_set_option_value("scrolloff", 0, { win = window }) + vim.api.nvim_set_option_value("cursorline", true, { win = window }) + + vim.api.nvim_win_set_cursor(window, { 1, 0 }) + local guicursor = vim.o.guicursor + vim.opt.guicursor = "a:noCursor" + + local function make_on_choice(choosen) + return function() + local row = unpack(vim.api.nvim_win_get_cursor(window)) + if vim.api.nvim_win_is_valid(window) then + vim.api.nvim_win_close(window, true) + end + vim.opt.guicursor = guicursor + if choosen then + on_choice(items[row], row) + else + on_choice(nil, nil) + end + end + end + + vim.keymap.set({ "n", "v" }, "<cr>", make_on_choice(true), { buffer = buffer }) + vim.keymap.set({ "n", "v" }, "<2-LeftMouse>", make_on_choice(true), { buffer = buffer }) + vim.keymap.set({ "n", "v" }, "<esc>", make_on_choice(false), { buffer = buffer }) + vim.keymap.set({ "n", "v" }, "q", make_on_choice(false), { buffer = buffer }) + vim.api.nvim_create_autocmd({ "BufLeave" }, { + buffer = buffer, + callback = make_on_choice(false), + }) + + vim.api.nvim_create_autocmd({ "CursorMoved" }, { + buffer = buffer, + callback = function() + local row = unpack(vim.api.nvim_win_get_cursor(window)) + if items[row].ctx then + vim.api.nvim_win_set_config(window, { + footer = vim.lsp.get_client_by_id(items[row].ctx.client_id).name, + }) + end + end, + }) +end + +function M.input(opts, on_confirm) + vim.validate({ + opts = { opts, "table", true }, + on_confirm = { on_confirm, "function", false }, + }) + + opts = opts or {} + M.completion = opts.completion + + local config = { + relative = "cursor", + width = vim.print(math.max(vim.api.nvim_strwidth(opts.prompt or ""), 20)), + height = 1, + row = 1, + col = 0, + zindex = 200, + style = "minimal", + border = "single", + title = opts.prompt, + } + + local buffer = vim.api.nvim_create_buf(false, true) + local window = vim.api.nvim_open_win(buffer, true, config) + local ns_id = vim.api.nvim_create_namespace("select") + + vim.b[buffer].completefunc = function(findstart, base) + if not opts.completion then + return findstart == 1 and 0 or {} + end + if findstart == 1 then + return 0 + else + local pieces = vim.split(opts.completion, ",", { plain = true }) + if pieces[1] == "custom" or pieces[1] == "customlist" then + local vimfunc = pieces[2] + local ret + if vim.startswith(vimfunc, "v:lua.") then + local load_func = string.format("return %s(...)", vimfunc:sub(7)) + local luafunc, err = loadstring(load_func) + if not luafunc then + vim.api.nvim_err_writeln( + string.format("Could not find completion function %s: %s", vimfunc, err) + ) + return {} + end + ret = luafunc(base, base, vim.fn.strlen(base)) + else + ret = vim.fn[vimfunc](base, base, vim.fn.strlen(base)) + end + if pieces[1] == "custom" then + ret = vim.split(ret, "\n", { plain = true }) + end + return ret + else + local ok, result = pcall(vim.fn.getcompletion, base, opts.completion) + return ok and result or {} + end + end + end + + vim.api.nvim_buf_add_highlight(buffer, ns_id, "Pmenu", 0, 0, -1) + vim.api.nvim_set_hl(ns_id, "CursorLine", { link = "PmenuSel" }) + vim.api.nvim_win_set_hl_ns(window, ns_id) + + vim.api.nvim_buf_set_lines(buffer, 0, 0, false, { opts.default }) + vim.api.nvim_buf_set_lines(buffer, -2, -1, false, {}) + + vim.api.nvim_set_option_value("filetype", "input", { buf = buffer }) + vim.api.nvim_set_option_value("swapfile", false, { buf = buffer }) + vim.api.nvim_set_option_value("bufhidden", "wipe", { buf = buffer }) + vim.api.nvim_set_option_value("scrolloff", 0, { win = window }) + vim.api.nvim_set_option_value("completefunc", "v:lua.vim.b.completefunc", { buf = buffer }) + vim.api.nvim_set_option_value("omnifunc", "v:lua.vim.b.completefunc", { buf = buffer }) + + vim.cmd.startinsert({ bang = true }) + + vim.keymap.set("i", "<cr>", function() + local text = vim.api.nvim_buf_get_lines(buffer, 0, 1, false)[1] + + if vim.fn.pumvisible() == 1 then + local escape_key = vim.api.nvim_replace_termcodes("<C-e>", true, false, true) + vim.api.nvim_feedkeys(escape_key, "n", true) + end + + vim.cmd.stopinsert() + vim.defer_fn(function() + pcall(vim.api.nvim_win_close, window, true) + vim.defer_fn(function() + on_confirm(text) + end, 5) + end, 5) + end, { buffer = buffer }) + + vim.api.nvim_create_autocmd({ "BufLeave", "InsertLeave" }, { + desc = "Cancel vim.ui.input", + buffer = buffer, + nested = true, + once = true, + callback = function() + pcall(vim.api.nvim_win_close, window, true) + on_confirm(nil) + end, + }) +end + +return M |