- Notifications
You must be signed in to change notification settings - Fork103
Neovim plugin for a code outline window
License
stevearc/aerial.nvim
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A code outline window for skimming and quick navigation
- Requirements
- Installation
- Setup
- Commands
- Options
- Third-party integrations
- Highlight
- API
- TreeSitter queries
- FAQ
aerial.mp4
- Neovim 0.9+ (for older versions, use anvim-0.x branch)
- One or more of the following:
- A working LSP setup (seenvim-lspconfig)
- Tree-sitter parsers
aerial supports all the usual plugin managers
lazy.nvim
{'stevearc/aerial.nvim',opts= {},-- Optional dependenciesdependencies= {"nvim-treesitter/nvim-treesitter","nvim-tree/nvim-web-devicons" },}Packer
require("packer").startup(function()use({"stevearc/aerial.nvim",config=function()require("aerial").setup()end, })end)
Paq
require("paq")({ {"stevearc/aerial.nvim"},})
vim-plug
Plug'stevearc/aerial.nvim'dein
calldein#add('stevearc/aerial.nvim')
Pathogen
git clone --depth=1 https://github.com/stevearc/aerial.nvim.git~/.vim/bundle/Neovim native package
git clone --depth=1 https://github.com/stevearc/aerial.nvim.git \"${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/pack/aerial/start/aerial.nvimSomewhere in your init.lua you will need to callaerial.setup(). See below fora full list of options.
require("aerial").setup({-- optionally use on_attach to set keymaps when aerial has attached to a bufferon_attach=function(bufnr)-- Jump forwards/backwards with '{' and '}'vim.keymap.set("n","{","<cmd>AerialPrev<CR>", {buffer=bufnr })vim.keymap.set("n","}","<cmd>AerialNext<CR>", {buffer=bufnr })end,})-- You probably also want to set a keymap to toggle aerialvim.keymap.set("n","<leader>a","<cmd>AerialToggle!<CR>")
In addition, you will need to have either Treesitter or a working LSP client. You can configure your preferred source(s) with thebackends option (seeOptions). The default is to prefer Treesitter when it's available and fall back to LSP.
Supported treesitter languages
- bash
- c
- c_sharp
- cpp
- css
- dart
- djot
- editorconfig
- elixir
- enforce
- fish
- go
- groovy
- hcl
- help
- html
- ini
- java
- javascript
- json
- julia
- just
- latex
- lua
- make
- markdown
- norg
- nu
- objdump
- php
- proto
- python
- r
- rst
- ruby
- rust
- scala
- snakemake
- solidity
- ssh_config
- starlark
- swift
- teal
- terraform
- toml
- tsx
- typescript
- usd
- vim
- vimdoc
- vue
- xml
- yaml
- zig
Don't see your language here?Request support forit
| Command | Args | Description |
|---|---|---|
AerialToggle[!] | left/right/float | Open or close the aerial window. With! cursor stays in current window |
AerialOpen[!] | left/right/float | Open the aerial window. With! cursor stays in current window |
AerialOpenAll | Open an aerial window for each visible window. | |
AerialClose | Close the aerial window. | |
AerialCloseAll | Close all visible aerial windows. | |
[count]AerialNext | Jump forwards {count} symbols (default 1). | |
[count]AerialPrev | Jump backwards [count] symbols (default 1). | |
[count]AerialGo[!] | Jump to the [count] symbol (default 1). | |
AerialInfo | Print out debug info related to aerial. | |
AerialNavToggle | Open or close the aerial nav window. | |
AerialNavOpen | Open the aerial nav window. | |
AerialNavClose | Close the aerial nav window. |
-- Call the setup function to change the default behaviorrequire("aerial").setup({-- Priority list of preferred backends for aerial.-- This can be a filetype map (see :help aerial-filetype-map)backends= {"treesitter","lsp","markdown","asciidoc","man"},layout= {-- These control the width of the aerial window.-- They can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)-- min_width and max_width can be a list of mixed types.-- max_width = {40, 0.2} means "the lesser of 40 columns or 20% of total"max_width= {40,0.2 },width=nil,min_width=10,-- key-value pairs of window-local options for aerial window (e.g. winhl)win_opts= {},-- Determines the default direction to open the aerial window. The 'prefer'-- options will open the window in the other direction *if* there is a-- different buffer in the way of the preferred direction-- Enum: prefer_right, prefer_left, right, left, floatdefault_direction="prefer_right",-- Determines where the aerial window will be opened-- edge - open aerial at the far right/left of the editor-- window - open aerial to the right/left of the current windowplacement="window",-- When the symbols change, resize the aerial window (within min/max constraints) to fitresize_to_content=true,-- Preserve window size equality with (:help CTRL-W_=)preserve_equality=false, },-- Determines how the aerial window decides which buffer to display symbols for-- window - aerial window will display symbols for the buffer in the window from which it was opened-- global - aerial window will display symbols for the current windowattach_mode="window",-- List of enum values that configure when to auto-close the aerial window-- unfocus - close aerial when you leave the original source window-- switch_buffer - close aerial when you change buffers in the source window-- unsupported - close aerial when attaching to a buffer that has no symbol sourceclose_automatic_events= {},-- Keymaps in aerial window. Can be any value that `vim.keymap.set` accepts OR a table of keymap-- options with a `callback` (e.g. { callback = function() ... end, desc = "", nowait = true })-- Additionally, if it is a string that matches "actions.<name>",-- it will use the mapping at require("aerial.actions").<name>-- Set to `false` to remove a keymapkeymaps= { ["?"]="actions.show_help", ["g?"]="actions.show_help", ["<CR>"]="actions.jump", ["<2-LeftMouse>"]="actions.jump", ["<C-v>"]="actions.jump_vsplit", ["<C-s>"]="actions.jump_split", ["p"]="actions.scroll", ["<C-j>"]="actions.down_and_scroll", ["<C-k>"]="actions.up_and_scroll", ["{"]="actions.prev", ["}"]="actions.next", ["[["]="actions.prev_up", ["]]"]="actions.next_up", ["q"]="actions.close", ["o"]="actions.tree_toggle", ["za"]="actions.tree_toggle", ["O"]="actions.tree_toggle_recursive", ["zA"]="actions.tree_toggle_recursive", ["l"]="actions.tree_open", ["zo"]="actions.tree_open", ["L"]="actions.tree_open_recursive", ["zO"]="actions.tree_open_recursive", ["h"]="actions.tree_close", ["zc"]="actions.tree_close", ["H"]="actions.tree_close_recursive", ["zC"]="actions.tree_close_recursive", ["zr"]="actions.tree_increase_fold_level", ["zR"]="actions.tree_open_all", ["zm"]="actions.tree_decrease_fold_level", ["zM"]="actions.tree_close_all", ["zx"]="actions.tree_sync_folds", ["zX"]="actions.tree_sync_folds", },-- When true, don't load aerial until a command or function is called-- Defaults to true, unless `on_attach` is provided, then it defaults to falselazy_load=true,-- Disable aerial on files with this many linesdisable_max_lines=10000,-- Disable aerial on files this size or larger (in bytes)disable_max_size=2000000,-- Default 2MB-- A list of all symbols to display. Set to false to display all symbols.-- This can be a filetype map (see :help aerial-filetype-map)-- To see all available values, see :help SymbolKindfilter_kind= {"Class","Constructor","Enum","Function","Interface","Module","Method","Struct", },-- Determines line highlighting mode when multiple splits are visible.-- split_width Each open window will have its cursor location marked in the-- aerial buffer. Each line will only be partially highlighted-- to indicate which window is at that location.-- full_width Each open window will have its cursor location marked as a-- full-width highlight in the aerial buffer.-- last Only the most-recently focused window will have its location-- marked in the aerial buffer.-- none Do not show the cursor locations in the aerial window.highlight_mode="split_width",-- Highlight the closest symbol if the cursor is not exactly on one.highlight_closest=true,-- Highlight the symbol in the source buffer when cursor is in the aerial winhighlight_on_hover=false,-- When jumping to a symbol, highlight the line for this many ms.-- Set to false to disablehighlight_on_jump=300,-- Jump to symbol in source window when the cursor movesautojump=false,-- Define symbol icons. You can also specify "<Symbol>Collapsed" to change the-- icon when the tree is collapsed at that symbol, or "Collapsed" to specify a-- default collapsed icon. The default icon set is determined by the-- "nerd_font" option below.-- If you have lspkind-nvim installed, it will be the default icon set.-- This can be a filetype map (see :help aerial-filetype-map)icons= {},-- Control which windows and buffers aerial should ignore.-- Aerial will not open when these are focused, and existing aerial windows will not be updatedignore= {-- Ignore unlisted buffers. See :help buflistedunlisted_buffers=false,-- Ignore diff windows (setting to false will allow aerial in diff windows)diff_windows=true,-- List of filetypes to ignore.filetypes= {},-- Ignored buftypes.-- Can be one of the following:-- false or nil - No buftypes are ignored.-- "special" - All buffers other than normal, help and man page buffers are ignored.-- table - A list of buftypes to ignore. See :help buftype for the-- possible values.-- function - A function that returns true if the buffer should be-- ignored or false if it should not be ignored.-- Takes two arguments, `bufnr` and `buftype`.buftypes="special",-- Ignored wintypes.-- Can be one of the following:-- false or nil - No wintypes are ignored.-- "special" - All windows other than normal windows are ignored.-- table - A list of wintypes to ignore. See :help win_gettype() for the-- possible values.-- function - A function that returns true if the window should be-- ignored or false if it should not be ignored.-- Takes two arguments, `winid` and `wintype`.wintypes="special", },-- Use symbol tree for folding. Set to true or false to enable/disable-- Set to "auto" to manage folds if your previous foldmethod was 'manual'-- This can be a filetype map (see :help aerial-filetype-map)manage_folds=false,-- When you fold code with za, zo, or zc, update the aerial tree as well.-- Only works when manage_folds = truelink_folds_to_tree=false,-- Fold code when you open/collapse symbols in the tree.-- Only works when manage_folds = truelink_tree_to_folds=true,-- Set default symbol icons to use patched font icons (see https://www.nerdfonts.com/)-- "auto" will set it to true if nvim-web-devicons or lspkind-nvim is installed.nerd_font="auto",-- Call this function when aerial attaches to a buffer.on_attach=function(bufnr)end,-- Call this function when aerial first sets symbols on a buffer.on_first_symbols=function(bufnr)end,-- Automatically open aerial when entering supported buffers.-- This can be a function (see :help aerial-open-automatic)open_automatic=false,-- Run this command after jumping to a symbol (false will disable)post_jump_cmd="normal! zz",-- Invoked after each symbol is parsed, can be used to modify the parsed item,-- or to filter it by returning false.---- bufnr: a neovim buffer number-- item: of type aerial.Symbol-- ctx: a record containing the following fields:-- * backend_name: treesitter, lsp, man...-- * lang: info about the language-- * symbols?: specific to the lsp backend-- * symbol?: specific to the lsp backend-- * syntax_tree?: specific to the treesitter backend-- * match?: specific to the treesitter backend, TS query matchpost_parse_symbol=function(bufnr,item,ctx)returntrueend,-- Invoked after all symbols have been parsed and post-processed,-- allows to modify the symbol structure before final display---- bufnr: a neovim buffer number-- items: a collection of aerial.Symbol items, organized in a tree,-- with 'parent' and 'children' fields-- ctx: a record containing the following fields:-- * backend_name: treesitter, lsp, man...-- * lang: info about the language-- * symbols?: specific to the lsp backend-- * syntax_tree?: specific to the treesitter backendpost_add_all_symbols=function(bufnr,items,ctx)returnitemsend,-- When true, aerial will automatically close after jumping to a symbolclose_on_select=false,-- The autocmds that trigger symbols update (not used for LSP backend)update_events="TextChanged,InsertLeave",-- Show box drawing characters for the tree hierarchyshow_guides=false,-- Customize the characters used when show_guides = trueguides= {-- When the child item has a sibling below itmid_item="├─",-- When the child item is the last in the listlast_item="└─",-- When there are nested child guides to the rightnested_top="│",-- Raw indentationwhitespace="", },-- Set this function to override the highlight groups for certain symbolsget_highlight=function(symbol,is_icon,is_collapsed)-- return "MyHighlight" .. symbol.kindend,-- Options for opening aerial in a floating winfloat= {-- Controls border appearance. Passed to nvim_open_winborder="rounded",-- Determines location of floating window-- cursor - Opens float on top of the cursor-- editor - Opens float centered in the editor-- win - Opens float centered in the windowrelative="cursor",-- These control the height of the floating window.-- They can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)-- min_height and max_height can be a list of mixed types.-- min_height = {8, 0.1} means "the greater of 8 rows or 10% of total"max_height=0.9,height=nil,min_height= {8,0.1 },override=function(conf,source_winid)-- This is the config that will be passed to nvim_open_win.-- Change values here to customize the layoutreturnconfend, },-- Options for the floating nav windowsnav= {border="rounded",max_height=0.9,min_height= {10,0.1 },max_width=0.5,min_width= {0.2,20 },win_opts= {cursorline=true,winblend=10, },-- Jump to symbol in source window when the cursor movesautojump=false,-- Show a preview of the code in the right column, when there are no child symbolspreview=false,-- Keymaps in the nav windowkeymaps= { ["<CR>"]="actions.jump", ["<2-LeftMouse>"]="actions.jump", ["<C-v>"]="actions.jump_vsplit", ["<C-s>"]="actions.jump_split", ["h"]="actions.left", ["l"]="actions.right", ["<C-c>"]="actions.close", }, },lsp= {-- If true, fetch document symbols when LSP diagnostics update.diagnostics_trigger_update=false,-- Set to false to not update the symbols when there are LSP errorsupdate_when_errors=true,-- How long to wait (in ms) after a buffer change before updating-- Only used when diagnostics_trigger_update = falseupdate_delay=300,-- Map of LSP client name to priority. Default value is 10.-- Clients with higher (larger) priority will be used before those with lower priority.-- Set to -1 to never use the client.priority= {-- pyright = 10, }, },treesitter= {-- How long to wait (in ms) after a buffer change before updatingupdate_delay=300, },markdown= {-- How long to wait (in ms) after a buffer change before updatingupdate_delay=300, },asciidoc= {-- How long to wait (in ms) after a buffer change before updatingupdate_delay=300, },man= {-- How long to wait (in ms) after a buffer change before updatingupdate_delay=300, },})
All possible SymbolKind values can be foundin the LSPspec.These are the values used for configuring icons, highlight groups, andfiltering.
Theaerial.Symbol type used in some optional callbacks is:
{kind:SymbolKind,name:string,level:number,parent:aerial.Symbol,lnum:number,end_lnum:number,col:number,end_col:number}
If you havesnacks.nvim installed, you can use the picker to find and jump to symbols.
require("aerial").snacks_picker()
You can pass in an options table that will get sent toSnacks.picker.pick directly. Use this to customize the display.
require("aerial").snacks_picker({layout= {preset="dropdown",preview=false, }})
If you havetelescopeinstalled, there is an extension for fuzzy finding and jumping to symbols. Itfunctions similarly to the builtinlsp_document_symbols picker, the maindifference being that it uses the aerial backend for the source (e.g. LSP,treesitter, etc) and that it filters out some symbols (see thefilter_kindoption).
You can activate the picker with:Telescope aerial or:lua require("telescope").extensions.aerial.aerial()
The extension can be customized with the following options:
require("telescope").setup({extensions= {aerial= {-- Set the width of the first two columns (the second-- is relevant only when show_columns is set to 'both')col1_width=4,col2_width=30,-- How to format the symbolsformat_symbol=function(symbol_path,filetype)iffiletype=="json"orfiletype=="yaml"thenreturntable.concat(symbol_path,".")elsereturnsymbol_path[#symbol_path]endend,-- Available modes: symbols, lines, bothshow_columns="both", }, },})
If you want the command to autocomplete, you can load the extension first (this line must come after the setup section from above):
require("telescope").load_extension("aerial")
If you havefzf-lua installed, you can use the picker to find and jump to symbols.It supports multi-select and uses the default actions from thefiles picker (e.g.<C-s> to open a symbol in a split).
require("aerial").fzf_lua_picker()
You can pass in an options table that will get sent torequire('fzf-lua').fzf_exec directly. Use this to customize the display.
require("aerial").fzf_lua_picker({profile='ivy',})
If you havefzf installed you can triggerfuzzy finding with:call aerial#fzf(). To create a mapping:
nmap<silent><leader>ds<cmd>call aerial#fzf()<cr>
There is a lualine component to display the symbols for your current cursorposition
require("lualine").setup({sections= {lualine_x= {"aerial"},-- Or you can customize itlualine_y= { {"aerial",-- The separator to be used to separate symbols in status line.sep=" )",-- The number of symbols to render top-down. In order to render only 'N' last-- symbols, negative numbers may be supplied. For instance, 'depth = -1' can-- be used in order to render only current symbol.depth=nil,-- When 'dense' mode is on, icons are not rendered near their symbols. Only-- a single icon that represents the kind of current symbol is rendered at-- the beginning of status line.dense=false,-- The separator to be used to separate symbols in dense mode.dense_sep=".",-- Color the symbol icons.colored=true, }, }, },})
There are highlight groups created for eachSymbolKind. There will be one forthe name of the symbol (Aerial<SymbolKind>, and one for the icon(Aerial<SymbolKind>Icon). For example:
hilinkAerialClassTypehilinkAerialClassIconSpecialhilinkAerialFunctionSpecialhi AerialFunctionIcon guifg=#cb4b16 guibg=NONE guisp=NONEgui=NONE cterm=NONE" There's also this group for the fallback of the text if a specific" class highlight isn't definedhilinkAerialNormalNormal" There's also this group for the cursor positionhilinkAerialLineQuickFixLine" If highlight_mode="split_width", you can set a separate color for the" non-current location highlighthi AerialLineNC guibg=Gray" You can customize the guides (if show_guide=true)hilinkAerialGuideComment" You can set a different guide color for each levelhi AerialGuide1 guifg=Redhi AerialGuide2 guifg=Blue
- setup(opts)
- sync_load()
- is_open(opts)
- close()
- close_all()
- close_all_but_current()
- open(opts)
- open_in_win(target_win, source_win)
- open_all()
- focus()
- toggle(opts)
- refetch_symbols(bufnr)
- select(opts)
- next(step)
- prev(step)
- next_up(count)
- prev_up(count)
- snacks_picker(opts)
- fzf_lua_picker(opts)
- get_location(exact)
- tree_close_all(bufnr)
- tree_open_all(bufnr)
- tree_set_collapse_level(bufnr, level)
- tree_increase_fold_level(bufnr, count)
- tree_decrease_fold_level(bufnr, count)
- tree_open(opts)
- tree_close(opts)
- tree_toggle(opts)
- nav_is_open()
- nav_open()
- nav_close()
- nav_toggle()
- treesitter_clear_query_cache()
- sync_folds(bufnr)
- info()
- num_symbols(bufnr)
- was_closed(default)
When writing queries, the following captures and metadata are used by Aerial:
@symbol-required capture for the logical region being capturedkind-required metadata, a string value matching one ofvim.lsp.protocol.SymbolKind@name- capture to extract a name from its text@start- a start of the match, influences matching of cursor position to aerial tree, defaults to@symbol@end- an end of the match, influences matching of cursor position to aerial tree, defaults to@start@selection- position to jump to when using Aerial for navigation, falls back to@nameand@symbol@scope- a node naming a scope for the match, its text is used to generate a custom "Comment" linked highlight for the entry, with exception of "public"A
@scopenode with text "developers" will result in its entry in the tree having an "AerialDevelopers" highlight applied to it.scope- a metadata value serving the same role as@scopecapture, overriding aforementioned capture
Note: a capture's text can be set or modified with#set! and#gsub! respectively.
Q: I accidentally opened a file into the aerial window and it looks bad. How can I prevent this from happening?
Try installingstickybuf. It was designed to prevent exactly this problem.
About
Neovim plugin for a code outline window
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.