-- misc stuff implemented in lua local M = {} 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 get_searchdirs = function(dirs) if type(dirs) == 'table' and #dirs > 0 then return dirs elseif type(dirs) == 'string' and not (dirs == '') then dirs = vim.split(dirs, ',') end -- skip asking if we're looking at known filetypes local ft = vim.api.nvim_buf_get_option(0, 'filetype') if #dirs == 0 and (ft == 'dirbuf' or ft == 'alpha') then dirs = { '%:p:h' } end -- ask user if #dirs == 0 then vim.ui.input({ prompt = 'Search directories: ' }, function(result) dirs = { result } end) end -- default to something reasonable if #dirs == 0 then dirs = { '%:p:h' } end -- finally return for i = 1, #dirs do dirs[i] = vim.fn.expand(dirs[i]) end return dirs end local function onchoice(opts, cb) if not cb then return end opts.attach_mappings = function(prompt_bufnr) require('telescope.actions').select_default:replace(function() local selection = require('telescope.actions.state').get_selected_entry() if selection == nil then return end require('telescope.actions').close(prompt_bufnr) cb(selection.path) end) return true end end function M.live_grep(dirs, opts, cb) opts = opts or {} local search_dirs = get_searchdirs(dirs) opts.search_dirs = search_dirs opts.prompt_title = 'Grep: ' .. vim.inspect(search_dirs) onchoice(opts, cb) require('telescope.builtin').live_grep(opts) end function M.find_files(dirs, opts, cb) -- convenience aliases 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: ' .. vim.inspect(search_dirs) onchoice(opts, cb) require('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('\\', '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('\\', '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('') 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 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, }) :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 function M.setup(opts) opts = opts or {} if opts.sortline then vim.api.nvim_create_user_command( 'SortLine', M.sort_lines, { desc = 'sort line', range = '%', preview = M.sort_lines } ) end if opts.grep then vim.api.nvim_create_user_command('Grep', function(o) M.live_grep(table.concat(o.fargs)) end, { desc = 'live grep (rg)', nargs = '*', complete = 'dir', }) end if opts.find then vim.api.nvim_create_user_command('Find', function(o) M.find_files(table.concat(o.fargs)) end, { desc = 'find files (fd)', nargs = '*', complete = 'dir', }) end end return M