1

Refresh generated neovim config

This commit is contained in:
2024-07-14 21:12:36 +02:00
parent f215ce2ab5
commit 00464e0e65
731 changed files with 6780 additions and 31110 deletions

View File

@ -1,89 +0,0 @@
name: Bug Report v3
description: File a bug/issue
title: "bug v3: "
labels: [bug v3]
body:
- type: markdown
attributes:
value: |
**Before** reporting an issue, make sure to read the [documentation](https://github.com/folke/trouble.nvim/tree/dev) and search [existing issues](https://github.com/folke/trouble.nvim/issues). Usage questions such as ***"How do I...?"*** belong in [Discussions](https://github.com/folke/trouble.nvim/discussions) and will be closed.
- type: checkboxes
attributes:
label: Did you check docs and existing issues?
description: Make sure you checked all of the below before submitting an issue
options:
- label: I have read all the trouble.nvim docs
required: true
- label: I have searched the existing issues of trouble.nvim
required: true
- label: I have searched the existing issues of plugins related to this issue
required: true
- type: input
attributes:
label: "Neovim version (nvim -v)"
placeholder: "0.8.0 commit db1b0ee3b30f"
validations:
required: true
- type: input
attributes:
label: "Operating system/version"
placeholder: "MacOS 11.5"
validations:
required: true
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is. Please include any related errors you see in Neovim.
validations:
required: true
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Repro
description: Minimal `init.lua` to reproduce this issue. Save as `repro.lua` and run with `nvim -u repro.lua`
value: |
-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "cache" }) do
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end
vim.opt.runtimepath:prepend(lazypath)
-- install plugins
local plugins = {
"folke/tokyonight.nvim",
"folke/trouble.nvim",
-- add any other plugins here
}
require("lazy").setup(plugins, {
root = root .. "/plugins",
})
vim.cmd.colorscheme("tokyonight")
-- add anything else here
render: Lua
validations:
required: false

View File

@ -1,36 +0,0 @@
name: Feature Request v3
description: Suggest a new feature
title: "feature: "
labels: [enhancement v3]
body:
- type: checkboxes
attributes:
label: Did you check the docs?
description: Make sure you read all the docs before submitting a feature request
options:
- label: I have read all the trouble.nvim docs
required: true
- type: textarea
validations:
required: true
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
- type: textarea
validations:
required: true
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
- type: textarea
validations:
required: true
attributes:
label: Describe alternatives you've considered
description: A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
validations:
required: false
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.

View File

@ -29,9 +29,21 @@ jobs:
docs:
runs-on: ubuntu-latest
needs: tests
if: ${{ github.ref == 'refs/heads/main' }}
steps:
- uses: actions/checkout@v3
- name: Install Neovim
shell: bash
run: |
mkdir -p /tmp/nvim
wget -q https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -O /tmp/nvim/nvim.appimage
cd /tmp/nvim
chmod a+x ./nvim.appimage
./nvim.appimage --appimage-extract
echo "/tmp/nvim/squashfs-root/usr/bin/" >> $GITHUB_PATH
- name: Generate docs
run: |
nvim --version
nvim --headless -u tests/init.lua -l "lua/trouble/docs.lua"
- name: panvimdoc
uses: kdheepak/panvimdoc@main
with:

View File

@ -1,3 +0,0 @@
{
"Lua.diagnostics.disable": ["undefined-local"]
}

View File

@ -1,5 +1,281 @@
# Changelog
## [3.4.2](https://github.com/folke/trouble.nvim/compare/v3.4.1...v3.4.2) (2024-06-14)
### Bug Fixes
* correct invalid float positions. Fixes [#502](https://github.com/folke/trouble.nvim/issues/502) ([88a40f1](https://github.com/folke/trouble.nvim/commit/88a40f1cc3af846b520ae167f0177b5faa148c86))
* **diagnostics:** custom format for code. Fixes [#508](https://github.com/folke/trouble.nvim/issues/508) ([ada78fa](https://github.com/folke/trouble.nvim/commit/ada78fae41fc05d52883f19fb5e22d5a61e0ef08))
* fixup ([60b0ac3](https://github.com/folke/trouble.nvim/commit/60b0ac3772e991bc194207afc28368a5f15d913a))
* **highlights:** link TroubleBasename to TroubleFilename. Fixes [#507](https://github.com/folke/trouble.nvim/issues/507) ([276e7b7](https://github.com/folke/trouble.nvim/commit/276e7b7a8764cd59de5c8a588771a54a979ab3c3))
* **main:** handle windows with changed buffers ([286c044](https://github.com/folke/trouble.nvim/commit/286c04474cbb24894d233e6b0c00f1e6c8d2ae54))
* **view:** dont go to main when not in the trouble window when closing ([8d5e05c](https://github.com/folke/trouble.nvim/commit/8d5e05c0d0ce7a2c630ce92cb3cc923044848063))
## [3.4.1](https://github.com/folke/trouble.nvim/compare/v3.4.0...v3.4.1) (2024-06-12)
### Bug Fixes
* **fzf:** added descriptions ([5e45bb7](https://github.com/folke/trouble.nvim/commit/5e45bb78f8da3444d35616934c180fce3742c439))
## [3.4.0](https://github.com/folke/trouble.nvim/compare/v3.3.0...v3.4.0) (2024-06-11)
### Features
* added fzf-lua integration ([d14323f](https://github.com/folke/trouble.nvim/commit/d14323fe3461b89e91fb569148b44731655ae196))
* **fzf-lua:** added smart open/add that will use selection or all when nothing selected. ([bed3c5b](https://github.com/folke/trouble.nvim/commit/bed3c5b79298d94d4981d86ed699c70f58ceccff))
### Bug Fixes
* **fzf-lua:** smart-open on windows ([4d0f045](https://github.com/folke/trouble.nvim/commit/4d0f0454ae2a246ec3e0ff541a347164dac23b7b))
* initialize `auto_open`. Fixes [#489](https://github.com/folke/trouble.nvim/issues/489) ([0793267](https://github.com/folke/trouble.nvim/commit/0793267d3d4b782e46161931b7cbaaf062a892d7))
* **spec:** properly process actions. Fixes [#494](https://github.com/folke/trouble.nvim/issues/494) ([3082f4b](https://github.com/folke/trouble.nvim/commit/3082f4b10fe9f0a8aa922065b998bc37115c4bef))
* **telescope:** autmatically select telescope_files mode if list are files without locations. Fixes [#466](https://github.com/folke/trouble.nvim/issues/466) ([1ad6b14](https://github.com/folke/trouble.nvim/commit/1ad6b141316f90a658c6d654516092d43e3e596c))
* **telescope:** set end_pos to end of word ([4deb811](https://github.com/folke/trouble.nvim/commit/4deb8111e7ffa48a4a27bad1ecdfb7779f4efb7d))
* **views:** pending should be considered open. Fixes [#492](https://github.com/folke/trouble.nvim/issues/492) ([57b50a6](https://github.com/folke/trouble.nvim/commit/57b50a6dc129f3a82c3bdd9f81b9f2d4e770ac09))
## [3.3.0](https://github.com/folke/trouble.nvim/compare/v3.2.0...v3.3.0) (2024-06-07)
### Features
* **lsp:** most lsp sources now support `params.include_current`. Fixes [#482](https://github.com/folke/trouble.nvim/issues/482) ([29d19d4](https://github.com/folke/trouble.nvim/commit/29d19d4f2102306176578f1fe537fbd9740b19e1))
* **window:** more options for mapping keys ([fdcfc5a](https://github.com/folke/trouble.nvim/commit/fdcfc5a200491e9509e56e04c6b3cdee8ada3153))
* you can now use `dd` and `d` to delete items in the trouble list. Fixes [#149](https://github.com/folke/trouble.nvim/issues/149). Fixes [#347](https://github.com/folke/trouble.nvim/issues/347) ([e879302](https://github.com/folke/trouble.nvim/commit/e879302d003bf5bda746a36365431d4a72cf3226))
### Bug Fixes
* **api:** only refresh on open if there's no action. Fixes [#488](https://github.com/folke/trouble.nvim/issues/488) ([2661f46](https://github.com/folke/trouble.nvim/commit/2661f4612209cbbc1106fb9537666ea0133e4859))
* **preview:** fixed mouse clicks in the preview main window. Fixes [#484](https://github.com/folke/trouble.nvim/issues/484) ([98d9ed7](https://github.com/folke/trouble.nvim/commit/98d9ed74aec4e82171de3ae0541cdd078558e546))
* **telescope:** show error when use tries to add when telescope picker does not exist ([c11dc27](https://github.com/folke/trouble.nvim/commit/c11dc2777d52da2c8da25836817e43608ec951a5))
* use vim.loop for nvim 0.9 in view/init.lua ([#487](https://github.com/folke/trouble.nvim/issues/487)) ([791278e](https://github.com/folke/trouble.nvim/commit/791278e498e1147520e4214982767f77ca4a99df))
* **view:** when calling open when the view is already open, do a refresh. See [#485](https://github.com/folke/trouble.nvim/issues/485) ([39595e8](https://github.com/folke/trouble.nvim/commit/39595e883e2f91456413ca4df287575d31665940))
## [3.2.0](https://github.com/folke/trouble.nvim/compare/v3.1.0...v3.2.0) (2024-06-06)
### Features
* **lsp:** add incoming/outgoing calls to lsp mode ([8adafc1](https://github.com/folke/trouble.nvim/commit/8adafc14d8fe2a4471a0311ff72927250390d7bd))
* **lsp:** added support for showing locations from lsp execute commands ([b1d16ac](https://github.com/folke/trouble.nvim/commit/b1d16ac02d787e40165130e0cd09474ce639b175))
* promise class ([84f0c6d](https://github.com/folke/trouble.nvim/commit/84f0c6d047dbf182622f3d89bc47ec4a70c900b2))
### Bug Fixes
* **api:** show error when an invalid mode was used. Fixes [#465](https://github.com/folke/trouble.nvim/issues/465) ([4b1914c](https://github.com/folke/trouble.nvim/commit/4b1914c5cdbf7be18fee797c410df2faa2be13f2))
* **format:** pos format. See [#472](https://github.com/folke/trouble.nvim/issues/472) ([abdfa1d](https://github.com/folke/trouble.nvim/commit/abdfa1daeb9713470a9b61676a82f24f32e31900))
* **lsp:** check for nil on faulty lsp results ([d7f69ff](https://github.com/folke/trouble.nvim/commit/d7f69ff5638cf1864cabac54ade1b1694adfe085))
* **lsp:** dont process nil results ([06a4892](https://github.com/folke/trouble.nvim/commit/06a48922e83b114a78c63ec770819b4afacd2166))
* **lsp:** send request only to needed clients ([c147a75](https://github.com/folke/trouble.nvim/commit/c147a75c421b2df6986d82f61657ccec2f302091))
* **lsp:** use document uri of document symbols don't have an uri set. Fixes [#480](https://github.com/folke/trouble.nvim/issues/480) ([358f0ee](https://github.com/folke/trouble.nvim/commit/358f0ee6ce4c379a3b0c37bb04ab6587c86e285a))
* **preview:** hide winbar when previewing in main. Fixes [#464](https://github.com/folke/trouble.nvim/issues/464) ([250ea79](https://github.com/folke/trouble.nvim/commit/250ea79c810a3e5fff846c788792441f1c795c92))
* **preview:** respect fold settings. Fixes [#459](https://github.com/folke/trouble.nvim/issues/459) ([29d1bb8](https://github.com/folke/trouble.nvim/commit/29d1bb81adc847e89ddbbf5b11ff0079daf7cc0a))
* **preview:** set correct extmark priorities in preview highlight. Fixes [#476](https://github.com/folke/trouble.nvim/issues/476) ([13ad959](https://github.com/folke/trouble.nvim/commit/13ad95902cf479b0fa091a77368af0e03b486fe3))
* **view:** correctly set folding options to wo. See [#477](https://github.com/folke/trouble.nvim/issues/477) ([9151797](https://github.com/folke/trouble.nvim/commit/915179759c9459b69faae90a38da6fc1ca6b90d7))
* **view:** ensure fold settings are correct for the trouble views. See [#477](https://github.com/folke/trouble.nvim/issues/477) ([b5181b6](https://github.com/folke/trouble.nvim/commit/b5181b65912c704d5378f8fe6889924f0182c357))
* **view:** execute actions on first render ([97bfb74](https://github.com/folke/trouble.nvim/commit/97bfb74826476b26634b5321c5d8dfbc46e41497))
* **window:** account for winbar for preview in main. Fixes [#468](https://github.com/folke/trouble.nvim/issues/468) ([23ded52](https://github.com/folke/trouble.nvim/commit/23ded52593d017fd7d6042215460419801e35481))
* **window:** set default winblend=0. See [#468](https://github.com/folke/trouble.nvim/issues/468) ([e296940](https://github.com/folke/trouble.nvim/commit/e2969409cf3f38f69913cc8fd9aa13137aabe760))
### Performance Improvements
* use promises for fetching sections ([e49a490](https://github.com/folke/trouble.nvim/commit/e49a49044cca072c4aca1cb3a5013aa92ac3b4f9))
## [3.1.0](https://github.com/folke/trouble.nvim/compare/v3.0.0...v3.1.0) (2024-05-31)
### Features
* added severity filter keymap and improved filtering actions ([7842dbb](https://github.com/folke/trouble.nvim/commit/7842dbb70f088cbaae969004bd2fbae09b2a2d26))
* only open trouble when results (optionally). Fixes [#450](https://github.com/folke/trouble.nvim/issues/450) ([8fbd2ab](https://github.com/folke/trouble.nvim/commit/8fbd2abb3ff42ebb134e389f405bfa9140db1fe3))
* **telescope:** allow passing additional trouble options to telescope open/add. Fixes [#457](https://github.com/folke/trouble.nvim/issues/457) ([4eaaf9c](https://github.com/folke/trouble.nvim/commit/4eaaf9cf8b967010998ccfc4af525b3e6d70b8b5))
### Bug Fixes
* close section session when needed ([2caf73d](https://github.com/folke/trouble.nvim/commit/2caf73d2d136625d77c0d25cc3b5d5e1e0bef3d0))
* **fold:** start folding with closest non leaf node. Fixes [#420](https://github.com/folke/trouble.nvim/issues/420) ([f248c69](https://github.com/folke/trouble.nvim/commit/f248c6941ba5a48be531cbb25aac32e1042c65ad))
* **follow:** improve the way follow works ([cf81aac](https://github.com/folke/trouble.nvim/commit/cf81aaca820017388fc630c534774c95b58233f2))
* **format:** compat old signs ([0e843ed](https://github.com/folke/trouble.nvim/commit/0e843edbdc1b25ca6a5468d636b22e7035a4ad69))
* **format:** fallback to sign_defined. Fixes [#448](https://github.com/folke/trouble.nvim/issues/448) ([36545cb](https://github.com/folke/trouble.nvim/commit/36545cb88fa999f211bfc341998f501803bf5434))
* **lsp:** batch get offset position for lsp results. See [#452](https://github.com/folke/trouble.nvim/issues/452) ([96c30dc](https://github.com/folke/trouble.nvim/commit/96c30dc6ae10e42ab47c1f68d7f715bf01100c48))
* **lsp:** correctly clear location cache ([7ea94a6](https://github.com/folke/trouble.nvim/commit/7ea94a6366141878758938010e4a0818a56721ad))
* **lsp:** exclude locations that match the current line ([8c03e13](https://github.com/folke/trouble.nvim/commit/8c03e133bc88fb7c242e9915d06f0a8978511c29))
* make sure line is always a string passed to get_line_col ([5a12185](https://github.com/folke/trouble.nvim/commit/5a12185787896da209738bd41cbe4133d82ce9bb))
* **preview:** correctly load non-scratch buffers ([965f56f](https://github.com/folke/trouble.nvim/commit/965f56f3e17baee4213cf50637f92de4be32d8e9))
* **preview:** correctly pass options to create scratch buffers. Fixes [#451](https://github.com/folke/trouble.nvim/issues/451) ([c50c7e3](https://github.com/folke/trouble.nvim/commit/c50c7e35d4f504d6336875994109c546ff0634b5))
* **preview:** don't error on invalid positions ([6112c3c](https://github.com/folke/trouble.nvim/commit/6112c3c5c903a05178276a083edc756ba3cb65a0))
* **qf:** only listen for TextChanged in the main buffer. See [#201](https://github.com/folke/trouble.nvim/issues/201) ([f75992f](https://github.com/folke/trouble.nvim/commit/f75992f9a1b93cc4490dca28f93acc921c25419e))
* **qf:** update qflist on TextChanged to update pos. Fixes [#201](https://github.com/folke/trouble.nvim/issues/201) ([c1d9294](https://github.com/folke/trouble.nvim/commit/c1d9294eb73479fd4007237613eb7e945cd84e20))
* stop ([bda8de4](https://github.com/folke/trouble.nvim/commit/bda8de4205f06c3939b8b59e4da1f3713d04ea05))
* **telescope:** remove filter on `buf = 0`. See [#399](https://github.com/folke/trouble.nvim/issues/399) ([f776ab0](https://github.com/folke/trouble.nvim/commit/f776ab0ff1658f052b7345d4bbd5961b443ea8a0))
* **view:** restore loc on first render and dont delete last loc if trouble window was never visisted. See [#367](https://github.com/folke/trouble.nvim/issues/367) ([51bf510](https://github.com/folke/trouble.nvim/commit/51bf51068d929173157ebcfb863115760c837355))
### Performance Improvements
* **lsp:** cache location requests ([6053627](https://github.com/folke/trouble.nvim/commit/6053627943020d9774c75ec637eb06847a79c7a1))
* **lsp:** optimize batch fetching lsp item locations. Fixes [#452](https://github.com/folke/trouble.nvim/issues/452) ([a6f1af5](https://github.com/folke/trouble.nvim/commit/a6f1af567fc987306f0f328e78651bab1bfe874e))
* much faster treesitter highlighter ([d4de08d](https://github.com/folke/trouble.nvim/commit/d4de08d9314a9ddf7278ee16efb58d0efe332bc8))
* prevent autocmd leaks ([9e3391c](https://github.com/folke/trouble.nvim/commit/9e3391ce735f4f6fa98fe70ba9a3e444f2fd539a))
* **preview:** re-use existing preview when preview is for the same file ([a415b64](https://github.com/folke/trouble.nvim/commit/a415b64b8a702ab6388e3aaaf16306750fc53f79))
## [3.0.0](https://github.com/folke/trouble.nvim/compare/v2.10.0...v3.0.0) (2024-05-30)
### ⚠ BREAKING CHANGES
* Trouble v3 is now merged in main. You may need to update your configs.
### Features
* `Trouble` now shows vim.ui.select to chose a mode ([0189184](https://github.com/folke/trouble.nvim/commit/01891844a9adb3b5b2de508724024d516a2b891a))
* added basename/dirname ([bb3740a](https://github.com/folke/trouble.nvim/commit/bb3740a1c41e83bcd59c3fe04714a85b445c4742))
* added help ([68ac238](https://github.com/folke/trouble.nvim/commit/68ac238aeef333a37dc95d875bed46a2698793d5))
* added kind symbol highlights ([de08657](https://github.com/folke/trouble.nvim/commit/de086574208b19b762055487334ce50ca95cc008))
* added lpeg parser for parsing `:Trouble` args into lua tables ([b25ef53](https://github.com/folke/trouble.nvim/commit/b25ef53117b0bdc5733d26e42a55c7f32daadbe5))
* added missing fold keymaps. folding is now feature complete ([9fb1be0](https://github.com/folke/trouble.nvim/commit/9fb1be0915202989bd17e0c9768be23ae7b15010))
* added multiline option back ([d80e978](https://github.com/folke/trouble.nvim/commit/d80e978f70cc3c026ad028dafbde9e3ad45ba54c))
* added proper api ([a327003](https://github.com/folke/trouble.nvim/commit/a3270035999dc965176ccd140dcc9afe57f0934a))
* added support for formatting fields with a treesitter language ([21cfee9](https://github.com/folke/trouble.nvim/commit/21cfee9e4e026482c1c9719156aae3152b2c590a))
* allow items without buf ([c3b01ce](https://github.com/folke/trouble.nvim/commit/c3b01ce7662dda3a542c52aa1521f8467300c84a))
* allow top-level filter ([12447df](https://github.com/folke/trouble.nvim/commit/12447df2a81205b8bda12dd1c9271c1c0059184f))
* **config:** added `auto_jump` to jump to the item when there's only one. Fixes [#409](https://github.com/folke/trouble.nvim/issues/409) ([94a84ab](https://github.com/folke/trouble.nvim/commit/94a84ab884757b1a9f697807e7bdace8b8919afb))
* **config:** added keymap to inspect an item. Useful for dev ([9da1a47](https://github.com/folke/trouble.nvim/commit/9da1a4783bc0d87427f5cbf6964321774e0bb1bc))
* **config:** set `focus=false` by default ([c7e5398](https://github.com/folke/trouble.nvim/commit/c7e539819e6d21428a747f46715a23b3d1a204b6))
* **diagnostics:** added support for diagnostics signs on Neovim >= 0.10.0. Fixes [#369](https://github.com/folke/trouble.nvim/issues/369), fixes [#389](https://github.com/folke/trouble.nvim/issues/389) ([6303740](https://github.com/folke/trouble.nvim/commit/6303740eb1a0730b5654d554ba38bd9614c87e28))
* **filter:** added filetype filter ([e541444](https://github.com/folke/trouble.nvim/commit/e5414444bdbd5fb70a954ad24abeaa0866179f62))
* **filter:** easier filtering of any values ([1b528d8](https://github.com/folke/trouble.nvim/commit/1b528d8f3b91fe07ab4f27cbe8eee65b0532192b))
* **filter:** range filter ([34a06d6](https://github.com/folke/trouble.nvim/commit/34a06d6f4bd32b37f685a36a5037c1556ce6b88f))
* filters, formatters and sorters are now configurable ([c16679d](https://github.com/folke/trouble.nvim/commit/c16679ddf67f28b5df0735f488497a4c1e7881ee))
* **format:** formats now support `{one|two}`. First field that returns a value will be used ([26ad82e](https://github.com/folke/trouble.nvim/commit/26ad82eb3c81a434ade3d7bebd97e02565ac717e))
* global view filters and easy toggling of just items of the current buffer ([11e7c39](https://github.com/folke/trouble.nvim/commit/11e7c39803ff33c68346019a46172fe9be5f3f6d))
* improved commandline parser and completion ([f7eccfb](https://github.com/folke/trouble.nvim/commit/f7eccfbddef64f3379cf6997617cb41e3005f355))
* initial commit of rewrite ([d9542ca](https://github.com/folke/trouble.nvim/commit/d9542ca97e37a43844d9088bf453bbb257de423c))
* item hierarchies and directory grouping ([d2ed413](https://github.com/folke/trouble.nvim/commit/d2ed41320e548149d024634d8a6aa1b5c40396a1))
* Item.get_lang and Item.get_ft ([498da6b](https://github.com/folke/trouble.nvim/commit/498da6bcff8170f620506f66dd71465b3565baaa))
* **item:** util method to add missing text to items ([de9e7e6](https://github.com/folke/trouble.nvim/commit/de9e7e68ebb7aa36d78a68207d42943d49a31a85))
* **lsp:** added `lsp_incoming_calls` and `lsp_outgoing_calls`. Closes [#222](https://github.com/folke/trouble.nvim/issues/222) ([b855469](https://github.com/folke/trouble.nvim/commit/b855469429f10c74a3314432ba2735a32115cbb2))
* **lsp:** document symbols caching and compat with Neovim 0.9.5 ([2f49b92](https://github.com/folke/trouble.nvim/commit/2f49b920b0822a3d06c25d24d840830016168a82))
* main window tracking ([23a0631](https://github.com/folke/trouble.nvim/commit/23a06316607fe2d2ab311fdb5bb45157c2d8ec91))
* make the preview action a toggle ([86da179](https://github.com/folke/trouble.nvim/commit/86da1794855f71ec592efec2a6a65911f08892a2))
* preview can now be shown in a split/float ([e2919eb](https://github.com/folke/trouble.nvim/commit/e2919eb565ccc66d4adad729b4e323a718d41953))
* preview is now fully configurable ([b99110a](https://github.com/folke/trouble.nvim/commit/b99110adc3815f1b7b8fe3dd40f4c9da315f7cca))
* **preview:** option to force loading real buffers in preview. Fixes [#435](https://github.com/folke/trouble.nvim/issues/435) ([ccacba2](https://github.com/folke/trouble.nvim/commit/ccacba22b2c1946cfe1b9f767f7880bcd031ad7c))
* **preview:** use a float to show preview in the main window instead of messing with the main window itself ([9e0311d](https://github.com/folke/trouble.nvim/commit/9e0311d177af7cd6750d88280d589ceca4f7685a))
* **preview:** window var to know a window is a preview win ([dcecbb9](https://github.com/folke/trouble.nvim/commit/dcecbb9b9d67770c8df4c1c49b91631fbdae8ae5))
* **qf:** add treesitter highlighting to quickfix/loclist. Fixes [#441](https://github.com/folke/trouble.nvim/issues/441) ([325d681](https://github.com/folke/trouble.nvim/commit/325d681953611336cdfdf08a3d71e5125c5f89a5))
* **render:** `{field:ts}` will now use the treesitter lang of the item buffer for highlighting ([21af85c](https://github.com/folke/trouble.nvim/commit/21af85cc97860e3bcf157891c2598af517f9b421))
* **render:** added support for rendering multiple sections ([332b25b](https://github.com/folke/trouble.nvim/commit/332b25b09c7159a82322ec97f7aa1717133ffa6f))
* **source:** added lsp source ([3969907](https://github.com/folke/trouble.nvim/commit/39699074cd18cdeb5e9a29e80ffd2d239c58ac7e))
* **source:** added quickfix source ([3507b7b](https://github.com/folke/trouble.nvim/commit/3507b7b694ddee5921c7004c6bed0b71ab8e0920))
* **sources:** added support for loading external sources ([89ac6f1](https://github.com/folke/trouble.nvim/commit/89ac6f1a7f238ca65d964569786b205a496ad213))
* **sources:** added telescope source ([39069e2](https://github.com/folke/trouble.nvim/commit/39069e2f4139c7ae28cf7e16fe610b8462fb3939))
* **source:** sources can now have multiple child sources ([c433301](https://github.com/folke/trouble.nvim/commit/c4333014a770eca5a66c7685f4063d8de13517db))
* **source:** sources now always execute in the context of the main window even when a preview is active ([4eab561](https://github.com/folke/trouble.nvim/commit/4eab56122bb335a5627405791e4691af5043493e))
* **statusline:** added statusline component ([5c0b163](https://github.com/folke/trouble.nvim/commit/5c0b1639c83266427489bb515bffd8b8bc055809))
* **statusline:** allow 'fixing' the statusline bg color based on a hl_group. Fixes [#411](https://github.com/folke/trouble.nvim/issues/411) ([986b44d](https://github.com/folke/trouble.nvim/commit/986b44d4471ee8b8a708a0172fb0829a9c858543))
* **statusline:** statusline api ([c219a1a](https://github.com/folke/trouble.nvim/commit/c219a1a9f56a70ac55e89325c333fcfd0616ea97))
* **telescope:** added option to add telescope results to trouble, without clearing the existing results. Fixes [#370](https://github.com/folke/trouble.nvim/issues/370) ([a7119ab](https://github.com/folke/trouble.nvim/commit/a7119abb0cd1b1ef058fc99c036230bbe153504f))
* **tree:** added `flatten()` to get all items from the tree ([35c0236](https://github.com/folke/trouble.nvim/commit/35c0236ceb78fc37a94f5882f736416ebb15c306))
* Trouble v3 is now merged in main. You may need to update your configs. ([1b362b8](https://github.com/folke/trouble.nvim/commit/1b362b861eacb9b2367ce92129fad86352707311))
* **util:** better notify functions ([c68c915](https://github.com/folke/trouble.nvim/commit/c68c915353dc5162e5d7494b5ca0919f0e336318))
* **util:** fast get_lines for a buffer ([6940cd8](https://github.com/folke/trouble.nvim/commit/6940cd8c6913e834254e7221ede0ca6a38c81fc0))
* **util:** fast plain text split ([6a30aec](https://github.com/folke/trouble.nvim/commit/6a30aec15ca90e8b396a381f8f1b7c452f6ce68a))
* **util:** make throttles configurable ([8c297c1](https://github.com/folke/trouble.nvim/commit/8c297c171547e8c81fc918a7f31b3c2a8ce58512))
* **view:** added support for pinned views. Main window of the view will stay the same as long as its a valid window ([17131e2](https://github.com/folke/trouble.nvim/commit/17131e2b9a0b7d17046cb9b7ed9b7eeb36b6423a))
* **view:** expose some params in the trouble window var. Fixes [#357](https://github.com/folke/trouble.nvim/issues/357) ([a4b9849](https://github.com/folke/trouble.nvim/commit/a4b9849ce7ec14213069034403f5fc96d174046b))
* **view:** follow now also scrolls to the file in the list when not on an item ([30b939e](https://github.com/folke/trouble.nvim/commit/30b939efebd8559e9e84c95e3658c447f702b1c2))
* **view:** follow the current item in the list ([e76e280](https://github.com/folke/trouble.nvim/commit/e76e280701e643e8a3074edcb86e819298e7df12))
* **view:** when toggling a trouble list, restore to the last location. Fixes [#367](https://github.com/folke/trouble.nvim/issues/367) ([1d951f5](https://github.com/folke/trouble.nvim/commit/1d951f5c13fd56933e9170b84bfcbbf8ca1a582b))
* **window:** added possibility to override TroubleNormalNC. Fixes [#216](https://github.com/folke/trouble.nvim/issues/216) ([daa5157](https://github.com/folke/trouble.nvim/commit/daa5157e3f0f6cf80ca473d7e43bd73734d6594d))
* **window:** added support for showing a floating window over the main window ([3525169](https://github.com/folke/trouble.nvim/commit/35251698e7836ecb3ee981efe2efe7bcb64ca5f3))
* **window:** allow setting width/height a size for splits. either will be used based on position ([e8ee9b0](https://github.com/folke/trouble.nvim/commit/e8ee9b01ee46f9cd2e2a8fe8b883320f3212608d))
* **window:** expose some window vars for integration with other plugins (edgy.nvim) ([aae1da8](https://github.com/folke/trouble.nvim/commit/aae1da81cba50ca207ce3681e5ef927bd369f074))
### Bug Fixes
* add vim to parser globals ([6077342](https://github.com/folke/trouble.nvim/commit/6077342efe9e7f77756dd064cdb2129ffea5674f))
* **api:** make sure new=true works when opening with a mode string ([398ac76](https://github.com/folke/trouble.nvim/commit/398ac76019a74bbbe0c2b77c0a0a7a1e4ce71c3d))
* better defaults for lsp/diagnostics ([569416d](https://github.com/folke/trouble.nvim/commit/569416d52f1953c35ba8494d7cab2be1b01fe409))
* better way of creating preview buffers ([667b010](https://github.com/folke/trouble.nvim/commit/667b010ba81d7ce49fa2cca6cb80c0b85b328543))
* **command:** improved command completion ([9f59aac](https://github.com/folke/trouble.nvim/commit/9f59aac5ccdb3b5c2c1425176e0112efd7b84a16))
* **commmand:** show mode descriptions ([ce488b9](https://github.com/folke/trouble.nvim/commit/ce488b9b4ddc0f9a61d48d0ae8974c22e5472e0c))
* **config:** fixed some highlights to use the latest treesitter hl groups ([63313cd](https://github.com/folke/trouble.nvim/commit/63313cd5a1e55d1ec870f9716f2e6cc9b6471cfc))
* deprecated tbl_islist ([#436](https://github.com/folke/trouble.nvim/issues/436)) ([5aa7993](https://github.com/folke/trouble.nvim/commit/5aa79935f1de301ed3592981ad7031c166cc5c84))
* diagnostics sections ([27efb63](https://github.com/folke/trouble.nvim/commit/27efb6326d8bb9019d2b69e737c1c3741a3af568))
* **diagnostics:** use main buffer for buffer-local diags ([259770d](https://github.com/folke/trouble.nvim/commit/259770dd860fd08007d13c116a5a7ee985e5f5bf))
* **filter:** fix range filter to include col ([6cae8af](https://github.com/folke/trouble.nvim/commit/6cae8af72ccf1be72718d3f735a467bff23c9beb))
* **filter:** range should also check that the buffer is the same ([fdd27d8](https://github.com/folke/trouble.nvim/commit/fdd27d8ac5276147b91cee2c2578b178a3dd7be2))
* **format:** always pass a valid buffer to ftdetect even just the current onw ([b01b11e](https://github.com/folke/trouble.nvim/commit/b01b11efc901dc3bc5f89d164de5eb71d56cc257))
* **help:** sort keymaps case incensitive ([5d81927](https://github.com/folke/trouble.nvim/commit/5d81927bc7eb9de085d9ea6cf8b977616694f771))
* **highlights:** reset statusline hl groups when colorscheme changes ([a665272](https://github.com/folke/trouble.nvim/commit/a665272b1e1d4b06b1b6824cc3f853874b06c0a1))
* **item:** clamp pos ([6c0204c](https://github.com/folke/trouble.nvim/commit/6c0204cb7d758d70edc5b88919f19a76de853aa7))
* **jump:** save current main cursor to jump list before jumping. Fixes [#385](https://github.com/folke/trouble.nvim/issues/385) ([bd8bfc8](https://github.com/folke/trouble.nvim/commit/bd8bfc8abedbf992a6d8c0db941780e1a79d3b41))
* **lsp:** check if buf is still valid after receiving document symbols ([33ec71c](https://github.com/folke/trouble.nvim/commit/33ec71cf377c518d8b8c022e2b46511f85c3a47d))
* **lsp:** handle invalid positions. Fixes [#434](https://github.com/folke/trouble.nvim/issues/434) ([371cf26](https://github.com/folke/trouble.nvim/commit/371cf26bcbddb39e2e91d69dae90a480f29c3fc0))
* **lsp:** refresh on LspAttach ([17afc44](https://github.com/folke/trouble.nvim/commit/17afc44fc317449128f1804ea6f316ce457295cc))
* **main:** always return a main window, even when no main. Fixes [#426](https://github.com/folke/trouble.nvim/issues/426) ([bda72a5](https://github.com/folke/trouble.nvim/commit/bda72a548e4eb9cab3bcf567ca965b21a136263d))
* make focus the default ([ba1ae49](https://github.com/folke/trouble.nvim/commit/ba1ae497e1899af0e57adb815ab30e37b73d0b76))
* **parser:** handle empty args ([e667da7](https://github.com/folke/trouble.nvim/commit/e667da705c64509347829326d19668e3276355e9))
* **preview:** better preview for multiline items ([60c9fdc](https://github.com/folke/trouble.nvim/commit/60c9fdcad7003fe6ed6f4a225bf709acd19068df))
* **preview:** center preview location and open folds. See [#408](https://github.com/folke/trouble.nvim/issues/408) ([a87fa2a](https://github.com/folke/trouble.nvim/commit/a87fa2ae521d058ad67dc7610efdd234b792d6ef))
* **preview:** clear highlights of preview buffer ([d590491](https://github.com/folke/trouble.nvim/commit/d590491de9515caf5ec3a3a0bd0fdb3047b1fda3))
* **preview:** dont show preview for directories. Fixes [#410](https://github.com/folke/trouble.nvim/issues/410) ([769ee0f](https://github.com/folke/trouble.nvim/commit/769ee0f632ea3b6ffc5716590a711db340e80caf))
* **preview:** fixup for directory check ([eed25b2](https://github.com/folke/trouble.nvim/commit/eed25b2bcea6e59e5f5c92c184ac08be4590b6de))
* **preview:** pass valid buffer so that ftdetect works for ts files. See [#435](https://github.com/folke/trouble.nvim/issues/435) ([65f2430](https://github.com/folke/trouble.nvim/commit/65f2430f6d6276832ec9500b5eafabb01e17d01a))
* **preview:** set correct winhighlight for preview window in main. See [#408](https://github.com/folke/trouble.nvim/issues/408) ([8c3c1db](https://github.com/folke/trouble.nvim/commit/8c3c1db742e74f0e48134cd4e84c976c2706e6b6))
* **preview:** unload preview buffer again when closing and when it wasnt loaded before ([8cc680a](https://github.com/folke/trouble.nvim/commit/8cc680a25f30e63c9e92005155c7916b9a000ac9))
* proper deprecated fix ffs... Fixes [#438](https://github.com/folke/trouble.nvim/issues/438) ([a8264a6](https://github.com/folke/trouble.nvim/commit/a8264a65a0b894832ea642844f5b7c30112c458f))
* properly deal with multiline treesitter segments ([31681a9](https://github.com/folke/trouble.nvim/commit/31681a92e2e7fa0537284ad1516561b46cdb4a24))
* **qf:** col/row offsets ([8ad817f](https://github.com/folke/trouble.nvim/commit/8ad817f12b4c9c4d6bd239c963cda3ac518d272a))
* remove `buf = 0` sorting since it acts weirdly with next/prev ([2b589e9](https://github.com/folke/trouble.nvim/commit/2b589e938c4b5245d7f74b7f23293645e566cee3))
* remove space from `zz zv` command ([ca2cd56](https://github.com/folke/trouble.nvim/commit/ca2cd56d14df8fc619ba44bebd5334d78b57d74c))
* require Neovim >= 0.9.2 ([2448521](https://github.com/folke/trouble.nvim/commit/24485219198a1ab10731e45229f2736ec3242231))
* **section:** dont trigger on invalid buffers ([29ee890](https://github.com/folke/trouble.nvim/commit/29ee890b28280b0a8a504571596a0508244122e1))
* **setup:** add check for NEovim 0.10.0 or markdown parsers. Fixes [#413](https://github.com/folke/trouble.nvim/issues/413) ([6267ef1](https://github.com/folke/trouble.nvim/commit/6267ef15e98bd8df29be7a8d6f47b0e724ceaaaf))
* **sources:** always load sources when not registered yet. Fixes [#393](https://github.com/folke/trouble.nvim/issues/393) ([1470302](https://github.com/folke/trouble.nvim/commit/1470302bd7eef110aef3710dfc8808bc3c3a2179))
* specs and tests ([315f624](https://github.com/folke/trouble.nvim/commit/315f624492c54f9893631459fc79e6c0b33b7cad))
* **statusline:** double escape `#`. Fixes [#424](https://github.com/folke/trouble.nvim/issues/424) ([9ddfd47](https://github.com/folke/trouble.nvim/commit/9ddfd47eec3a1bd43f5e7dd34eb1084f6793eaba))
* **statusline:** make sure max_items is honored ([da8ba7d](https://github.com/folke/trouble.nvim/commit/da8ba7dfba2341c5ea679e6cff85c01943777380))
* **statusline:** schedule statusline refresh ([f000daa](https://github.com/folke/trouble.nvim/commit/f000daadd6d49b30eebacb2a6dd7c4d9758f2de6))
* **telescope:** close telescope after sending results to trouble ([2753932](https://github.com/folke/trouble.nvim/commit/2753932bed13cff73be80e2565043dccce899983))
* **telescope:** deprecation warning for old telescope provider ([0d7cdeb](https://github.com/folke/trouble.nvim/commit/0d7cdeba2d139f26314d53e2e06507b6a7b72e3b))
* **throttle:** fixed throttling so that it now only gets scheduled when there are pending args ([0db2084](https://github.com/folke/trouble.nvim/commit/0db20847636e6715cb2d1c542fee34d349f47ee3))
* **tree:** fixed tree item count. Fixes [#419](https://github.com/folke/trouble.nvim/issues/419) ([cb59440](https://github.com/folke/trouble.nvim/commit/cb594402cf4407bbf54111c20ef39d42d9b017f6))
* **tree:** make sure qf items always have a unique id. Fixes [#367](https://github.com/folke/trouble.nvim/issues/367) ([c0755d5](https://github.com/folke/trouble.nvim/commit/c0755d59731869994187b04adcb89ebce75c27eb))
* **treesitter:** show warning for missing treesitter parsers ([4253652](https://github.com/folke/trouble.nvim/commit/425365272136c731eea9da4c337f7b1dfe4d44d6))
* **tree:** use format as node id for group without fields ([a29c293](https://github.com/folke/trouble.nvim/commit/a29c29382da0dcb8554da25e40a4d2495dff771f))
* **ui:** better deal with invalid items positions and extmarks. Fixes [#404](https://github.com/folke/trouble.nvim/issues/404) ([bc0a194](https://github.com/folke/trouble.nvim/commit/bc0a19482ee8f68eb427939df2e28cca800b9cbb))
* **util:** deprecation warnings for tbl_islist ([7577f3a](https://github.com/folke/trouble.nvim/commit/7577f3a82ff60ef7425451b1f40dd83ffee12307))
* **util:** typo ([37f6266](https://github.com/folke/trouble.nvim/commit/37f62665dfc8db002f7fe62ae6b467c566329ec3))
* **util:** use xpcall in throttle for better stack traces ([6d9a0ba](https://github.com/folke/trouble.nvim/commit/6d9a0baeb226548b967329d7c045c38ff16a19e8))
* **view:** check if trouble win is still valid in OptionSet. Fixes [#400](https://github.com/folke/trouble.nvim/issues/400) ([e9fae8c](https://github.com/folke/trouble.nvim/commit/e9fae8c453eac69aa33dc4899c46b76417a04e3e))
* **view:** check that window is open before checking active item ([5b5446d](https://github.com/folke/trouble.nvim/commit/5b5446ddf2d6c50b555d28459ce7632ca39d6ac0))
* **view:** do `norm! zz zv` after jump. See [#408](https://github.com/folke/trouble.nvim/issues/408) ([74e31e7](https://github.com/folke/trouble.nvim/commit/74e31e732fa6888a72f6b73b3115b8ea84ef47f5))
* **view:** dont refresh items when calling `open` and already open ([7485aa7](https://github.com/folke/trouble.nvim/commit/7485aa70e0341c55bd25e2287b29e991c61297d1))
* **view:** dont trigger follow when moving. Fixes [#3359](https://github.com/folke/trouble.nvim/issues/3359) ([7cc4df2](https://github.com/folke/trouble.nvim/commit/7cc4df259b208a1f19a67a171da7d5f7e917e7c4))
* **view:** store restore locations when moving the cursor. See [#367](https://github.com/folke/trouble.nvim/issues/367) ([d8265a6](https://github.com/folke/trouble.nvim/commit/d8265a6f0eea8fff249decf3a1304991f850715b))
* **window:** main window float should have regular winhighlight ([6ccd579](https://github.com/folke/trouble.nvim/commit/6ccd579a177dc81d81706194131e23b24e93e5fa))
* **window:** properly deal with alien buffers opening in trouble windows ([92832c4](https://github.com/folke/trouble.nvim/commit/92832c4676e079c4fe824fd5c9a5ba3259d2e506))
* **windows:** Corrected regex matching path with backslash. ([#396](https://github.com/folke/trouble.nvim/issues/396)) ([a784506](https://github.com/folke/trouble.nvim/commit/a784506b4e5f649e568ec6763aa90d7a7ec4c0b3))
* **window:** set cursorlineopt for the trouble window. Fixes [#356](https://github.com/folke/trouble.nvim/issues/356) ([4c07228](https://github.com/folke/trouble.nvim/commit/4c07228dec2663d9dda9b12f68785a9f9ec9fd72))
### Performance Improvements
* better throttle ([c10d53d](https://github.com/folke/trouble.nvim/commit/c10d53d3d7a48dc8090e44f375d2a12ca7ef0fb6))
* only trigger refresh when event happens in main for some sources ([6eac568](https://github.com/folke/trouble.nvim/commit/6eac5689fe59fbb8038eebb150c66dbb2a3960a0))
* use weak references to prevent memory leaks ([4d31d77](https://github.com/folke/trouble.nvim/commit/4d31d77561860cbe582239ebb970db1c75872018))
* **util:** get_lines can now use a buf or filename or both ([e987642](https://github.com/folke/trouble.nvim/commit/e9876428329f2a91e5dd8b29bd854d9b9ff7813a))
## [2.10.0](https://github.com/folke/trouble.nvim/compare/v2.9.1...v2.10.0) (2023-10-18)

View File

@ -1,43 +1,54 @@
# 🚦 Trouble v3 Beta!
❗**Trouble** has been rewritten from scratch. If you'd like to try the new version,
please refer to the [beta docs](https://github.com/folke/trouble.nvim/tree/dev)
![image](https://github.com/folke/trouble.nvim/assets/292349/481bc1f7-cb93-432d-8ab6-f54044334b96)
---
# 🚦 Trouble v2
# 🚦 Trouble
A pretty list for showing diagnostics, references, telescope results, quickfix and location lists to help you solve all the trouble your code is causing.
![LSP Trouble Screenshot](./media/shot.png)
![image](https://github.com/folke/trouble.nvim/assets/292349/481bc1f7-cb93-432d-8ab6-f54044334b96)
## ✨ Features
- pretty list of:
- Diagnostics
- LSP references
- LSP implementations
- LSP definitions
- LSP type definitions
- quickfix list
- location list
- [Telescope](https://github.com/nvim-telescope/telescope.nvim) search results
- automatically updates on new diagnostics
- toggle **diagnostics** mode between **workspace** or **document**
- **interactive preview** in your last accessed window
- _cancel_ preview or _jump_ to the location
- configurable actions, signs, highlights,...
- Diagnostics
- LSP references
- LSP implementations
- LSP definitions
- LSP type definitions
- LSP Document Symbols
- LSP Incoming/Outgoing calls
- quickfix list
- location list
- [Telescope](https://github.com/nvim-telescope/telescope.nvim) search results
- [fzf-lua](https://github.com/ibhagwan/fzf-lua) results
## 📰 What's new?
This is a full rewrite of the original **trouble.nvim**.
The new version is much more flexible and powerful,
with a lot of new features and improvements:
- multiple trouble windows at the same time
- LSP document symbols
- LSP incoming/outgoing calls
- lots of options to configure trouble windows (floats or splits)
- `focus` option to focus the trouble window when opened (or not)
- `follow` option to follow the item under the cursor
- `pinned` option to pin the buffer as the source for the opened trouble window
- full tree views of anything
- highly configurable views with custom formatters, filters, and sorters
- show multiple sections in the same view
- multi-line messages
- prettier and configurable indent guides
- tree view that follows the natural hierarchy of the items (like document symbols, or file structure)
- expansive API and `Trouble` command
- trouble `modes` to define custom views
- statusline component (useful with document symbols)
## ⚡️ Requirements
- Neovim >= 0.7.2
- Neovim >= 0.9.2
- Neovim >= 0.10.0 **OR** the `markdown` and `markdown_inline` [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) parsers
- Properly configured Neovim LSP client
- [nvim-web-devicons](https://github.com/nvim-tree/nvim-web-devicons) is optional to enable file icons
- a theme with properly configured highlight groups for Neovim Diagnostics
- or install 🌈 [lsp-colors](https://github.com/folke/lsp-colors.nvim) to automatically create the missing highlight groups
- a [patched font](https://www.nerdfonts.com/) for the default severity and fold icons
## 📦 Installation
@ -47,14 +58,42 @@ Install the plugin with your preferred package manager:
### [lazy.nvim](https://github.com/folke/lazy.nvim)
```lua
return {
"folke/trouble.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
-- your configuration comes here
-- or leave it empty to use the default settings
-- refer to the configuration section below
},
{
"folke/trouble.nvim",
opts = {}, -- for default options, refer to the configuration section for custom setup.
cmd = "Trouble",
keys = {
{
"<leader>xx",
"<cmd>Trouble diagnostics toggle<cr>",
desc = "Diagnostics (Trouble)",
},
{
"<leader>xX",
"<cmd>Trouble diagnostics toggle filter.buf=0<cr>",
desc = "Buffer Diagnostics (Trouble)",
},
{
"<leader>cs",
"<cmd>Trouble symbols toggle focus=false<cr>",
desc = "Symbols (Trouble)",
},
{
"<leader>cl",
"<cmd>Trouble lsp toggle focus=false win.position=right<cr>",
desc = "LSP Definitions / references / ... (Trouble)",
},
{
"<leader>xL",
"<cmd>Trouble loclist toggle<cr>",
desc = "Location List (Trouble)",
},
{
"<leader>xQ",
"<cmd>Trouble qflist toggle<cr>",
desc = "Quickfix List (Trouble)",
},
},
}
```
@ -62,206 +101,625 @@ return {
### Setup
Trouble comes with the following defaults:
**Trouble** is highly configurable. Please refer to the default settings below.
<details><summary>Default Settings</summary>
<!-- config:start -->
```lua
{
position = "bottom", -- position of the list can be: bottom, top, left, right
height = 10, -- height of the trouble list when position is top or bottom
width = 50, -- width of the list when position is left or right
icons = true, -- use devicons for filenames
mode = "workspace_diagnostics", -- "workspace_diagnostics", "document_diagnostics", "quickfix", "lsp_references", "loclist"
severity = nil, -- nil (ALL) or vim.diagnostic.severity.ERROR | WARN | INFO | HINT
fold_open = "", -- icon used for open folds
fold_closed = "", -- icon used for closed folds
group = true, -- group results by file
padding = true, -- add an extra new line on top of the list
cycle_results = true, -- cycle item list when reaching beginning or end of list
action_keys = { -- key mappings for actions in the trouble list
-- map to {} to remove a mapping, for example:
-- close = {},
close = "q", -- close the list
cancel = "<esc>", -- cancel the preview and get back to your last window / buffer / cursor
refresh = "r", -- manually refresh
jump = { "<cr>", "<tab>", "<2-leftmouse>" }, -- jump to the diagnostic or open / close folds
open_split = { "<c-x>" }, -- open buffer in new split
open_vsplit = { "<c-v>" }, -- open buffer in new vsplit
open_tab = { "<c-t>" }, -- open buffer in new tab
jump_close = {"o"}, -- jump to the diagnostic and close the list
toggle_mode = "m", -- toggle between "workspace" and "document" diagnostics mode
switch_severity = "s", -- switch "diagnostics" severity filter level to HINT / INFO / WARN / ERROR
toggle_preview = "P", -- toggle auto_preview
hover = "K", -- opens a small popup with the full multiline message
preview = "p", -- preview the diagnostic location
open_code_href = "c", -- if present, open a URI with more information about the diagnostic error
close_folds = {"zM", "zm"}, -- close all folds
open_folds = {"zR", "zr"}, -- open all folds
toggle_fold = {"zA", "za"}, -- toggle fold of current file
previous = "k", -- previous item
next = "j" -- next item
help = "?" -- help menu
---@class trouble.Mode: trouble.Config,trouble.Section.spec
---@field desc? string
---@field sections? string[]
---@class trouble.Config
---@field mode? string
---@field config? fun(opts:trouble.Config)
---@field formatters? table<string,trouble.Formatter> custom formatters
---@field filters? table<string, trouble.FilterFn> custom filters
---@field sorters? table<string, trouble.SorterFn> custom sorters
local defaults = {
auto_close = false, -- auto close when there are no items
auto_open = false, -- auto open when there are items
auto_preview = true, -- automatically open preview when on an item
auto_refresh = true, -- auto refresh when open
auto_jump = false, -- auto jump to the item when there's only one
focus = false, -- Focus the window when opened
restore = true, -- restores the last location in the list when opening
follow = true, -- Follow the current item
indent_guides = true, -- show indent guides
max_items = 200, -- limit number of items that can be displayed per section
multiline = true, -- render multi-line messages
pinned = false, -- When pinned, the opened trouble window will be bound to the current buffer
warn_no_results = true, -- show a warning when there are no results
open_no_results = false, -- open the trouble window when there are no results
---@type trouble.Window.opts
win = {}, -- window options for the results window. Can be a split or a floating window.
-- Window options for the preview window. Can be a split, floating window,
-- or `main` to show the preview in the main editor window.
---@type trouble.Window.opts
preview = {
type = "main",
-- when a buffer is not yet loaded, the preview window will be created
-- in a scratch buffer with only syntax highlighting enabled.
-- Set to false, if you want the preview to always be a real loaded buffer.
scratch = true,
},
-- Throttle/Debounce settings. Should usually not be changed.
---@type table<string, number|{ms:number, debounce?:boolean}>
throttle = {
refresh = 20, -- fetches new data when needed
update = 10, -- updates the window
render = 10, -- renders the window
follow = 100, -- follows the current item
preview = { ms = 100, debounce = true }, -- shows the preview for the current item
},
-- Key mappings can be set to the name of a builtin action,
-- or you can define your own custom action.
---@type table<string, trouble.Action.spec>
keys = {
["?"] = "help",
r = "refresh",
R = "toggle_refresh",
q = "close",
o = "jump_close",
["<esc>"] = "cancel",
["<cr>"] = "jump",
["<2-leftmouse>"] = "jump",
["<c-s>"] = "jump_split",
["<c-v>"] = "jump_vsplit",
-- go down to next item (accepts count)
-- j = "next",
["}"] = "next",
["]]"] = "next",
-- go up to prev item (accepts count)
-- k = "prev",
["{"] = "prev",
["[["] = "prev",
dd = "delete",
d = { action = "delete", mode = "v" },
i = "inspect",
p = "preview",
P = "toggle_preview",
zo = "fold_open",
zO = "fold_open_recursive",
zc = "fold_close",
zC = "fold_close_recursive",
za = "fold_toggle",
zA = "fold_toggle_recursive",
zm = "fold_more",
zM = "fold_close_all",
zr = "fold_reduce",
zR = "fold_open_all",
zx = "fold_update",
zX = "fold_update_all",
zn = "fold_disable",
zN = "fold_enable",
zi = "fold_toggle_enable",
gb = { -- example of a custom action that toggles the active view filter
action = function(view)
view:filter({ buf = 0 }, { toggle = true })
end,
desc = "Toggle Current Buffer Filter",
},
multiline = true, -- render multi-line messages
indent_lines = true, -- add an indent guide below the fold icons
win_config = { border = "single" }, -- window configuration for floating windows. See |nvim_open_win()|.
auto_open = false, -- automatically open the list when you have diagnostics
auto_close = false, -- automatically close the list when you have no diagnostics
auto_preview = true, -- automatically preview the location of the diagnostic. <esc> to close preview and go back to last window
auto_fold = false, -- automatically fold a file trouble list at creation
auto_jump = {"lsp_definitions"}, -- for the given modes, automatically jump if there is only a single result
include_declaration = { "lsp_references", "lsp_implementations", "lsp_definitions" }, -- for the given modes, include the declaration of the current symbol in the results
signs = {
-- icons / text used for a diagnostic
error = "",
warning = "",
hint = "",
information = "",
other = "",
s = { -- example of a custom action that toggles the severity
action = function(view)
local f = view:get_filter("severity")
local severity = ((f and f.filter.severity or 0) + 1) % 5
view:filter({ severity = severity }, {
id = "severity",
template = "{hl:Title}Filter:{hl} {severity}",
del = severity == 0,
})
end,
desc = "Toggle Severity Filter",
},
use_diagnostic_signs = false -- enabling this will use the signs defined in your lsp client
},
---@type table<string, trouble.Mode>
modes = {
-- sources define their own modes, which you can use directly,
-- or override like in the example below
lsp_references = {
-- some modes are configurable, see the source code for more details
params = {
include_declaration = true,
},
},
-- The LSP base mode for:
-- * lsp_definitions, lsp_references, lsp_implementations
-- * lsp_type_definitions, lsp_declarations, lsp_command
lsp_base = {
params = {
-- don't include the current location in the results
include_current = false,
},
},
-- more advanced example that extends the lsp_document_symbols
symbols = {
desc = "document symbols",
mode = "lsp_document_symbols",
focus = false,
win = { position = "right" },
filter = {
-- remove Package since luals uses it for control flow structures
["not"] = { ft = "lua", kind = "Package" },
any = {
-- all symbol kinds for help / markdown files
ft = { "help", "markdown" },
-- default set of symbol kinds
kind = {
"Class",
"Constructor",
"Enum",
"Field",
"Function",
"Interface",
"Method",
"Module",
"Namespace",
"Package",
"Property",
"Struct",
"Trait",
},
},
},
},
},
-- stylua: ignore
icons = {
---@type trouble.Indent.symbols
indent = {
top = "│ ",
middle = "├╴",
last = "└╴",
-- last = "-╴",
-- last = "╰╴", -- rounded
fold_open = " ",
fold_closed = " ",
ws = " ",
},
folder_closed = " ",
folder_open = " ",
kinds = {
Array = " ",
Boolean = "󰨙 ",
Class = " ",
Constant = "󰏿 ",
Constructor = " ",
Enum = " ",
EnumMember = " ",
Event = " ",
Field = " ",
File = " ",
Function = "󰊕 ",
Interface = " ",
Key = " ",
Method = "󰊕 ",
Module = " ",
Namespace = "󰦮 ",
Null = " ",
Number = "󰎠 ",
Object = " ",
Operator = " ",
Package = " ",
Property = " ",
String = " ",
Struct = "󰆼 ",
TypeParameter = " ",
Variable = "󰀫 ",
},
},
}
```
> 💡 if you don't want to use icons or a patched font, you can use the settings below
<!-- config:end -->
```lua
-- settings without a patched font or icons
{
icons = false,
fold_open = "v", -- icon used for open folds
fold_closed = ">", -- icon used for closed folds
indent_lines = false, -- add an indent guide below the fold icons
signs = {
-- icons / text used for a diagnostic
error = "error",
warning = "warn",
hint = "hint",
information = "info"
},
use_diagnostic_signs = false -- enabling this will use the signs defined in your lsp client
}
```
</details>
Make sure to check the [Examples](/docs/examples.md)!
## 🚀 Usage
### Commands
Trouble comes with the following commands:
The **Trouble** command is a wrapper around the **Trouble** API.
It can do anything the regular API can do.
- `Trouble [mode]`: open the list
- `TroubleClose [mode]`: close the list
- `TroubleToggle [mode]`: toggle the list
- `TroubleRefresh`: manually refresh the active list
- `Trouble [mode] [action] [options]`
Some examples:
- Toggle diagnostics for the current buffer and stay in the current window:
- `Trouble diagnostics toggle focus=false filter.buf=0`
- Show document symbols on the right of the current window.
Keep the document symbols in sync with the buffer you started the command in.
- `Trouble symbols toggle pinned=true results.win.relative=win results.win.position=right`
- You can use **lua** code in the options for the `Trouble` command.
The examples below all do the same thing.
- `Trouble diagnostics filter.severity=vim.diagnostic.severity.ERROR`
- `Trouble diagnostics filter.severity = vim.diagnostic.severity.ERROR`
- `Trouble diagnostics filter = { severity=vim.diagnostic.severity.ERROR }`
- Merging of nested options, with or without quoting strings:
- `Trouble diagnostics results.win.type = split result.win.position=right`
- `Trouble diagnostics results.win = { type = split, position=right}`
- `Trouble diagnostics results.win = { type = "split", position='right'}`
Please refer to the API section for more information on the available actions and options.
Modes:
- **document_diagnostics:** document diagnostics from the builtin LSP client
- **workspace_diagnostics:** workspace diagnostics from the builtin LSP client
- **lsp_references:** references of the word under the cursor from the builtin LSP client
- **lsp_definitions:** definitions of the word under the cursor from the builtin LSP client
<!-- modes:start -->
* **lsp_type_definitions:** type definitions of the word under the cursor from the builtin LSP client
- **diagnostics**: diagnostics
- **fzf**: FzfLua results previously opened with `require('trouble.sources.fzf').open()`.
- **fzf_files**: FzfLua results previously opened with `require('trouble.sources.fzf').open()`.
- **loclist**: Location List
- **lsp**: LSP definitions, references, implementations, type definitions, and declarations
- **lsp_command**: command
- **lsp_declarations**: declarations
- **lsp_definitions**: definitions
- **lsp_document_symbols**: document symbols
- **lsp_implementations**: implementations
- **lsp_incoming_calls**: Incoming Calls
- **lsp_outgoing_calls**: Outgoing Calls
- **lsp_references**: references
- **lsp_type_definitions**: type definitions
- **qflist**: Quickfix List
- **quickfix**: Quickfix List
- **symbols**: document symbols
- **telescope**: Telescope results previously opened with `require('trouble.sources.telescope').open()`.
- **telescope_files**: Telescope results previously opened with `require('trouble.sources.telescope').open()`.
- **quickfix:** [quickfix](https://neovim.io/doc/user/quickfix.html) items
- **loclist:** items from the window's [location list](https://neovim.io/doc/user/quickfix.html)
<!-- modes:end -->
Example keybindings:
### Filters
```vim
" Vim Script
nnoremap <leader>xx <cmd>TroubleToggle<cr>
nnoremap <leader>xw <cmd>TroubleToggle workspace_diagnostics<cr>
nnoremap <leader>xd <cmd>TroubleToggle document_diagnostics<cr>
nnoremap <leader>xq <cmd>TroubleToggle quickfix<cr>
nnoremap <leader>xl <cmd>TroubleToggle loclist<cr>
nnoremap gR <cmd>TroubleToggle lsp_references<cr>
```
```lua
-- Lua
vim.keymap.set("n", "<leader>xx", function() require("trouble").toggle() end)
vim.keymap.set("n", "<leader>xw", function() require("trouble").toggle("workspace_diagnostics") end)
vim.keymap.set("n", "<leader>xd", function() require("trouble").toggle("document_diagnostics") end)
vim.keymap.set("n", "<leader>xq", function() require("trouble").toggle("quickfix") end)
vim.keymap.set("n", "<leader>xl", function() require("trouble").toggle("loclist") end)
vim.keymap.set("n", "gR", function() require("trouble").toggle("lsp_references") end)
```
Please refer to the [filter docs](docs/filter.md) for more information examples on filters.
### API
You can use the following functions in your keybindings:
<details><summary>API</summary>
<!-- api:start -->
```lua
-- toggle trouble with optional mode
require("trouble").toggle(mode?)
-- Opens trouble with the given mode.
-- If a view is already open with the same mode,
-- it will be focused unless `opts.focus = false`.
-- When a view is already open and `opts.new = true`,
-- a new view will be created.
---@param opts? trouble.Mode | { new?: boolean, refresh?: boolean } | string
---@return trouble.View?
require("trouble").open(opts)
-- open trouble with optional mode
require("trouble").open(mode?)
-- Closes the last open view matching the filter.
---@param opts? trouble.Mode|string
---@return trouble.View?
require("trouble").close(opts)
-- close trouble
require("trouble").close()
-- Toggle the view with the given mode.
---@param opts? trouble.Mode|string
---@return trouble.View?
require("trouble").toggle(opts)
-- jump to the next item, skipping the groups
require("trouble").next({skip_groups = true, jump = true});
-- Returns true if there is an open view matching the mode.
---@param opts? trouble.Mode|string
require("trouble").is_open(opts)
-- jump to the previous item, skipping the groups
require("trouble").previous({skip_groups = true, jump = true});
-- Refresh all open views. Normally this is done automatically,
-- unless you disabled auto refresh.
---@param opts? trouble.Mode|string
require("trouble").refresh(opts)
-- jump to the first item, skipping the groups
require("trouble").first({skip_groups = true, jump = true});
-- Get all items from the active view for a given mode.
---@param opts? trouble.Mode|string
require("trouble").get_items(opts)
-- jump to the last item, skipping the groups
require("trouble").last({skip_groups = true, jump = true});
-- Renders a trouble list as a statusline component.
-- Check the docs for examples.
---@param opts? trouble.Mode|string|{hl_group?:string}
---@return {get: (fun():string), has: (fun():boolean)}
require("trouble").statusline(opts)
-- Closes the preview and goes to the main window.
-- The Trouble window is not closed.
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").cancel(opts)
-- Open the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").delete(opts)
-- filter
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").filter(opts)
-- Go to the first item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").first(opts)
-- Focus the trouble window
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").focus(opts)
-- Fold close
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close(opts)
-- fold close all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close_all(opts)
-- Fold close recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close_recursive(opts)
-- fold disable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_disable(opts)
-- fold enable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_enable(opts)
-- fold more
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_more(opts)
-- Fold open
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open(opts)
-- fold open all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open_all(opts)
-- Fold open recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open_recursive(opts)
-- fold reduce
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_reduce(opts)
-- Fold toggle
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle(opts)
-- fold toggle enable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle_enable(opts)
-- Fold toggle recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle_recursive(opts)
-- fold update
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_update(opts)
-- fold update all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_update_all(opts)
-- Show the help
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").help(opts)
-- Dump the item to the console
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").inspect(opts)
-- Jump to the item if on an item, otherwise fold the node
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump(opts)
-- Jump to the item and close the trouble window
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_close(opts)
-- Jump to the item if on an item, otherwise do nothing
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_only(opts)
-- Open the item in a split
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_split(opts)
-- Open the item in a vsplit
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_vsplit(opts)
-- Go to the last item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").last(opts)
-- Go to the next item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").next(opts)
-- Go to the previous item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").prev(opts)
-- Open the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").preview(opts)
-- Refresh the trouble source
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").refresh(opts)
-- Toggle the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").toggle_preview(opts)
-- Toggle the auto refresh
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").toggle_refresh(opts)
```
<!-- api:end -->
</details>
### Telescope
You can easily open any search results in **Trouble**, by defining a custom action:
```lua
local actions = require("telescope.actions")
local trouble = require("trouble.providers.telescope")
local open_with_trouble = require("trouble.sources.telescope").open
-- Use this to add more results without clearing the trouble list
local add_to_trouble = require("trouble.sources.telescope").add
local telescope = require("telescope")
telescope.setup {
telescope.setup({
defaults = {
mappings = {
i = { ["<c-t>"] = trouble.open_with_trouble },
n = { ["<c-t>"] = trouble.open_with_trouble },
i = { ["<c-t>"] = open_with_trouble },
n = { ["<c-t>"] = open_with_trouble },
},
},
}
})
```
When you open telescope, you can now hit `<c-t>` to open the results in **Trouble**
### fzf-lua
You can easily open any search results in **Trouble**, by defining a custom action:
```lua
local config = require("fzf-lua.config")
local actions = require("trouble.sources.fzf").actions
config.defaults.actions.files["ctrl-t"] = actions.open
```
When you open fzf-lua, you can now hit `<c-t>` to open the results in **Trouble**
### Statusline Component
Example for [lualine.nvim](https://github.com/nvim-lualine/lualine.nvim):
```lua
{
"nvim-lualine/lualine.nvim",
opts = function(_, opts)
local trouble = require("trouble")
local symbols = trouble.statusline({
mode = "lsp_document_symbols",
groups = {},
title = false,
filter = { range = true },
format = "{kind_icon}{symbol.name:Normal}",
-- The following line is needed to fix the background color
-- Set it to the lualine section you want to use
hl_group = "lualine_c_normal",
})
table.insert(opts.sections.lualine_c, {
symbols.get,
cond = symbols.has,
})
end,
}
```
## 🎨 Colors
The table below shows all the highlight groups defined for Trouble.
| Highlight Group |
| ------------------------ |
| _TroubleCount_ |
| _TroubleError_ |
| _TroubleNormal_ |
| _TroubleTextInformation_ |
| _TroubleSignWarning_ |
| _TroubleLocation_ |
| _TroubleWarning_ |
| _TroublePreview_ |
| _TroubleTextError_ |
| _TroubleSignInformation_ |
| _TroubleIndent_ |
| _TroubleSource_ |
| _TroubleSignHint_ |
| _TroubleSignOther_ |
| _TroubleFoldIcon_ |
| _TroubleTextWarning_ |
| _TroubleCode_ |
| _TroubleInformation_ |
| _TroubleSignError_ |
| _TroubleFile_ |
| _TroubleHint_ |
| _TroubleTextHint_ |
| _TroubleText_ |
<details><summary>Highlight Groups</summary>
<!-- colors:start -->
| Highlight Group | Default Group | Description |
| --- | --- | --- |
| **TroubleBasename** | ***TroubleFilename*** | |
| **TroubleCode** | ***Special*** | |
| **TroubleCount** | ***TabLineSel*** | |
| **TroubleDirectory** | ***Directory*** | |
| **TroubleFilename** | ***Directory*** | |
| **TroubleIconArray** | ***@punctuation.bracket*** | |
| **TroubleIconBoolean** | ***@boolean*** | |
| **TroubleIconClass** | ***@type*** | |
| **TroubleIconConstant** | ***@constant*** | |
| **TroubleIconConstructor** | ***@constructor*** | |
| **TroubleIconDirectory** | ***Special*** | |
| **TroubleIconEnum** | ***@lsp.type.enum*** | |
| **TroubleIconEnumMember** | ***@lsp.type.enumMember*** | |
| **TroubleIconEvent** | ***Special*** | |
| **TroubleIconField** | ***@variable.member*** | |
| **TroubleIconFile** | ***Normal*** | |
| **TroubleIconFunction** | ***@function*** | |
| **TroubleIconInterface** | ***@lsp.type.interface*** | |
| **TroubleIconKey** | ***@lsp.type.keyword*** | |
| **TroubleIconMethod** | ***@function.method*** | |
| **TroubleIconModule** | ***@module*** | |
| **TroubleIconNamespace** | ***@module*** | |
| **TroubleIconNull** | ***@constant.builtin*** | |
| **TroubleIconNumber** | ***@number*** | |
| **TroubleIconObject** | ***@constant*** | |
| **TroubleIconOperator** | ***@operator*** | |
| **TroubleIconPackage** | ***@module*** | |
| **TroubleIconProperty** | ***@property*** | |
| **TroubleIconString** | ***@string*** | |
| **TroubleIconStruct** | ***@lsp.type.struct*** | |
| **TroubleIconTypeParameter** | ***@lsp.type.typeParameter*** | |
| **TroubleIconVariable** | ***@variable*** | |
| **TroubleIndent** | ***LineNr*** | |
| **TroubleIndentFoldClosed** | ***CursorLineNr*** | |
| **TroubleIndentFoldOpen** | ***TroubleIndent*** | |
| **TroubleIndentLast** | ***TroubleIndent*** | |
| **TroubleIndentMiddle** | ***TroubleIndent*** | |
| **TroubleIndentTop** | ***TroubleIndent*** | |
| **TroubleIndentWs** | ***TroubleIndent*** | |
| **TroubleNormal** | ***NormalFloat*** | |
| **TroubleNormalNC** | ***NormalFloat*** | |
| **TroublePos** | ***LineNr*** | |
| **TroublePreview** | ***Visual*** | |
| **TroubleSource** | ***Comment*** | |
| **TroubleText** | ***Normal*** | |
<!-- colors:end -->
</details>

View File

@ -1,11 +1,11 @@
trouble.nvim-links trouble.nvim.txt /*trouble.nvim-links*
trouble.nvim-table-of-contents trouble.nvim.txt /*trouble.nvim-table-of-contents*
trouble.nvim-trouble-v2 trouble.nvim.txt /*trouble.nvim-trouble-v2*
trouble.nvim-trouble-v2-colors trouble.nvim.txt /*trouble.nvim-trouble-v2-colors*
trouble.nvim-trouble-v2-configuration trouble.nvim.txt /*trouble.nvim-trouble-v2-configuration*
trouble.nvim-trouble-v2-features trouble.nvim.txt /*trouble.nvim-trouble-v2-features*
trouble.nvim-trouble-v2-installation trouble.nvim.txt /*trouble.nvim-trouble-v2-installation*
trouble.nvim-trouble-v2-requirements trouble.nvim.txt /*trouble.nvim-trouble-v2-requirements*
trouble.nvim-trouble-v2-usage trouble.nvim.txt /*trouble.nvim-trouble-v2-usage*
trouble.nvim-trouble-v3-beta! trouble.nvim.txt /*trouble.nvim-trouble-v3-beta!*
trouble.nvim-trouble trouble.nvim.txt /*trouble.nvim-trouble*
trouble.nvim-trouble-colors trouble.nvim.txt /*trouble.nvim-trouble-colors*
trouble.nvim-trouble-configuration trouble.nvim.txt /*trouble.nvim-trouble-configuration*
trouble.nvim-trouble-features trouble.nvim.txt /*trouble.nvim-trouble-features*
trouble.nvim-trouble-installation trouble.nvim.txt /*trouble.nvim-trouble-installation*
trouble.nvim-trouble-requirements trouble.nvim.txt /*trouble.nvim-trouble-requirements*
trouble.nvim-trouble-usage trouble.nvim.txt /*trouble.nvim-trouble-usage*
trouble.nvim-trouble-whats-new? trouble.nvim.txt /*trouble.nvim-trouble-whats-new?*
trouble.nvim.txt trouble.nvim.txt /*trouble.nvim.txt*

View File

@ -1,63 +1,76 @@
*trouble.nvim.txt* For Neovim >= 0.8.0 Last change: 2024 May 19
*trouble.nvim.txt* For Neovim >= 0.8.0 Last change: 2024 June 14
==============================================================================
Table of Contents *trouble.nvim-table-of-contents*
1. Trouble v3 Beta! |trouble.nvim-trouble-v3-beta!|
2. Trouble v2 |trouble.nvim-trouble-v2|
- Features |trouble.nvim-trouble-v2-features|
- Requirements |trouble.nvim-trouble-v2-requirements|
- Installation |trouble.nvim-trouble-v2-installation|
- Configuration |trouble.nvim-trouble-v2-configuration|
- Usage |trouble.nvim-trouble-v2-usage|
- Colors |trouble.nvim-trouble-v2-colors|
3. Links |trouble.nvim-links|
1. Trouble |trouble.nvim-trouble|
- Features |trouble.nvim-trouble-features|
- Whats new? |trouble.nvim-trouble-whats-new?|
- Requirements |trouble.nvim-trouble-requirements|
- Installation |trouble.nvim-trouble-installation|
- Configuration |trouble.nvim-trouble-configuration|
- Usage |trouble.nvim-trouble-usage|
- Colors |trouble.nvim-trouble-colors|
2. Links |trouble.nvim-links|
==============================================================================
1. Trouble v3 Beta! *trouble.nvim-trouble-v3-beta!*
**Trouble**has been rewritten from scratch. If youd like to try the new
version, please refer to the beta docs
<https://github.com/folke/trouble.nvim/tree/dev>
------------------------------------------------------------------------------
==============================================================================
2. Trouble v2 *trouble.nvim-trouble-v2*
1. Trouble *trouble.nvim-trouble*
A pretty list for showing diagnostics, references, telescope results, quickfix
and location lists to help you solve all the trouble your code is causing.
FEATURES *trouble.nvim-trouble-v2-features*
FEATURES *trouble.nvim-trouble-features*
- pretty list of:
- Diagnostics
- LSP references
- LSP implementations
- LSP definitions
- LSP type definitions
- quickfix list
- location list
- Telescope <https://github.com/nvim-telescope/telescope.nvim> search results
- automatically updates on new diagnostics
- toggle **diagnostics** mode between **workspace** or **document**
- **interactive preview** in your last accessed window
- _cancel_ preview or _jump_ to the location
- configurable actions, signs, highlights,…
- Diagnostics
- LSP references
- LSP implementations
- LSP definitions
- LSP type definitions
- LSP Document Symbols
- LSP Incoming/Outgoing calls
- quickfix list
- location list
- Telescope <https://github.com/nvim-telescope/telescope.nvim> search results
- fzf-lua <https://github.com/ibhagwan/fzf-lua> results
REQUIREMENTS *trouble.nvim-trouble-v2-requirements*
WHATS NEW? *trouble.nvim-trouble-whats-new?*
- Neovim >= 0.7.2
This is a full rewrite of the original **trouble.nvim**.
The new version is much more flexible and powerful, with a lot of new features
and improvements:
- multiple trouble windows at the same time
- LSP document symbols
- LSP incoming/outgoing calls
- lots of options to configure trouble windows (floats or splits)
- `focus` option to focus the trouble window when opened (or not)
- `follow` option to follow the item under the cursor
- `pinned` option to pin the buffer as the source for the opened trouble window
- full tree views of anything
- highly configurable views with custom formatters, filters, and sorters
- show multiple sections in the same view
- multi-line messages
- prettier and configurable indent guides
- tree view that follows the natural hierarchy of the items (like document symbols, or file structure)
- expansive API and `Trouble` command
- trouble `modes` to define custom views
- statusline component (useful with document symbols)
REQUIREMENTS *trouble.nvim-trouble-requirements*
- Neovim >= 0.9.2
- Neovim >= 0.10.0 **OR** the `markdown` and `markdown_inline` nvim-treesitter <https://github.com/nvim-treesitter/nvim-treesitter> parsers
- Properly configured Neovim LSP client
- nvim-web-devicons <https://github.com/nvim-tree/nvim-web-devicons> is optional to enable file icons
- a theme with properly configured highlight groups for Neovim Diagnostics
- or install lsp-colors <https://github.com/folke/lsp-colors.nvim> to automatically create the missing highlight groups
- a patched font <https://www.nerdfonts.com/> for the default severity and fold icons
INSTALLATION *trouble.nvim-trouble-v2-installation*
INSTALLATION *trouble.nvim-trouble-installation*
Install the plugin with your preferred package manager:
@ -65,178 +78,538 @@ Install the plugin with your preferred package manager:
LAZY.NVIM ~
>lua
return {
"folke/trouble.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
opts = {
-- your configuration comes here
-- or leave it empty to use the default settings
-- refer to the configuration section below
},
{
"folke/trouble.nvim",
opts = {}, -- for default options, refer to the configuration section for custom setup.
cmd = "Trouble",
keys = {
{
"<leader>xx",
"<cmd>Trouble diagnostics toggle<cr>",
desc = "Diagnostics (Trouble)",
},
{
"<leader>xX",
"<cmd>Trouble diagnostics toggle filter.buf=0<cr>",
desc = "Buffer Diagnostics (Trouble)",
},
{
"<leader>cs",
"<cmd>Trouble symbols toggle focus=false<cr>",
desc = "Symbols (Trouble)",
},
{
"<leader>cl",
"<cmd>Trouble lsp toggle focus=false win.position=right<cr>",
desc = "LSP Definitions / references / ... (Trouble)",
},
{
"<leader>xL",
"<cmd>Trouble loclist toggle<cr>",
desc = "Location List (Trouble)",
},
{
"<leader>xQ",
"<cmd>Trouble qflist toggle<cr>",
desc = "Quickfix List (Trouble)",
},
},
}
<
CONFIGURATION *trouble.nvim-trouble-v2-configuration*
CONFIGURATION *trouble.nvim-trouble-configuration*
SETUP ~
Trouble comes with the following defaults:
**Trouble** is highly configurable. Please refer to the default settings below.
Default Settings ~
>lua
{
position = "bottom", -- position of the list can be: bottom, top, left, right
height = 10, -- height of the trouble list when position is top or bottom
width = 50, -- width of the list when position is left or right
icons = true, -- use devicons for filenames
mode = "workspace_diagnostics", -- "workspace_diagnostics", "document_diagnostics", "quickfix", "lsp_references", "loclist"
severity = nil, -- nil (ALL) or vim.diagnostic.severity.ERROR | WARN | INFO | HINT
fold_open = "", -- icon used for open folds
fold_closed = "", -- icon used for closed folds
group = true, -- group results by file
padding = true, -- add an extra new line on top of the list
cycle_results = true, -- cycle item list when reaching beginning or end of list
action_keys = { -- key mappings for actions in the trouble list
-- map to {} to remove a mapping, for example:
-- close = {},
close = "q", -- close the list
cancel = "<esc>", -- cancel the preview and get back to your last window / buffer / cursor
refresh = "r", -- manually refresh
jump = { "<cr>", "<tab>", "<2-leftmouse>" }, -- jump to the diagnostic or open / close folds
open_split = { "<c-x>" }, -- open buffer in new split
open_vsplit = { "<c-v>" }, -- open buffer in new vsplit
open_tab = { "<c-t>" }, -- open buffer in new tab
jump_close = {"o"}, -- jump to the diagnostic and close the list
toggle_mode = "m", -- toggle between "workspace" and "document" diagnostics mode
switch_severity = "s", -- switch "diagnostics" severity filter level to HINT / INFO / WARN / ERROR
toggle_preview = "P", -- toggle auto_preview
hover = "K", -- opens a small popup with the full multiline message
preview = "p", -- preview the diagnostic location
open_code_href = "c", -- if present, open a URI with more information about the diagnostic error
close_folds = {"zM", "zm"}, -- close all folds
open_folds = {"zR", "zr"}, -- open all folds
toggle_fold = {"zA", "za"}, -- toggle fold of current file
previous = "k", -- previous item
next = "j" -- next item
help = "?" -- help menu
---@class trouble.Mode: trouble.Config,trouble.Section.spec
---@field desc? string
---@field sections? string[]
---@class trouble.Config
---@field mode? string
---@field config? fun(opts:trouble.Config)
---@field formatters? table<string,trouble.Formatter> custom formatters
---@field filters? table<string, trouble.FilterFn> custom filters
---@field sorters? table<string, trouble.SorterFn> custom sorters
local defaults = {
auto_close = false, -- auto close when there are no items
auto_open = false, -- auto open when there are items
auto_preview = true, -- automatically open preview when on an item
auto_refresh = true, -- auto refresh when open
auto_jump = false, -- auto jump to the item when there's only one
focus = false, -- Focus the window when opened
restore = true, -- restores the last location in the list when opening
follow = true, -- Follow the current item
indent_guides = true, -- show indent guides
max_items = 200, -- limit number of items that can be displayed per section
multiline = true, -- render multi-line messages
pinned = false, -- When pinned, the opened trouble window will be bound to the current buffer
warn_no_results = true, -- show a warning when there are no results
open_no_results = false, -- open the trouble window when there are no results
---@type trouble.Window.opts
win = {}, -- window options for the results window. Can be a split or a floating window.
-- Window options for the preview window. Can be a split, floating window,
-- or `main` to show the preview in the main editor window.
---@type trouble.Window.opts
preview = {
type = "main",
-- when a buffer is not yet loaded, the preview window will be created
-- in a scratch buffer with only syntax highlighting enabled.
-- Set to false, if you want the preview to always be a real loaded buffer.
scratch = true,
},
-- Throttle/Debounce settings. Should usually not be changed.
---@type table<string, number|{ms:number, debounce?:boolean}>
throttle = {
refresh = 20, -- fetches new data when needed
update = 10, -- updates the window
render = 10, -- renders the window
follow = 100, -- follows the current item
preview = { ms = 100, debounce = true }, -- shows the preview for the current item
},
-- Key mappings can be set to the name of a builtin action,
-- or you can define your own custom action.
---@type table<string, trouble.Action.spec>
keys = {
["?"] = "help",
r = "refresh",
R = "toggle_refresh",
q = "close",
o = "jump_close",
["<esc>"] = "cancel",
["<cr>"] = "jump",
["<2-leftmouse>"] = "jump",
["<c-s>"] = "jump_split",
["<c-v>"] = "jump_vsplit",
-- go down to next item (accepts count)
-- j = "next",
["}"] = "next",
["]]"] = "next",
-- go up to prev item (accepts count)
-- k = "prev",
["{"] = "prev",
["[["] = "prev",
dd = "delete",
d = { action = "delete", mode = "v" },
i = "inspect",
p = "preview",
P = "toggle_preview",
zo = "fold_open",
zO = "fold_open_recursive",
zc = "fold_close",
zC = "fold_close_recursive",
za = "fold_toggle",
zA = "fold_toggle_recursive",
zm = "fold_more",
zM = "fold_close_all",
zr = "fold_reduce",
zR = "fold_open_all",
zx = "fold_update",
zX = "fold_update_all",
zn = "fold_disable",
zN = "fold_enable",
zi = "fold_toggle_enable",
gb = { -- example of a custom action that toggles the active view filter
action = function(view)
view:filter({ buf = 0 }, { toggle = true })
end,
desc = "Toggle Current Buffer Filter",
},
multiline = true, -- render multi-line messages
indent_lines = true, -- add an indent guide below the fold icons
win_config = { border = "single" }, -- window configuration for floating windows. See |nvim_open_win()|.
auto_open = false, -- automatically open the list when you have diagnostics
auto_close = false, -- automatically close the list when you have no diagnostics
auto_preview = true, -- automatically preview the location of the diagnostic. <esc> to close preview and go back to last window
auto_fold = false, -- automatically fold a file trouble list at creation
auto_jump = {"lsp_definitions"}, -- for the given modes, automatically jump if there is only a single result
include_declaration = { "lsp_references", "lsp_implementations", "lsp_definitions" }, -- for the given modes, include the declaration of the current symbol in the results
signs = {
-- icons / text used for a diagnostic
error = "",
warning = "",
hint = "",
information = "",
other = "",
s = { -- example of a custom action that toggles the severity
action = function(view)
local f = view:get_filter("severity")
local severity = ((f and f.filter.severity or 0) + 1) % 5
view:filter({ severity = severity }, {
id = "severity",
template = "{hl:Title}Filter:{hl} {severity}",
del = severity == 0,
})
end,
desc = "Toggle Severity Filter",
},
use_diagnostic_signs = false -- enabling this will use the signs defined in your lsp client
},
---@type table<string, trouble.Mode>
modes = {
-- sources define their own modes, which you can use directly,
-- or override like in the example below
lsp_references = {
-- some modes are configurable, see the source code for more details
params = {
include_declaration = true,
},
},
-- The LSP base mode for:
-- * lsp_definitions, lsp_references, lsp_implementations
-- * lsp_type_definitions, lsp_declarations, lsp_command
lsp_base = {
params = {
-- don't include the current location in the results
include_current = false,
},
},
-- more advanced example that extends the lsp_document_symbols
symbols = {
desc = "document symbols",
mode = "lsp_document_symbols",
focus = false,
win = { position = "right" },
filter = {
-- remove Package since luals uses it for control flow structures
["not"] = { ft = "lua", kind = "Package" },
any = {
-- all symbol kinds for help / markdown files
ft = { "help", "markdown" },
-- default set of symbol kinds
kind = {
"Class",
"Constructor",
"Enum",
"Field",
"Function",
"Interface",
"Method",
"Module",
"Namespace",
"Package",
"Property",
"Struct",
"Trait",
},
},
},
},
},
-- stylua: ignore
icons = {
---@type trouble.Indent.symbols
indent = {
top = "│ ",
middle = "├╴",
last = "└╴",
-- last = "-╴",
-- last = "╰╴", -- rounded
fold_open = " ",
fold_closed = " ",
ws = " ",
},
folder_closed = " ",
folder_open = " ",
kinds = {
Array = " ",
Boolean = "󰨙 ",
Class = " ",
Constant = "󰏿 ",
Constructor = " ",
Enum = " ",
EnumMember = " ",
Event = " ",
Field = " ",
File = " ",
Function = "󰊕 ",
Interface = " ",
Key = " ",
Method = "󰊕 ",
Module = " ",
Namespace = "󰦮 ",
Null = " ",
Number = "󰎠 ",
Object = " ",
Operator = " ",
Package = " ",
Property = " ",
String = " ",
Struct = "󰆼 ",
TypeParameter = " ",
Variable = "󰀫 ",
},
},
}
<
if you dont want to use icons or a patched font, you can use the settings
below
>lua
-- settings without a patched font or icons
{
icons = false,
fold_open = "v", -- icon used for open folds
fold_closed = ">", -- icon used for closed folds
indent_lines = false, -- add an indent guide below the fold icons
signs = {
-- icons / text used for a diagnostic
error = "error",
warning = "warn",
hint = "hint",
information = "info"
},
use_diagnostic_signs = false -- enabling this will use the signs defined in your lsp client
}
<
Make sure to check the Examples </docs/examples.md>!
USAGE *trouble.nvim-trouble-v2-usage*
USAGE *trouble.nvim-trouble-usage*
COMMANDS ~
Trouble comes with the following commands:
The **Trouble** command is a wrapper around the **Trouble** API. It can do
anything the regular API can do.
- `Trouble [mode]`open the list
- `TroubleClose [mode]`close the list
- `TroubleToggle [mode]`toggle the list
- `TroubleRefresh`manually refresh the active list
- `Trouble [mode] [action] [options]`
Some examples:
- Toggle diagnostics for the current buffer and stay in the current window:
- `Trouble diagnostics toggle focus=false filter.buf=0`
- Show document symbols on the right of the current window.
Keep the document symbols in sync with the buffer you started the command in.
- `Trouble symbols toggle pinned=true results.win.relative=win results.win.position=right`
- You can use **lua** code in the options for the `Trouble` command.
The examples below all do the same thing.
- `Trouble diagnostics filter.severity=vim.diagnostic.severity.ERROR`
- `Trouble diagnostics filter.severity = vim.diagnostic.severity.ERROR`
- `Trouble diagnostics filter = { severity=vim.diagnostic.severity.ERROR }`
- Merging of nested options, with or without quoting strings:
- `Trouble diagnostics results.win.type = split result.win.position=right`
- `Trouble diagnostics results.win = { type = split, position=right}`
- `Trouble diagnostics results.win = { type = "split", position='right'}`
Please refer to the API section for more information on the available actions
and options.
Modes:
- **document_diagnostics:** document diagnostics from the builtin LSP client
- **workspace_diagnostics:** workspace diagnostics from the builtin LSP client
- **lsp_references:** references of the word under the cursor from the builtin
LSP client
- **lsp_definitions:** definitions of the word under the cursor from the builtin
LSP client
- **lsp_type_definitions:** type definitions of the word under the cursor from
the builtin LSP client
- **quickfix:** |quickfix| items
- **loclist:** items from the windows |location list|
- **diagnostics**diagnostics
- **fzf**FzfLua results previously opened with `require('trouble.sources.fzf').open()`.
- **fzf_files**FzfLua results previously opened with `require('trouble.sources.fzf').open()`.
- **loclist**Location List
- **lsp**LSP definitions, references, implementations, type definitions, and declarations
- **lsp_command**command
- **lsp_declarations**declarations
- **lsp_definitions**definitions
- **lsp_document_symbols**document symbols
- **lsp_implementations**implementations
- **lsp_incoming_calls**Incoming Calls
- **lsp_outgoing_calls**Outgoing Calls
- **lsp_references**references
- **lsp_type_definitions**type definitions
- **qflist**Quickfix List
- **quickfix**Quickfix List
- **symbols**document symbols
- **telescope**Telescope results previously opened with `require('trouble.sources.telescope').open()`.
- **telescope_files**Telescope results previously opened with `require('trouble.sources.telescope').open()`.
Example keybindings:
>vim
" Vim Script
nnoremap <leader>xx <cmd>TroubleToggle<cr>
nnoremap <leader>xw <cmd>TroubleToggle workspace_diagnostics<cr>
nnoremap <leader>xd <cmd>TroubleToggle document_diagnostics<cr>
nnoremap <leader>xq <cmd>TroubleToggle quickfix<cr>
nnoremap <leader>xl <cmd>TroubleToggle loclist<cr>
nnoremap gR <cmd>TroubleToggle lsp_references<cr>
<
FILTERS ~
>lua
-- Lua
vim.keymap.set("n", "<leader>xx", function() require("trouble").toggle() end)
vim.keymap.set("n", "<leader>xw", function() require("trouble").toggle("workspace_diagnostics") end)
vim.keymap.set("n", "<leader>xd", function() require("trouble").toggle("document_diagnostics") end)
vim.keymap.set("n", "<leader>xq", function() require("trouble").toggle("quickfix") end)
vim.keymap.set("n", "<leader>xl", function() require("trouble").toggle("loclist") end)
vim.keymap.set("n", "gR", function() require("trouble").toggle("lsp_references") end)
<
Please refer to the filter docs <docs/filter.md> for more information examples
on filters.
API ~
You can use the following functions in your keybindings:
API ~
>lua
-- toggle trouble with optional mode
require("trouble").toggle(mode?)
-- Opens trouble with the given mode.
-- If a view is already open with the same mode,
-- it will be focused unless `opts.focus = false`.
-- When a view is already open and `opts.new = true`,
-- a new view will be created.
---@param opts? trouble.Mode | { new?: boolean, refresh?: boolean } | string
---@return trouble.View?
require("trouble").open(opts)
-- open trouble with optional mode
require("trouble").open(mode?)
-- Closes the last open view matching the filter.
---@param opts? trouble.Mode|string
---@return trouble.View?
require("trouble").close(opts)
-- close trouble
require("trouble").close()
-- Toggle the view with the given mode.
---@param opts? trouble.Mode|string
---@return trouble.View?
require("trouble").toggle(opts)
-- jump to the next item, skipping the groups
require("trouble").next({skip_groups = true, jump = true});
-- Returns true if there is an open view matching the mode.
---@param opts? trouble.Mode|string
require("trouble").is_open(opts)
-- jump to the previous item, skipping the groups
require("trouble").previous({skip_groups = true, jump = true});
-- Refresh all open views. Normally this is done automatically,
-- unless you disabled auto refresh.
---@param opts? trouble.Mode|string
require("trouble").refresh(opts)
-- jump to the first item, skipping the groups
require("trouble").first({skip_groups = true, jump = true});
-- Get all items from the active view for a given mode.
---@param opts? trouble.Mode|string
require("trouble").get_items(opts)
-- jump to the last item, skipping the groups
require("trouble").last({skip_groups = true, jump = true});
-- Renders a trouble list as a statusline component.
-- Check the docs for examples.
---@param opts? trouble.Mode|string|{hl_group?:string}
---@return {get: (fun():string), has: (fun():boolean)}
require("trouble").statusline(opts)
-- Closes the preview and goes to the main window.
-- The Trouble window is not closed.
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").cancel(opts)
-- Open the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").delete(opts)
-- filter
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").filter(opts)
-- Go to the first item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").first(opts)
-- Focus the trouble window
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").focus(opts)
-- Fold close
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close(opts)
-- fold close all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close_all(opts)
-- Fold close recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_close_recursive(opts)
-- fold disable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_disable(opts)
-- fold enable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_enable(opts)
-- fold more
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_more(opts)
-- Fold open
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open(opts)
-- fold open all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open_all(opts)
-- Fold open recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_open_recursive(opts)
-- fold reduce
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_reduce(opts)
-- Fold toggle
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle(opts)
-- fold toggle enable
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle_enable(opts)
-- Fold toggle recursive
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_toggle_recursive(opts)
-- fold update
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_update(opts)
-- fold update all
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").fold_update_all(opts)
-- Show the help
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").help(opts)
-- Dump the item to the console
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").inspect(opts)
-- Jump to the item if on an item, otherwise fold the node
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump(opts)
-- Jump to the item and close the trouble window
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_close(opts)
-- Jump to the item if on an item, otherwise do nothing
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_only(opts)
-- Open the item in a split
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_split(opts)
-- Open the item in a vsplit
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").jump_vsplit(opts)
-- Go to the last item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").last(opts)
-- Go to the next item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").next(opts)
-- Go to the previous item
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").prev(opts)
-- Open the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").preview(opts)
-- Refresh the trouble source
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").refresh(opts)
-- Toggle the preview
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").toggle_preview(opts)
-- Toggle the auto refresh
---@param opts? trouble.Mode | { new? : boolean } | string
---@return trouble.View
require("trouble").toggle_refresh(opts)
<
@ -247,58 +620,127 @@ action:
>lua
local actions = require("telescope.actions")
local trouble = require("trouble.providers.telescope")
local open_with_trouble = require("trouble.sources.telescope").open
-- Use this to add more results without clearing the trouble list
local add_to_trouble = require("trouble.sources.telescope").add
local telescope = require("telescope")
telescope.setup {
telescope.setup({
defaults = {
mappings = {
i = { ["<c-t>"] = trouble.open_with_trouble },
n = { ["<c-t>"] = trouble.open_with_trouble },
i = { ["<c-t>"] = open_with_trouble },
n = { ["<c-t>"] = open_with_trouble },
},
},
}
})
<
When you open telescope, you can now hit `<c-t>` to open the results in
**Trouble**
COLORS *trouble.nvim-trouble-v2-colors*
FZF-LUA ~
You can easily open any search results in **Trouble**, by defining a custom
action:
>lua
local config = require("fzf-lua.config")
local actions = require("trouble.sources.fzf").actions
config.defaults.actions.files["ctrl-t"] = actions.open
<
When you open fzf-lua, you can now hit `<c-t>` to open the results in
**Trouble**
STATUSLINE COMPONENT ~
Example for lualine.nvim <https://github.com/nvim-lualine/lualine.nvim>
>lua
{
"nvim-lualine/lualine.nvim",
opts = function(_, opts)
local trouble = require("trouble")
local symbols = trouble.statusline({
mode = "lsp_document_symbols",
groups = {},
title = false,
filter = { range = true },
format = "{kind_icon}{symbol.name:Normal}",
-- The following line is needed to fix the background color
-- Set it to the lualine section you want to use
hl_group = "lualine_c_normal",
})
table.insert(opts.sections.lualine_c, {
symbols.get,
cond = symbols.has,
})
end,
}
<
COLORS *trouble.nvim-trouble-colors*
The table below shows all the highlight groups defined for Trouble.
Highlight Group
------------------------
TroubleCount
TroubleError
TroubleNormal
TroubleTextInformation
TroubleSignWarning
TroubleLocation
TroubleWarning
TroublePreview
TroubleTextError
TroubleSignInformation
TroubleIndent
TroubleSource
TroubleSignHint
TroubleSignOther
TroubleFoldIcon
TroubleTextWarning
TroubleCode
TroubleInformation
TroubleSignError
TroubleFile
TroubleHint
TroubleTextHint
TroubleText
Highlight Groups ~
Highlight Group Default Group Description
-------------------------- ------------------------- -------------
TroubleBasename TroubleFilename
TroubleCode Special
TroubleCount TabLineSel
TroubleDirectory Directory
TroubleFilename Directory
TroubleIconArray @punctuation.bracket
TroubleIconBoolean @boolean
TroubleIconClass @type
TroubleIconConstant @constant
TroubleIconConstructor @constructor
TroubleIconDirectory Special
TroubleIconEnum @lsp.type.enum
TroubleIconEnumMember @lsp.type.enumMember
TroubleIconEvent Special
TroubleIconField @variable.member
TroubleIconFile Normal
TroubleIconFunction @function
TroubleIconInterface @lsp.type.interface
TroubleIconKey @lsp.type.keyword
TroubleIconMethod @function.method
TroubleIconModule @module
TroubleIconNamespace @module
TroubleIconNull @constant.builtin
TroubleIconNumber @number
TroubleIconObject @constant
TroubleIconOperator @operator
TroubleIconPackage @module
TroubleIconProperty @property
TroubleIconString @string
TroubleIconStruct @lsp.type.struct
TroubleIconTypeParameter @lsp.type.typeParameter
TroubleIconVariable @variable
TroubleIndent LineNr
TroubleIndentFoldClosed CursorLineNr
TroubleIndentFoldOpen TroubleIndent
TroubleIndentLast TroubleIndent
TroubleIndentMiddle TroubleIndent
TroubleIndentTop TroubleIndent
TroubleIndentWs TroubleIndent
TroubleNormal NormalFloat
TroubleNormalNC NormalFloat
TroublePos LineNr
TroublePreview Visual
TroubleSource Comment
TroubleText Normal
==============================================================================
3. Links *trouble.nvim-links*
2. Links *trouble.nvim-links*
1. *image*: https://github.com/folke/trouble.nvim/assets/292349/481bc1f7-cb93-432d-8ab6-f54044334b96
2. *LSP Trouble Screenshot*: ./media/shot.png
Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>

View File

@ -1,34 +0,0 @@
local util = require("trouble.util")
local M = {}
local links = {
TextError = "TroubleText",
TextWarning = "TroubleText",
TextInformation = "TroubleText",
TextHint = "TroubleText",
Text = "Normal",
File = "Directory",
Source = "Comment",
Code = "Comment",
Location = "LineNr",
FoldIcon = "CursorLineNr",
Normal = "Normal",
Count = "TabLineSel",
Preview = "Search",
Indent = "LineNr",
SignOther = "TroubleSignInformation",
}
function M.setup()
for k, v in pairs(links) do
vim.api.nvim_command("hi def link Trouble" .. k .. " " .. v)
end
for _, severity in pairs(util.severity) do
vim.api.nvim_command("hi def link Trouble" .. severity .. " " .. util.get_severity_label(severity))
vim.api.nvim_command("hi def link TroubleSign" .. severity .. " " .. util.get_severity_label(severity, "Sign"))
end
end
return M

View File

@ -1,83 +0,0 @@
local M = {}
M.namespace = vim.api.nvim_create_namespace("Trouble")
---@class TroubleOptions
---@field buf number|nil
---@field win number|nil
---@field severity lsp.DiagnosticSeverity|nil
-- TODO: make some options configurable per mode
-- TODO: make it possible to have multiple trouble lists open at the same time
local defaults = {
debug = false,
cmd_options = {},
group = true, -- group results by file
padding = true, -- add an extra new line on top of the list
position = "bottom", -- position of the list can be: bottom, top, left, right
height = 10, -- height of the trouble list when position is top or bottom
width = 50, -- width of the list when position is left or right
icons = true, -- use devicons for filenames
mode = "workspace_diagnostics", -- "workspace_diagnostics", "document_diagnostics", "quickfix", "lsp_references", "loclist"
severity = nil, -- nil (ALL) or vim.diagnostic.severity.ERROR | WARN | INFO | HINT
fold_open = "", -- icon used for open folds
fold_closed = "", -- icon used for closed folds
cycle_results = true, -- cycle item list when reaching beginning or end of list
action_keys = { -- key mappings for actions in the trouble list
close = "q", -- close the list
cancel = "<esc>", -- cancel the preview and get back to your last window / buffer / cursor
refresh = "r", -- manually refresh
jump = { "<cr>", "<tab>", "<2-leftmouse>" }, -- jump to the diagnostic or open / close folds
open_split = { "<c-x>" }, -- open buffer in new split
open_vsplit = { "<c-v>" }, -- open buffer in new vsplit
open_tab = { "<c-t>" }, -- open buffer in new tab
jump_close = { "o" }, -- jump to the diagnostic and close the list
toggle_mode = "m", -- toggle between "workspace" and "document" mode
switch_severity = "s", -- switch "diagnostics" severity filter level to ALL / HINT / INFO / WARN / ERROR
toggle_preview = "P", -- toggle auto_preview
hover = "K", -- opens a small popup with the full multiline message
preview = "p", -- preview the diagnostic location
open_code_href = "c", -- if present, open a URI with more information about the diagnostic error
close_folds = { "zM", "zm" }, -- close all folds
open_folds = { "zR", "zr" }, -- open all folds
toggle_fold = { "zA", "za" }, -- toggle fold of current file
previous = "k", -- preview item
next = "j", -- next item
help = "?", -- help menu
},
multiline = true, -- render multi-line messages
indent_lines = true, -- add an indent guide below the fold icons
win_config = { border = "single" }, -- window configuration for floating windows. See |nvim_open_win()|.
auto_open = false, -- automatically open the list when you have diagnostics
auto_close = false, -- automatically close the list when you have no diagnostics
auto_preview = true, -- automatically preview the location of the diagnostic. <esc> to close preview and go back to last window
auto_fold = false, -- automatically fold a file trouble list at creation
auto_jump = { "lsp_definitions" }, -- for the given modes, automatically jump if there is only a single result
include_declaration = { "lsp_references", "lsp_implementations", "lsp_definitions" }, -- for the given modes, include the declaration of the current symbol in the results
signs = {
-- icons / text used for a diagnostic
error = "",
warning = "",
hint = "",
information = "",
other = "",
},
use_diagnostic_signs = false, -- enabling this will use the signs defined in your lsp client
sort_keys = {
"severity",
"filename",
"lnum",
"col",
},
}
---@type TroubleOptions
M.options = {}
---@return TroubleOptions
function M.setup(options)
M.options = vim.tbl_deep_extend("force", {}, defaults, options or {})
end
M.setup()
return M

View File

@ -1,24 +0,0 @@
local config = require("trouble.config")
local M = {}
M.folded = {}
function M.is_folded(filename)
local fold = M.folded[filename]
return (fold == nil and config.options.auto_fold == true) or (fold == true)
end
function M.toggle(filename)
M.folded[filename] = not M.is_folded(filename)
end
function M.close(filename)
M.folded[filename] = true
end
function M.open(filename)
M.folded[filename] = false
end
return M

View File

@ -1,300 +1,13 @@
local View = require("trouble.view")
local config = require("trouble.config")
local colors = require("trouble.colors")
local util = require("trouble.util")
---@class trouble: trouble.api
local M = {}
colors.setup()
local Trouble = {}
local view
function Trouble.is_open()
return view and view:is_valid() or false
---@param opts? trouble.Config
function M.setup(opts)
require("trouble.config").setup(opts)
end
function Trouble.setup(options)
if vim.fn.has("nvim-0.7.2") == 0 then
util.error("Trouble needs Neovim >= 0.7.2")
return
end
config.setup(options)
util.fix_mode(config.options)
colors.setup()
end
function Trouble.close()
if Trouble.is_open() then
view:close()
end
end
local function get_opts(...)
local args = { ... }
if (vim.islist or vim.tbl_islist)(args) and #args == 1 and type(args[1]) == "table" then
args = args[1]
end
local opts = {}
for key, value in pairs(args) do
if type(key) == "number" then
local k, v = value:match("^(.*)=(.*)$")
if k then
opts[k] = v
elseif opts.mode then
util.error("unknown option " .. value)
else
opts.mode = value
end
else
opts[key] = value
end
end
opts = opts or {}
util.fix_mode(opts)
config.options.cmd_options = opts
return opts
end
function Trouble.open(...)
local opts = get_opts(...)
if opts.mode and (opts.mode ~= config.options.mode) then
config.options.mode = opts.mode
end
if opts.severity and (opts.severity ~= config.options.severity) then
config.options.severity = opts.severity
end
opts.focus = (opts.focus == nil and not opts.auto) and true or opts.focus
opts.on_open = true
if Trouble.is_open() then
Trouble.refresh(opts)
elseif not opts.auto and vim.tbl_contains(config.options.auto_jump, opts.mode) then
require("trouble.providers").get(vim.api.nvim_get_current_win(), vim.api.nvim_get_current_buf(), function(results)
if #results == 1 then
util.jump_to_item(opts.win, opts.precmd, results[1])
elseif #results > 0 then
view = View.create(opts)
end
end, config.options)
else
view = View.create(opts)
end
end
function Trouble.toggle(...)
local opts = get_opts(...)
if opts.mode and (opts.mode ~= config.options.mode) then
config.options.mode = opts.mode
Trouble.open(...)
return
end
if Trouble.is_open() then
Trouble.close()
else
Trouble.open(...)
end
end
function Trouble.help()
local lines = { "# Key Bindings" }
local height = 1
for command, key in pairs(config.options.action_keys) do
if type(key) == "table" then
key = table.concat(key, " | ")
end
table.insert(lines, " * **" .. key .. "** " .. command:gsub("_", " "))
height = height + 1
end
-- help
vim.lsp.util.open_floating_preview(lines, "markdown", config.options.win_config)
end
local updater = util.debounce(100, function()
-- buff might have been closed during the debounce
if not Trouble.is_open() then
util.debug("refresh: not open anymore")
return
end
util.debug("refresh: auto")
view:update({ auto = true })
end)
function Trouble.refresh(opts)
opts = opts or {}
-- dont do an update if this is an automated refresh from a different provider
if opts.auto then
if opts.provider == "diagnostics" and config.options.mode == "document_diagnostics" then
opts.provider = "document_diagnostics"
elseif opts.provider == "diagnostics" and config.options.mode == "workspace_diagnostics" then
opts.provider = "workspace_diagnostics"
elseif opts.provider == "qf" and config.options.mode == "quickfix" then
opts.provider = "quickfix"
elseif opts.provider == "qf" and config.options.mode == "loclist" then
opts.provider = "loclist"
end
if opts.provider ~= config.options.mode then
return
end
end
if Trouble.is_open() then
if opts.auto then
updater()
else
util.debug("refresh")
view:update(opts)
end
elseif opts.auto and config.options.auto_open and opts.provider == config.options.mode then
require("trouble.providers").get(vim.api.nvim_get_current_win(), vim.api.nvim_get_current_buf(), function(results)
if #results > 0 then
Trouble.open(opts)
end
end, config.options)
end
end
function Trouble.action(action)
if action == "toggle_mode" then
if config.options.mode == "document_diagnostics" then
config.options.mode = "workspace_diagnostics"
elseif config.options.mode == "workspace_diagnostics" then
config.options.mode = "document_diagnostics"
end
action = "refresh"
end
if action == "switch_severity" then
if config.options.severity == nil then
config.options.severity = vim.diagnostic.severity.ERROR
elseif config.options.severity < 4 then
config.options.severity = config.options.severity + 1
else
config.options.severity = nil
end
action = "refresh"
end
if view and action == "on_win_enter" then
view:on_win_enter()
end
if not Trouble.is_open() then
return Trouble
end
if action == "hover" then
view:hover()
end
if action == "jump" then
view:jump()
elseif action == "open_split" then
view:jump({ precmd = "split" })
elseif action == "open_vsplit" then
view:jump({ precmd = "vsplit" })
elseif action == "open_tab" then
view:jump({ precmd = "tabe" })
end
if action == "jump_close" then
view:jump()
Trouble.close()
end
if action == "open_folds" then
Trouble.refresh({ open_folds = true })
end
if action == "close_folds" then
Trouble.refresh({ close_folds = true })
end
if action == "toggle_fold" then
view:toggle_fold()
end
if action == "on_enter" then
view:on_enter()
end
if action == "on_leave" then
view:on_leave()
end
if action == "cancel" then
view:switch_to_parent()
end
if action == "next" then
view:next_item()
return Trouble
end
if action == "previous" then
view:previous_item()
return Trouble
end
if action == "first" then
view:first_item()
return Trouble
end
if action == "last" then
view:last_item()
return Trouble
end
if action == "toggle_preview" then
config.options.auto_preview = not config.options.auto_preview
if not config.options.auto_preview then
view:close_preview()
else
action = "preview"
end
end
if action == "auto_preview" and config.options.auto_preview then
action = "preview"
end
if action == "preview" then
view:preview()
end
if action == "open_code_href" then
view:open_code_href()
end
if Trouble[action] then
Trouble[action]()
end
return Trouble
end
function Trouble.next(opts)
util.fix_mode(opts)
if view then
view:next_item(opts)
end
end
function Trouble.previous(opts)
util.fix_mode(opts)
if view then
view:previous_item(opts)
end
end
function Trouble.first(opts)
util.fix_mode(opts)
if view then
view:first_item(opts)
end
end
function Trouble.last(opts)
util.fix_mode(opts)
if view then
view:last_item(opts)
end
end
function Trouble.get_items()
if view ~= nil then
return view.items
else
return {}
end
end
return Trouble
return setmetatable(M, {
__index = function(_, k)
return require("trouble.api")[k]
end,
})

View File

@ -1,59 +0,0 @@
local util = require("trouble.util")
---@class Lsp
local M = {}
local severity = {
[1] = "ERROR",
[2] = "WARN",
[3] = "INFO",
[4] = "HINT",
}
---@param options TroubleOptions
---@return Item[]
function M.diagnostics(_, buf, cb, options)
if options.mode == "workspace_diagnostics" then
buf = nil
end
local items = {}
if vim.diagnostic then
local diags = vim.diagnostic.get(buf, { severity = options.severity })
for _, item in ipairs(diags) do
table.insert(items, util.process_item(item))
end
else
---@diagnostic disable-next-line: deprecated
local diags = buf and { [buf] = vim.lsp.diagnostic.get(buf) } or vim.lsp.diagnostic.get_all()
items = util.locations_to_items(diags, 1)
end
local messages = {}
if severity[options.severity] then
table.insert(messages, { text = "filter:", group = "Information" })
table.insert(messages, { text = severity[options.severity], group = "Sign" .. util.severity[options.severity] })
end
cb(items, messages)
end
function M.get_signs()
local signs = {}
for _, v in pairs(util.severity) do
if v ~= "Other" then
-- pcall to catch entirely unbound or cleared out sign hl group
local status, sign = pcall(function()
return vim.trim(vim.fn.sign_getdefined(util.get_severity_label(v, "Sign"))[1].text)
end)
if not status then
sign = v:sub(1, 1)
end
signs[string.lower(v)] = sign
end
end
return signs
end
return M

View File

@ -1,94 +0,0 @@
local util = require("trouble.util")
local qf = require("trouble.providers.qf")
local telescope = require("trouble.providers.telescope")
local lsp = require("trouble.providers.lsp")
local diagnostic = require("trouble.providers.diagnostic")
local M = {}
M.providers = {
workspace_diagnostics = diagnostic.diagnostics,
document_diagnostics = diagnostic.diagnostics,
lsp_references = lsp.references,
lsp_implementations = lsp.implementations,
lsp_definitions = lsp.definitions,
lsp_type_definitions = lsp.type_definitions,
quickfix = qf.qflist,
loclist = qf.loclist,
telescope = telescope.telescope,
}
---@param options TroubleOptions
function M.get(win, buf, cb, options)
local name = options.mode
local provider = M.providers[name]
if not provider then
local ok, mod = pcall(require, "trouble.providers." .. name)
if ok then
M.providers[name] = mod
provider = mod
end
end
if not provider then
util.error(("invalid provider %q"):format(name))
return {}
end
local sort_keys = vim.list_extend({
function(item)
local cwd = vim.loop.fs_realpath(vim.fn.getcwd())
local path = vim.loop.fs_realpath(item.filename)
if not path then
return 200
end
local ret = string.find(path, cwd, 1, true) == 1 and 10 or 100
-- prefer non-hidden files
if string.find(path, ".") then
ret = ret + 1
end
return ret
end,
}, options.sort_keys)
provider(win, buf, function(items, messages)
table.sort(items, function(a, b)
for _, key in ipairs(sort_keys) do
local ak = type(key) == "string" and a[key] or key(a)
local bk = type(key) == "string" and b[key] or key(b)
if ak ~= bk then
return ak < bk
end
end
end)
cb(items, messages)
end, options)
end
---@param items Item[]
---@return table<string, Item[]>
function M.group(items)
local keys = {}
local keyid = 0
local groups = {}
for _, item in ipairs(items) do
if groups[item.filename] == nil then
groups[item.filename] = { filename = item.filename, items = {} }
keys[item.filename] = keyid
keyid = keyid + 1
end
table.insert(groups[item.filename].items, item)
end
local ret = {}
for _, group in pairs(groups) do
table.insert(ret, group)
end
table.sort(ret, function(a, b)
return keys[a.filename] < keys[b.filename]
end)
return ret
end
return M

View File

@ -1,93 +0,0 @@
local lsp = require("vim.lsp")
local util = require("trouble.util")
---@class Lsp
local M = {}
local function lsp_buf_request(buf, method, params, handler)
lsp.buf_request(buf, method, params, function(err, m, result)
handler(err, method == m and result or m)
end)
end
---@return Item[]
function M.references(win, buf, cb, options)
local method = "textDocument/references"
local params = util.make_position_params(win, buf)
params.context = { includeDeclaration = vim.tbl_contains(options.include_declaration, options.mode) }
lsp_buf_request(buf, method, params, function(err, result)
if err then
util.error("an error happened getting references: " .. err.message)
return cb({})
end
if result == nil or #result == 0 then
return cb({})
end
local ret = util.locations_to_items({ result }, 0)
cb(ret)
end)
end
---@return Item[]
function M.implementations(win, buf, cb, options)
local method = "textDocument/implementation"
local params = util.make_position_params(win, buf)
params.context = { includeDeclaration = vim.tbl_contains(options.include_declaration, options.mode) }
lsp_buf_request(buf, method, params, function(err, result)
if err then
util.error("an error happened getting implementation: " .. err.message)
return cb({})
end
if result == nil or #result == 0 then
return cb({})
end
local ret = util.locations_to_items({ result }, 0)
cb(ret)
end)
end
---@return Item[]
function M.definitions(win, buf, cb, options)
local method = "textDocument/definition"
local params = util.make_position_params(win, buf)
params.context = { includeDeclaration = vim.tbl_contains(options.include_declaration, options.mode) }
lsp_buf_request(buf, method, params, function(err, result)
if err then
util.error("an error happened getting definitions: " .. err.message)
return cb({})
end
if result == nil or #result == 0 then
return cb({})
end
for _, value in ipairs(result) do
value.uri = value.targetUri or value.uri
value.range = value.targetSelectionRange or value.range
end
local ret = util.locations_to_items({ result }, 0)
cb(ret)
end)
end
---@return Item[]
function M.type_definitions(win, buf, cb, _options)
local method = "textDocument/typeDefinition"
local params = util.make_position_params(win, buf)
lsp_buf_request(buf, method, params, function(err, result)
if err then
util.error("an error happened getting type definitions: " .. err.message)
return cb({})
end
if result == nil or #result == 0 then
return cb({})
end
for _, value in ipairs(result) do
value.uri = value.targetUri or value.uri
value.range = value.targetSelectionRange or value.range
end
local ret = util.locations_to_items({ result }, 0)
cb(ret)
end)
end
return M

View File

@ -1,47 +0,0 @@
local util = require("trouble.util")
local M = {}
local severities = { E = 1, W = 2, I = 3, H = 4 }
function M.get_list(winid)
local list = winid == nil and vim.fn.getqflist({ all = true }) or vim.fn.getloclist(winid, { all = true })
local ret = {}
for _, item in pairs(list.items) do
local row = (item.lnum == 0 and 1 or item.lnum) - 1
local col = (item.col == 0 and 1 or item.col) - 1
if item.valid == 1 then
ret[#ret + 1] = {
row = row,
col = col,
message = item.text,
severity = severities[item.type] or 0,
bufnr = item.bufnr,
range = {
start = { line = row, character = col },
["end"] = { line = row, character = -1 },
},
}
elseif #ret > 0 then
ret[#ret].message = ret[#ret].message .. "\n" .. item.text
end
end
for i, item in ipairs(ret) do
ret[i] = util.process_item(item)
end
return ret
end
function M.loclist(win, _buf, cb, _options)
return cb(M.get_list(win))
end
function M.qflist(_win, _buf, cb, _options)
return cb(M.get_list())
end
return M

View File

@ -1,86 +1,19 @@
local util = require("trouble.util")
local T = require("trouble.sources.telescope")
local M = {}
return setmetatable({}, {
__index = function(_, k)
require("trouble.util").warn(
([[
`%s()` is deprecated
```lua
-- Use this:
require("trouble.sources.telescope").open()
M.results = {}
--- Turns a Telescope item into a Trouble item.
local function item_to_result(item)
local row = (item.lnum or 1) - 1
local col = (item.col or 1) - 1
if not item.bufnr then
local fname = vim.fn.fnamemodify(item.filename, ":p")
if vim.fn.filereadable(fname) == 0 and item.cwd then
fname = vim.fn.fnamemodify(item.cwd .. "/" .. item.filename, ":p")
end
item.bufnr = vim.fn.bufnr(fname, true)
end
local pitem = {
row = row,
col = col,
message = item.text,
severity = 0,
range = {
start = { line = row, character = col },
["end"] = { line = row, character = -1 },
},
}
return util.process_item(pitem, item.bufnr)
end
--- Shows all Telescope results in Trouble.
function M.open_with_trouble(prompt_bufnr, _mode)
local action_state = require("telescope.actions.state")
local actions = require("telescope.actions")
local picker = action_state.get_current_picker(prompt_bufnr)
local manager = picker.manager
M.results = {}
for item in manager:iter() do
table.insert(M.results, item_to_result(item))
end
actions.close(prompt_bufnr)
require("trouble").open("telescope")
end
--- Shows the selected Telescope results in Trouble.
function M.open_selected_with_trouble(prompt_bufnr, _mode)
local action_state = require("telescope.actions.state")
local actions = require("telescope.actions")
local picker = action_state.get_current_picker(prompt_bufnr)
M.results = {}
for _, item in ipairs(picker:get_multi_selection()) do
table.insert(M.results, item_to_result(item))
end
actions.close(prompt_bufnr)
require("trouble").open("telescope")
end
--- Shows the selected Telescope results in Trouble.
--- If no results are currently selected, shows all of them.
function M.smart_open_with_trouble(prompt_bufnr, _mode)
local action_state = require("telescope.actions.state")
local picker = action_state.get_current_picker(prompt_bufnr)
if #picker:get_multi_selection() > 0 then
M.open_selected_with_trouble(prompt_bufnr, _mode)
else
M.open_with_trouble(prompt_bufnr, _mode)
end
end
function M.telescope(_win, _buf, cb, _options)
if #M.results == 0 then
util.warn(
"No Telescope results found. Open Telescope and send results to Trouble first. Refer to the documentation for more info."
-- Instead of:
require("trouble.providers.telescope").%s()
]]):format(k, k),
{ once = true }
)
end
cb(M.results)
end
return M
return T.open
end,
})

View File

@ -1,173 +0,0 @@
local providers = require("trouble.providers")
local util = require("trouble.util")
local config = require("trouble.config")
local Text = require("trouble.text")
local folds = require("trouble.folds")
---@class Renderer
local renderer = {}
renderer.signs = {}
local function get_icon(file)
local ok, icons = pcall(require, "nvim-web-devicons")
if not ok then
util.warn(
"'nvim-web-devicons' is not installed. Install it, or set icons=false in your configuration to disable this message"
)
return ""
end
local fname = vim.fn.fnamemodify(file, ":t")
local ext = vim.fn.fnamemodify(file, ":e")
return icons.get_icon(fname, ext, { default = true })
end
local function update_signs()
renderer.signs = config.options.signs
if config.options.use_diagnostic_signs then
local lsp_signs = require("trouble.providers.diagnostic").get_signs()
renderer.signs = vim.tbl_deep_extend("force", {}, renderer.signs, lsp_signs)
end
end
---@param view TroubleView
function renderer.render(view, opts)
opts = opts or {}
local buf = vim.api.nvim_win_get_buf(view.parent)
providers.get(view.parent, buf, function(items, messages)
local auto_jump = vim.tbl_contains(config.options.auto_jump, opts.mode)
if opts.on_open and #items == 1 and auto_jump and not opts.auto then
view:close()
util.jump_to_item(opts.win, opts.precmd, items[1])
return
end
local grouped = providers.group(items)
local count = util.count(grouped)
-- check for auto close
if opts.auto and config.options.auto_close then
if count == 0 then
view:close()
return
end
end
-- Update lsp signs
update_signs()
local text = Text:new()
view.items = {}
if config.options.padding then
if messages ~= nil then
for _, msg in ipairs(messages) do
text:render(" " .. msg.text, msg.group, { append = " " })
end
end
text:nl()
end
-- render file groups
for _, group in ipairs(grouped) do
if opts.open_folds then
folds.open(group.filename)
end
if opts.close_folds then
folds.close(group.filename)
end
renderer.render_file(view, text, group.filename, group.items)
end
view:render(text)
if opts.focus then
view:focus()
end
end, config.options)
end
---@param view TroubleView
---@param text Text
---@param items Item[]
---@param filename string
function renderer.render_file(view, text, filename, items)
view.items[text.lineNr + 1] = { filename = filename, is_file = true }
if view.group == true then
local count = util.count(items)
text:render(" ")
if folds.is_folded(filename) then
text:render(config.options.fold_closed, "FoldIcon", " ")
else
text:render(config.options.fold_open, "FoldIcon", " ")
end
if config.options.icons then
local icon, icon_hl = get_icon(filename)
text:render(icon, icon_hl, { exact = true, append = " " })
end
text:render(vim.fn.fnamemodify(filename, ":p:."), "File", " ")
text:render(" " .. count .. " ", "Count")
text:nl()
end
if not folds.is_folded(filename) then
renderer.render_diagnostics(view, text, items)
end
end
---@param view TroubleView
---@param text Text
---@param items Item[]
function renderer.render_diagnostics(view, text, items)
for _, diag in ipairs(items) do
view.items[text.lineNr + 1] = diag
local sign = diag.sign or renderer.signs[string.lower(diag.type)]
if not sign then
sign = diag.type
end
local indent = " "
if config.options.indent_lines then
indent = ""
elseif config.options.group == false then
indent = " "
end
local sign_hl = diag.sign_hl or ("TroubleSign" .. diag.type)
text:render(indent, "Indent")
text:render(sign .. " ", sign_hl, { exact = true })
local lines = config.options.multiline and vim.split(diag.full_text, "\n") or { diag.text }
text:render(lines[1], "Text" .. diag.type, " ")
if diag.source then
text:render(diag.source, "Source")
end
if diag.code and diag.code ~= vim.NIL then
text:render(" (" .. diag.code .. ")", "Code")
end
text:render(" ")
text:render("[" .. diag.lnum .. ", " .. diag.col .. "]", "Location")
for l = 2, #lines do
local str = lines[l]
text:nl()
view.items[text.lineNr + 1] = diag
text:render(indent .. " ", "Indent")
text:render(str, "Text" .. diag.type, " ")
end
text:nl()
end
end
return renderer

View File

@ -1,52 +0,0 @@
---@class Text
---@field lines string[]
---@field hl Highlight[]
---@field lineNr number
---@field current string
local Text = {}
Text.__index = Text
function Text:new()
local this = { lines = {}, hl = {}, lineNr = 0, current = "" }
setmetatable(this, self)
return this
end
function Text:nl()
table.insert(self.lines, self.current)
self.current = ""
self.lineNr = self.lineNr + 1
end
function Text:render(str, group, opts)
str = str:gsub("[\n]", " ")
if type(opts) == "string" then
opts = { append = opts }
end
opts = opts or {}
if group then
if opts.exact ~= true then
group = "Trouble" .. group
end
local from = string.len(self.current)
---@class Highlight
local hl
hl = {
line = self.lineNr,
from = from,
to = from + string.len(str),
group = group,
}
table.insert(self.hl, hl)
end
self.current = self.current .. str
if opts.append then
self.current = self.current .. opts.append
end
if opts.nl then
self:nl()
end
end
return Text

View File

@ -1,242 +1,317 @@
local config = require("trouble.config")
local uv = vim.loop
local Config = require("trouble.config")
local uv = vim.loop or vim.uv
local M = {}
function M.jump_to_item(win, precmd, item)
-- requiring here, as otherwise we run into a circular dependency
local View = require("trouble.view")
-- save position in jump list
vim.cmd("normal! m'")
View.switch_to(win)
if precmd then
vim.cmd(precmd)
end
if not vim.bo[item.bufnr].buflisted then
vim.bo[item.bufnr].buflisted = true
end
if not vim.api.nvim_buf_is_loaded(item.bufnr) then
vim.fn.bufload(item.bufnr)
end
vim.api.nvim_set_current_buf(item.bufnr)
vim.api.nvim_win_set_cursor(win or 0, { item.start.line + 1, item.start.character })
vim.api.nvim_exec_autocmds("User", { pattern = "TroubleJump", modeline = false })
---@param fn function
function M.noautocmd(fn)
local ei = vim.o.eventignore
vim.o.eventignore = "all"
fn()
vim.o.eventignore = ei
end
function M.fix_mode(opts)
if opts.use_lsp_diagnostic_signs then
opts.use_diagnostic_signs = opts.use_lsp_diagnostic_signs
M.warn("The Trouble option use_lsp_diagnostic_signs has been renamed to use_diagnostic_signs")
end
local replace = {
lsp_workspace_diagnostics = "workspace_diagnostics",
lsp_document_diagnostics = "document_diagnostics",
workspace = "workspace_diagnostics",
document = "document_diagnostics",
}
function M.is_win()
return vim.uv.os_uname().sysname:find("Windows") ~= nil
end
for old, new in pairs(replace) do
if opts.mode == old then
opts.mode = new
M.warn("Using " .. old .. " for Trouble is deprecated. Please use " .. new .. " instead.")
---@param opts? {msg?: string}
function M.try(fn, opts)
local ok, err = pcall(fn)
if not ok then
local msg = opts and opts.msg or "Something went wrong:"
msg = msg .. "\n" .. err
M.error(msg)
end
end
M.islist = vim.islist or vim.tbl_islist
---@alias NotifyOpts {level?: number, title?: string, once?: boolean, id?:string}
---@type table<string, any>
local notif_ids = {}
---@param msg string|string[]
---@param opts? NotifyOpts
function M.notify(msg, opts)
opts = opts or {}
msg = type(msg) == "table" and table.concat(msg, "\n") or msg
---@cast msg string
msg = vim.trim(msg)
local ret = vim[opts.once and "notify_once" or "notify"](msg, opts.level, {
replace = opts.id and notif_ids[opts.id] or nil,
title = opts.title or "Trouble",
on_open = function(win)
vim.wo.conceallevel = 3
vim.wo.concealcursor = "n"
vim.wo.spell = false
vim.treesitter.start(vim.api.nvim_win_get_buf(win), "markdown")
end,
})
if opts.id then
notif_ids[opts.id] = ret
end
return ret
end
---@param msg string|string[]
---@param opts? NotifyOpts
function M.warn(msg, opts)
M.notify(msg, vim.tbl_extend("keep", { level = vim.log.levels.WARN }, opts or {}))
end
---@param msg string|string[]
---@param opts? NotifyOpts
function M.info(msg, opts)
M.notify(msg, vim.tbl_extend("keep", { level = vim.log.levels.INFO }, opts or {}))
end
---@param msg string|string[]
---@param opts? NotifyOpts
function M.error(msg, opts)
M.notify(msg, vim.tbl_extend("keep", { level = vim.log.levels.ERROR }, opts or {}))
end
---@param msg string|string[]
function M.debug(msg, ...)
if Config.debug then
if select("#", ...) > 0 then
local obj = select("#", ...) == 1 and ... or { ... }
msg = msg .. "\n```lua\n" .. vim.inspect(obj) .. "\n```"
end
M.notify(msg, { title = "Trouble (debug)" })
end
end
---@return number
function M.count(tab)
local count = 0
for _ in pairs(tab) do
count = count + 1
end
return count
end
function M.warn(msg)
vim.notify(msg, vim.log.levels.WARN, { title = "Trouble" })
end
function M.error(msg)
vim.notify(msg, vim.log.levels.ERROR, { title = "Trouble" })
end
function M.debug(msg)
if config.options.debug then
vim.notify(msg, vim.log.levels.DEBUG, { title = "Trouble" })
---@param buf number
---@param row number
---@param ns number
---@param col number
---@param opts vim.api.keyset.set_extmark
---@param debug_info? any
function M.set_extmark(buf, ns, row, col, opts, debug_info)
local ok, err = pcall(vim.api.nvim_buf_set_extmark, buf, ns, row, col, opts)
if not ok and Config.debug then
M.debug("Failed to set extmark for preview", { info = debug_info, row = row, col = col, opts = opts, error = err })
end
end
function M.debounce(ms, fn)
local timer = vim.loop.new_timer()
return function(...)
local argv = { ... }
timer:start(ms, 0, function()
timer:stop()
vim.schedule_wrap(fn)(unpack(argv))
---@param str string
---@param sep? string
function M.camel(str, sep)
local parts = vim.split(str, "[%.%-%_]")
---@diagnostic disable-next-line: no-unknown
return table.concat(
vim.tbl_map(function(part)
return part:sub(1, 1):upper() .. part:sub(2)
end, parts),
sep or ""
)
end
---@param opts? {ms?: number, debounce?: boolean}|number
---@param default Throttle.opts
---@return Throttle.opts
function M.throttle_opts(opts, default)
opts = opts or {}
if type(opts) == "number" then
opts = { ms = opts }
end
return vim.tbl_deep_extend("force", default, opts)
end
---@alias Throttle.opts {ms:number, debounce?:boolean, is_running?:fun():boolean}
-- throttle with trailing execution
---@generic T: fun()
---@param fn T
---@param opts? Throttle.opts
---@return T
function M.throttle(fn, opts)
opts = opts or {}
opts.ms = opts.ms or 20
local last = 0
local args = nil ---@type {n?:number}?
local timer = assert(uv.new_timer())
local pending = false -- from run() till end of fn
local running = false -- from run() till end of fn with is_running()
local t = {}
function t.run()
pending = true
running = true
timer:stop()
last = uv.now()
vim.schedule(function()
xpcall(function()
if not args then
return M.debug("Empty args. This should not happen.")
end
fn(vim.F.unpack_len(args))
args = nil
end, function(err)
vim.schedule(function()
M.error(err)
end)
end)
pending = false
t.check()
end)
end
end
function M.throttle(ms, fn)
local timer = vim.loop.new_timer()
local running = false
function t.schedule()
local now = uv.now()
local delay = opts.debounce and opts.ms or (opts.ms - (now - last))
timer:stop()
timer:start(math.max(0, delay), 0, t.run)
end
function t.check()
if running and not pending and not (opts.is_running and opts.is_running()) then
running = false
if args then -- schedule if there are pending args
t.schedule()
end
end
end
local check = assert(uv.new_check())
check:start(t.check)
return function(...)
if not running then
local argv = { ... }
local argc = select("#", ...)
args = vim.F.pack_len(...)
timer:start(ms, 0, function()
running = false
pcall(vim.schedule_wrap(fn), unpack(argv, 1, argc))
end)
running = true
if timer:is_active() and not opts.debounce then
return
elseif not running then
t.schedule()
end
end
end
M.severity = {
[0] = "Other",
[1] = "Error",
[2] = "Warning",
[3] = "Information",
[4] = "Hint",
}
-- returns a hl or sign label for the givin severity and type
-- correctly handles new names introduced in vim.diagnostic
function M.get_severity_label(severity, type)
local label = severity
local prefix = "LspDiagnostics" .. (type or "Default")
if vim.diagnostic then
prefix = type and ("Diagnostic" .. type) or "Diagnostic"
label = ({
Warning = "Warn",
Information = "Info",
})[severity] or severity
end
return prefix .. label
---@param s string
function M.lines(s)
return M.split(s, "\n")
end
-- based on the Telescope diagnostics code
-- see https://github.com/nvim-telescope/telescope.nvim/blob/0d6cd47990781ea760dd3db578015c140c7b9fa7/lua/telescope/utils.lua#L85
function M.process_item(item, bufnr)
bufnr = bufnr or item.bufnr
local filename = vim.api.nvim_buf_get_name(bufnr)
local range = item.range or item.targetSelectionRange
---@param s string
---@param c? string
function M.split(s, c)
c = c or "\n"
local pos = 1
local l = 0
return function()
if pos == -1 then
return
end
l = l + 1
local start = {
line = range and vim.tbl_get(range, "start", "line") or item.lnum,
character = range and vim.tbl_get(range, "start", "character") or item.col,
}
local finish = {
line = range and vim.tbl_get(range, "end", "line") or item.end_lnum,
character = range and vim.tbl_get(range, "end", "character") or item.end_col,
}
local nl = s:find(c, pos, true)
if not nl then
local lastLine = s:sub(pos)
pos = -1
return l, lastLine
end
if start.character == nil or start.line == nil then
M.error("Found an item for Trouble without start range " .. vim.inspect(start))
local line = s:sub(pos, nl - 1)
pos = nl + 1
return l, line
end
if finish.character == nil or finish.line == nil then
M.error("Found an item for Trouble without finish range " .. vim.inspect(finish))
end
local row = start.line ---@type number
local col = start.character ---@type number
end
if not item.message and filename then
-- check if the filename is a uri
if string.match(filename, "^%w+://") ~= nil then
if not vim.api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
--- Gets lines from a file or buffer
---@param opts {path?:string, buf?: number, rows?: number[]}
---@return table<number, string>?
function M.get_lines(opts)
if opts.buf then
local uri = vim.uri_from_bufnr(opts.buf)
if uri:sub(1, 4) ~= "file" then
vim.fn.bufload(opts.buf)
end
if vim.api.nvim_buf_is_loaded(opts.buf) then
local lines = {} ---@type table<number, string>
if not opts.rows then
return vim.api.nvim_buf_get_lines(opts.buf, 0, -1, false)
end
local lines = vim.api.nvim_buf_get_lines(bufnr, row, row + 1, false)
item.message = lines[1] or ""
else
local fd = assert(uv.fs_open(filename, "r", 438))
local stat = assert(uv.fs_fstat(fd))
local data = assert(uv.fs_read(fd, stat.size, 0))
assert(uv.fs_close(fd))
for _, row in ipairs(opts.rows) do
lines[row] = vim.api.nvim_buf_get_lines(opts.buf, row - 1, row, false)[1]
end
return lines
end
opts.path = vim.uri_to_fname(uri)
elseif not opts.path then
error("buf or filename is required")
end
item.message = vim.split(data, "\n", { plain = true })[row + 1] or ""
local fd = uv.fs_open(opts.path, "r", 438)
if not fd then
return
end
local stat = assert(uv.fs_fstat(fd))
if not (stat.type == "file" or stat.type == "link") then
return
end
local data = assert(uv.fs_read(fd, stat.size, 0)) --[[@as string]]
assert(uv.fs_close(fd))
local todo = 0
local ret = {} ---@type table<number, string|boolean>
for _, r in ipairs(opts.rows or {}) do
if not ret[r] then
todo = todo + 1
ret[r] = true
end
end
---@class Item
---@field is_file boolean
---@field fixed boolean
local ret = {
bufnr = bufnr,
filename = filename,
lnum = row + 1,
col = col + 1,
start = start,
finish = finish,
sign = item.sign, ---@type string?
sign_hl = item.sign_hl, ---@type string?
-- remove line break to avoid display issues
text = vim.trim(item.message:gsub("[\n]+", "")):sub(0, vim.o.columns),
full_text = vim.trim(item.message),
type = M.severity[item.severity] or M.severity[0],
code = item.code or (item.user_data and item.user_data.lsp and item.user_data.lsp.code), ---@type string?
code_href = (item.codeDescription and item.codeDescription.href)
or (
item.user_data
and item.user_data.lsp
and item.user_data.lsp.codeDescription
and item.user_data.lsp.codeDescription.href
), ---@type string?
source = item.source, ---@type string?
severity = item.severity or 0,
}
return ret
end
-- takes either a table indexed by bufnr, or an lsp result with uri
---@return Item[]
function M.locations_to_items(results, default_severity)
default_severity = default_severity or 0
local ret = {}
for bufnr, locs in pairs(results or {}) do
for _, loc in pairs(locs.result or locs) do
if not vim.tbl_isempty(loc) then
local uri = loc.uri or loc.targetUri
local buf = uri and vim.uri_to_bufnr(uri) or bufnr
loc.severity = loc.severity or default_severity
table.insert(ret, M.process_item(loc, buf))
for row, line in M.lines(data) do
if not opts.rows or ret[row] then
todo = todo - 1
ret[row] = line
if todo == 0 then
break
end
end
end
for i, r in pairs(ret) do
if r == true then
ret[i] = ""
end
end
return ret
end
-- @private
local function make_position_param(win, buf)
local row, col = unpack(vim.api.nvim_win_get_cursor(win))
row = row - 1
local line = vim.api.nvim_buf_get_lines(buf, row, row + 1, true)[1]
if not line then
return { line = 0, character = 0 }
--- Creates a weak reference to an object.
--- Calling the returned function will return the object if it has not been garbage collected.
---@generic T: table
---@param obj T
---@return T|fun():T?
function M.weak(obj)
local weak = { _obj = obj }
---@return table<any, any>
local function get()
local ret = rawget(weak, "_obj")
return ret == nil and error("Object has been garbage collected", 2) or ret
end
col = vim.str_utfindex(line, col)
return { line = row, character = col }
end
function M.make_text_document_params(buf)
return { uri = vim.uri_from_bufnr(buf) }
end
--- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position.
---
-- @returns `TextDocumentPositionParams` object
-- @see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams
function M.make_position_params(win, buf)
return {
textDocument = M.make_text_document_params(buf),
position = make_position_param(win, buf),
local mt = {
__mode = "v",
__call = function(t)
return rawget(t, "_obj")
end,
__index = function(_, k)
return get()[k]
end,
__newindex = function(_, k, v)
get()[k] = v
end,
__pairs = function()
return pairs(get())
end,
}
return setmetatable(weak, mt)
end
return M

View File

@ -1,581 +0,0 @@
local renderer = require("trouble.renderer")
local config = require("trouble.config")
local folds = require("trouble.folds")
local util = require("trouble.util")
local highlight = vim.api.nvim_buf_add_highlight
---@class TroubleView
---@field buf number
---@field win number
---@field group boolean
---@field items Item[]
---@field folded table<string, boolean>
---@field parent number
---@field float number
local View = {}
View.__index = View
-- keep track of buffers with added highlights
-- highlights are cleared on BufLeave of Trouble
local hl_bufs = {}
local function clear_hl(bufnr)
if vim.api.nvim_buf_is_valid(bufnr) then
vim.api.nvim_buf_clear_namespace(bufnr, config.namespace, 0, -1)
end
end
---Find a rogue Trouble buffer that might have been spawned by i.e. a session.
local function find_rogue_buffer()
for _, v in ipairs(vim.api.nvim_list_bufs()) do
if vim.fn.bufname(v) == "Trouble" then
return v
end
end
return nil
end
---Find pre-existing Trouble buffer, delete its windows then wipe it.
---@private
local function wipe_rogue_buffer()
local bn = find_rogue_buffer()
if bn then
local win_ids = vim.fn.win_findbuf(bn)
for _, id in ipairs(win_ids) do
if vim.fn.win_gettype(id) ~= "autocmd" and vim.api.nvim_win_is_valid(id) then
vim.api.nvim_win_close(id, true)
end
end
vim.api.nvim_buf_set_name(bn, "")
vim.schedule(function()
pcall(vim.api.nvim_buf_delete, bn, {})
end)
end
end
---@return TroubleView
function View:new(opts)
opts = opts or {}
local group
if opts.group ~= nil then
group = opts.group
else
group = config.options.group
end
local this = {
buf = vim.api.nvim_get_current_buf(),
win = opts.win or vim.api.nvim_get_current_win(),
parent = opts.parent,
items = {},
group = group,
}
setmetatable(this, self)
return this
end
function View:set_option(name, value, win)
if win then
return vim.api.nvim_set_option_value(name, value, { win = self.win, scope = "local" })
else
return vim.api.nvim_set_option_value(name, value, { buf = self.buf })
end
end
---@param text Text
function View:render(text)
if not self:is_valid() then
return
end
self:unlock()
self:set_lines(text.lines)
self:lock()
clear_hl(self.buf)
for _, data in ipairs(text.hl) do
highlight(self.buf, config.namespace, data.group, data.line, data.from, data.to)
end
end
function View:clear()
return vim.api.nvim_buf_set_lines(self.buf, 0, -1, false, {})
end
function View:unlock()
self:set_option("modifiable", true)
self:set_option("readonly", false)
end
function View:lock()
self:set_option("readonly", true)
self:set_option("modifiable", false)
end
function View:set_lines(lines, first, last, strict)
first = first or 0
last = last or -1
strict = strict or false
return vim.api.nvim_buf_set_lines(self.buf, first, last, strict, lines)
end
function View:is_valid()
return vim.api.nvim_buf_is_valid(self.buf) and vim.api.nvim_buf_is_loaded(self.buf)
end
function View:update(opts)
util.debug("update")
renderer.render(self, opts)
end
function View:setup(opts)
util.debug("setup")
opts = opts or {}
vim.cmd("setlocal nonu")
vim.cmd("setlocal nornu")
if not pcall(vim.api.nvim_buf_set_name, self.buf, "Trouble") then
wipe_rogue_buffer()
vim.api.nvim_buf_set_name(self.buf, "Trouble")
end
self:set_option("bufhidden", "wipe")
self:set_option("buftype", "nofile")
self:set_option("swapfile", false)
self:set_option("cursorline", true, true)
self:set_option("buflisted", false)
self:set_option("winfixwidth", true, true)
self:set_option("wrap", false, true)
self:set_option("spell", false, true)
self:set_option("list", false, true)
self:set_option("winfixheight", true, true)
self:set_option("signcolumn", "no", true)
self:set_option("foldmethod", "manual", true)
self:set_option("foldcolumn", "0", true)
self:set_option("foldlevel", 3, true)
self:set_option("foldenable", false, true)
self:set_option("winhighlight", "Normal:TroubleNormal,EndOfBuffer:TroubleNormal,SignColumn:TroubleNormal", true)
self:set_option("fcs", "eob: ", true)
for action, keys in pairs(config.options.action_keys) do
if type(keys) == "string" then
keys = { keys }
end
for _, key in pairs(keys) do
vim.api.nvim_buf_set_keymap(
self.buf,
"n",
key,
[[<cmd>lua require("trouble").action("]] .. action .. [[")<cr>]],
{
silent = true,
noremap = true,
nowait = true,
}
)
end
end
if config.options.position == "top" or config.options.position == "bottom" then
vim.api.nvim_win_set_height(self.win, config.options.height)
else
vim.api.nvim_win_set_width(self.win, config.options.width)
end
self:set_option("filetype", "Trouble")
vim.api.nvim_exec(
[[
augroup TroubleHighlights
autocmd! * <buffer>
autocmd BufEnter <buffer> lua require("trouble").action("on_enter")
autocmd CursorMoved <buffer> lua require("trouble").action("auto_preview")
autocmd BufLeave <buffer> lua require("trouble").action("on_leave")
augroup END
]],
false
)
if not opts.parent then
self:on_enter()
end
self:lock()
self:update(opts)
end
function View:on_enter()
util.debug("on_enter")
self.parent = self.parent or vim.fn.win_getid(vim.fn.winnr("#"))
if (not self:is_valid_parent(self.parent)) or self.parent == self.win then
util.debug("not valid parent")
for _, win in pairs(vim.api.nvim_list_wins()) do
if self:is_valid_parent(win) and win ~= self.win then
self.parent = win
break
end
end
end
if not vim.api.nvim_win_is_valid(self.parent) then
return self:close()
end
self.parent_state = {
buf = vim.api.nvim_win_get_buf(self.parent),
cursor = vim.api.nvim_win_get_cursor(self.parent),
}
end
function View:on_leave()
util.debug("on_leave")
self:close_preview()
end
function View:close_preview()
-- Clear preview highlights
for buf, _ in pairs(hl_bufs) do
clear_hl(buf)
end
hl_bufs = {}
-- Reset parent state
local valid_win = vim.api.nvim_win_is_valid(self.parent)
local valid_buf = self.parent_state and vim.api.nvim_buf_is_valid(self.parent_state.buf)
if self.parent_state and valid_buf and valid_win then
vim.api.nvim_win_set_buf(self.parent, self.parent_state.buf)
vim.api.nvim_win_set_cursor(self.parent, self.parent_state.cursor)
end
self.parent_state = nil
end
function View:is_float(win)
local opts = vim.api.nvim_win_get_config(win)
return opts and opts.relative and opts.relative ~= ""
end
function View:is_valid_parent(win)
if not vim.api.nvim_win_is_valid(win) then
return false
end
-- dont do anything for floating windows
if View:is_float(win) then
return false
end
local buf = vim.api.nvim_win_get_buf(win)
-- Skip special buffers
if vim.api.nvim_buf_get_option(buf, "buftype") ~= "" then
return false
end
return true
end
function View:on_win_enter()
util.debug("on_win_enter")
local current_win = vim.api.nvim_get_current_win()
if vim.fn.winnr("$") == 1 and current_win == self.win then
vim.cmd([[q]])
return
end
if not self:is_valid_parent(current_win) then
return
end
local current_buf = vim.api.nvim_get_current_buf()
-- update parent when needed
if current_win ~= self.parent and current_win ~= self.win then
self.parent = current_win
-- update diagnostics to match the window we are viewing
if self:is_valid() then
vim.defer_fn(function()
util.debug("update_on_win_enter")
self:update()
end, 100)
end
end
-- check if another buffer took over our window
local parent = self.parent
if current_win == self.win and current_buf ~= self.buf then
-- open the buffer in the parent
vim.api.nvim_win_set_buf(parent, current_buf)
-- HACK: some window local settings need to be reset
vim.api.nvim_win_set_option(parent, "winhl", "")
-- close the current trouble window
vim.api.nvim_win_close(self.win, false)
-- open a new trouble window
require("trouble").open()
-- switch back to the opened window / buffer
View.switch_to(parent, current_buf)
-- util.warn("win_enter pro")
end
end
function View:focus()
if not self:is_valid() then
return
end
View.switch_to(self.win, self.buf)
local line = self:get_line()
if line == 1 then
self:next_item()
if config.options.padding then
self:next_item()
end
end
end
function View.switch_to(win, buf)
if win then
vim.api.nvim_set_current_win(win)
if buf then
vim.api.nvim_win_set_buf(win, buf)
end
end
end
function View:switch_to_parent()
-- vim.cmd("wincmd p")
View.switch_to(self.parent)
end
function View:close()
util.debug("close")
if vim.api.nvim_win_is_valid(self.win) then
if vim.api.nvim_win_is_valid(self.parent) then
vim.api.nvim_set_current_win(self.parent)
end
vim.api.nvim_win_close(self.win, {})
end
if vim.api.nvim_buf_is_valid(self.buf) then
vim.api.nvim_buf_delete(self.buf, {})
end
end
function View.create(opts)
opts = opts or {}
---@type TroubleView
local view
vim.api.nvim_win_call(0, function()
if opts.win then
View.switch_to(opts.win)
vim.cmd("enew")
else
vim.cmd("below new")
local pos = { bottom = "J", top = "K", left = "H", right = "L" }
vim.cmd("wincmd " .. (pos[config.options.position] or "K"))
end
view = View:new(opts)
view:setup(opts)
end)
if opts.focus == true then
view:focus()
end
return view
end
function View:get_cursor()
return vim.api.nvim_win_get_cursor(self.win)
end
function View:get_line()
return self:get_cursor()[1]
end
function View:get_col()
return self:get_cursor()[2]
end
function View:current_item()
local line = self:get_line()
local item = self.items[line]
return item
end
function View:next_item(opts)
opts = opts or { skip_groups = false }
local line = opts.first and 0 or self:get_line() + 1
if line > #self.items then
if config.options.cycle_results then
self:first_item(opts)
end
else
for i = line, vim.api.nvim_buf_line_count(self.buf), 1 do
if self.items[i] and not (opts.skip_groups and self.items[i].is_file) then
vim.api.nvim_win_set_cursor(self.win, { i, self:get_col() })
if opts.jump then
self:jump()
end
return
end
end
end
end
function View:previous_item(opts)
opts = opts or { skip_groups = false }
local line = opts.last and vim.api.nvim_buf_line_count(self.buf) or self:get_line() - 1
for i = 0, vim.api.nvim_buf_line_count(self.buf), 1 do
if self.items[i] then
if line < i + (opts.skip_groups and 1 or 0) then
if config.options.cycle_results then
self:last_item(opts)
end
return
end
break
end
end
for i = line, 0, -1 do
if self.items[i] and not (opts.skip_groups and self.items[i].is_file) then
vim.api.nvim_win_set_cursor(self.win, { i, self:get_col() })
if opts.jump then
self:jump()
end
return
end
end
end
function View:first_item(opts)
opts = opts or {}
opts.first = true
return self:next_item(opts)
end
function View:last_item(opts)
opts = opts or {}
opts.last = true
return self:previous_item(opts)
end
function View:hover(opts)
opts = opts or {}
local item = opts.item or self:current_item()
if not (item and item.full_text) then
return
end
vim.lsp.util.open_floating_preview(vim.split(item.full_text, "\n"), "markdown", config.options.win_config)
end
function View:jump(opts)
opts = opts or {}
local item = opts.item or self:current_item()
if not item then
return
end
if item.is_file == true then
folds.toggle(item.filename)
self:update()
else
util.jump_to_item(opts.win or self.parent, opts.precmd, item)
end
end
function View:toggle_fold()
folds.toggle(self:current_item().filename)
self:update()
end
function View:_preview()
if not vim.api.nvim_win_is_valid(self.parent) then
return
end
if not vim.api.nvim_win_is_valid(self.win) then
return
end
local item = self:current_item()
if not item then
return
end
if item.bufnr == 0 then
return
end
util.debug("preview")
if item.is_file ~= true then
vim.api.nvim_win_set_buf(self.parent, item.bufnr)
local pos = { item.start.line + 1, item.start.character }
local line_count = vim.api.nvim_buf_line_count(item.bufnr)
pos[1] = math.min(pos[1], line_count)
vim.api.nvim_win_set_cursor(self.parent, pos)
vim.api.nvim_buf_call(item.bufnr, function()
-- Center preview line on screen and open enough folds to show it
vim.cmd("norm! zz zv")
if not vim.api.nvim_buf_is_loaded(item.bufnr) then
vim.fn.bufload(item.bufnr)
end
end)
clear_hl(item.bufnr)
hl_bufs[item.bufnr] = true
for row = item.start.line, item.finish.line, 1 do
local col_start = 0
local col_end = -1
if row == item.start.line then
col_start = item.start.character
end
if row == item.finish.line then
col_end = item.finish.character
end
highlight(item.bufnr, config.namespace, "TroublePreview", row, col_start, col_end)
end
end
end
-- View.preview = View._preview
View.preview = util.throttle(50, View._preview)
function View:open_code_href()
if not vim.api.nvim_win_is_valid(self.parent) then
return
end
local item = self:current_item()
if not item then
return
end
util.debug("open code href")
if item.is_file ~= true and item.code_href then
local cmd
if vim.fn.has("win32") == 1 then
cmd = "explorer"
elseif vim.fn.executable("xdg-open") == 1 then
cmd = "xdg-open"
elseif vim.fn.executable("wslview") == 1 then
cmd = "wslview"
else
cmd = "open"
end
local ret = vim.fn.jobstart({ cmd, item.code_href }, { detach = true })
if ret <= 0 then
local msg = {
"Failed to open code href",
ret,
vim.inspect(cmd),
}
vim.notify(table.concat(msg, "\n"), vim.log.levels.ERROR)
end
end
end
return View

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 KiB

View File

@ -1,21 +0,0 @@
augroup Trouble
autocmd!
if has('nvim-0.6')
" Use the new diagnostic subsystem for neovim 0.6 and up
au DiagnosticChanged * lua require'trouble'.refresh({auto = true, provider = "diagnostics"})
else
au User LspDiagnosticsChanged lua require'trouble'.refresh({auto = true, provider = "diagnostics"})
endif
autocmd BufWinEnter,BufEnter * lua require("trouble").action("on_win_enter")
augroup end
function! s:complete(arg,line,pos) abort
return join(sort(luaeval('vim.tbl_keys(require("trouble.providers").providers)')), "\n")
endfunction
command! -nargs=* -complete=custom,s:complete Trouble lua require'trouble'.open(<f-args>)
command! -nargs=* -complete=custom,s:complete TroubleToggle lua require'trouble'.toggle(<f-args>)
command! TroubleClose lua require'trouble'.close()
command! TroubleRefresh lua require'trouble'.refresh()

View File

@ -1 +1,4 @@
std="lua51+vim"
std = "vim"
[lints]
mixed_table = "allow"

View File

@ -1,3 +1,6 @@
indent_type = "Spaces"
indent_width = 2
column_width = 120
column_width = 120
[sort_requires]
enabled = true

View File

@ -1,2 +1,49 @@
[selene]
base = "lua51"
name = "vim"
[vim]
any = true
[jit]
any = true
[[describe.args]]
type = "string"
[[describe.args]]
type = "function"
[[it.args]]
type = "string"
[[it.args]]
type = "function"
[[before_each.args]]
type = "function"
[[after_each.args]]
type = "function"
[assert.is_not]
any = true
[[assert.equals.args]]
type = "any"
[[assert.equals.args]]
type = "any"
[[assert.equals.args]]
type = "any"
required = false
[[assert.same.args]]
type = "any"
[[assert.same.args]]
type = "any"
[[assert.truthy.args]]
type = "any"
[[assert.spy.args]]
type = "any"
[[assert.stub.args]]
type = "any"