summary refs log tree commit diff
path: root/.vim/lua/internal/misc.lua
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2022-10-14 20:57:03 +0200
committerRobert Günzler <r@gnzler.io>2022-10-14 21:01:15 +0200
commit2d2009413f8be624a7cca95cf702e32d9315cbef (patch)
treef024c1b5b27b886530e86221593e3cfdc3672d7e /.vim/lua/internal/misc.lua
parent6d7e524d3d7a71da2cea61b335a59e9544e2a6f7 (diff)
vim: move custom modules under internal/
Diffstat (limited to '.vim/lua/internal/misc.lua')
-rw-r--r--.vim/lua/internal/misc.lua210
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