Eric's Blog 时光荏苒,岁月如梭

Neovim quickfix 窗口内的一些快捷键

2024-12-30
Eric Wong

Neovim 的 quickfix 窗口还是比较常用的功能,在这里,我实现了一些 quickfix 窗口内常用的快捷键。

删除单行或者多行

在 quickfix 窗口内,默认情况下 Normal 模式下的 dd 和 Visual 模式下的 d 快捷键是不可用的,会提示:

E21: Cannot make changes, 'modifiable' is off

但是有时候,会感觉 quickfix 展示的结果太多了,有些内容不是我所需要的。使用如下代码实现了 Normal 模式下 dd 删除光标下的结果,Visual 模式下 d 删除选中行的结果。

local group = vim.api.nvim_create_augroup('quickfix_mapping', {
  clear = true,
})

vim.api.nvim_create_autocmd({ 'FileType' }, {
  pattern = 'qf',
  group = group,
  callback = function(ev)
    vim.keymap.set('n', 'dd', function()
      local qflist = vim.fn.getqflist()
      local line = vim.fn.line('.')
      table.remove(qflist, line)
      vim.fn.setqflist(qflist)
      vim.cmd(tostring(line))
    end, { buffer = ev.buf })
  end,
})

local function table_remove(t, from, to)
  local rst = {}
  for i = 1, #t, 1 do
    if i < from or i > to then
      rst[#rst + 1] = t[i]
      -- else
      -- i = to + 1
    end
  end
  return rst
end

vim.api.nvim_create_autocmd({ 'FileType' }, {
  pattern = 'qf',
  group = group,
  callback = function(ev)
    vim.keymap.set('v', 'd', function()
      local esc = vim.api.nvim_replace_termcodes('<esc>', true, false, true)
      vim.api.nvim_feedkeys(esc, 'x', false)
      local qflist = vim.fn.getqflist()
      local from = vim.fn.getpos("'<")[2]
      local to = vim.fn.getpos("'>")[2]
      if from > to then
        from, to = to, from
      end
      qflist = table_remove(qflist, from, to)
      vim.fn.setqflist(qflist)
      vim.cmd(tostring(from))
    end, { buffer = ev.buf })
  end,
})

结果过滤(Filter)

这里主要是为了实现一个功能,移除文件路径匹配输入表达式的结果。

local group = vim.api.nvim_create_augroup('quickfix_mapping', {
  clear = true,
})
vim.api.nvim_create_autocmd({ 'FileType' }, {
  pattern = 'qf',
  group = group,
  callback = function(ev)
    vim.keymap.set('n', 'c', function()
      local input_pattern = vim.fn.input('filter pattern:')
      -- vim.cmd('noautocmd normal! :')
      local re = vim.regex(input_pattern)
      local qf = {}
      for _, item in ipairs(vim.fn.getqflist()) do
        if not re:match_str(vim.fn.bufname(item.bufnr)) then
          table.insert(qf, item)
        end
      end
      vim.fn.setqflist(qf)
    end, { buffer = ev.buf })
  end,
})

上述代码,设定的快捷键为 c, 按下快捷键后会弹出一个出入提示,输入一段字符串,可以是 Vim 正则,回车后会移除 quickfix 窗口中文件名称匹配字符串的结果。

如果需要保留文件名匹配字符串的结果,可以增加一个新的快捷键,比如 C,代码如下:

local group = vim.api.nvim_create_augroup('quickfix_mapping', {
  clear = true,
})
vim.api.nvim_create_autocmd({ 'FileType' }, {
  pattern = 'qf',
  group = group,
  callback = function(ev)
    vim.keymap.set('n', 'C', function()
      local input_pattern = vim.fn.input('filter pattern:')
      -- vim.cmd('noautocmd normal! :')
      local re = vim.regex(input_pattern)
      local qf = {}
      for _, item in ipairs(vim.fn.getqflist()) do
        if re:match_str(vim.fn.bufname(item.bufnr)) then
          table.insert(qf, item)
        end
      end
      vim.fn.setqflist(qf)
    end, { buffer = ev.buf })
  end,
})

上述功能汇总为插件 quickfix.nvim.


版权声明:本文为原创文章,遵循 署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)版权协议,转载请附上原文出处链接和本声明。


延生阅读

分享到:

评论

目前只支持使用邮件参与评论。