vim-matchup

repository·master·Indexed 23 days ago

https://github.com/andymass/vim-matchup

A Vim plugin that enhances the % motion to navigate and operate on language-specific matching words, such as HTML tags or programming keywords. It serves as a modern replacement for matchit.vim and matchparen, providing enhanced highlighting, Tree-sitter integration for Neovim, and specialized text objects (i% and a%) for operating on blocks.

Tokens
4K
Snippets
18
Records
24
Agent score
34%

What's inside vim-matchup

  1. Use deferred highlighting for performance

    master

    Deferred highlighting improves cursor movement performance (e.g., when using hjkl) by delaying highlighting until the cursor stops moving.

    Requirements:

    • Vim version 7.4.2180 or later with timers support.

    Configuration:

    • g:matchup_matchparen_deferred: Enable the feature (default: 0).
    • g:matchup_matchparen_deferred_show_delay: Delay in milliseconds before showing the highlight (default: 50).
    • g:matchup_matchparen_deferred_hide_delay: Delay in milliseconds before hiding the highlight (default: 700).

    Note: These delays cannot be changed dynamically and must be configured in your vimrc before the plugin loads.

    " Enable deferred highlighting
    let g:matchup_matchparen_deferred = 1
    let g:matchup_matchparen_deferred_show_delay = 50
    let g:matchup_matchparen_deferred_hide_delay = 700
  2. How match-up handles matchparen emulation

    master

    match-up automatically loads the matchparen plugin if it isn't already loaded.

    By default, match-up disables matchparen's highlighting and uses its own engine to highlight symbols defined in the matchpairs option (typically (), [], and {}).

    If you disable match-up for a specific buffer using b:matchup_matchparen_enabled, the plugin will fall back to using the standard matchparen highlighting. Behavior regarding this fallback can be further controlled via b:matchup_matchparen_fallback.

  3. How vim-matchup works

    master

    match-up extends Vim's % motion to work with language-specific words instead of just single characters (like () or []). It provides highlighting for symbols and words under the cursor that % can jump to, and highlights their matching counterparts.

    It is compatible with matchit.vim by using the same b:match_words variable and is intended to replace the standard matchparen plugin.

  4. Use Tree-sitter integration in Neovim

    master

    In Neovim, vim-matchup can use Tree-sitter for enhanced language support. This feature is automatically enabled if you are using Neovim and does not require additional plugins.

    Configuration options for Tree-sitter use the g:matchup_treesitter prefix. For example, you can set a stopline to limit Tree-sitter processing.

    -- Example configuration for Tree-sitter in lazy.nvim
    require('match-up').setup({
      treesitter = {
        stopline = 500
      }
    })
  5. Configure matchparen on a per-buffer basis

    master

    You can disable the matchparen module or its fallback for specific buffers (e.g., using an autocmd for a specific filetype).

    • b:matchup_matchparen_enabled: Disables match-up's highlighting for the buffer. If disabled, Vim's built-in |pi_paren| plugin may still be used unless explicitly handled.
    • b:matchup_matchparen_fallback: If b:matchup_matchparen_enabled is 0, this controls whether the plugin falls back to Vim's standard matchpairs (e.g., (), [], {}).

    Example: Disabling matchparen for LaTeX files:

    " Disable both match-up and standard fallback for tex files
    augroup matchup_matchparen_disable_ft
      autocmd!
      autocmd FileType tex let [b:matchup_matchparen_fallback, \
          \ b:matchup_matchparen_enabled] = [0, 0]
    augroup END
  6. Customize matchparen highlighting colors

    master

    The matchparen module uses standard Vim highlighting groups. You can customize them to change how matches look.

    Available Highlighting Groups:

    • MatchParen: The default group for matching parentheses/delimiters.
    • MatchWord: Used to highlight words differently than parentheses.
    • MatchParenCur: Highlight for the match currently under the cursor.
    • MatchWordCur: Highlight for the word currently under the cursor.

    Example: Setting colors via an autocmd to preserve them during colorscheme changes:

    " Customizing MatchParen
    :hi MatchParen ctermbg=blue guibg=lightblue cterm=italic gui=italic
    
    " Customizing MatchWord
    :hi MatchWord ctermfg=red guifg=blue cterm=underline gui=underline
    
    " Preserving highlights with an autocmd
    augroup matchup_matchparen_highlight
      autocmd!
      autocmd ColorScheme * hi MatchParen guifg=red
    augroup END
  7. Jump inside a block with z%

    master

    Use z% to jump to the inside of the [count]th nearest inner contained block. This is an exclusive motion when used with operators, but it automatically eats whitespace.

    Example:

      █ call somefunction(param1, param2)

    Running dz% results in:

      param1, param2)
    z%
  8. Jump between matching words with % and g%

    master

    Use % to jump forward to the next matching word. If the cursor is at a close word, it cycles back to the corresponding open word. Use g% to jump backward to the [count]th previous matching word. If at an open word, it cycles to the corresponding close word.

    • %: Forward to next match.
    • {count}%: Forward {count} times (requires {count} <= g:matchup_motion_override_Npercent).
    • g%: Backward to previous match.
    %
  9. Configure matchit.vim interoperability

    master

    match-up attempts to work around matchit.vim automatically, but manual configuration may be required depending on your editor:

    For Vim

    matchit.vim should not be loaded, or it must be loaded after match-up. If matchit.vim is loaded after match-up, match-up will be disabled. If you use plugins like vim-sensible that load matchit.vim, ensure they are initialized after match-up.

    For Neovim

    matchit.vim is loaded by default and usually works fine. To potentially improve startup time, you can disable it using:

    let g:loaded_matchit = 1
  10. Use text objects i% and a%

    master

    Match-up provides text objects for navigating and operating on blocks defined by matching words.

    Inside blocks (i%)

    • i%: The inside of an 'any' block (e.g., else in an if/else/endif construct).
    • 1i%: The inside of an 'open-to-close' block (e.g., the content between if and endif).
    • {count}i%: The inside of the {count}th surrounding open-to-close block.

    Any/Surrounding blocks (a%)

    • a%: An 'any' block.
    • 1a%: An 'open-to-close' block (includes mids but excludes open/close words).
    • {count}a%: The {count}th surrounding open-to-close block.
    i%
  11. Find your position with MatchupWhereAmI?

    master

    If you are lost in nested blocks, use the following commands to see your position in a breadcrumb style:

    • :MatchupWhereAmI?: Echos your position by finding successive matching words.
    • :MatchupWhereAmI??: Provides a more detailed print out.

    Recommended keybinding:

    noremap <c-k> :<c-u>MatchupWhereAmI?<cr>
    nnoremap <c-k> :<c-u>MatchupWhereAmI?<cr>
  12. Jump to surrounding open and close words with [% and ]%

    master

    Navigate to the boundaries of the blocks surrounding your cursor.

    • [%: Go to the [count]th previous outer open word (exclusive motion).
    • ]%: Go to the [count]th next surrounding close word (exclusive motion).
    [%