From f05ee881bc8341e3c80f64fe48df6215f852689d Mon Sep 17 00:00:00 2001 From: handdara Date: Tue, 21 Jan 2025 15:47:25 -0500 Subject: [PATCH] Wrote quick neovim list ranker --- .../nvim-nrw/lua/handdara/config/commands.lua | 16 +++-- fst/him/nvim-nrw/lua/handdara/util/init.lua | 15 ++-- fst/him/nvim-nrw/lua/handdara/util/ranker.lua | 72 +++++++++++++++++++ 3 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 fst/him/nvim-nrw/lua/handdara/util/ranker.lua diff --git a/fst/him/nvim-nrw/lua/handdara/config/commands.lua b/fst/him/nvim-nrw/lua/handdara/config/commands.lua index 7cc3491..f03f84d 100644 --- a/fst/him/nvim-nrw/lua/handdara/config/commands.lua +++ b/fst/him/nvim-nrw/lua/handdara/config/commands.lua @@ -1,8 +1,12 @@ + return function() - vim.api.nvim_create_user_command('W', 'write', {}) - vim.api.nvim_create_user_command('Wq', 'wq', {}) - vim.api.nvim_create_user_command('Q', 'quit', {}) - vim.api.nvim_create_user_command('Qa', 'qall', {}) - vim.api.nvim_create_user_command('Wqa', 'wqall', {}) - vim.api.nvim_create_user_command('FO', 'Fo', {}) + vim.api.nvim_create_user_command('W', 'write', {}) + vim.api.nvim_create_user_command('Wq', 'wq', {}) + vim.api.nvim_create_user_command('Q', 'quit', {}) + vim.api.nvim_create_user_command('Qa', 'qall', {}) + vim.api.nvim_create_user_command('Wqa', 'wqall', {}) + vim.api.nvim_create_user_command('FO', 'Fo', {}) + vim.api.nvim_create_user_command('Ranker', function (opts) + require('handdara.util.ranker').ranker(opts.line1, opts.line2) + end , { range = true }) end diff --git a/fst/him/nvim-nrw/lua/handdara/util/init.lua b/fst/him/nvim-nrw/lua/handdara/util/init.lua index 3e09163..820ff6e 100644 --- a/fst/him/nvim-nrw/lua/handdara/util/init.lua +++ b/fst/him/nvim-nrw/lua/handdara/util/init.lua @@ -1,5 +1,7 @@ +local M = {} + -- datetime number to string -local function dtnum2str(x) +function M.dtnum2str(x) local xs = tostring(x) if x < 10 then return '0' .. xs @@ -8,7 +10,7 @@ local function dtnum2str(x) end end -local function timestamp() +function M.timestamp() local ts = os.date('*t') local months = { 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' } local weekdays = { 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' } @@ -19,12 +21,9 @@ local function timestamp() mo_num = ts.month, wd = weekdays[ts.wday], wd_num = ts.wday, - hr = dtnum2str(ts.hour), - mi = dtnum2str(ts.min), + hr = M.dtnum2str(ts.hour), + mi = M.dtnum2str(ts.min), } end -return { - timestamp = timestamp, - dtnum2str = dtnum2str, -} +return M diff --git a/fst/him/nvim-nrw/lua/handdara/util/ranker.lua b/fst/him/nvim-nrw/lua/handdara/util/ranker.lua new file mode 100644 index 0000000..8948b7d --- /dev/null +++ b/fst/him/nvim-nrw/lua/handdara/util/ranker.lua @@ -0,0 +1,72 @@ +local M = {} + +local function user_cmp_sync(prompt, x, y) + -- Create a placeholder for the input result + local result = nil + + -- Create a coroutine + local co = coroutine.running() + if not co then + error("This function must be called from within a coroutine") + end + vim.ui.select({ x, y }, { + prompt = prompt, + format_item = function(item) + return '- ' .. item + end, + }, function(choice) + result = choice + coroutine.resume(co) + end) + -- Yield control until the coroutine is resumed + coroutine.yield() + return result +end + +local function sort(xs, cmp) + if #xs <= 1 then + return + else + local left, right = {}, {} + local pivot = xs[1] + for i = 2, #xs do + -- cmp ~ < + if cmp(pivot, xs[i]) then + table.insert(right, xs[i]) + else + table.insert(left, xs[i]) + end + end + sort(left, cmp) + sort(right, cmp) + for j, v in ipairs(left) do + xs[j] = v + end + xs[#left + 1] = pivot + for j, v in ipairs(right) do + xs[j + 1 + #left] = v + end + end +end + +-- Example usage +local function rank(items, line1, line2) + local cmp = function(x, y) + local result = user_cmp_sync("Pick better:", x, y) + if result then + return x == result + else + vim.notify("cancelled ranker") + error("cancelled sort") + end + end + sort(items, cmp) + vim.api.nvim_buf_set_lines(0, line1 - 1, line2, false, items) +end + +function M.ranker(line1, line2) + local items = vim.api.nvim_buf_get_lines(0, line1 - 1, line2, false) + coroutine.wrap(rank)(items, line1, line2) +end + +return M