vimtricks.wiki Concise Vim tricks, one at a time.

How do I inspect all syntax highlight groups stacked under the cursor to debug colorscheme or syntax issues?

Answer

:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')

Explanation

When syntax highlighting looks wrong or a colorscheme override isn't taking effect, you need to know exactly which highlight groups are active under the cursor. The synstack() function returns a list of all syntax group IDs at a given position (innermost first), and combining it with synIDattr() and map() gives you the human-readable group names — all in one command.

How it works

  • line('.') — the current line number
  • col('.') — the current column number
  • synstack(line, col) — returns a list of syntax IDs active at that position (deepest/innermost first)
  • synIDattr(id, 'name') — converts a syntax ID to its group name
  • map(list, expr) — applies the expression to each element of the list
  • :echo — prints the resulting list of group names

The output looks like: ['goFunction', 'goFunctionCall', 'Function'] showing all the stacked groups from deepest to shallowest.

Example

With the cursor on a function call in a Go file:

:echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')
['goFunctionCall', 'goFunction']

Now you know to override goFunctionCall or goFunction in your colorscheme.

Tips

  • Map this to a key for easy repeated inspection: nnoremap <F10> :echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")')<CR>
  • Use synIDattr(synID(line('.'), col('.'), 1), 'name') to get just the effective (resolved) highlight group
  • In Neovim 0.9+, :Inspect does this visually — synstack() works in both Vim and Neovim
  • Get the linked-to group with 'fg#' or 'bg#' attrs: synIDattr(synIDtrans(synID(line('.'),col('.'),1)), 'fg#')

Next

How do I insert all completion matches at once on the command line instead of cycling through them one by one?