summaryrefslogtreecommitdiff
path: root/lua/quicker/init.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua/quicker/init.lua')
-rw-r--r--lua/quicker/init.lua189
1 files changed, 189 insertions, 0 deletions
diff --git a/lua/quicker/init.lua b/lua/quicker/init.lua
new file mode 100644
index 0000000..42ae32b
--- /dev/null
+++ b/lua/quicker/init.lua
@@ -0,0 +1,189 @@
+local M = {}
+
+---@param opts? quicker.SetupOptions
+local function setup(opts)
+ local config = require("quicker.config")
+ config.setup(opts)
+
+ local aug = vim.api.nvim_create_augroup("quicker", { clear = true })
+ vim.api.nvim_create_autocmd("FileType", {
+ pattern = "qf",
+ group = aug,
+ desc = "quicker.nvim set up quickfix mappings",
+ callback = function(args)
+ require("quicker.highlight").set_highlight_groups()
+ require("quicker.opts").set_opts(args.buf)
+ require("quicker.keys").set_keymaps(args.buf)
+ vim.api.nvim_buf_create_user_command(args.buf, "Refresh", function()
+ require("quicker.context").refresh()
+ end, {
+ desc = "Update the quickfix list with the current buffer text for each item",
+ })
+
+ if config.constrain_cursor then
+ require("quicker.cursor").constrain_cursor(args.buf)
+ end
+
+ config.on_qf(args.buf)
+ end,
+ })
+ vim.api.nvim_create_autocmd("ColorScheme", {
+ pattern = "*",
+ group = aug,
+ desc = "quicker.nvim set up quickfix highlight groups",
+ callback = function()
+ require("quicker.highlight").set_highlight_groups()
+ end,
+ })
+ if config.edit.enabled then
+ vim.api.nvim_create_autocmd("BufReadPost", {
+ pattern = "quickfix",
+ group = aug,
+ desc = "quicker.nvim set up quickfix editing",
+ callback = function(args)
+ require("quicker.editor").setup_editor(args.buf)
+ end,
+ })
+ end
+ if config.follow.enabled then
+ vim.api.nvim_create_autocmd({ "CursorMoved", "BufEnter" }, {
+ desc = "quicker.nvim scroll to nearest location in quickfix",
+ pattern = "*",
+ group = aug,
+ callback = function()
+ require("quicker.follow").seek_to_position()
+ end,
+ })
+ end
+
+ vim.o.quickfixtextfunc = "v:lua.require'quicker.display'.quickfixtextfunc"
+
+ -- If the quickfix/loclist is already open, refresh it so the quickfixtextfunc will take effect.
+ -- This is required for lazy-loading to work properly.
+ local list = vim.fn.getqflist({ all = 0 })
+ if not vim.tbl_isempty(list.items) then
+ vim.fn.setqflist({}, "r", list)
+ end
+ for _, winid in ipairs(vim.api.nvim_list_wins()) do
+ if vim.api.nvim_win_is_valid(winid) then
+ local llist = vim.fn.getloclist(winid, { all = 0 })
+ if not vim.tbl_isempty(list.items) then
+ vim.fn.setloclist(winid, {}, "r", llist)
+ end
+ end
+ end
+end
+
+M.setup = setup
+
+---Expand the context around the quickfix results.
+---@param opts? quicker.ExpandOpts
+---@note
+--- If there are multiple quickfix items for the same line of a file, only the first
+--- one will remain after calling expand().
+M.expand = function(opts)
+ return require("quicker.context").expand(opts)
+end
+
+---Collapse the context around quickfix results, leaving only the `valid` items.
+M.collapse = function()
+ return require("quicker.context").collapse()
+end
+
+---Toggle the expanded context around the quickfix results.
+---@param opts? quicker.ExpandOpts
+M.toggle_expand = function(opts)
+ return require("quicker.context").toggle(opts)
+end
+
+---Update the quickfix list with the current buffer text for each item.
+---@param loclist_win? integer
+---@param opts? quicker.RefreshOpts
+M.refresh = function(loclist_win, opts)
+ return require("quicker.context").refresh(loclist_win, opts)
+end
+
+---@param loclist_win? integer Check if loclist is open for the given window. If nil, check quickfix.
+M.is_open = function(loclist_win)
+ return require("quicker.util").is_open(loclist_win)
+end
+
+---@class quicker.OpenCmdMods: vim.api.keyset.parse_cmd.mods
+
+---@class (exact) quicker.OpenOpts
+---@field loclist? boolean Toggle the loclist instead of the quickfix list
+---@field focus? boolean Focus the quickfix window after toggling (default false)
+---@field height? integer Height of the quickfix window when opened. Defaults to number of items in the list.
+---@field min_height? integer Minimum height of the quickfix window. Default 4.
+---@field max_height? integer Maximum height of the quickfix window. Default 10.
+---@field open_cmd_mods? quicker.OpenCmdMods A table of modifiers for the quickfix or loclist open commands.
+
+---Toggle the quickfix or loclist window.
+---@param opts? quicker.OpenOpts
+M.toggle = function(opts)
+ ---@type {loclist: boolean, focus: boolean, height?: integer, min_height: integer, max_height: integer, open_cmd_mods?: quicker.OpenCmdMods}
+ opts = vim.tbl_deep_extend("keep", opts or {}, {
+ loclist = false,
+ focus = false,
+ min_height = 4,
+ max_height = 10,
+ open_cmd_mods = {},
+ })
+ local loclist_win = opts.loclist and 0 or nil
+ if M.is_open(loclist_win) then
+ M.close({ loclist = opts.loclist })
+ else
+ M.open(opts)
+ end
+end
+
+---Open the quickfix or loclist window.
+---@param opts? quicker.OpenOpts
+M.open = function(opts)
+ local util = require("quicker.util")
+ ---@type {loclist: boolean, focus: boolean, height?: integer, min_height: integer, max_height: integer, open_cmd_mods?: quicker.OpenCmdMods}
+ opts = vim.tbl_deep_extend("keep", opts or {}, {
+ loclist = false,
+ focus = false,
+ min_height = 4,
+ max_height = 10,
+ open_cmd_mods = {},
+ })
+ local height
+ if opts.loclist then
+ local ok, err = pcall(vim.cmd.lopen, { mods = opts.open_cmd_mods })
+ if not ok then
+ vim.notify(err, vim.log.levels.ERROR)
+ return
+ end
+ height = #vim.fn.getloclist(0)
+ else
+ vim.cmd.copen({ mods = opts.open_cmd_mods })
+ height = #vim.fn.getqflist()
+ end
+
+ -- only set the height if the quickfix is not a full-height vsplit
+ if not util.is_full_height_vsplit(0) then
+ height = math.min(opts.max_height, math.max(opts.min_height, height))
+ vim.api.nvim_win_set_height(0, height)
+ end
+
+ if not opts.focus then
+ vim.cmd.wincmd({ args = { "p" } })
+ end
+end
+
+---@class (exact) quicker.CloseOpts
+---@field loclist? boolean Close the loclist instead of the quickfix list
+
+---Close the quickfix or loclist window.
+---@param opts? quicker.CloseOpts
+M.close = function(opts)
+ if opts and opts.loclist then
+ vim.cmd.lclose()
+ else
+ vim.cmd.cclose()
+ end
+end
+
+return M