diff options
Diffstat (limited to '.vim/lua/internal/misc.lua')
| -rw-r--r-- | .vim/lua/internal/misc.lua | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/.vim/lua/internal/misc.lua b/.vim/lua/internal/misc.lua new file mode 100644 index 0000000..5a2ae21 --- /dev/null +++ b/.vim/lua/internal/misc.lua @@ -0,0 +1,210 @@ +-- misc stuff implemented in lua + +local M = {} + +function M.do_under_cursor(obj, cb) + return cb(vim.fn.expand(vim.fn.expand(obj))) +end + +function M.word_under_cursor(cb) + return M.do_under_cursor('<cword>', cb) +end + +function M.expr_under_cursor(cb) + return M.do_under_cursor('<cexpr>', cb) +end + +function M.file_under_cursor(cb) + return M.do_under_cursor('<cfile>', cb) +end + +function M.open_under_cursor(cmd, detect_cmd) + return M.file_under_cursor(function(txt) + txt = vim.trim(txt) + if not cmd and detect_cmd then + if vim.regex([[^http.*$]]):match_str(txt) then + cmd = 'url-launcher' + end + if vim.regex([[^(\.\./|[\w\d_/\-])*(\.[\w\d]+)?$]]):match_str(txt) then + cmd = ':edit' + end + vim.notify("open_under_cursor: detected command " .. txt .. " => " .. (cmd or "<nil>")) + end + if not cmd then + vim.fn.inputsave() + vim.ui.input('open with: ', function(result) cmd = result end) + vim.fn.inputrestore() + if not cmd then return end + end + -- detect vim command + if cmd:sub(1, 1) == ":" then + vim.cmd(cmd:sub(2) .. ' ' .. txt) + else + vim.loop.spawn(cmd, {args = {txt}}) + end + end) +end + +local function get_visual_selection() + local top = vim.fn.getpos("'<") + top = { ln = top[2], col = top[3] } + local bot = vim.fn.getpos("'>") + bot = { ln = bot[2], col = bot[3] } + local lines = vim.api.nvim_buf_get_lines(0, (top.ln - 1), bot.ln, false) + if vim.opt.selection:get() == 'inclusive' then + lines[#lines] = lines[#lines]:sub(1, bot.col) + else + lines[#lines] = lines[#lines]:sub(1, (bot.col -1)) + end + lines[1] = lines[1]:sub(top.col) + return top, bot, lines +end + +function M.sort_lines(_, preview_ns, preview_bufnr) + local bufnr = vim.api.nvim_get_current_buf() + + local top, bot, lines = get_visual_selection() + for i=1, #lines do + lines[i] = vim.fn.join(vim.fn.sort(vim.fn.split(lines[i], " "))) + end + + if not preview_ns then + vim.api.nvim_buf_set_lines(bufnr, top.ln-1, bot.ln, false, lines) + vim.notify('no preview') + return 0 + end + + -- inccommand preview + if preview_ns ~= nil then + for i, line in ipairs(lines) do + vim.api.nvim_buf_set_extmark(bufnr, preview_ns, top.ln+i - 2, 0, { + hl_mode = 'combine', + virt_text_pos = 'overlay', + virt_text = {{line, 'Substitute'}}, + }) + + if preview_bufnr ~= nil then + local prefix = string.format('|%d| ', top.ln + i - 1) + vim.api.nvim_buf_set_lines(preview_bufnr, i-1, -1, false, { prefix .. line }) + vim.api.nvim_buf_add_highlight(preview_bufnr, preview_ns, 'Substitute', i, #prefix, #prefix+#line) + end + end + return (#lines > 1 and 2 or 1) + end +end + +local telescope_builtin = require('telescope.builtin') +local telescope_actions = require('telescope.actions') +local telescope_action_state = require('telescope.actions.state') + +local get_searchdirs = function(dirs) + -- skip asking if we're looking at known filetypes + local ft = vim.api.nvim_buf_get_option(0, 'filetype') + if not dirs and (ft == 'dirbuf' or ft == 'alpha') then + dirs = '%:p:h' + end + if not dirs then + vim.ui.input('Search directories: ', function(result) dirs = result end) + end + -- default to something reasonable + if not dirs then dirs = '%:p:h' end + return vim.split(vim.fn.expand(dirs), ',') +end + +function M.live_grep(dirs, opts, on_choice) + opts = opts or {} + local search_dirs = get_searchdirs(dirs) + opts.search_dirs = search_dirs + opts.prompt_title = 'Grep: '.. table.concat(search_dirs) + if on_choice then + opts.attach_mappings = function(prompt_bufnr) + telescope_actions.select_default:replace(function() + local selection = telescope_action_state.get_selected_entry() + if selection == nil then return end + telescope_actions.close(prompt_bufnr) + on_choice(selection.path) + end) + return true + end + end + telescope_builtin.live_grep(opts) +end + +function M.find_files(dirs, opts, on_choice) + if dirs == 'plugins' then dirs = vim.fn.stdpath('data') .. '/site/pack/' end + + opts = opts or {} + local search_dirs = dirs + if type(dirs) == 'string' then search_dirs = get_searchdirs(dirs) end + opts.search_dirs = search_dirs + opts.prompt_title = 'Find: '.. table.concat(search_dirs) + if on_choice then + opts.attach_mappings = function(prompt_bufnr) + telescope_actions.select_default:replace(function() + local selection = telescope_action_state.get_selected_entry() + if not selection then + vim.notify('Nothing selected', vim.log.levels.WARN) + return + end + telescope_actions.close(prompt_bufnr) + on_choice(selection.path) + end) + return true + end + end + telescope_builtin.find_files(opts) +end + + +function M.fold_block() -- {{{ + local Comment = require('Comment.api') + local m = vim.api.nvim_buf_get_mark + local inital_cusor_pos = vim.api.nvim_win_get_cursor(0) + local spos, epos = m(0, '<'), m(0, '>') + + -- do start of selection + vim.api.nvim_win_set_cursor(0, spos) + Comment.insert_linewise_eol() + vim.api.nvim_feedkeys('\\<esc>', 'ni', true) + local sln = vim.api.nvim_get_current_line() + vim.api.nvim_set_current_line(sln .. '{{{') + + -- do end of selection + vim.api.nvim_win_set_cursor(0, epos) + Comment.insert_linewise_eol() + vim.api.nvim_feedkeys('\\<esc>', 'ni', true) + local eln = vim.api.nvim_get_current_line() + vim.api.nvim_set_current_line(eln .. '}}}') + + -- restore initial cursor postition + vim.api.nvim_win_set_cursor(0, inital_cusor_pos) +end -- }}} + +function M.link_preview() + local link = vim.fn.expand('<cfile>') + if not link then return end + + local buf = vim.api.nvim_get_current_buf() + local ln = (vim.api.nvim_win_get_cursor(0)[1]) - 1 + + local j = require('job').jobstart({ + format_title = function() return "link-preview" end, + command = vim.env.SHELL, + args = {'-c', [[ curl -sSfL ]] .. link .. [[ | grep -iPo '(?<=property="og:title" content=")([^\"]+)(?=")' ]]}, + populate_quickfix = false, + enable_recording = true, + }) + + j:after_success(vim.schedule_wrap(function(j, code, _) + local results = j:result() + if not code == 0 or #results == 0 then return end + + local ns = vim.api.nvim_create_namespace('') + vim.api.nvim_buf_set_extmark(buf, ns, ln, 0, { + virt_text = {{results[1], 'Error'}}, + virt_text_pos = 'eol' + }) + end)) +end + +return M |