saghen/blink.indent

github github
formattingindent
stars 107
issues 4
subscribers 1
forks 5
CREATED

UPDATED


blink.indent provides indent guides with scope on every keystroke (0.1-2ms per render), including on massive files, in 700 LoC. These indent guides work in the vast majority of valid code and compute quicker (10x) than via Treesitter. If you want something more feature rich, consider using indent-blankline instead.

code from frizbee

Install

-- lazy.nvim
{
  'saghen/blink.indent',
  --- @module 'blink.indent'
  --- @type blink.indent.Config
  -- opts = {},
}

-- vim.pack
vim.pack.add({ 'saghen/blink.indent' })
-- require('blink.indent').setup({})

Options

Note that calling setup() is optional, as the plugin will automatically initialize with the default configuration.

Disable with vim.g.indent_guide = false (global) or vim.b[bufnr].indent_guide = false (per-buffer). Some filetypes and buftypes are disabled by default, see below. You may also create a keymap to toggle visibility like so:

local indent = require('blink.indent')
vim.keymap.set('n', 'some-key', function() indent.enable(not indent.is_enabled()) end, { desc = 'Toggle indent guides' })

or toggle on a per-buffer basis with indent.enable(not indent.is_enabled({ bufnr = 0 }), { bufnr = 0 }).

require('blink.indent').setup({
  blocked = {
    -- default: 'terminal', 'quickfix', 'nofile', 'prompt'
    buftypes = { include_defaults = true },
    -- default: 'lspinfo', 'packer', 'checkhealth', 'help', 'man', 'gitcommit', 'dashboard', ''
    filetypes = { include_defaults = true },
  },
  mappings = {
    -- which lines around the scope are included for 'ai': 'top', 'bottom', 'both', or 'none'
    border = 'both',
    -- set to '' to disable
    -- textobjects (e.g. `y2ii` to yank current and outer scope)
    object_scope = 'ii',
    object_scope_with_border = 'ai',
    -- motions
    goto_top = '[i',
    goto_bottom = ']i',
  },
  static = {
    enabled = true,
    char = '▎',
    priority = 1,
    -- specify multiple highlights here for rainbow-style indent guides
    -- highlights = { 'BlinkIndentRed', 'BlinkIndentOrange', 'BlinkIndentYellow', 'BlinkIndentGreen', 'BlinkIndentViolet', 'BlinkIndentCyan' },
    highlights = { 'BlinkIndent' },
  },
  scope = {
    enabled = true,
    char = '▎',
    priority = 1000,
    -- set this to a single highlight, such as 'BlinkIndent' to disable rainbow-style indent guides
    -- highlights = { 'BlinkIndentScope' },
    -- optionally add: 'BlinkIndentRed', 'BlinkIndentCyan', 'BlinkIndentYellow', 'BlinkIndentGreen'
    highlights = { 'BlinkIndentOrange', 'BlinkIndentViolet', 'BlinkIndentBlue' },
    -- enable to show underlines on the line above the current scope
    underline = {
      enabled = false,
      -- optionally add: 'BlinkIndentRedUnderline', 'BlinkIndentCyanUnderline', 'BlinkIndentYellowUnderline', 'BlinkIndentGreenUnderline'
      highlights = { 'BlinkIndentOrangeUnderline', 'BlinkIndentVioletUnderline', 'BlinkIndentBlueUnderline' },
    },
  },
})

Performance

To compare the performance to indent-blankline, I monkey patched the draw/refresh code of both projects, enabling each separately to compare. On my machine, blink.indent took ~0.2ms per render while indent-blankline took ~2-5ms.

local refresh = require('ibl').refresh
require('ibl').refresh = function(...)
  local start_time = vim.loop.hrtime()
  refresh(...)
  local end_time = vim.loop.hrtime()
  print(string.format('indent-blankline.nvim: %.2fms', (end_time - start_time) / 1e6))
end

local draw = require('blink.indent').draw
require('blink.indent').draw = function(...)
  local start_time = vim.loop.hrtime()
  draw(...)
  local end_time = vim.loop.hrtime()
  print(string.format('blink.indent: %.2fms', (end_time - start_time) / 1e6))
end