Home

Awesome

<!-- panvimdoc-ignore-start --> <details> <summary>⚠️ Coming from <strong>symbols-outline.nvim</strong>?</summary>

This is a fork of the original symbols-outline.nvim with many fixes and improvements, you can see the full list in #12 on github with links to issues from the original repo, and after outline.nvim was detached as a fork, all changes are documented in the changelog.

Migrating your configuration

If you have existing setup opts for symbols-outline.nvim, you can convert it to be usable for outline.nvim using this script: scripts/convert-symbols-outline-opts.lua.

</details> <!-- panvimdoc-ignore-end -->
<!-- panvimdoc-ignore-start -->

outline.nvim

A sidebar with a tree-like outline of symbols from your code, powered by LSP.

https://github.com/hedyhli/outline.nvim/assets/50042066/f66fa661-b66a-4b48-84e8-37920a3d8d2c

Features

Still not sure whether to use this? Read about related plugins.

<!-- panvimdoc-ignore-end -->

Prerequisites

<!-- panvimdoc-ignore-start -->

Contents

<!-- mtoc-start --> <!-- mtoc-end --> <!-- panvimdoc-ignore-end -->

Installation

Lazy.nvim example:

{
  "hedyhli/outline.nvim",
  config = function()
    -- Example mapping to toggle outline
    vim.keymap.set("n", "<leader>o", "<cmd>Outline<CR>",
      { desc = "Toggle Outline" })

    require("outline").setup {
      -- Your setup opts here (leave empty to use defaults)
    }
  end,
},

Lazy.nvim with lazy-loading example:

{
  "hedyhli/outline.nvim",
  lazy = true,
  cmd = { "Outline", "OutlineOpen" },
  keys = { -- Example mapping to toggle outline
    { "<leader>o", "<cmd>Outline<CR>", desc = "Toggle outline" },
  },
  opts = {
    -- Your setup opts here
  },
},

This allows Lazy.nvim to lazy-load the plugin on commands Outline, OutlineOpen, and your keybindings.

Setup

Call the setup function with your configuration options.

Note that a call to .setup() is required for this plugin to work (otherwise you might see this error: simrat39/symbols-outline.nvim#213).

require("outline").setup({})

Skip to commands

Configuration

The configuration structure has been heavily improved and refactored in this plugin. If you're migrating from the original symbols-outline, see #12 on github under "breaking changes" section.

Terminology

Check this list if you have any confusion with the terms used in the configuration.

Skip to commands

Default options

Pass a table to the setup call with your configuration options.

<details><summary>Show defaults</summary>
{
  outline_window = {
    -- Where to open the split window: right/left
    position = 'right',
    -- The default split commands used are 'topleft vs' and 'botright vs'
    -- depending on `position`. You can change this by providing your own
    -- `split_command`.
    -- `position` will not be considered if `split_command` is non-nil.
    -- This should be a valid vim command used for opening the split for the
    -- outline window. Eg, 'rightbelow vsplit'.
    -- Width can be included (with will override the width setting below):
    -- Eg, `topleft 20vsp` to prevent a flash of windows when resizing.
    split_command = nil,

    -- Percentage or integer of columns
    width = 25,
    -- Whether width is relative to the total width of nvim
    -- When relative_width = true, this means take 25% of the total
    -- screen width for outline window.
    relative_width = true,

    -- Auto close the outline window if goto_location is triggered and not for
    -- peek_location
    auto_close = false,
    -- Automatically scroll to the location in code when navigating outline window.
    auto_jump = false,
    -- boolean or integer for milliseconds duration to apply a temporary highlight
    -- when jumping. false to disable.
    jump_highlight_duration = 300,
    -- Whether to center the cursor line vertically in the screen when
    -- jumping/focusing. Executes zz.
    center_on_jump = true,

    -- Vim options for the outline window
    show_numbers = false,
    show_relative_numbers = false,
    wrap = false,

    -- true/false/'focus_in_outline'/'focus_in_code'.
    -- The last two means only show cursorline when the focus is in outline/code.
    -- 'focus_in_outline' can be used if the outline_items.auto_set_cursor
    -- operations are too distracting due to visual contrast caused by cursorline.
    show_cursorline = true,
    -- Enable this only if you enabled cursorline so your cursor color can
    -- blend with the cursorline, in effect, as if your cursor is hidden
    -- in the outline window.
    -- This makes your line of cursor have the same color as if the cursor
    -- wasn't focused on the outline window.
    -- This feature is experimental.
    hide_cursor = false,

    -- Whether to auto-focus on the outline window when it is opened.
    -- Set to false to *always* retain focus on your previous buffer when opening
    -- outline.
    -- If you enable this you can still use bangs in :Outline! or :OutlineOpen! to
    -- retain focus on your code. If this is false, retaining focus will be
    -- enforced for :Outline/:OutlineOpen and you will not be able to have the
    -- other behaviour.
    focus_on_open = true,
    -- Winhighlight option for outline window.
    -- See :help 'winhl'
    -- To change background color to "CustomHl" for example, use "Normal:CustomHl".
    winhl = '',
  },

  outline_items = {
    -- Show extra details with the symbols (lsp dependent) as virtual next
    show_symbol_details = true,
    -- Show corresponding line numbers of each symbol on the left column as
    -- virtual text, for quick navigation when not focused on outline.
    -- Why? See this comment:
    -- https://github.com/simrat39/symbols-outline.nvim/issues/212#issuecomment-1793503563
    show_symbol_lineno = false,
    -- Whether to highlight the currently hovered symbol and all direct parents
    highlight_hovered_item = true,
    -- Whether to automatically set cursor location in outline to match
    -- location in code when focus is in code. If disabled you can use
    -- `:OutlineFollow[!]` from any window or `<C-g>` from outline window to
    -- trigger this manually.
    auto_set_cursor = true,
    -- Autocmd events to automatically trigger these operations.
    auto_update_events = {
      -- Includes both setting of cursor and highlighting of hovered item.
      -- The above two options are respected.
      -- This can be triggered manually through `follow_cursor` lua API,
      -- :OutlineFollow command, or <C-g>.
      follow = { 'CursorMoved' },
      -- Re-request symbols from the provider.
      -- This can be triggered manually through `refresh_outline` lua API, or
      -- :OutlineRefresh command.
      items = { 'InsertLeave', 'WinEnter', 'BufEnter', 'BufWinEnter', 'TabEnter', 'BufWritePost' },
    },
  },

  -- Options for outline guides which help show tree hierarchy of symbols
  guides = {
    enabled = true,
    markers = {
      -- It is recommended for bottom and middle markers to use the same number
      -- of characters to align all child nodes vertically.
      bottom = '└',
      middle = '├',
      vertical = '│',
    },
  },

  symbol_folding = {
    -- Depth past which nodes will be folded by default. Set to false to unfold all on open.
    autofold_depth = 1,
    -- When to auto unfold nodes
    auto_unfold = {
      -- Auto unfold currently hovered symbol
      hovered = true,
      -- Auto fold when the root level only has this many nodes.
      -- Set true for 1 node, false for 0.
      only = true,
    },
    markers = { '', '' },
  },

  preview_window = {
    -- Automatically open preview of code location when navigating outline window
    auto_preview = false,
    -- Automatically open hover_symbol when opening preview (see keymaps for
    -- hover_symbol).
    -- If you disable this you can still open hover_symbol using your keymap
    -- below.
    open_hover_on_preview = false,
    width = 50,     -- Percentage or integer of columns
    min_width = 50, -- This is the number of columns
    -- Whether width is relative to the total width of nvim.
    -- When relative_width = true, this means take 50% of the total
    -- screen width for preview window, ensure the result width is at least 50
    -- characters wide.
    relative_width = true,
    -- Border option for floating preview window.
    -- Options include: single/double/rounded/solid/shadow or an array of border
    -- characters.
    -- See :help nvim_open_win() and search for "border" option.
    border = 'single',
    -- winhl options for the preview window, see ':h winhl'
    winhl = 'NormalFloat:',
    -- Pseudo-transparency of the preview window, see ':h winblend'
    winblend = 0,
    -- Experimental feature that let's you edit the source content live
    -- in the preview window. Like VS Code's "peek editor".
    live = false
  },

  -- These keymaps can be a string or a table for multiple keys.
  -- Set to `{}` to disable. (Using 'nil' will fallback to default keys)
  keymaps = {
    show_help = '?',
    close = {'<Esc>', 'q'},
    -- Jump to symbol under cursor.
    -- It can auto close the outline window when triggered, see
    -- 'auto_close' option above.
    goto_location = '<Cr>',
    -- Jump to symbol under cursor but keep focus on outline window.
    peek_location = 'o',
    -- Visit location in code and close outline immediately
    goto_and_close = '<S-Cr>',
    -- Change cursor position of outline window to match current location in code.
    -- 'Opposite' of goto/peek_location.
    restore_location = '<C-g>',
    -- Open LSP/provider-dependent symbol hover information
    hover_symbol = '<C-space>',
    -- Preview location code of the symbol under cursor
    toggle_preview = 'K',
    rename_symbol = 'r',
    code_actions = 'a',
    -- These fold actions are collapsing tree nodes, not code folding
    fold = 'h',
    unfold = 'l',
    fold_toggle = '<Tab>',
    -- Toggle folds for all nodes.
    -- If at least one node is folded, this action will fold all nodes.
    -- If all nodes are folded, this action will unfold all nodes.
    fold_toggle_all = '<S-Tab>',
    fold_all = 'W',
    unfold_all = 'E',
    fold_reset = 'R',
    -- Move down/up by one line and peek_location immediately.
    -- You can also use outline_window.auto_jump=true to do this for any
    -- j/k/<down>/<up>.
    down_and_jump = '<C-j>',
    up_and_jump = '<C-k>',
  },

  providers = {
    priority = { 'lsp', 'coc', 'markdown', 'norg' },
    -- Configuration for each provider (3rd party providers are supported)
    lsp = {
      -- Lsp client names to ignore
      blacklist_clients = {},
    },
    markdown = {
      -- List of supported ft's to use the markdown provider
      filetypes = {'markdown'},
    },
  },

  symbols = {
    -- Filter by kinds (string) for symbols in the outline.
    -- Possible kinds are the Keys in the icons table below.
    -- A filter list is a string[] with an optional exclude (boolean) field.
    -- The symbols.filter option takes either a filter list or ft:filterList
    -- key-value pairs.
    -- Put  exclude=true  in the string list to filter by excluding the list of
    -- kinds instead.
    -- Include all except String and Constant:
    --   filter = { 'String', 'Constant', exclude = true }
    -- Only include Package, Module, and Function:
    --   filter = { 'Package', 'Module', 'Function' }
    -- See more examples below.
    filter = nil,

    -- You can use a custom function that returns the icon for each symbol kind.
    -- This function takes a kind (string) as parameter and should return an
    -- icon as string.
    ---@param kind string Key of the icons table below
    ---@param bufnr integer Code buffer
    ---@returns string|boolean The icon string to display, such as "f", or `false`
    ---                        to fallback to `icon_source`.
    icon_fetcher = nil,
    -- 3rd party source for fetching icons. This is used as a fallback if
    -- icon_fetcher returned an empty string.
    -- Currently supported values: 'lspkind'
    icon_source = nil,
    -- The next fallback if both icon_fetcher and icon_source has failed, is
    -- the custom mapping of icons specified below. The icons table is also
    -- needed for specifying hl group.
    icons = {
      File = { icon = '󰈔', hl = 'Identifier' },
      Module = { icon = '󰆧', hl = 'Include' },
      Namespace = { icon = '󰅪', hl = 'Include' },
      Package = { icon = '󰏗', hl = 'Include' },
      Class = { icon = '𝓒', hl = 'Type' },
      Method = { icon = 'ƒ', hl = 'Function' },
      Property = { icon = '', hl = 'Identifier' },
      Field = { icon = '󰆨', hl = 'Identifier' },
      Constructor = { icon = '', hl = 'Special' },
      Enum = { icon = 'ℰ', hl = 'Type' },
      Interface = { icon = '󰜰', hl = 'Type' },
      Function = { icon = '', hl = 'Function' },
      Variable = { icon = '', hl = 'Constant' },
      Constant = { icon = '', hl = 'Constant' },
      String = { icon = '𝓐', hl = 'String' },
      Number = { icon = '#', hl = 'Number' },
      Boolean = { icon = '⊨', hl = 'Boolean' },
      Array = { icon = '󰅪', hl = 'Constant' },
      Object = { icon = '⦿', hl = 'Type' },
      Key = { icon = '🔐', hl = 'Type' },
      Null = { icon = 'NULL', hl = 'Type' },
      EnumMember = { icon = '', hl = 'Identifier' },
      Struct = { icon = '𝓢', hl = 'Structure' },
      Event = { icon = '🗲', hl = 'Type' },
      Operator = { icon = '+', hl = 'Identifier' },
      TypeParameter = { icon = '𝙏', hl = 'Identifier' },
      Component = { icon = '󰅴', hl = 'Function' },
      Fragment = { icon = '󰅴', hl = 'Constant' },
      TypeAlias = { icon = ' ', hl = 'Type' },
      Parameter = { icon = ' ', hl = 'Identifier' },
      StaticMethod = { icon = ' ', hl = 'Function' },
      Macro = { icon = ' ', hl = 'Function' },
    },
  },
}
</details>

To find out exactly what some of the options do, please see the recipes section at the bottom for screen-recordings/shots.

Symbols table

filter

Include all symbols except kinds String and Variable:

symbols.filter = { 'String', 'Variable', exclude=true }

Include only Function symbols:

symbols.filter = { 'Function' }

Per-filetype filtering example:

symbols.filter = {
  default = { 'String', exclude=true },
  python = { 'Function', 'Class' },
}

Note how the python filter list and the default filter list is NOT merged.

Setting any filter list to nil or false means include all symbols, where a filter list is an array of strings with an optional exclude field.

icons

The order in which the sources for icons are checked is:

  1. Icon fetcher function
  2. Icon source (only lspkind is supported for this option as of now)
  3. Icons table

A fallback is always used if the previous candidate returned a falsey value.

Providers

The current list of tested providers are:

  1. LSP (requires a suitable LSP server to be configured for the requested buffer)
    • For JSX support, javascript parser for treesitter is required
  2. Markdown (no external requirements)
  3. Norg (requires norg parser for treesitter)

External providers:

<details> <summary>How to implement an external provider</summary>

External providers are separate plugins that users can install in addition to outline.nvim. Their names can be appended to the providers.priority list in the outline.nvim config. Each item in the providers.priority list is used to form an import path "outline.providers.<item>" and then require()'ed for use as a provider.

External providers from plugins should define the provider module at lua/outline/providers/<name>.lua with these functions:

The built-in markdown provider is a good example of a very simple outline-provider module which parses raw buffer lines and uses regex; the built-in norg provider is an example which uses treesitter.

All providers should support at least nvim 0.7. You can make use of _G._outline_nvim_has with fields [8], [9], and [10]. For instance, _G._outline_nvim_has[8] is equivalent to: vim.fn.has('nvim-0.8') == 1.

If a higher nvim version is required, it is recommended to check for this requirement in the supports_buffer function.

Hover symbol, code action and rename functions are defined from providers. You can customize what these functions do if these functions are triggered when your provider is active. See the built-in LSP provider for an example.

Other functions such as goto-location may also be delegated to providers in the future.

</details>

Commands

" in config: position='right'
:topleft Outline     " opens with 'topleft vsplit'
:belowright Outline  " opens with 'belowright vsplit'
:Outline             " opens with 'botright vsplit'
" in config: position='left'
:aboveleft OutlineOpen   " opens with 'aboveleft vsplit'
:belowright OutlineOpen  " opens with 'belowright vsplit'
:OutlineOpen             " opens with 'topleft vsplit'

If the outline is already open, running this command without bang will focus on the outline window.

Default keymaps

These mappings are active only for the outline window.

You can open a floating window showing the following list of keymaps using the ? key by default from the outline window.

KeyAction
Esc / qClose outline
EnterGo to symbol location in code
oGo to symbol location in code without losing focus
Shift+EnterGo to symbol location in code and close outline
Ctrl+gUpdate outline window to focus on code location
KToggles the current symbol preview
Ctrl+SpaceHover current symbol (provider action)
rRename symbol
aCode actions
hFold symbol or parent symbol
TabToggle fold under cursor
Shift+TabToggle all folds
lUnfold symbol
WFold all symbols
EUnfold all symbols
RReset all folding
Ctrl+kGo up and peek location
Ctrl+jGo down and peek location
?Show current keymaps in a floating window

If you frequently use horizontal splits and need <C-k/j> to navigate them, you may want to remap:

keymaps = {
  up_and_jump = '<C-p>',
  down_and_jump = '<C-n>',
}

Or if you never use arrow keys to move around, you can use:

keymaps = {
  up_and_jump = '<up>',
  down_and_jump = '<down>',
}

Highlights

Outline window

Default:

outline_window = {
  winhl = '',
},

Possible highlight groups for the outline window:

HighlightDescription
OutlineCurrentCurrent symbol under cursor
OutlineGuidesGuide markers section in each line of the outline
OutlineFoldMarkerFold markers in the outline
OutlineDetailsSymbol details in virtual text
OutlineLinenoThe Lineno column virtual text

You can customize any other highlight groups using winhl, this option is passed directly to the winhl vim option unprocessed.

If any of the above highlights have not already been set before outline.setup is called (say by a theme), the following links are used:

HighlightLink
OutlineGuidesComment
OutlineFoldMarkerNormal
OutlineDetailsComment
OutlineLinenoLineNr

For OutlineCurrent, foreground is set to String and background CursorLine.

To customize colors of the symbol icons, use the symbols.icons table. See config.

Preview window

preview_window = {
  winhl = 'NormalFloat:',
},

Help windows

HighlightLink
OutlineHelpTipComment
OutlineStatusFtType
OutlineStatusErrorErrorMsg
OutlineStatusProviderSpecial
OutlineKeymapHelpKeySpecial
OutlineKeymapHelpDisabledComment

Help windows include:

  1. the keymap help from pressing ? in the outline window
  2. :OutlineStatus

Other highlight groups

HighlightDescription
OutlineJumpHighlightIndicating cursor position when jumping/focusing, defaults to Visual

You can also use outline_window.jump_highlight_duration to customize in milliseconds, how long the highlight is applied for.

Lua API

Outline.nvim provides the following public API for use in lua.

require'outline'

Tips

symbols = {
  icon_fetcher = function(k)
    if k == 'Package' then
      return ""
    end
    return false
  end,
  icon_source = 'lspkind',
}

The icon_fetcher function may also accept a second parameter, the buffer number of the code buffer. For example, you can use it to determine the icon to use based on the filetype.

symbols = {
  icon_fetcher = function(kind, bufnr)
    local ft = vim.api.nvim_buf_get_option(bufnr, 'ft')
    -- ...
  end,
}

See this section for other examples of this function.

Recipes

Behaviour you may want to achieve and the combination of configuration options to achieve it.

Code snippets in this section are to be placed in .setup({ <HERE> }) directly unless specified otherwise.

Unfold others

(Now a default behaviour, different to symbols-outline.nvim.)

Unfold all others except currently hovered item.

symbol_folding = {
  autofold_depth = 1,
  auto_unfold = {
    hovered = true,
  },
},
<div align=center><img width="900" alt="outline window showing auto fold depth" src="https://github.com/hedyhli/outline.nvim/assets/50042066/2e0c5f91-a979-4e64-a100-256ad062dce3"></div>

Unfold entire symbol tree by default

symbol_folding = {
  autofold_depth = false,
},

Auto-unfold when there's only two (or any number of) root nodes

symbol_folding = {
  auto_unfold = {
    only = 2,
  },
},

auto_unfold.only = 2:

https://github.com/hedyhli/outline.nvim/assets/50042066/035fadac-ecee-4427-9ee1-795dac215cea

auto_unfold.only = 1:

https://github.com/hedyhli/outline.nvim/assets/50042066/3a123b7e-ccf6-4278-9a8c-41d2e1865d83

In words "auto unfold nodes when there is only 2 nodes shown in the outline."

For auto_unfold.only = true: "auto unfold nodes when the root node is the only node left visible in the outline."

Auto-jump

Use outline window as a quick-jump window

preview_window = {
  auto_preview = true,
},

https://github.com/hedyhli/outline.nvim/assets/50042066/a473d791-d1b9-48e9-917f-b816b564a645

Note that auto-resizing of the preview window is only enabled for auto-preview. Otherwise, close and reopen the preview after resizing the code window.

https://github.com/hedyhli/outline.nvim/assets/50042066/b7f6d2b6-98b3-4557-8143-e49583e99d3b

Alternatively, if you want to automatically navigate to the corresponding code location directly and not use the preview window:

outline_window = {
  auto_jump = true,
},

https://github.com/hedyhli/outline.nvim/assets/50042066/3d06e342-97ac-400c-8598-97a9235de66c

Or, you can use keys <C-j> and <C-k> to achieve the same effect, whilst not having auto_jump on by default.

Symbol details

Hide the extra details after each symbol name

outline_items = {
  show_symbol_details = false,
},

You can customize its highlight group by setting OutlineDetails in outline_window.winhl.

Line numbers

Show line numbers next to each symbol to jump to that symbol quickly

outline_items = {
  show_symbol_lineno = true,
},

The default highlight group for the line numbers is LineNr, you can customize it using outline_window.winhl: please see highlights.

<div align=center><img width="900" alt="outline window showing lineno" src="https://github.com/hedyhli/outline.nvim/assets/50042066/2bbb5833-f40b-4c53-8338-407252d61443"></div>

Blend cursor with cursorline

Hide the cursor within cursorline. This setting changes the cursor color to be that of Cursorline when focus is in outline window. As of now guicursor is a global option, so outline.nvim has to set and reset responsibly hence this feature may be unstable. You can inspect require('outline').state.original_cursor and set guicursor accordingly, though you should almost never need to do this.

outline_window = {
  show_cursorline = true,
  hide_cursor = true,
}

This will be how the outline window looks like when focused:

<div align=center><img width="500" alt="outline window showing another example of hide_cursor" src="https://github.com/hedyhli/outline.nvim/assets/50042066/527c567b-a777-4518-a9da-51d8bcb445e7"></div>

Some may find this unhelpful, but one may argue that elements in each row of the outline becomes more readable this way, hence this is an option.

Custom icons

You can write your own function for fetching icons. Here is one such example that simply returns in plain text, the first letter of the given kind.

symbols = {
  icon_fetcher = function(kind, bufnr) return kind:sub(1,1) end,
}

The fetcher function, if provided, is checked first before using icon_source and icons as fallback.

<div align=center><img width="500" alt="outline with plain text icons" src="https://github.com/hedyhli/outline.nvim/assets/50042066/655b534b-da16-41a7-926e-f14475376a04"></div>

Different icons based on filetype

symbols = {
  icon_fetcher = function(kind, bufnr)
    local ft = vim.api.nvim_buf_get_option(bufnr, 'ft')
    -- ...
  end,
}

Disable icons

Disable all icons:

symbols = {
  icon_fetcher = function() return "" end,
}

Disable icons for specific kinds, and for others use lspkind:

symbols = {
  icon_fetcher = function(k, buf)
    if k == 'String' then
      return ""
    end
    return false
  end,
  icon_source = 'lspkind',
}
<div align=center><img width="500" alt="outline with disabled icon for String" src="https://github.com/hedyhli/outline.nvim/assets/50042066/26d258c6-9530-43d4-b88b-963304e3bf2d"></div>

Disable icons for a specific filetype

In this example, icons are disabled for markdown, and lspkind is used for other filetypes.

symbols = {
  icon_fetcher = function(k, buf)
    local ft = vim.api.nvim_buf_get_option(buf, "ft")
    if ft == 'markdown' then
      return ""
    end
    return false
  end,
  icon_source = "lspkind",
}

Live, editable previews

Press K to open the preview, press K again to focus on the preview window to make any quick edits, similar to VS Code's reference window "peek editor".

Then use :q to close the window, and continue browsing the outline.

preview_window = {
  live = true,
}

Note that this feature is experimental and may be unstable.

https://github.com/hedyhli/outline.nvim/assets/50042066/183fc5f9-b369-41e2-a831-a4185704d76d

Auto-preview with the feature is also supported, set auto_preview = true and press K to focus on the auto-opened preview window. :q to quit the window.

<!-- panvimdoc-ignore-start -->

Any other recipes you think others may also find useful? Feel free to open a PR.

<!-- panvimdoc-ignore-end -->

Neovim 0.7

The following features and fixes are not included in Neovim 0.7.

Limitations

Preview window

Sometimes the preview window could be slow in loading. This could be due to the code buffer being large. As of now there are no good solutions in circumventing this problem — currently the entire code buffer is read, and then put into the preview buffer. If only the required portion to preview is read and set instead, there would be highlighting issues (say the calculated starting line was within a markdown code block, so what was previously not supposed to be code is now highlighted as code).

If this poses a problem for you, you should try out the live-preview feature, which uses the code buffer directly for displaying the preview.

Many outlines

Outline.nvim supports opening independent outline windows for different tabpages, but does not support multiple outline windows in the same tabpage as of now. However, this feature is planned. Alternatively, you can use a single outline that auto-updates on buffer switches, which is turned on by default.

Related plugins

<hr>

If you've read this much, maybe you should subscribe to the breaking changes announcements to get updates when there are breaking changes. It's low-volume, I promise ;)