luaneovim

How to customize the output style of quickfix list and location list using Lua?


Based on

:h quickfix-window-function

<filename>|<lnum> col <col>|<text>

I want to change it to something like this:

<filename>:<lnum>:<col>:<text>

How can this be achieved using Lua?


Solution

  • If you're looking to customize the display of entries in Neovim's quickfix or location list, you can use the quickfixtextfunc option to define a custom formatting function. The following Lua code provides a clean and flexible way to format quickfix or location list entries, showing

    in a consistent format.

    function _G.qftf(info)
      local items
      local ret = {}
    
      if info.quickfix == 1 then
        items = vim.fn.getqflist({ id = info.id, items = 0 }).items
      else
        items = vim.fn.getloclist(info.winid, { id = info.id, items = 0 }).items
      end
      local valid_fmt = "%s:%d:%d:%s %s" -- filepath : line : col : type : text
    
      for i = info.start_idx, info.end_idx do
        local e = items[i]
        local fname = ""
        local str
    
        if e.valid == 1 then
          if e.bufnr > 0 then
            fname = vim.fn.bufname(e.bufnr)
            if fname == "" then
              fname = "[No Name]"
            else
              fname = fname:gsub("^" .. vim.env.HOME, "~")
            end
          end
          local lnum = e.lnum
          local col = e.col
          local qtype = e.type == "" and "" or " " .. e.type:sub(1, 1):upper()
          str = valid_fmt:format(fname, lnum, col, qtype, e.text)
        else
          str = e.text
        end
        table.insert(ret, str)
      end
    
      return ret
    end
    
    vim.o.quickfixtextfunc = "{info -> v:lua._G.qftf(info)}"
    

    (optional) highlight/syntax

    After setting _G.qftf()..., the original qf highlight may be affected

    Therefore, you can consider adding qf.lua, for example:

    ~/.config/nvim/after/syntax/qf.lua
    

    And add the following content to highlight the filepath and line number

    -- ~/.config/nvim/after/syntax/qf.lua
    
    local win_id = vim.api.nvim_get_current_win()
    local ns_id = vim.api.nvim_create_namespace("qf_highlight_" .. win_id)
    
    -- (optional)
    if vim.g.qffiletype ~= nil then
      -- let g:qffiletype="cpp"
      vim.fn.clearmatches(win_id)
      vim.api.nvim_set_option_value('filetype', vim.g.qffiletype, { buf = buf_id })
    else
      vim.fn.matchadd("Normal", [[.*]], 0, -1, { window = win_id })
    end
    
    vim.api.nvim_set_hl(ns_id, "HLFilepath", { fg = "#b38bfd" })
    vim.api.nvim_set_hl(ns_id, "HLLine", { fg = "#3fb440" })
    vim.api.nvim_win_set_hl_ns(win_id, ns_id)
    
    vim.fn.matchadd("HLFilepath", [[^\s*.*\ze:\d\+:\d\+]], 10, -1, { window = win_id })
    vim.fn.matchadd("HLLine", [[^\s*.*:\zs\d\+\ze:\d\+]], 10, -1, { window = win_id })
    

    enter image description here