You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
8.9 KiB
309 lines
8.9 KiB
local builtin |
|
local telescope |
|
|
|
local F = require("core.functions") |
|
|
|
local M = {} |
|
|
|
M.setup = function() |
|
-- Prevent dependency loop |
|
builtin = require("telescope.builtin") |
|
telescope = require("telescope") |
|
end |
|
|
|
-- Set which-key key section description |
|
M.wk = function(keybind, description, bufnr) |
|
require("which-key").register({ |
|
[keybind] = { name = description, _ = "which_key_ignore" }, |
|
}, { mode = { "n", "v" }, buffer = bufnr }) -- bufnr = nil means global |
|
end |
|
|
|
M.buffer_close = function() |
|
-- Check if there are more than 2 buffers and alternate file is set |
|
local command = vim.fn.expand("#") ~= "" and #vim.fn.getbufinfo({ buflisted = 1 }) > 1 |
|
and "e #|bd #|bwipeout #" -- see `:h c_#` |
|
or "bd" |
|
vim.api.nvim_command(command) |
|
end |
|
|
|
M.buffer_dashboard = function() |
|
vim.api.nvim_command("Dashboard") |
|
end |
|
|
|
M.file_config = function() |
|
builtin.find_files({ |
|
prompt_title = "Nvim Config", |
|
cwd = "~/.config/nvim", |
|
hidden = true, |
|
no_ignore = true, |
|
-- path_display = { "shorten" }, |
|
}) |
|
end |
|
|
|
M.file_find = function() |
|
builtin.find_files({ |
|
cwd = F.get_current_directory(), |
|
hidden = true, |
|
no_ignore = true, |
|
}) |
|
end |
|
|
|
M.file_find_home = function() |
|
builtin.find_files({ |
|
cwd = "~", |
|
hidden = true, |
|
no_ignore = true, |
|
}) |
|
end |
|
|
|
M.file_find_root = function() |
|
local cwd = F.get_current_directory():gsub("^/", "") |
|
builtin.find_files({ default_text = cwd, cwd = "/" }) |
|
end |
|
|
|
M.file_find_recent = function() |
|
telescope.extensions.recent_files.pick() |
|
end |
|
|
|
M.file_save = function() |
|
vim.api.nvim_command("w") |
|
end |
|
|
|
M.goto_trouble = function() |
|
vim.api.nvim_command("Trouble") |
|
end |
|
|
|
M.goto_todos_telescope = function() |
|
vim.api.nvim_command("TodoTelescope") |
|
end |
|
|
|
M.goto_todos_trouble = function() |
|
vim.api.nvim_command("TodoTrouble") |
|
end |
|
|
|
-- Smart delete |
|
M.hungry_delete = function() |
|
return function() |
|
local start_line = vim.fn.line(".") |
|
local start_col = vim.fn.col(".") |
|
local start_line_content = vim.fn.getline(start_line) |
|
local line_length = start_line_content:len() |
|
|
|
-- Check if there are multiple whitespace characters after the cursor |
|
local is_1_whitespace = start_line_content:sub(start_col, start_col):match("%s") |
|
local is_2_whitespace = start_line_content:sub(start_col + 1, start_col + 1):match("%s") |
|
if (start_col <= line_length - 1 and is_1_whitespace and is_2_whitespace) |
|
or (start_col == line_length and is_1_whitespace) |
|
or start_col - 1 == line_length then -- in insert mode, the column is 1 higher |
|
-- Hungry delete |
|
|
|
-- Iterate forwards through each line and character |
|
local last_line = vim.fn.line("$") |
|
for line = start_line, last_line do |
|
local line_content = (line == start_line) and start_line_content or vim.fn.getline(line) |
|
local col = (line == start_line) and start_col or 1 |
|
|
|
for c = col, #line_content do |
|
local char = line_content:sub(c, c) |
|
|
|
-- Look until it hits a non-whitespace character |
|
if not vim.fn.strcharpart(char, 0, 1):match("%s") then |
|
-- Delete empty lines, from the starting line to the current line |
|
vim.api.nvim_buf_set_lines(0, start_line - 1, line - 1, false, {}) |
|
|
|
-- Keep the content that was before the cursor at the start_line, |
|
-- plus the content from the current column to the end of the current line |
|
vim.fn.setline(start_line, |
|
start_line_content:sub(1, start_col - 1) .. line_content:sub(c)) |
|
|
|
vim.fn.cursor({ start_line, start_col }) |
|
return |
|
end |
|
end |
|
end |
|
|
|
-- Delete empty lines, if the end of the buffer was only whitespace |
|
vim.api.nvim_buf_set_lines(0, start_line - 1, last_line, false, {}) |
|
|
|
-- Keep the content that was before the cursor |
|
vim.fn.setline(start_line, start_line_content:sub(1, start_col - 1)) |
|
|
|
vim.fn.cursor({ start_line, start_col }) |
|
else |
|
-- Normal delete |
|
vim.cmd("normal! x") |
|
end |
|
end |
|
end |
|
|
|
-- Smart backspace |
|
M.hungry_delete_backspace = function() |
|
-- Cache some values |
|
local core = require("ultimate-autopair.core") |
|
local keycode = vim.api.nvim_replace_termcodes("<Plug>ultimate-autopair-BS", true, false, true) |
|
local fallback = vim.api.nvim_replace_termcodes("<C-h>", true, false, true) -- <BS> => <C-h>, \b |
|
|
|
return function() |
|
local start_line = vim.fn.line(".") |
|
local start_col = vim.fn.col(".") |
|
local start_line_content = vim.fn.getline(start_line) |
|
|
|
-- Check if there are multiple whitespace characters before the cursor |
|
local is_1_whitespace = start_line_content:sub(start_col - 1, start_col - 1):match("%s") |
|
local is_2_whitespace = start_line_content:sub(start_col - 2, start_col - 2):match("%s") |
|
if (start_col >= 3 and is_1_whitespace and is_2_whitespace) |
|
or (start_col == 2 and is_1_whitespace) |
|
or start_col == 1 then |
|
-- Hungry delete |
|
|
|
-- Iterate backwards through each line and character |
|
for line = start_line, 1, -1 do |
|
local line_content = (line == start_line) and start_line_content or vim.fn.getline(line) |
|
local col = (line == start_line) and (start_col - 1) or #line_content |
|
|
|
for c = col, 1, -1 do |
|
local char = line_content:sub(c, c) |
|
|
|
-- Look until it hits a non-whitespace character |
|
if not vim.fn.strcharpart(char, 0, 1):match("%s") then |
|
-- Delete empty lines, from the starting line to the current line |
|
vim.api.nvim_buf_set_lines(0, line - 1, start_line - 1, false, {}) |
|
|
|
-- Keep the content from the start of the current line to the current column, |
|
-- plus the content that was after the cursor at the start_line |
|
vim.fn.setline(line, line_content:sub(1, c) .. (line == start_line |
|
and line_content:sub(start_col) -- found non-whitespace on the same line it started |
|
or start_line_content:sub(start_col))) -- jumped through empty lines |
|
|
|
vim.fn.cursor({ line, c + 1 }) |
|
return |
|
end |
|
end |
|
end |
|
|
|
-- Delete empty lines, if the start of the buffer was only whitespace |
|
vim.api.nvim_buf_set_lines(0, 0, start_line - 1, false, {}) |
|
|
|
-- Keep the content that was after the cursor |
|
vim.fn.setline(1, "" .. start_line_content:sub(start_col)) |
|
else |
|
-- Normal backspace, prevent run_run recursive mapping via fallback to \b |
|
local actions = core.run_run(keycode) |
|
vim.api.nvim_feedkeys(actions ~= keycode and actions or fallback, "n", false) -- equivalent to { expr = true } |
|
end |
|
end |
|
end |
|
|
|
M.lsp_format_buffer = function() |
|
vim.lsp.buf.format({ |
|
formatting_options = { |
|
tabSize = 4, |
|
insertSpaces = false, |
|
}, |
|
}) |
|
end |
|
|
|
M.project_file = function() |
|
local res, err = F.find_project_root() |
|
if res then |
|
builtin.git_files({ cwd = res }) |
|
else -- fall-back to find_files, if current buffer isnt in a project |
|
builtin.find_files({ cwd = err }) |
|
end |
|
end |
|
|
|
M.project_grep = function() |
|
local res, err = F.find_project_root() |
|
builtin.live_grep({ cwd = res or err }) |
|
end |
|
|
|
M.project_list = function() |
|
telescope.extensions.projects.projects() |
|
end |
|
|
|
M.search_buffer = function() |
|
builtin.current_buffer_fuzzy_find({ |
|
previewer = false, |
|
sorting_strategy = "ascending", |
|
}) |
|
end |
|
|
|
-- TODO: Temporary copy/pasted until project_nvim exposes this function |
|
-- https://github.com/ahmedkhalf/project.nvim/issues/145 |
|
-- TODO: Create a Telescope extension out of this, for telescope-all-recent |
|
local function create_finder() |
|
local results = require("project_nvim").get_recent_projects() |
|
local entry_display = require("telescope.pickers.entry_display") |
|
local finders = require("telescope.finders") |
|
|
|
-- Reverse results |
|
for i = 1, math.floor(#results / 2) do |
|
results[i], results[#results - i + 1] = results[#results - i + 1], results[i] |
|
end |
|
local displayer = entry_display.create({ |
|
separator = " ", |
|
items = { |
|
{ |
|
width = 30, |
|
}, |
|
{ |
|
remaining = true, |
|
}, |
|
}, |
|
}) |
|
|
|
local function make_display(entry) |
|
return displayer({ entry.name, { entry.value, "Comment" } }) |
|
end |
|
|
|
return finders.new_table({ |
|
results = results, |
|
entry_maker = function(entry) |
|
local name = vim.fn.fnamemodify(entry, ":t") |
|
return { |
|
display = make_display, |
|
name = name, |
|
value = entry, |
|
ordinal = name .. " " .. entry, |
|
} |
|
end, |
|
}) |
|
end |
|
|
|
M.vc_select_repo = function() |
|
-- local projects = require("project_nvim").get_recent_projects() |
|
|
|
local actions = require("telescope.actions") |
|
local action_state = require("telescope.actions.state") |
|
local conf = require("telescope.config").values |
|
-- local finders = require("telescope.finders") |
|
local pickers = require("telescope.pickers") |
|
pickers.new({}, { |
|
prompt_title = "Select Project", |
|
finder = create_finder(), |
|
-- finder = telescope.extensions.projects.create_finder(), |
|
-- finder = finders.new_table { |
|
-- results = projects, |
|
-- }, |
|
previewer = false, |
|
sorter = conf.generic_sorter({}), |
|
attach_mappings = function(prompt_bufnr) |
|
actions.select_default:replace(function() |
|
actions.close(prompt_bufnr) |
|
|
|
local selection = action_state.get_selected_entry() |
|
-- require("neogit").open({ cwd = selection[1] }) |
|
require("neogit").open({ cwd = selection.value }) |
|
end) |
|
|
|
return true |
|
end, |
|
}):find() |
|
end |
|
|
|
M.vc_status = function() |
|
-- Open the repository of the current file |
|
require("neogit").open({ cwd = "%:p:h" }) |
|
end |
|
|
|
return M
|
|
|