{"id":13412584,"url":"https://github.com/kevinhwang91/nvim-bqf","last_synced_at":"2025-10-17T19:18:18.587Z","repository":{"id":37389963,"uuid":"300256771","full_name":"kevinhwang91/nvim-bqf","owner":"kevinhwang91","description":"Better quickfix window in Neovim, polish old quickfix window.","archived":false,"fork":false,"pushed_at":"2025-03-29T14:25:38.000Z","size":363,"stargazers_count":1846,"open_issues_count":18,"forks_count":33,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-12T20:43:26.123Z","etag":null,"topics":["fzf","lua","neovim","neovim-lua","neovim-plugin","nvim","qf","quickfix","vim"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevinhwang91.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-10-01T11:36:18.000Z","updated_at":"2025-04-11T02:42:48.000Z","dependencies_parsed_at":"2024-03-28T14:29:07.149Z","dependency_job_id":"a9c5611b-266f-4441-9e9d-4d20e1528652","html_url":"https://github.com/kevinhwang91/nvim-bqf","commit_stats":{"total_commits":322,"total_committers":11,"mean_commits":"29.272727272727273","dds":"0.037267080745341574","last_synced_commit":"1b24dc6050c34e8cd377b6b4cd6abe40509e0187"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinhwang91%2Fnvim-bqf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinhwang91%2Fnvim-bqf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinhwang91%2Fnvim-bqf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinhwang91%2Fnvim-bqf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevinhwang91","download_url":"https://codeload.github.com/kevinhwang91/nvim-bqf/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129481,"owners_count":22019628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fzf","lua","neovim","neovim-lua","neovim-plugin","nvim","qf","quickfix","vim"],"created_at":"2024-07-30T20:01:26.434Z","updated_at":"2025-10-17T19:18:18.575Z","avatar_url":"https://github.com/kevinhwang91.png","language":"Lua","funding_links":[],"categories":["Debugging","Lua"],"sub_categories":["Quickfix"],"readme":"# nvim-bqf\n\nThe goal of nvim-bqf is to make Neovim's quickfix window better.\n\n\u003chttps://user-images.githubusercontent.com/17562139/137736502-91d32251-96a2-4c3f-ba74-65cfd336473e.mp4\u003e\n\n---\n\nIn today's era of floating windows, are you afraid to toggle quickfix window to make your eyes\nuncomfortable? Are you constantly jumping between the edit window and the quickfix window when you\nuse quickfix window to refactor because of lacking a sustainable preview window? Do you think\nquickfix window lacks a fuzzy search function? At present, nvim-bqf can solve the above problems.\n\nYou really don't need any search replace plugins, because nvim-bqf with the built-in function of the\nquickfix window allows you to easily search and replace targets.\n\nSo why not nvim-bqf?\n\n## Table of contents\n\n- [Table of contents](#table-of-contents)\n- [Features](#features)\n- [TODO](#todo)\n- [Quickstart](#quickstart)\n  - [Requirements](#requirements)\n  - [Installation](#installation)\n  - [Minimal configuration](#minimal-configuration)\n  - [Usage](#usage)\n    - [Filter with signs](#filter-with-signs)\n    - [Fzf mode](#fzf-mode)\n    - [Filter items with signs demo](#filter-items-with-signs-demo)\n    - [Search and replace demo](#search-and-replace-demo)\n- [Documentation](#documentation)\n  - [Setup and description](#setup-and-description)\n  - [Function table](#function-table)\n  - [Buffer Commands](#buffer-commands)\n  - [Commands](#commands)\n  - [API](#api)\n  - [Quickfix context](#quickfix-context)\n    - [Why use an additional context?](#why-use-an-additional-context)\n    - [Supported keys](#supported-keys)\n    - [Simple lua tests for understanding](#simple-lua-tests-for-understanding)\n  - [Highlight groups](#highlight-groups)\n- [Advanced configuration](#advanced-configuration)\n  - [Customize configuration](#customize-configuration)\n  - [Integrate with other plugins](#integrate-with-other-plugins)\n- [Customize quickfix window (Easter egg)](#customize-quickfix-window-easter-egg)\n  - [Format new quickfix](#format-new-quickfix)\n  - [Rebuild syntax for quickfix](#rebuild-syntax-for-quickfix)\n- [Feedback](#feedback)\n- [License](#license)\n\n## Features\n\n- Toggle quickfix window with magic window keep your eyes comfortable\n- Extend built-in context of quickfix to build an eye friendly highlighting at preview\n- Support convenient actions inside quickfix window, see [Function table](#function-table) below\n- Optimize the buffer preview under treesitter to get extreme performance\n- Using signs to filter the items of quickfix window\n- Integrate [fzf](https://github.com/junegunn/fzf) as a picker/filter in quickfix window\n- Mouse supported for preview window\n\n## TODO\n\n- [ ] Find a better way to list history and switch to one\n- [ ] Use context field to override the existed configuration\n- [ ] Add tests\n\n## Quickstart\n\n### Requirements\n\n- [Neovim](https://github.com/neovim/neovim) 0.6.1 or later\n- [fzf](https://github.com/junegunn/fzf) (optional, 0.42.0 later)\n- [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) (optional)\n\n### Installation\n\nInstall with [Packer.nvim](https://github.com/wbthomason/packer.nvim):\n\n```lua\nuse {'kevinhwang91/nvim-bqf'}\n```\n\n### Minimal configuration\n\n```lua\nuse {'kevinhwang91/nvim-bqf', ft = 'qf'}\n\n-- optional\nuse {'junegunn/fzf', run = function()\n    vim.fn['fzf#install']()\nend\n}\n\n-- optional, highly recommended\nuse {'nvim-treesitter/nvim-treesitter', run = ':TSUpdate'}\n```\n\nThe nvim-bqf's preview builds upon the buffers. I highly recommended to use\n[nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) to do syntax for the buffer,\nbecause vim's syntax is very lagging and is extremely bad for the user experience in large files.\n\n\u003e nvim-bqf has optimized the preview performance for treesitter\n\n### Usage\n\n1. If you are familiar with quickfix, use quickfix as usual.\n2. If you don't know quickfix well, you can run `:vimgrep /\\w\\+/j % | copen` under a buffer inside\n   nvim to get started quickly.\n3. If you want to taste quickfix like demo, check out\n   [Integrate with other plugins](#integrate-with-other-plugins), and pick up the configuration you\n   like.\n\n#### Filter with signs\n\n1. Press `\u003cTab\u003e` or `\u003cS-Tab\u003e` to toggle the sign of item\n2. Press `zn` or `zN` will create new quickfix list\n\n#### Fzf mode\n\nPress `zf` in quickfix window will enter fzf mode.\n\nfzf in nvim-bqf supports `ctrl-t`/`ctrl-x`/`ctrl-v` key bindings that allow you to open up an item\nin a new tab, a new horizontal split, or in a new vertical split.\n\nfzf becomes a quickfix filter and create a new quickfix list when multiple items are selected and\naccepted.\n\nnvim-bqf also supports `ctrl-q` to toggle items' sign and adapts `preview-half-page-up`,\n`preview-half-page-down` and `toggle-preview` fzf's actions for preview.\n\nPlease run `man fzf` and check out `KEY/EVENT BINDINGS` section for details.\n\nThere're two ways to adapt fzf's actions for preview function, use `ctrl-f`and `ctrl-b` keys as\nexample.\n\n1. Make `$FZF_DEFAULT_OPTS` contains\n   `--bind=ctrl-f:preview-half-page-down,ctrl-b:preview-half-page-up`;\n2. Inject `extra_opts = {'--bind', 'ctrl-f:preview-half-page-down,ctrl-b:preview-half-page-up'}` to\n   `setup` function;\n\n#### Filter items with signs demo\n\n\u003chttps://user-images.githubusercontent.com/17562139/137736623-e436cb3e-af40-4a00-b08a-b7120d41821e.mp4\u003e\n\n\u003e input `^^` in fzf prompt will find all signed items, `ctrl-o` in fzf mode has bind `toggle-all`\n\n#### Search and replace demo\n\nUsing external grep-like program to search `display` and replace it to `show`, but exclude\n`session.lua` file.\n\n\u003chttps://user-images.githubusercontent.com/17562139/137747257-ff8fb5cf-e437-42e3-b4e4-76c72a0273aa.mp4\u003e\n\n\u003e Demonstrating batch undo just show that quickfix has this feature\n\n## Documentation\n\n### Setup and description\n\n```lua\n{\n    auto_enable = {\n        description = [[Enable nvim-bqf in quickfix window automatically]],\n        default = true\n    },\n    magic_window = {\n        description = [[Give the window magic, when the window is splited horizontally, keep\n            the distance between the current line and the top/bottom border of neovim unchanged.\n            It's a bit like a floating window, but the window is indeed a normal window, without\n            any floating attributes.]],\n        default = true\n    },\n    auto_resize_height = {\n        description = [[Resize quickfix window height automatically.\n            Shrink higher height to size of list in quickfix window, otherwise extend height\n            to size of list or to default height (10)]],\n        default = false\n    },\n    preview = {\n        auto_preview = {\n            description = [[Enable preview in quickfix window automatically]],\n            default = true\n        },\n        border = {\n            description = [[The border for preview window,\n                `:h nvim_open_win() | call search('border:')`]],\n            default = 'rounded',\n        },\n        show_title = {\n            description = [[Show the window title]],\n            default = true\n        },\n        show_scroll_bar = {\n            description = [[Show the scroll bar]],\n            default = true\n        },\n        delay_syntax = {\n            description = [[Delay time, to do syntax for previewed buffer, unit is millisecond]],\n            default = 50\n        },\n        win_height = {\n            description = [[The height of preview window for horizontal layout,\n                large value (like 999) perform preview window as a \"full\" mode]],\n            default = 15\n        },\n        win_vheight = {\n            description = [[The height of preview window for vertical layout]],\n            default = 15\n        },\n        winblend = {\n            description = [[The winblend for preview window, `:h winblend`]],\n            default = 12\n        },\n        wrap = {\n            description = [[Wrap the line, `:h wrap` for detail]],\n            default = false\n        },\n        buf_label = {\n            description = [[Add label of current item buffer at the end of the item line]],\n            default = true\n        },\n        should_preview_cb = {\n            description = [[A callback function to decide whether to preview while switching buffer,\n                with (bufnr: number, qwinid: number) parameters]],\n            default = nil\n        }\n    },\n    func_map = {\n        description = [[The table for {function = key}]],\n        default = [[see ###Function table for detail]],\n    },\n    filter = {\n        fzf = {\n            action_for = {\n                ['ctrl-t'] = {\n                    description = [[Press ctrl-t to open up the item in a new tab]],\n                    default = 'tabedit'\n                },\n                ['ctrl-v'] = {\n                    description = [[Press ctrl-v to open up the item in a new vertical split]],\n                    default = 'vsplit'\n                },\n                ['ctrl-x'] = {\n                    description = [[Press ctrl-x to open up the item in a new horizontal split]],\n                    default = 'split'\n                },\n                ['ctrl-q'] = {\n                    description = [[Press ctrl-q to toggle sign for the selected items]],\n                    default = 'signtoggle'\n                },\n                ['ctrl-c'] = {\n                    description = [[Press ctrl-c to close quickfix window and abort fzf]],\n                    default = 'closeall'\n                }\n            },\n            extra_opts = {\n                description = 'Extra options for fzf',\n                default = {'--bind', 'ctrl-o:toggle-all'}\n            }\n        }\n    }\n}\n```\n\nBefore loading any modules, `:lua =require('bqf.config')` will show you everything\nabout current configuration.\n\n### Function table\n\n`Function` only works in the quickfix window, keys can be customized by\n`lua require('bqf').setup({func_map = {}})`.\n\n\u003e You can reference [Customize configuration](#customize-configuration) to configure `func_map`.\n\n| Function    | Action                                                     | Def Key   |\n| ----------- | ---------------------------------------------------------- | --------- |\n| open        | open the item under the cursor                             | `\u003cCR\u003e`    |\n| openc       | open the item, and close quickfix window                   | `o`       |\n| drop        | use `drop` to open the item, and close quickfix window     | `O`       |\n| tabdrop     | use `tab drop` to open the item, and close quickfix window |           |\n| tab         | open the item in a new tab                                 | `t`       |\n| tabb        | open the item in a new tab, but stay in quickfix window    | `T`       |\n| tabc        | open the item in a new tab, and close quickfix window      | `\u003cC-t\u003e`   |\n| split       | open the item in horizontal split                          | `\u003cC-x\u003e`   |\n| vsplit      | open the item in vertical split                            | `\u003cC-v\u003e`   |\n| prevfile    | go to previous file under the cursor in quickfix window    | `\u003cC-p\u003e`   |\n| nextfile    | go to next file under the cursor in quickfix window        | `\u003cC-n\u003e`   |\n| prevhist    | cycle to previous quickfix list in quickfix window         | `\u003c`       |\n| nexthist    | cycle to next quickfix list in quickfix window             | `\u003e`       |\n| lastleave   | go to last selected item in quickfix window                | `'\"`      |\n| stoggleup   | toggle sign and move cursor up                             | `\u003cS-Tab\u003e` |\n| stoggledown | toggle sign and move cursor down                           | `\u003cTab\u003e`   |\n| stogglevm   | toggle multiple signs in visual mode                       | `\u003cTab\u003e`   |\n| stogglebuf  | toggle signs for same buffers under the cursor             | `'\u003cTab\u003e`  |\n| sclear      | clear the signs in current quickfix list                   | `z\u003cTab\u003e`  |\n| pscrollup   | scroll up half-page in preview window                      | `\u003cC-b\u003e`   |\n| pscrolldown | scroll down half-page in preview window                    | `\u003cC-f\u003e`   |\n| pscrollorig | scroll back to original position in preview window         | `zo`      |\n| ptogglemode | toggle preview window between normal and max size          | `zp`      |\n| ptoggleitem | toggle preview for a quickfix list item                    | `p`       |\n| ptoggleauto | toggle auto-preview when cursor moves                      | `P`       |\n| filter      | create new list for signed items                           | `zn`      |\n| filterr     | create new list for non-signed items                       | `zN`      |\n| fzffilter   | enter fzf mode                                             | `zf`      |\n\nAdditional mouse supported:\n\n1. `\u003cScrollWheelUp\u003e` and `\u003cScrollWheelDown\u003e`: Scroll preview window.\n2. `\u003c2-LeftMouse\u003e`:\n   - In quickfix window: Type `\u003cCR\u003e`;\n   - In preview window: Jump to the location even it has scrolled;\n\n### Buffer Commands\n\n- `BqfEnable`: Enable nvim-bqf in quickfix window\n- `BqfDisable`: Disable nvim-bqf in quickfix window\n- `BqfToggle`: Toggle nvim-bqf in quickfix window\n\n### Commands\n\n- `BqfAutoToggle`: Toggle nvim-bqf enable automatically\n\n### API\n\n[bqf.lua](./lua/bqf.lua)\n\n### Quickfix context\n\nVim grant users an ability to stuff a context to quickfix, please run `:help quickfix-context` for\ndetail.\n\n#### Why use an additional context?\n\nnvim-bqf will use the context to implement missing features of quickfix. To get better highlighting\nexperience, nvim-bqf processeds the vim regrex pattern and\n[lsp range](https://microsoft.github.io/language-server-protocol/specification#range) from the\ncontext additionally.\n\nThe context's format that can be processed by nvim-bqf is:\n\n```lua\nlocal context = {context = {bqf = {}}}\n```\n\nnvim-bqf only occupies a key of `context`, which makes nvim-bqf get along well with other plugins in\ncontext of the quickfix window.\n\n#### Supported keys\n\n```lua\ncontext = {\n    bqf = {\n        pattern_hl = {\n            description = [[search pattern from current position]],\n            type = 'string'\n        },\n        lsp_ranges_hl = {\n            description = [[a list of lsp range. The length of list is equal to the items',\n            pairwise correspondence each other]],\n            type = 'table'\n        }\n    }\n}\n```\n\n#### Simple lua tests for understanding\n\n```lua\nlocal cmd = vim.cmd\nlocal api = vim.api\nlocal fn = vim.fn\n\nlocal function createQf()\n    cmd('enew')\n    local bufnr = api.nvim_get_current_buf()\n    local lines = {}\n    for i = 1, 3 do\n        table.insert(lines, ('%d | %s'):format(i, fn.strftime('%F')))\n    end\n    api.nvim_buf_set_lines(bufnr, 0, -1, false, lines)\n    fn.setqflist({\n        {bufnr = bufnr, lnum = 1, col = 5}, {bufnr = bufnr, lnum = 2, col = 10},\n        {bufnr = bufnr, lnum = 3, col = 13}\n    })\nend\n\nfunction _G.bqfPattern()\n    createQf()\n    fn.setqflist({}, 'r', {context = {bqf = {pattern_hl = [[\\d\\+]]}}, title = 'patternHl'})\n    cmd('cw')\nend\n\nfunction _G.bqfLspRanges()\n    createQf()\n    local lspRanges = {}\n    table.insert(lspRanges,\n        {start = {line = 0, character = 4}, ['end'] = {line = 0, character = 8}})\n    table.insert(lspRanges,\n        {start = {line = 1, character = 9}, ['end'] = {line = 1, character = 11}})\n    table.insert(lspRanges,\n        {start = {line = 2, character = 12}, ['end'] = {line = 2, character = 14}})\n    fn.setqflist({}, 'r', {context = {bqf = {lsp_ranges_hl = lspRanges}}, title = 'lspRangesHl'})\n    cmd('cw')\nend\n\nfunction _G.qfRanges()\n    createQf()\n    local items = fn.getqflist()\n    local it1, it2, it3 = items[1], items[2], items[3]\n    it1.end_lnum, it1.end_col = it1.lnum, it1.col + 4\n    it2.end_lnum, it2.end_col = it2.lnum, it2.col + 2\n    it3.end_lnum, it3.end_col = it3.lnum, it3.col + 2\n    fn.setqflist({}, 'r', {items = items, title = 'qfRangesHl'})\n    cmd('cw')\nend\n\n-- Save and source me(`so %`). Run `:lua bqfPattern()`, `:lua bqfLspRanges()` and `:lua qfRanges()`\n```\n\nnvim-bqf actually works with context in\n[Integrate with other plugins](#integrate-with-other-plugins).\n\n### Highlight groups\n\n```vim\nhi default link BqfPreviewFloat Normal\nhi default link BqfPreviewBorder FloatBorder\nhi default link BqfPreviewTitle Title\nhi default link BqfPreviewThumb PmenuThumb\nhi default link BqfPreviewSbar PmenuSbar\nhi default link BqfPreviewCursor Cursor\nhi default link BqfPreviewCursorLine CursorLine\nhi default link BqfPreviewRange IncSearch\nhi default link BqfPreviewBufLabel BqfPreviewRange\nhi default BqfSign ctermfg=14 guifg=Cyan\n```\n\n- `BqfPreviewFloat`: Floating window.\n- `BqfPreviewBorder`: Border of floating window.\n- `BqfPreviewTitle`: Title of preview window.\n- `BqfPreviewThumb`: Thumb of preview window.\n- `BqfPreviewSbar`: Scroll bar of preview window, only take effect if the border is missing right.\n- `BqfPreviewCursor`: The cursor format `[lnum, col]` in preview window.\n- `BqfPreviewCursorLine`: The text line of the cursor in preview window.\n- `BqfPreviewRange`: The range format `[lnum, col, range]`, which is produced by\n  `pattern_hl`, `lsp_ranges_hl` and quickfix range.\n- `BqfPreviewBufLabel`: The index and count of the buffer under the cursor\n- `BqfSign`: The sign in quickfix window.\n\n## Advanced configuration\n\n### Customize configuration\n\n```lua\nvim.cmd([[\n    hi BqfPreviewBorder guifg=#3e8e2d ctermfg=71\n    hi BqfPreviewTitle guifg=#3e8e2d ctermfg=71\n    hi BqfPreviewThumb guibg=#3e8e2d ctermbg=71\n    hi link BqfPreviewRange Search\n]])\n\nrequire('bqf').setup({\n    auto_enable = true,\n    auto_resize_height = true, -- highly recommended enable\n    preview = {\n        win_height = 12,\n        win_vheight = 12,\n        delay_syntax = 80,\n        border = {'┏', '━', '┓', '┃', '┛', '━', '┗', '┃'},\n        show_title = false,\n        should_preview_cb = function(bufnr, qwinid)\n            local ret = true\n            local bufname = vim.api.nvim_buf_get_name(bufnr)\n            local fsize = vim.fn.getfsize(bufname)\n            if fsize \u003e 100 * 1024 then\n                -- skip file size greater than 100k\n                ret = false\n            elseif bufname:match('^fugitive://') then\n                -- skip fugitive buffer\n                ret = false\n            end\n            return ret\n        end\n    },\n    -- make `drop` and `tab drop` to become preferred\n    func_map = {\n        drop = 'o',\n        openc = 'O',\n        split = '\u003cC-s\u003e',\n        tabdrop = '\u003cC-t\u003e',\n        -- set to empty string to disable\n        tabc = '',\n        ptogglemode = 'z,',\n    },\n    filter = {\n        fzf = {\n            action_for = {['ctrl-s'] = 'split', ['ctrl-t'] = 'tab drop'},\n            extra_opts = {'--bind', 'ctrl-o:toggle-all', '--prompt', '\u003e '}\n        }\n    }\n})\n```\n\n### Integrate with other plugins\n\n```lua\nlocal fn = vim.fn\nlocal cmd = vim.cmd\nlocal api = vim.api\n\ncmd([[\n    packadd nvim-bqf\n    packadd fzf\n    packadd nvim-treesitter\n    packadd vim-grepper\n    packadd coc.nvim\n]])\n\n-- https://github.com/mhinz/vim-grepper\nvim.g.grepper = {tools = {'rg', 'grep'}, searchreg = 1}\ncmd(([[\n    aug Grepper\n        au!\n        au User Grepper ++nested %s\n    aug END\n]]):format([[call setqflist([], 'r', {'context': {'bqf': {'pattern_hl': '\\%#' . getreg('/')}}})]]))\n\n-- try `gsiw` under word\ncmd([[\n    nmap gs  \u003cplug\u003e(GrepperOperator)\n    xmap gs  \u003cplug\u003e(GrepperOperator)\n]])\n\n-- https://github.com/neoclide/coc.nvim\n-- if you use coc-fzf, you should disable its CocLocationsChange event\n-- to make bqf work for \u003cPlug\u003e(coc-references)\n\n-- vim.schedule(function()\n--     cmd('au! CocFzfLocation User CocLocationsChange')\n-- end)\nvim.g.coc_enable_locationlist = 0\ncmd([[\n    aug Coc\n        au!\n        au User CocLocationsChange lua _G.jumpToLoc()\n    aug END\n]])\n\ncmd([[\n    nmap \u003csilent\u003e gr \u003cPlug\u003e(coc-references)\n    nnoremap \u003csilent\u003e \u003cleader\u003eqd \u003cCmd\u003elua _G.diagnostic()\u003cCR\u003e\n]])\n\n-- just use `_G` prefix as a global function for a demo\n-- please use module instead in reality\nfunction _G.jumpToLoc(locs)\n    locs = locs or vim.g.coc_jump_locations\n    fn.setloclist(0, {}, ' ', {title = 'CocLocationList', items = locs})\n    local winid = fn.getloclist(0, {winid = 0}).winid\n    if winid == 0 then\n        cmd('abo lw')\n    else\n        api.nvim_set_current_win(winid)\n    end\nend\n\nfunction _G.diagnostic()\n    fn.CocActionAsync('diagnosticList', '', function(err, res)\n        if err == vim.NIL then\n            local items = {}\n            for _, d in ipairs(res) do\n                local text = ('[%s%s] %s'):format((d.source == '' and 'coc.nvim' or d.source),\n                    (d.code == vim.NIL and '' or ' ' .. d.code), d.message:match('([^\\n]+)\\n*'))\n                local item = {\n                    filename = d.file,\n                    lnum = d.lnum,\n                    end_lnum = d.end_lnum,\n                    col = d.col,\n                    end_col = d.end_col,\n                    text = text,\n                    type = d.severity\n                }\n                table.insert(items, item)\n            end\n            fn.setqflist({}, ' ', {title = 'CocDiagnosticList', items = items})\n\n            cmd('bo cope')\n        end\n    end)\nend\n-- you can also subscribe User `CocDiagnosticChange` event to reload your diagnostic in quickfix\n-- dynamically, enjoy yourself :)\n```\n\n## Customize quickfix window (Easter egg)\n\nQuickfix window default UI is extremely outdated and low level aesthetics. However, you can dress up\nyour personal quickfix window:) Here is the configuration for demo:\n\n\u003e This section is not `nvim-bqf` exclusive, you can use the configuration without `nvim-bqf`\n\n### Format new quickfix\n\nSet `quickfixtextfunc` option and write down corresponding function:\n\n```lua\nlocal fn = vim.fn\n\nfunction _G.qftf(info)\n    local items\n    local ret = {}\n    -- The name of item in list is based on the directory of quickfix window.\n    -- Change the directory for quickfix window make the name of item shorter.\n    -- It's a good opportunity to change current directory in quickfixtextfunc :)\n    --\n    -- local alterBufnr = fn.bufname('#') -- alternative buffer is the buffer before enter qf window\n    -- local root = getRootByAlterBufnr(alterBufnr)\n    -- vim.cmd(('noa lcd %s'):format(fn.fnameescape(root)))\n    --\n    if info.quickfix == 1 then\n        items = fn.getqflist({id = info.id, items = 0}).items\n    else\n        items = fn.getloclist(info.winid, {id = info.id, items = 0}).items\n    end\n    local limit = 31\n    local fnameFmt1, fnameFmt2 = '%-' .. limit .. 's', '…%.' .. (limit - 1) .. 's'\n    local validFmt = '%s │%5d:%-3d│%s %s'\n    for i = info.start_idx, info.end_idx do\n        local e = items[i]\n        local fname = ''\n        local str\n        if e.valid == 1 then\n            if e.bufnr \u003e 0 then\n                fname = fn.bufname(e.bufnr)\n                if fname == '' then\n                    fname = '[No Name]'\n                else\n                    fname = fname:gsub('^' .. vim.env.HOME, '~')\n                end\n                -- char in fname may occur more than 1 width, ignore this issue in order to keep performance\n                if #fname \u003c= limit then\n                    fname = fnameFmt1:format(fname)\n                else\n                    fname = fnameFmt2:format(fname:sub(1 - limit))\n                end\n            end\n            local lnum = e.lnum \u003e 99999 and -1 or e.lnum\n            local col = e.col \u003e 999 and -1 or e.col\n            local qtype = e.type == '' and '' or ' ' .. e.type:sub(1, 1):upper()\n            str = validFmt:format(fname, lnum, col, qtype, e.text)\n        else\n            str = e.text\n        end\n        table.insert(ret, str)\n    end\n    return ret\nend\n\nvim.o.qftf = '{info -\u003e v:lua._G.qftf(info)}'\n\n-- Adapt fzf's delimiter in nvim-bqf\nrequire('bqf').setup({\n    filter = {\n        fzf = {\n            extra_opts = {'--bind', 'ctrl-o:toggle-all', '--delimiter', '│'}\n        }\n    }\n})\n```\n\n### Rebuild syntax for quickfix\n\nAdd `qf.vim` under your syntax path, for instance: `~/.config/nvim/syntax/qf.vim`\n\n```vim\nif exists('b:current_syntax')\n    finish\nendif\n\nsyn match qfFileName /^[^│]*/ nextgroup=qfSeparatorLeft\nsyn match qfSeparatorLeft /│/ contained nextgroup=qfLineNr\nsyn match qfLineNr /[^│]*/ contained nextgroup=qfSeparatorRight\nsyn match qfSeparatorRight '│' contained nextgroup=qfError,qfWarning,qfInfo,qfNote\nsyn match qfError / E .*$/ contained\nsyn match qfWarning / W .*$/ contained\nsyn match qfInfo / I .*$/ contained\nsyn match qfNote / [NH] .*$/ contained\n\nhi def link qfFileName Directory\nhi def link qfSeparatorLeft Delimiter\nhi def link qfSeparatorRight Delimiter\nhi def link qfLineNr LineNr\nhi def link qfError DiagnosticError\nhi def link qfWarning DiagnosticWarn\nhi def link qfInfo DiagnosticInfo\nhi def link qfNote DiagnosticHint\n\nlet b:current_syntax = 'qf'\n```\n\n## Feedback\n\n- If you get an issue or come up with an awesome idea, don't hesitate to open an issue in github.\n- If you think this plugin is useful or cool, consider rewarding it a star.\n\n## License\n\nThe project is licensed under a BSD-3-clause license. See [LICENSE](./LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinhwang91%2Fnvim-bqf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinhwang91%2Fnvim-bqf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinhwang91%2Fnvim-bqf/lists"}