Skip to content

Instantly share code, notes, and snippets.

@b0o
Last active June 12, 2024 15:44
Show Gist options
  • Save b0o/bb8ae867ccc0761c79c040a3ecd8dd0d to your computer and use it in GitHub Desktop.
Save b0o/bb8ae867ccc0761c79c040a3ecd8dd0d to your computer and use it in GitHub Desktop.
nvim-tree quickfix
-- Important: Put this in your config directory at lua/nvim-tree/renderer/decorator/bookmarks.lua
--
-- HACK: Although this file is named bookmarks.lua, it is actually a decorator
-- for the quickfix list. Because nvim-tree does not provide a way to add a custom decorator,
-- we are overriding the built-in bookmarks decorator with our own quickfix list decorator.
-- If you don't want to override the bookmarks.lua decorator, you can override a different one.
local HL_POSITION = require('nvim-tree.enum').HL_POSITION
local ICON_PLACEMENT = require('nvim-tree.enum').ICON_PLACEMENT
local Decorator = require 'nvim-tree.renderer.decorator'
---@class DecoratorQuickfix: Decorator
---@field icon HighlightedString|nil
local DecoratorQuickfix = Decorator:new()
---@return DecoratorQuickfix
function DecoratorQuickfix:new()
local o = Decorator.new(self, {
enabled = true,
hl_pos = HL_POSITION.all,
icon_placement = ICON_PLACEMENT.signcolumn,
})
---@cast o DecoratorQuickfix
if not o.enabled then
return o
end
o.icon = {
str = '',
hl = { 'QuickFixLine' },
}
o:define_sign(o.icon)
return o
end
---@param node Node
local function is_qf_item(node)
if node.name == '..' or node.type == 'directory' then
return false
end
local bufnr = vim.fn.bufnr(node.absolute_path)
return bufnr ~= -1 and vim.iter(vim.fn.getqflist()):any(function(qf)
return qf.bufnr == bufnr
end)
end
---@param node Node
---@return HighlightedString[]|nil icons
function DecoratorQuickfix:calculate_icons(node)
if not self.enabled or not is_qf_item(node) then
return nil
end
return { self.icon }
end
---Modified highlight: modified.enable, renderer.highlight_modified and node is modified
---@param node Node
---@return string|nil group
function DecoratorQuickfix:calculate_highlight(node)
if not self.enabled or self.hl_pos == HL_POSITION.none or not is_qf_item(node) then
return nil
end
return 'QuickFixLine'
end
return DecoratorQuickfix
--- Wherever you're configuring nvim-tree:
local on_attach = function(bufnr)
local function opts(desc)
return { desc = 'nvim-tree: ' .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
end
local function get_visual_nodes()
local core = require 'nvim-tree.core'
local view = require 'nvim-tree.view'
local utils = require 'nvim-tree.utils'
if not core.get_explorer() then
return
end
local winnr = view.get_winnr()
if not winnr then
return
end
local start = vim.api.nvim_buf_get_mark(0, '<')[1]
local end_ = vim.api.nvim_buf_get_mark(0, '>')[1]
local nodes = utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())
return vim.list_slice(nodes, start, end_)
end
local update_qflist = function(entries)
local current_qflist = vim.fn.getqflist()
local filtered = vim
.iter(entries)
:filter(function(entry)
return not vim.iter(current_qflist):any(function(qfl)
return qfl.bufnr == vim.fn.bufnr(entry.filename)
end)
end)
:totable()
if #entries > 0 and #filtered == 0 then
local replace = vim
.iter(current_qflist)
:filter(function(qfl)
return not vim.iter(entries):any(function(entry)
return qfl.bufnr == vim.fn.bufnr(entry.filename)
end)
end)
:totable()
vim.fn.setqflist(replace, 'r')
else
vim.fn.setqflist(filtered, 'a')
end
require('nvim-tree.renderer').draw()
end
vim.keymap.set('n', '<C-q>', function()
local ok, node = pcall(api.tree.get_node_under_cursor)
if ok and node and node.name ~= '..' and node.type ~= 'directory' then
update_qflist { { filename = node.absolute_path, lnum = 1, col = 1 } }
end
end, opts 'Add to Quickfix')
vim.keymap.set('v', '<C-q>', function()
vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<esc>', true, false, true), 'n', false)
vim.schedule(function()
local ok, nodes = pcall(get_visual_nodes)
if ok and nodes then
local entries = vim
.iter(nodes)
:filter(function(node)
return node.name ~= '..' and node.type ~= 'directory'
end)
:map(function(node)
return { filename = node.absolute_path, lnum = 1, col = 1 }
end)
:totable()
update_qflist(entries)
end
end)
end, opts 'Add to Quickfix')
-- ... set up your other nvim-tree mappings here ...
end)
require('nvim-tree').setup {
on_attach = on_attach,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment