Skip to content

Instantly share code, notes, and snippets.

@igorburago
Last active October 30, 2022 10:16
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save igorburago/734422 to your computer and use it in GitHub Desktop.
Save igorburago/734422 to your computer and use it in GitHub Desktop.
Vim indentation guides emulation
" Simple emulation of indentation guides.
"
" For tab-based indentation, using the 'listchars' option works fine.
" For space-based indentation, one can either:
" • use the match highlighting feature (see ':help match-highlight'),
" as shown in ToggleMatchHighlightIndentGuides(); or
" • use the 'leadmultispace' setting of the 'listchars' option (added
" in Vim 9.0), as shown in ToggleListCharsIndentGuides().
"
" The mapping for toggling indentation guides will look like
" nnoremap <silent> <leader><bar> :call ToggleMatchHighlightIndentGuides()<cr>
" or
" nnoremap <silent> <leader><bar> :call ToggleListCharsIndentGuides()<cr>
" respectively.
function! ToggleMatchHighlightIndentGuides()
if !exists('b:indent_guides_enabled')
if !&expandtab && &tabstop == &shiftwidth
let b:indent_guides_enabled = 'tabs'
let b:indent_guides_list_opt = &l:list
let b:indent_guides_listchars_opt = &l:listchars
exe 'setl listchars'..'+'[!&l:list]..'=tab:˙\ list'
else
let b:indent_guides_enabled = 'spaces'
let pos = range(1, &textwidth > 0 ? &textwidth : 80, &shiftwidth)
call map(pos, '"\\%"..v:val.."v"')
let pat = '\%(\_^ *\)\@<=\%('..join(pos, '\|')..'\) '
let b:indent_guides_match = matchadd('ColorColumn', pat)
endif
else
if b:indent_guides_enabled == 'tabs'
let &l:list = b:indent_guides_list_opt
let &l:listchars = b:indent_guides_listchars_opt
unlet b:indent_guides_list_opt
unlet b:indent_guides_listchars_opt
else
call matchdelete(b:indent_guides_match)
unlet b:indent_guides_match
endif
unlet b:indent_guides_enabled
endif
endfunction
function! ToggleListCharsIndentGuides()
if !exists('b:indent_guides_enabled')
let b:indent_guides_enabled = 1
let b:indent_guides_list_opt = &l:list
let b:indent_guides_listchars_opt = &l:listchars
let lcs = &l:list ? [&listchars] : []
if !&expandtab
let lcs += ['tab:⋮ ']
endif
if &shiftwidth != 0 && &tabstop != &shiftwidth
let lcs += ['leadmultispace:⋮'..repeat(' ', &shiftwidth-1)]
endif
let &l:listchars = join(lcs, ',')
setl list
else
let &l:list = b:indent_guides_list_opt
let &l:listchars = b:indent_guides_listchars_opt
unlet b:indent_guides_list_opt
unlet b:indent_guides_listchars_opt
unlet b:indent_guides_enabled
endif
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment