Coder Social home page Coder Social logo

andymass / vim-matchup Goto Github PK

View Code? Open in Web Editor NEW
1.6K 20.0 64.0 847 KB

vim match-up: even better % :facepunch: navigate and highlight matching words :facepunch: modern matchit and matchparen. Supports both vim and neovim + tree-sitter.

Home Page: https://www.vim.org/scripts/script.php?script_id=5624

License: MIT License

HTML 0.62% PLpgSQL 0.29% TeX 0.38% Ruby 1.08% Shell 0.27% Vue 0.20% JavaScript 0.03% Fortran 0.27% C++ 0.23% Lua 6.44% Smalltalk 0.01% SystemVerilog 0.03% Scheme 7.07% Makefile 0.76% Python 0.07% C 8.22% Vim Script 74.03%
vim vim-plugin parenthesis-matching matching-pairs vimscript-5624 highlighting-matches matchparen motions nvim-treesitter

vim-matchup's Introduction

and in this corner...

vim match-up 🤜🤛

match-up is a plugin that lets you highlight, navigate, and operate on sets of matching text. It extends vim's % key to language-specific words instead of just single characters.

Screenshot

Table of contents

Overview

match-up can be used as a drop-in replacement for the classic plugin matchit.vim. match-up aims to enhance all of matchit's features, fix a number of its deficiencies and bugs, and add a few totally new features. It also replaces the standard plugin matchparen, allowing all of matchit's words to be highlighted along with the matchpairs ((){}[]).

See detailed feature documentation for more information. This plugin:

  • Extends vim's % motion to language-specific words. The following vim file type plugins currently provide special support for match-up:

    abaqus, ada, aspvbs, bash, c, cpp, chicken, clojure, cmake, cobol, context, csc, csh, dtd, dtrace, eiffel, eruby, falcon, fortran, framescript, haml, hamster, hog, html, ishd, j, javascript, javascriptreact, jsp, kconfig, liquid, lua, m3quake, make, matlab, mf, modula2, modula3, mp, nsis, ocaml, pascal, pdf, perl, php, plaintex, postscr, ruby, sh, spec, sql, tex (latex), typescriptreact, vb, verilog, vhdl, vim, xhtml, xml, zimbu, zsh

    Other file types can be supported by installing additional filetype plugins (not provided by match-up).

    Note: match-up uses the same b:match_words as matchit.

  • Adds motions g%, [%, ]%, and z%.

  • Combines these motions into convenient text objects i% and a%.

  • Highlights symbols and words under the cursor which % can work on, and highlights matching symbols and words. Now you can easily tell where % will jump to.

Installation

If you use vim-plug, then add the following line to your vimrc's plugin section:

Plug 'andymass/vim-matchup'

and then use :PlugInstall.

Or, if you use packer, add it to your init.vim

return require('packer').startup(function(use)
  use {
    'andymass/vim-matchup',
    setup = function()
      -- may set any options here
      vim.g.matchup_matchparen_offscreen = { method = "popup" }
    end
  }
end)

and run :PackerSync or similar.

See Tree-sitter integration for information on how to enable tree-sitter matching with neovim.

Note: I do not recommend using alternative loading strategies such as event = 'VimEnter' or event = 'CursorMoved' as match-up already loads a minimal amount of code on start-up. It may work, but if you run into issues, remove the event key as a first debugging step.

With LunarVim, tree-sitter integration can be enabled as follows:

{
  "andymass/vim-matchup",
  setup = function()
    vim.g.matchup_matchparen_offscreen = { method = "popup" }
  end,
},

lvim.builtin.treesitter.matchup.enable = true

You can use any other plugin manager such as vundle, dein, neobundle, or pathogen,

match-up should automatically disable matchit and matchparen, but if you are still having trouble, try placing this near the top of your vimrc:

let g:loaded_matchit = 1

See Interoperability for more information about working together with other plugins.

Tree-sitter integration

Note: Currently this feature is possible in neovim only. Only the latest version of neovim is supported.

match-up has support for language syntax provided by tree-sitter. The list of supported languages is available here.

This feature requires manual opt-in in your init.vim and requires nvim-treesitter to be installed.

Plug 'nvim-treesitter/nvim-treesitter'
lua <<EOF
require'nvim-treesitter.configs'.setup {
  matchup = {
    enable = true,              -- mandatory, false will disable the whole extension
    disable = { "c", "ruby" },  -- optional, list of language that will be disabled
    -- [options]
  },
}
EOF

Beside enable and disable, the following options are available, all defaulting to disabled:

  • disable_virtual_text: do not use virtual text to highlight the virtual end of a block, for languages without explicit end markers (e.g., Python).
  • include_match_words: additionally include traditional vim regex matches for symbols. For example, highlights /* */ comments in C++ which are not supported in tree-sitter matching.

Screenshot:

Features

feature match-up matchit matchparen
(a.1) jump between matching words 👍 👍
(a.2) jump to open & close words 👍 👍
(a.3) jump inside (z%) 👍
(b.1) full set of text objects 👍
(b.2) delete surrounding matched words 👍
(c.1) highlight (), [], & {} 👍 👍
(c.2) highlight all matching words 👍
(c.3) display matches off-screen 👍
(c.4) show where you are (breadcrumbs) 👍
(d.1) (neovim) tree-sitter integration 👍

Legend: 👍 supported. ❓ poorly implemented, broken, or uncertain. ❌ not possible.

Detailed feature documentation

What do we mean by open, close, mid? This depends on the specific file type and is configured through the variable b:match_words. Here are a couple examples:

vim-script

if l:x == 1
  call one()
elseif l:x == 2
  call two()
else
  call three()
endif

For the vim-script language, match-up understands the words if, else, elseif, endif and that they form a sequential construct. The "open" word is if, the "close" word is endif, and the "mid" words are else and elseif. The if/endif pair is called an "open-to-close" block and the if/else, else/elsif, and elseif/endif are called "any" blocks.

C, C++

#if 0
#else
#endif

void some_func() {
    if (true) {
      one();
    } else if (false && false) {
      two();
    } else {
      three();
    }
}

Since in C and C++, blocks are delimited using braces ({ & }), match-up will recognize { as the open word and } as the close word. It will ignore the if and else if because they are not defined in vim's default C file type plugin. (Note: In neovim, this is optionally supported via Tree-sitter)

On the other hand, match-up will recognize the #if, #else, #endif preprocessor directives.

(a.1) jump between matching words

  • % go forwards to next matching word. If at a close word, cycle back to the corresponding open word.
  • {count}% forwards {count} times. Requires {count} <= g:matchup_motion_override_Npercent. For larger {count}, {count}% goes to the {count} percentage in the file.
  • g% go backwards to [count]th previous matching word. If at an open word, cycle around to the corresponding close word.

(a.2) jump to open and close words

  • [% go to [count]th previous outer open word. Allows navigation to the start of blocks surrounding the cursor. This is similar to vim's built-in [( and [{ and is an exclusive motion.
  • ]% go to [count]th next surrounding close word. This is an exclusive motion.

(a.3) jump inside

  • z% go to inside [count]th nearest inner contained block. This is an exclusive motion when used with operators, except it eats whitespace. For example, where is the cursor position,
call somefunction(param1, param2)

dz% produces

  param1, param2)

but in

call somefunction(      param1, param2)

dz% also produces

  param1, param2)

(b.1) full set of text objects

  • i% the inside of an any block

  • 1i% the inside of an open-to-close block

  • {count}i% If count is greater than 1, the inside of the {count}th surrounding open-to-close block

  • a% an any block.

  • 1a% an open-to-close block. Includes mids but does not include open and close words.

  • {count}a% if {count} is greater than 1, the {count}th surrounding open-to-close block.

See here for some examples and important special cases.

(c.1) highlight (), [], and {}

match-up emulates vim's matchparen to highlight the symbols contained in the matchpairs setting.

(c.2) highlight all matches

To disable match highlighting at startup, use let g:matchup_matchparen_enabled = 0 in your vimrc. See here for more information and related options.

You can enable highlighting on the fly using :DoMatchParen. Likewise, you can disable highlighting at any time using :NoMatchParen.

After start-up, is better to use :NoMatchParen and :DoMatchParen to toggle highlighting globally than setting the global variable since these commands make sure not to leave stale matches around.

(c.3) display matches off screen

If a open or close which would have been highlighted is on a line positioned outside the current window, the match is shown in the status line or popup window. If both the open and close match are off-screen, the close match is preferred. See the option g:matchup_matchparen_offscreen for more details.

For popup style (supported in recent vim and neovim versions):

let g:matchup_matchparen_offscreen = {'method': 'popup'}

For status line style (default):

let g:matchup_matchparen_offscreen = {'method': 'status'}

(c.4) where am I?

If you are lost, you can ask match-up where you are using

:MatchupWhereAmI?

This echos your position in the code in a breadcrumb-style by finding successive matching words, like doing [% repeatedly.

It's useful to bind this to a key (not bound by default)

nnoremap <c-k> :<c-u>MatchupWhereAmI?<cr>

If you are really lost, you can ask a bit harder to get a more detailed print out.

:MatchupWhereAmI??

Inclusive and exclusive motions

In vim, character motions following operators (such as d for delete and c for change) are either inclusive or exclusive. This means they either include the ending position or not. Here, "ending position" means the line and column closest to the end of the buffer of the region swept over by the motion. match-up is designed so that d]% inside a set of parenthesis behaves exactly like d]), except generalized to words.

Put differently, forward exclusive motions will not include the close word. In this example, where is the cursor position,

ifx | continue | endif

pressing d]% will produce (cursor on the e)

if endif

To include the close word, use either dv]% or v]%d. This is also compatible with vim's d]) and d]}.

Operators over backward exclusive motions will instead exclude the position the cursor was on before the operator was invoked. For example, in

  ifx | continue | endif

pressing d[% will produce

x | continue | endif

This is compatible with vim's d[( and d[{.

Unlike ]%, % is an inclusive motion. As a special case for the d (delete) operator, if d% leaves behind lines white-space, they will be deleted also. In effect, it will be operating line-wise. As an example, pressing d% will leave behind nothing.

   █(

   )

To operate character-wise in this situation, use dv% or v%d. This is vim compatible with the built-in d% on matchpairs.

Line-wise operator/text-object combinations

Normally, the text objects i% and a% work character-wise. However, there are some special cases. For certain operators combined with i%, under certain conditions, match-up will effectively operate line-wise instead. For example, in

if condition
 █call one()
  call two()
endif

pressing di% will produce

if condition
endif

even though deleting condition would be suggested by the object i%. The intention is to make operators more useful in some cases. The following rules apply:

  1. The operator must be listed in g:matchup_text_obj_linewise_operators. By default this is d and y (e.g., di% and ya%).
  2. The outer block must span multiple lines.
  3. The open and close delimiters must be more than one character long. In particular, di% involving a (...) block will not be subject to these special rules.

To prevent this behavior for a particular operation, use vi%d. Note that special cases involving indentation still apply (like with |i)| etc).

To disable this entirely, remove the operator from the following variable,

let g:matchup_text_obj_linewise_operators = [ 'y' ]

Note: unlike vim's built-in i), ab, etc., i% does not make an existing visual mode character-wise.

A second special case involves da%. In this example,

    if condition
     █call one()
      call two()
    endif

pressing da% will delete all four lines and leave no white-space. This is vim compatible with da(, dab, etc.

Options

To disable the plugin entirely,

let g:matchup_enabled = 0

default: 1

To disable a particular module,

let g:matchup_matchparen_enabled = 0
let g:matchup_motion_enabled = 0
let g:matchup_text_obj_enabled = 0

defaults: 1

To enable the delete surrounding (ds%) and change surrounding (cs%) maps,

let g:matchup_surround_enabled = 1

default: 0

To enable the experimental transmute module,

let g:matchup_transmute_enabled = 1

default: 0

To configure the number of lines to search in either direction while using motions and text objects. Does not apply to match highlighting (see g:matchup_matchparen_stopline instead).

let g:matchup_delim_stopline = 1500

default: 1500

To disable matching within strings and comments,

let g:matchup_delim_noskips = 1   " recognize symbols within comments
let g:matchup_delim_noskips = 2   " don't recognize anything in comments

default: 0 (matching is enabled within strings and comments)

Variables

match-up understands the following variables from matchit.

  • b:match_words
  • b:match_skip
  • b:match_ignorecase

These are set in the respective ftplugin files. They may not exist for every file type. To support a new file type, create a file after/ftplugin/{filetype}.vim which sets them appropriately.

Module matchparen

To disable match highlighting at startup, use let g:matchup_matchparen_enabled = 0 in your vimrc. Note: vim's built-in plugin |pi_paren| plugin is also disabled. The variable g:loaded_matchparen has no effect on match-up.

Customizing the highlighting colors

match-up uses the MatchParen highlighting group by default, which can be configured. For example,

:hi MatchParen ctermbg=blue guibg=lightblue cterm=italic gui=italic

You may want to put this inside a ColorScheme autocmd so it is preserved after colorscheme changes:

augroup matchup_matchparen_highlight
  autocmd!
  autocmd ColorScheme * hi MatchParen guifg=red
augroup END

You can also highlight words differently than parentheses using the MatchWord highlighting group. You might do this if you find the MatchParen style distracting for large blocks.

:hi MatchWord ctermfg=red guifg=blue cterm=underline gui=underline

There are also MatchParenCur and MatchWordCur which allow you to configure the highlight separately for the match under the cursor.

:hi MatchParenCur cterm=underline gui=underline
:hi MatchWordCur cterm=underline gui=underline

The matchparen module can be disabled on a per-buffer basis (there is no command for this). By default, when disabling highlighting for a particular buffer, the standard plugin matchparen will still be used for that buffer.

let b:matchup_matchparen_enabled = 0

default: 1

If this module is disabled on a particular buffer, match-up will still fall-back to the vim standard plugin matchparen, which will highlight matchpairs such as (), [], & {}. To disable this,

let b:matchup_matchparen_fallback = 0

default: 1

A common usage of these options is to automatically disable matchparen for particular file types;

augroup matchup_matchparen_disable_ft
  autocmd!
  autocmd FileType tex let [b:matchup_matchparen_fallback,
      \ b:matchup_matchparen_enabled] = [0, 0]
augroup END

Whether to highlight known words even if there is no match:

let g:matchup_matchparen_singleton = 1

default: 0

Dictionary controlling the behavior with off-screen matches.

let g:matchup_matchparen_offscreen = { ... }

default: {'method': 'status'}

If empty, this feature is disabled. Else, it should contain the following optional keys:

  • method: Sets the method to use to show off-screen matches. Possible values are:

    'status' (default): Replace the status-line for off-screen matches.

    If a match is off of the screen, the line belonging to that match will be displayed syntax-highlighted in the status line along with the line number (if line numbers are enabled). If the match is above the screen border, an additional Δ symbol will be shown to indicate that the matching line is really above the cursor line.

    'popup': Show off-screen matches in a popup (vim) or floating (neovim) window.

    'status_manual': Compute the string which would be displayed in the status-line or popup, but do not display it. The function MatchupStatusOffscreen() can be used to get the text.

  • scrolloff: When enabled, off-screen matches will not be shown in the statusline while the cursor is at the screen edge (respects the value of 'scrolloff'). This is intended to prevent flickering while scrolling with j and k.

    default: 0.

The number of lines to search in either direction while highlighting matches. Set this conservatively since high values may cause performance issues.

let g:matchup_matchparen_stopline = 400  " for match highlighting only

default: 400

highlighting timeouts

Adjust timeouts in milliseconds for matchparen highlighting:

let g:matchup_matchparen_timeout = 300
let g:matchup_matchparen_insert_timeout = 60

default: 300, 60

deferred highlighting

Deferred highlighting improves cursor movement performance (for example, when using hjkl) by delaying highlighting for a short time and waiting to see if the cursor continues moving;

let g:matchup_matchparen_deferred = 1

default: 0 (disabled)

Note: this feature is only available if your vim version has timers and the function timer_pause, version 7.4.2180 and after.

Adjust delays in milliseconds for deferred highlighting:

let g:matchup_matchparen_deferred_show_delay = 50
let g:matchup_matchparen_deferred_hide_delay = 700

default: 50, 700

Note: these delays cannot be changed dynamically and should be configured before the plugin loads (e.g., in your vimrc).

highlight surrounding

To highlight the surrounding delimiters until the cursor moves, use a map such as the following

nmap <silent> <F7> <plug>(matchup-hi-surround)

There is no default map for this feature.

You can also highlight surrounding delimiters always as the cursor moves.

let g:matchup_matchparen_deferred = 1
let g:matchup_matchparen_hi_surround_always = 1

default: 0 (off)

This can be set on a per-buffer basis:

autocmd FileType tex let b:matchup_matchparen_hi_surround_always = 1

Note: this feature requires deferred highlighting to be supported and enabled.

Module motion

In vim, {count}% goes to the {count} percentage in the file. match-up overrides this motion for small {count} (by default, anything less than 7). To allow {count}% for {count} less than 12,

g:matchup_motion_override_Npercent = 11

To disable this feature, and restore vim's default {count}%,

g:matchup_motion_override_Npercent = 0

To always enable this feature, use any value greater than 99,

g:matchup_motion_override_Npercent = 100

default: 6

If enabled, cursor will land on the end of mid and close words while moving downwards (%/]%). While moving upwards (g%, [%) the cursor will land on the beginning. To disable,

let g:matchup_motion_cursor_end = 0

default: 1

Module text_obj

Modify the set of operators which may operate line-wise

let g:matchup_text_obj_linewise_operators = ['d', 'y']

default: ['d', 'y']

FAQ

  • match-up doesn't work

    This plugin requires at least vim 7.4. It should work in vim 7.4.898 but at least vim 7.4.1689 is better. I recommend using the most recent version of vim if possible.

    If you have issues, please tell me your vim version and error messages. Try updating vim and see if the problem persists.

  • Why does jumping not work for construct X in language Y?

    You can configure custom match expressions for a file type using

    autocmd FileType myft let b:match_words = 'something:else'`

    For more information about how to customize matching, see the wiki.

    For help, please open a new issue and be as specific as possible.

  • Highlighting is not correct for construct X

    match-up uses matchit's filetype-specific data, which may not give enough information to create proper highlights. To fix this, you may need to modify b:match_words in your configuration.

    For more help, please open a new issue and be as specific as possible.

  • I'm having performance problems

    match-up aims to be as fast as possible, but highlighting matching words can be intensive and may be slow on less powerful machines. There are a few things you can try to improve performance:

    1. Update to a recent version of vim. Newer versions are faster, more extensively tested, and better supported by match-up.
    2. Try deferred highlighting, which delays highlighting until the cursor is stationary to improve cursor movement performance.
    3. Lower the highlighting timeouts. Note that if highlighting takes longer than the timeout, highlighting will not be attempted again until the cursor moves.

    If are having any other performance issues, please open a new issue and report the output of :MatchupShowTimes.

  • Why is there a weird entry on the status line?

    This is a feature which helps you see matches that are outside of the vim screen, similar to some IDEs. If you wish to disable it, use

    let g:matchup_matchparen_offscreen = {}
  • Matching does not work when lines are too far apart.

    The number of search lines is limited for performance reasons. You may increase the limits with the following options:

    let g:matchup_delim_stopline      = 1500 " generally
    let g:matchup_matchparen_stopline = 400  " for match highlighting only
  • The maps 1i% and 1a% are difficult to press.

    You may use the following maps I% and A% for convenience:

    function! s:matchup_convenience_maps()
      xnoremap <sid>(std-I) I
      xnoremap <sid>(std-A) A
      xmap <expr> I mode()=='<c-v>'?'<sid>(std-I)':(v:count?'':'1').'i'
      xmap <expr> A mode()=='<c-v>'?'<sid>(std-A)':(v:count?'':'1').'a'
      for l:v in ['', 'v', 'V', '<c-v>']
        execute 'omap <expr>' l:v.'I%' "(v:count?'':'1').'".l:v."i%'"
        execute 'omap <expr>' l:v.'A%' "(v:count?'':'1').'".l:v."a%'"
      endfor
    endfunction
    call s:matchup_convenience_maps()

    Note: this is not compatible with the plugin targets.vim.

  • How can I contribute?

    Read the contribution guidelines and issue template. Be as precise and detailed as possible when submitting issues and pull requests.

Interoperability

vimtex, for LaTeX documents

By default, match-up will be disabled automatically for tex files when vimtex is detected. To enable match-up for tex files, use

let g:matchup_override_vimtex = 1

match-up's matching engine is more advanced than vimtex's and supports middle delimiters such as \middle| and \else. The exact set of delimiters recognized may differ between the two plugins. For example, the mappings da% and dad will not always match, particularly if you have customized vimtex's delimiters.

Surroundings

match-up provides built-in support for vim-surround-style ds% and cs% operations (let g:matchup_surround_enabled = 1). If vim-surround is installed, you can use vim-surround replacements such as cs%). % cannot be used as a replacement. An alternative plugin is vim-sandwich, which allows more complex surround replacement rules but is not currently supported.

Auto-closing plugins

match-up does not provide auto-complete or auto-insertion of matches. See for instance one of the following plugins for this;

Matchit

match-up tries to work around matchit.vim in all cases, but if you experience problems, read the following:

  • For vim, matchit.vim should not be loaded. If it is loaded, it should be loaded after match-up (in this case, matchit.vim will be disabled). Note that some plugins, such as vim-sensible, load matchit.vim so these should also be initialized after match-up.

  • For neovim, matchit.vim is loaded by default. This should not cause any problems, but you may see a very slight start-up time improvement by setting let g:loaded_matchit = 1 in your init.vim.

Matchparen emulation

match-up loads matchparen if it is not already loaded. Ordinarily, match-up disables matchparen's highlighting and emulates it to highlight the symbol contained in the 'matchpairs' option (by default (), [], and {}). If match-up is disabled per-buffer using b:matchup_matchparen_enabled, match-up will use matchparen instead of its own highlighting. See b:matchup_matchparen_fallback for more information.

Acknowledgments

Origins

match-up was originally based on @lervag's vimtex. The concept and style of this plugin and its development are heavily influenced by vimtex. 🍻

Other inspirations

Development

Reporting problems

Thorough issue reports are encouraged. Please read the issue template first. Be as precise and detailed as possible when submitting issues.

Feature requests are also welcome.

Contributing

Please read the contribution guidelines before contributing.

Contributions are welcome!

vim-matchup's People

Contributors

ahdinosaur avatar ajitid avatar aldhsu avatar amaanq avatar amopel avatar andymass avatar aster89 avatar axelf4 avatar bagohart avatar captainko avatar cocopon avatar cormacrelf avatar dtomvan avatar get-me-power avatar hinell avatar iamcco avatar kevinhwang91 avatar mehalter avatar mrcjkb avatar oncomouse avatar psvenk avatar radionoisee avatar ramilgn avatar rubixdev avatar sainnhe avatar seb-mueller avatar wsdjeg avatar wuelnerdotexe avatar yads avatar zeertzjq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vim-matchup's Issues

[feature] add match_words for latex

Cf. lervag/vimtex#1009. Goals:

  • Improve upon the default vim ftplugin's b:match_words
  • Integrate well with vimtex (override %, disable vimtex's matchparen)

For now, we introduce the following option to enable/disable this work:

 let g:matchup_override_vimtex = 1

TODO:

  • plainTeX, ConTeXt?
  • Use new b:match_words even when vimtex is not installed (requires testing)
  • Documentation (match-up and vimtex)

Not working in neovim with native packages (match-up must be loaded before matchit)

Explain the issue

Getting error match-up must be loaded before matchit when trying to use vim-matchup with native packages feature in neovim. Vim works fine.

adding let g:loaded_matchit = 1 at the beginning of script didn't work out.

  1. What vim version are you using - NVIM v0.3.0-dev
  2. Steps to reproduce - Just open neovim. Check minimal vimrc section.
  3. Expected behavior - To load matchup without any errors
  4. Observed behavior - It throws error match-up must be loaded before matchit

Minimal vimrc file

First add package:

mkdir -p ~/.config/nvim/pack/bundles/start
cd ~/.config/nvim/pack/bundles/start
git clone https://github.com/andymass/vim-matchup

Create ~/.config/nvim/init.vim

filetype plugin indent on
syntax on

Open anything with neovim.

Result of the :scriptnames in neovim:

  1: ~/.config/nvim/init.vim
  2: /usr/share/nvim/runtime/filetype.vim
  3: /usr/share/nvim/runtime/ftplugin.vim
  4: /usr/share/nvim/runtime/indent.vim
  5: /usr/share/nvim/runtime/syntax/syntax.vim
  6: /usr/share/nvim/runtime/syntax/synload.vim
  7: /usr/share/nvim/runtime/syntax/syncolor.vim
  8: /usr/share/nvim/runtime/plugin/gui_shim.vim
  9: /usr/share/nvim/runtime/plugin/gzip.vim
 10: /usr/share/nvim/runtime/plugin/health.vim
 11: /usr/share/nvim/runtime/plugin/man.vim
 12: /usr/share/nvim/runtime/plugin/matchit.vim
 13: /usr/share/nvim/runtime/plugin/matchparen.vim
 14: /usr/share/nvim/runtime/plugin/netrwPlugin.vim
 15: /usr/share/nvim/runtime/plugin/rplugin.vim
 16: ~/.local/share/nvim/rplugin.vim
 17: /usr/share/nvim/runtime/autoload/remote/host.vim
 18: /usr/share/nvim/runtime/autoload/remote/define.vim
 19: /usr/share/nvim/runtime/plugin/rrhelper.vim
 20: /usr/share/nvim/runtime/plugin/shada.vim
 21: /usr/share/nvim/runtime/plugin/spellfile.vim
 22: /usr/share/nvim/runtime/plugin/tarPlugin.vim
 23: /usr/share/nvim/runtime/plugin/tohtml.vim
 24: /usr/share/nvim/runtime/plugin/tutor.vim
 25: /usr/share/nvim/runtime/plugin/zipPlugin.vim
 26: ~/.config/nvim/pack/bundles/start/vim-matchup/plugin/matchup.vim
 27: ~/.config/nvim/pack/bundles/start/vim-matchup/after/plugin/matchit.vim
 28: /usr/share/nvim/runtime/scripts.vim
 29: /usr/share/nvim/runtime/ftplugin/vim.vim
 30: ~/.config/nvim/pack/bundles/start/vim-matchup/after/ftplugin/vim.vim
 31: ~/.config/nvim/pack/bundles/start/vim-matchup/autoload/matchup/util.vim
 32: /usr/share/nvim/runtime/indent/vim.vim
 33: /usr/share/nvim/runtime/syntax/vim.vim
 34: /usr/share/nvim/runtime/syntax/vim/generated.vim

And in Vim 8:

  1: ~/.vimrc
  2: /usr/local/share/vim/vim80/filetype.vim
  3: /usr/local/share/vim/vim80/ftplugin.vim
  4: /usr/local/share/vim/vim80/indent.vim
  5: /usr/local/share/vim/vim80/syntax/syntax.vim
  6: /usr/local/share/vim/vim80/syntax/synload.vim
  7: /usr/local/share/vim/vim80/syntax/syncolor.vim
  8: /usr/local/share/vim/vim80/plugin/getscriptPlugin.vim
  9: /usr/local/share/vim/vim80/plugin/gzip.vim
 10: /usr/local/share/vim/vim80/plugin/logiPat.vim
 11: /usr/local/share/vim/vim80/plugin/manpager.vim
 12: /usr/local/share/vim/vim80/plugin/matchparen.vim
 13: /usr/local/share/vim/vim80/plugin/netrwPlugin.vim
 14: /usr/local/share/vim/vim80/plugin/rrhelper.vim
 15: /usr/local/share/vim/vim80/plugin/spellfile.vim
 16: /usr/local/share/vim/vim80/plugin/tarPlugin.vim
 17: /usr/local/share/vim/vim80/plugin/tohtml.vim
 18: /usr/local/share/vim/vim80/plugin/vimballPlugin.vim
 19: /usr/local/share/vim/vim80/plugin/zipPlugin.vim
 20: ~/.vim/pack/bundles/start/vim-matchup/plugin/matchup.vim
 21: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup.vim
 22: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/perf.vim
 23: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/loader.vim
 24: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/matchparen.vim
 25: ~/.vim/pack/bundles/start/vim-matchup/after/plugin/matchit.vim
 26: /usr/local/share/vim/vim80/scripts.vim
 27: /usr/local/share/vim/vim80/ftplugin/vim.vim
 28: ~/.vim/pack/bundles/start/vim-matchup/after/ftplugin/vim.vim
 29: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/util.vim
 30: /usr/local/share/vim/vim80/indent/vim.vim
 31: /usr/local/share/vim/vim80/syntax/vim.vim
 32: /usr/local/share/vim/vim80/syntax/lua.vim
 33: /usr/local/share/vim/vim80/syntax/perl.vim
 34: /usr/local/share/vim/vim80/syntax/pod.vim
 35: /usr/local/share/vim/vim80/syntax/python.vim
 36: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/re.vim
 37: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/pos.vim
 38: ~/.vim/pack/bundles/start/vim-matchup/autoload/matchup/delim.vim

Looks like vim 8 doesn't have matchit. At least my installation.

Adding let g:loaded_matchit = 1 to beginning does prevent neovim to load matchit, but then matchup understands that the matchup was loaded, when it wasn't. I guess the check in plugin/matchup.vim should be changed to this:

if exists('g:loaded_matchit')  && g:loaded_matchit == 1
  echoerr 'match-up must be loaded before matchit'
  finish
endif

matchit will set it's value to 1 when it gets loaded, but we can set it to something else (0 or some number bigger than 1) at the beginning of the vimrc/init.vim, and this will also prevent matchit to load, because it only does exists check, like matchup is doing now.

Create github release which match vim.org versions

I've noticed that you've published your plugin match-up on https://vim.sourceforge.io/scripts/script.php?script_id=5624. My congratulations!

A minor thing which, however, I appreciate is if you could add to the github repository releases under https://github.com/andymass/vim-matchup/releases which match the releases under https://vim.sourceforge.io/scripts/script.php?script_id=5624. Right now what you call version 0.1 under vim.org should also exist here on github.

From my perspective this offers following advantages:

  • a user can decide to follow head or to checkout a release
  • a user can revert to a previous distinct version without remembering a commit hash which is not very user friendly.
  • indicates possibly a minimum level of what the developer considers stable and has 'aged' a little bit; commits can sometimes break existing functionality; this already happened to me more than once.
  • for non git experts this is an alternative possibility to get your plugin.
  • it is a backup for vim.org

I don't want to force you in a strict release model, but IMHO simply marking once in a while a version is good practice which you have already done.

Matching on end of line matches the next pair

Awesome plugin, really enjoy using it. There is only one behaviour that doesn't work like i'm used to.

Using % with vim-matchit on the end of a line matched on pair on the current line like this: https://asciinema.org/a/DPPj9AucHWXAiqqVbSgYRDqX3
But using % with vim-matchup on the end of a line matches on the next pair, not the pair on the current line like this: https://asciinema.org/a/KTK9LWM5Gt4pG3qSNMYqvpSor

This happens a lot to me when using $ to go to the do in a ruby block.

"Unhighlight" match after a few seconds

Hey Andy, first of all, thank you so much for the plugin. It really is a life saver, specially regarding the motions!

I have a doubt: Can you add an option to "unhighlight" the matches after a specified timeout? For example, I do have some legacy javascript and matchup perfectly matches the tags inside that strings, like the example below:

image

As you can see, when I'm inside the span, everything is highlighted. So visual selection doesn't work properly (I mean, I can still use visual select and it will yank/change/delete, but I can't see the visual selection itself).

Maybe add an option to remove the highlight after I've been in the tag, so I can set for something like, 2 seconds, and after that it won't highlight that part again until I leave that tag and comeback to it?

(Or if you have any suggestions on how I can circumvent this problem, I'm all ears).

Here's my matchup config, but I don't think that's the cause (running with the default options yields the same result)

" Enable experimental transmute module
" See https://github.com/andymass/vim-matchup#d1-parallel-transmutation
let g:matchup_transmute_enabled = 1

" Deferred highlight for performance reasons
let g:matchup_matchparen_deferred = 1

" Adjust highlight timeouts
let g:matchup_matchparen_timeout = 150
let g:matchup_matchparen_insert_timeout = 30

Thank you for your time :)

[question] How to highlight only the tag name?

a

Is it possible to highlight only the tag name? The screenshot is from a javascript file.

Looking at the plugin code, I found an option called tagnameonly but seems that doesn't work for javascript files.

Feature Request: Status line symbol

Hello, this is just a feature request.

I like the idea of the matching parent in the status line, but I do not want to replace the whole line as for example in a C/C++ header the status bar is always replaced by the #ifndef used as sentinel on the whole file.

Would it be possible to have a function that we could pass to the statusline ourselves?

Exemple of such a configuration:

let g:matchup_martchparent_status_offscreen = 0

set statusline+=%{MatchupStatusOffscreen()}

Thanks for this great plugin,
Charles

Improve documentation

as vim-matchup is a replacement... wouldn't be a good idea to include on the README instructions about how to disable the default plugins?

like...

let g:loaded_matchit = 1

Plug 'stuff'

Matching inside string

I am not sure how I think about this myself, but: With the old matchit/matchparen I would get highlighting of parentheses inside strings. This was particularly useful when writing v:val-type strings in vimscript.

Do you think something like this could be possible to support from vim-matchup? My initial thought is that this needs some special attention, and in particular, that it might need a customized engine. That is, when inside strings, one should use a different set of regexes and similar, in order to prevent what is inside the strings from affecting what is outside the strings.

In any case, here is an example:

let output = filter(list, "matchstr(v:val, '^\s*\zsfoo\ze\(bar\|baz\)')")

Missing addmatchpos

just git cloned the latest into my .vim/bundle directory. my vim is using pathogen to load the module

I opened up a python file and tried to match a try: and got a vim error of
"E117: Unknown function: matchaddpos"

I also tried this on other file types and situations and got the same error.

VIM - Vi IMproved 7.4 (2013 Aug 10)

match might get wrong when using jsx with arrow function

hi @andymass

matchit is too old, it is really thanks for your awesome plugin for vim matching function. :)

here is the code:

export default class App extends Component {
  render() {
    return (
      <TabBarIOS selectedTab={this.state.selectedTab}>
        <TabBarIOS.Item
          selected={this.state.selectedTab === 'accounting'}
          title="accounting"
          onPress={() => {
            this.setState({
              selectedTab: 'accounting'
            });
          }}>
          <Accounting categories={this.state.data.categories} log={this.state.data.log} />
        </TabBarIOS.Item>
    )
  }
}

step to reproduce

  1. put cursor on { after render()
  2. press % to find match
  3. you will find that cursor is on the } in <TabBarIOS selectedTab={this.state.selectedTab}>

Commentary gc + matchup a%

I was trying to comment a vimscript function by combining vim-commentary's operator gc with the text-object a% from match-up.

function! s:test()

    let l:str = "hello"

    return l:str

endfunction

Placing the cursor on let l:str = "hello" and pressing gca% changes the text to

" function! s:test()

"     let l:str = "hello"

"     return l:str
endfunction

As you can see endfunction is not commented. Also gci% does not what I would expect.

Did I miss something or can this be improved?

Plugin manager dein: after/ftplugin/tex.vim from vimtex and matchup clash by default

The plugin manager dein organizes all plugins in a single runtime path:

Merge the plugins directories automatically to avoid long 'runtimepath'

In my case, this is located here:

~/.cache/vim/dein/.cache/vimrc/.dein
❯ tree -d -L 1
.
├── UltiSnips
├── after
├── autoload
├── bin
├── colors
├── common
├── compiler
├── contrib
├── ctags
├── data
├── doc
├── docs
├── examples
├── ftdetect
├── ftplugin
...

However, since vimtex and matchup provide the same file

after/ftplugin/tex.vim

only one will be installed by default.

dein already provides a solution for this: add the flag merged=0:

call dein#add('andymass/vim-matchup', { 'merged': 0 })

However, for beginner this is not obvious and vim also provides a simple solution which makes this more fool proof and the runtime path can be kept as short as possible as intended: add _matchup to the filename`

after/ftplugin/tex_matchup.vim

(and similar for the additions to other filetypes.)

What do you think?

One minor thing is: I am used to open files related to tex settings via :Ve */ftplugin/tex.vim (:Ve from vim-scriptease). However, I should use :Ve */ftplugin/tex*.vim.


For reference :h ftplugin-name:

USING A FILETYPE PLUGIN					*ftplugin-name*

You can add a filetype plugin by dropping it in the right directory.  The
name of this directory is in the same directory mentioned above for global
plugins, but the last part is "ftplugin".  Suppose you have found a plugin for
the "stuff" filetype, and you are on Unix.  Then you can move this file to the
ftplugin directory: >

	mv thefile ~/.vim/ftplugin/stuff.vim

If that file already exists you already have a plugin for "stuff".  You might
want to check if the existing plugin doesn't conflict with the one you are
adding.  If it's OK, you can give the new one another name: >

	mv thefile ~/.vim/ftplugin/stuff_too.vim

The underscore is used to separate the name of the filetype from the rest,
which can be anything.  If you use "otherstuff.vim" it wouldn't work, it would
be loaded for the "otherstuff" filetype.

Not working in cmdline-window

Explain the issue

I hove trouble with using % in command-line-window. Is this in the specifications?

  1. What vim version are you using? -- VIM 8.1.0500
  2. Steps to reproduce -- See below
  3. Expected behavior -- Jump to match pair
  4. FYI, vim-matchup works fine in a normal window.

How to reproduce the problem

  1. start vim vim -u {PATH/TO/Minimal-vimrc}.
  2. type q/ and enter the command-line-window.
  3. type i[]<Esc> and try to jump with % .

Minimal vimrc file

unlet! skip_defaults_vim
source $VIMRUNTIME/defaults.vim
let g:loaded_matchit = 1
set rtp+={/PATH/TO/vim-matchup}
set packpath=

% jumps backwards

From docs:

% - Go forwards to next matching word. If at a close word, cycle back to the corresponding open word.

However for me, with this minimal vimrc,

set nocompatible

call plug#begin('~/.vim/bundle/')

Plug 'andymass/vim-matchup'

call plug#end()

In the following examples, jumps (and motion-s) backwards:

# `%` jumps to if
if test -z ""; then
    echo "cursor_position"
fi

# `%` jumps to while
while true; do
    echo "cursor_position"
done
; `%` jumps to (
(format t "cursor_position")

Effectively acting the same as g%. Been a long time, last tested at commit 62b3db9. Seems like I'm doing something wrong. Will appreciate any pointers / possible workarounds. ]% works correctly but further jumps lead to next closing matches, so it can't be substituted for %.

Does work correctly in some cases:

# `%` jumps to )
def cursor_position(name: str) -> str:
    return "Hello, " + name

# Seems that when jumping from outside of the pair, all the examples above also 
# jump to the closing "bracket".

Jumps over else directly to fi, in this example.

# `%` jumps to fi
if test -z ""; then
    echo "cursor_position"
else
    true
fi

Seems like it could be solved with matchup_hotfix. However the issue does not look to be filetype-specific. Will appreciate any pointers.

[Bug] Errors on startup when editing git commit message

Explain the issue

Steps to reproduce

  1. In any git repo, stage some changes: $ git add .
  2. Then open Vim to edit the commit message: $ git commit

Expected behavior

Vim opens without incident.

Observed behavior

Vim spits out an error immediately:

Error detected while processing function matchup#init[2]..<SNR>13_init_modules[7]..matchup#delim#init_module[11]..matchup#delim#init_buffer[3]..<SNR>14_init_delim_lists[61]..matchup#delim#get_capture_groups:
line   11:
E117: Unknown function: matchstrpos
E15: Invalid expression: matchstrpos(a:str, l:pat, l:start)
Press ENTER or type command to continue

And then once proceeding past this error to open Vim, another set of errors:

"~/dev/tempgit/.git/COMMIT_EDITMSG" 16L, 406C
Error detected while processing function matchup#delim#init_buffer[3]..<SNR>14_init_delim_lists[61]..matchup#delim#get_capture_groups:
line   11:
E117: Unknown function: matchstrpos
E15: Invalid expression: matchstrpos(a:str, l:pat, l:start)
line   12:
E121: Undefined variable: l:match
E15: Invalid expression: l:match[1] < 0 | break | endif
line   31:
E171: Missing :endif:   endwhile
line   11:
E117: Unknown function: matchstrpos
E15: Invalid expression: matchstrpos(a:str, l:pat, l:start)
line   12:
E121: Undefined variable: l:match
E15: Invalid expression: l:match[1] < 0 | break | endif
line   31:
<snip>

Truncated, because it loops apparently infinitely (if I hit G to go to the end of the errors, it just keeps scrolling and scrolling).

Minimal vimrc file

set nocompatible
filetype off

if empty(glob('~/.vim/autoload/plug.vim'))
  silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
        \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
  autocmd VimEnter * PlugInstall
  autocmd VimEnter * close
endif

call plug#begin()

Plug 'andymass/matchup.vim'

call plug#end()

Android Termux:'match-up must be loaded before matchit'

On the platform of Android Termux,I hava the same problem as #31 (comment) on vim.
I use command pkg install vim to install vim.the version information of my vim is below:

VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 21 2018 14:10:26)
Included patches: 1-300
Compiled by builder@ded341cd6b3c
Huge version without GUI.  Features included (+) or not (-):
+acl               +extra_search      +mouse_netterm     +tag_old_static
+arabic            +farsi             +mouse_sgr         -tag_any_white
+autocmd           +file_in_path      -mouse_sysmouse    -tcl
+autochdir         +find_in_path      +mouse_urxvt       +termguicolors
-autoservername    +float             +mouse_xterm       +terminal
-balloon_eval      +folding           +multi_byte        +terminfo
+balloon_eval_term -footer            +multi_lang        +termresponse
-browse            +fork()            -mzscheme          +textobjects
++builtin_terms    -gettext           +netbeans_intg     +timers
+byte_offset       -hangul_input      +num64             +title
+channel           +iconv             +packages          -toolbar
+cindent           +insert_expand     +path_extra        +user_commands
-clientserver      +job               -perl              +vartabs
-clipboard         +jumplist          +persistent_undo   +vertsplit
+cmdline_compl     +keymap            +postscript        +virtualedit
+cmdline_hist      +lambda            +printer           +visual
+cmdline_info      +langmap           +profile           +visualextra
+comments          +libcall           -python            +viminfo
+conceal           +linebreak         -python3           +vreplace
+cryptv            +lispindent        +quickfix          +wildignore
+cscope            +listcmds          +reltime           +wildmenu
+cursorbind        +localmap          +rightleft         +windows
+cursorshape       -lua               -ruby              +writebackup
+dialog_con        +menu              +scrollbind        -X11
+diff              +mksession         +signs             -xfontset
+digraphs          +modify_fname      +smartindent       -xim
-dnd               +mouse             +startuptime       -xpm
-ebcdic            -mouseshape        +statusline        -xsmp
+emacs_tags        +mouse_dec         -sun_workshop      -xterm_clipboard
+eval              -mouse_gpm         +syntax            -xterm_save
+ex_extra          -mouse_jsbterm     +tag_binary        
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/data/data/com.termux/files/usr/share/vim"
Compilation: aarch64-linux-android-clang -c -I. -Iproto -DHAVE_CONFIG_H   -I/data/data/com.termux/files/usr/include  -Oz -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: aarch64-linux-android-clang   -L/data/data/com.termux/files/usr/lib -Wl,--as-needed -o vim        -lm -lelf  -lncursesw -liconv           

In my case,your solution doesn't work.I try to motify the file matchup.vim(line:32).It looks like this:

if has('nvim')
   if exists(':MatchDebug')
      runtime! autoload/matchup/unmatchit.vim
  endif
elseif $HOME =~ "termux"
      runtime! autoload/matchup/unmatchit.vim
elseif exists('g:loaded_matchit')
    echoerr 'match-up must be loaded before matchit'
    finish
endif

Though everything looks well,I am not sure that it is a good solution.I hope a better way to handle it.

Originally posted by @King-1025 in #31 (comment)

[BUG] tag match bug

image

test example:

    <Flex justify="between" style={[tableStyle.mainWrapper, tableStyle.noData]}>
      <FlexItem flex>
        <ActivityIndicator animating size="large"/>
        <Text style={tableStyle.noDataText}>数据加载中。。。</Text>
      </FlexItem>
    </Flex>

Error "warning: adding embedded git repository"

  1. What vim version are you using?
MacVim Version 8.1.280 (151)
VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 15 2018)
  1. Steps to reproduce
  • Add Plug 'andymass/vim-matchup'
  • Run :PlugInstall
  1. Expected behavior

I was expecting to add this plugin (folder) to my repo (my vimfiles).

  1. Observed behavior

Git gets confused when I try to add the plugin to my repo (vimfiles):

$ git add plugged/vim-matchup

warning: adding embedded git repository: plugged/vim-matchup
hint: You've added another git repository inside your current repository.
hint: Clones of the outer repository will not contain the contents of
hint: the embedded repository and will not know how to obtain it.
hint: If you meant to add a submodule, use:
hint:
hint: 	git submodule add <url> plugged/vim-matchup
hint:
hint: If you added this path by mistake, you can remove it from the
hint: index with:
hint:
hint: 	git rm --cached plugged/vim-matchup
hint:
hint: See "git help submodule" for more information.

This doesn't happen with my other plugins.

Am I doing anything wrong? Could you please shed some light?
Thank you very much.

[improve][feature] only highlight the first word in an opening tag

Hey, no bug or such, and I really like to get started with this plugin, but something just popped up right away my mind as went along.

So on (long html) tags its pretty annoying that my colorscheme highlighting gets overwritten.
(So ether toggle the plugin when editing or: )

Great would be to highlight only the first word in an opening tag (including '<' and closing '>')
like so:
<li class="something" attr="attr and class is nicely highlighted" > item </li>
instead of:
<li class="something" keyattr="attr and class has no highlight anymore"> item </li>

Or maybe you have any hints for me to change the highlighting.. ? ..or the plugin is intended to work that way, and it's a bug I experience on my setup? I don't know.

ty in advance and sry if this is post is misplaced


Edit:

hi MatchParen gui=bold
Works fine for me, for now. But I'd like something better

ords

Explain the issue

Most issues are related to bugs or problems. In these cases, you should
include a minimal working example and a minimal vimrc file (see below), as
well as:

  1. What vim version are you using?
  2. Steps to reproduce
  3. Expected behavior
  4. Observed behavior

If your issue is instead a feature request or anything else, please
consider if minimal examples and vimrc files might still be relevant.

Minimal working example

Please provide a minimal working example, e.g.,

if l:x == 1
  call one()
elseif l:x == 2
  call two()
else
  call three()
endif

Minimal vimrc file

Please provide a minimal vimrc file that reproduces the issue. The
following should often suffice:

set nocompatible

" load match-up
let &rtp  = '~/.vim/bundle/vim-matchup,' . &rtp
let &rtp .= ',~/.vim/bundle/vim-matchup/after'

" load other plugins, if necessary
" let &rtp = '~/path/to/other/plugin,' . &rtp

filetype plugin indent on
syntax enable

" match-up options go here

tpope's vim-sensible and matchup

When I have vim-sensible loaded before vim-matchup, I get the error, 'match-up must be loaded before matchit'. But the docs say, 'matchit.vim should not be loaded. If it is loaded, it must be loaded before match-up (in this case, matchit will be disabled when match-up loads).'

Should the docs be fixed?

Hotfix for combined filetype

Hi, similar to issue 42, I'm try to highlight only tagname in JSX file follow the g:matchup_hotfix_javascript solution #42 (comment).

I can confirm it works except that my &:filetype is javascript.jsx (contains a dot .).
Read Vim help that 'filetype' can contain dots, which means several separated types, could we add support for this? Maybe detect dots and try each filetype's hotfix. Thank you very much.

Xcode-style highlighting

Hi,
I was wondering if it would be possible to implement highlighting in the style of Xcode? This would mean that the highlighted text would not be unhighlighted when the cursor is not on it anymore. Instead, a configurable amount (say, 500ms default) of time passes before the highlighting goes away again. In other words, positioning the cursor on a pair would cause a brief flash, which would go away again after a moment, regardless of whether the cursor moves away or stays on the pair.

Thanks for all the hard work you’ve put into this plugin 😀

Minor doc issue: there is no help tag *any*-block

You refer to *any* in

                                                         *v_a%* *a%*
a%                      select an |any| block.
                        This closely matches match vim's built-in |ab|.

and

i%                      select the inside of an |any| block.
                        This closely matches match vim's built-in |ib|.
                        See also |matchup-feat-linewise|.

However, there is no help tag *any* specified. Pressing <C-]> jumps to *tag-any-white* which is not helpful.

I suppose that you refer to following sentence in *matchup-features*:

The if/endif pair is called an "open-to-close" block and the if/else, else/elsif, and elseif/endif are called "any" blocks.

BTW: Since you call your plugin 'match-up' with a hyphen, I guess you want to rename in README.md:

diff --git a/README.md b/README.md
index 7fa243d..f3effd6 100644
--- a/README.md
+++ b/README.md
@@ -365,7 +365,7 @@ default: 0

 ### Variables

-matchup understands the following variables from matchit.
+match-up understands the following variables from matchit.
 - `b:match_words`
 - `b:match_skip`
 - `b:match_ignorecase`

I am not a big fan of using in ordinary text match-up and as a repository name, variable-, and help tag-prefix matchup. However, it apparently is done consistently, I never wonder whether I should use a hyphen or not.

Enable JSX syntax in Javascript files

Explain the issue

Enable JSX syntax.

Minimal working example

Example:
https://github.com/hoschi/yode/blob/develop/packages/demo/src/components/EditorPaper.js

const EditorPaper = ({header, style, isFocused, editorProps}) => {
    let zDepth
    if (isFocused) {
        zDepth = 3
    } else {
        zDepth = 1
    }
    let editorContainerStyle = Object.assign({}, editorContainerStyleBase)
    if (!editorProps.error && editorProps.hasConnectedError) {
        editorContainerStyle.opacity = 0.65
    }
    return <Paper zDepth={ zDepth } style={ Object.assign({}, style, paperStyle) }>
               <div style={ headerStyle }>
                   { header }
               </div>
               <div style={ editorContainerStyle }>
                   <Editor {...editorProps} />
               </div>
           </Paper>
}

Deepcopy in function "s:matchparen.highlight" fails when nesting is too deep

I am using VIM 8.0, with patches 1-1300.

After updating to the latest version of this plugin, while working on an HTML file and moving the cursor over certain tags, I get the error

Error detected while processing function 5:
line   91:
E698: variable nested too deep for making a copy

I traced this to the deepcopy call in the function s:matchparen.highlight in autoload/matchup/matchparen.vim. Not sure how this can be fixed, but I'm sure a silent failure would work for now, instead of the error message popup. I just wrapped the deepcopy line in a try..endtry statement; in the catch block, there is an empty return statement.

Thanks in advance.

[feature] implement deferred highlighting

Navigating with highlighting can sometimes be slow. Deferred highlighting would improve cursor performance, while introducing a short delay to highlighting (for example 40 milliseconds seems reasonable).

This would introduce the following options

let g:matchup_matchparen_deferred = 0 / 1
let g:matchup_matchparen_deferred_show_delay = 40
let g:matchup_matchparen_deferred_hide_delay = 200

Only available if has('timers').

cf #5.

plugin is always autoloaded

The call to matchup#init() in plugin/matchup.vim defeats the purpose of autoload/, it causes vim to source the autoload/ scripts as soon as plugin/matchup.vim is sourced (for most users that means "during startup"). Normally, plugins should keep minimal stuff in plugin/matchup.vim and only trigger autoload on first use.

It's somewhat academic since most files will need matchup, but if user starts vim to view text files or logs, or blank, startup cost for matchup is still present.

Really nice work on this plugin, use of the statusline is cool.

delim match hangs on file that has very long column

Explain the issue

  1. What vim version are you using?

    vim 8.1

  2. Steps to reproduce

    1. supply a file that has:
      • few lines
      • very very long column
      • typically, xxx.min.js files
    2. move cursor to line end
    3. move cursor by j or k
  3. Expected behavior

    cursor move freely

  4. Observed behavior

    vim hangs on matchup's delim match, ctrl-c to break would result on:

    Error detected while processing function 2[3]..3[55]..matchup#delim#get_current[1]..<SNR>171_get_delim:
    line  107:
    Interrupted
    

Minimal vimrc file

set synmaxcol=200

" match-up options go here
let g:matchup_matchparen_status_offscreen=0
let g:matchup_matchparen_pumvisible=0
let g:matchup_mappings_enabled=0
let g:matchup_text_obj_enabled=0
let g:matchup_matchparen_stopline=20

NOTE: g:matchup_matchparen_deferred would only delay the issue,
when it actually starts to match, vim still hangs on matching

Missing toggle function: DoMatchParen NoMatchParen

The original plugin matchparen.vim provides two functions

command! DoMatchParen call s:DoMatchParen()
command! NoMatchParen call s:NoMatchParen()

I am using them in the following way inspired by vim-unimpaired by defining in my vimrc:

augroup vimenter
  autocmd!
  autocmd VimEnter * NoMatchParen
augroup END
nnoremap [op :DoMatchParen<CR>
nnoremap ]op :NoMatchParen<CR>
nnoremap cop :<C-R>=exists("g:loaded_matchparen") ? 'NoMatchParen' : 'DoMatchParen'<CR><CR>

I enable highlighting of matching objects (parenthesis or b:match_words) only on demand with cop. I usually consider them too slow, however, sometimes it is good to see matching objects.

BTW, are you aware of the pull request vim/vim#1338?

[improve] add prefix spaces for 'screen-off'

When I set foldcolumn=[1...n] or signcolumn=[yes|auto], the screen-offf line will not 'match' others.

function! s:format_statusline(offscreen) " {{{1
  let l:line = getline(a:offscreen.lnum)

  let l:sl = ''
  if &number || &relativenumber
    let l:nw = max([strlen(line('$')), &numberwidth-1]) + &foldcolumn + (&signcolumn==#'no'?0:2)
.
.
.

Wrong Search Pattern

Hey, I don't have time to look at the code right now, but I was just writing a little vimL and I noticed a bug. When I was editing this function (with :setf vim):

function! s:InNumber() abort
	let l:line = getline('.')
	let l:col = col('.') - 1
	" virtcol for start of number
	let l:start = l:col
	" virtcol for last character in number
	let l:end = l:col
	if (l:line[l:col:] !~# '\d')
		return
	endif
	if (l:line[l:col] !~# '\d')
		" number in rest of line (not under cursor)
		let l:curCol = l:col + 1 " current column in for loop
		" while this might be confusing, it should work. Temporarily store the
		" length of l:line into l:end. Use this for the break condition for the
		" loop below. If th
		let l:end = len(l:line)
		" find the first number in rest of line
		" for l:ch in l:line[l:curCol:]
		while l:curCol < l:end
			let l:ch = l:line[l:curCol]
			if (l:ch =~# '\d')
				if (l:start !=# l:col)
					" l:start was not set yet, and current char is a number
					let l:start = l:curCol
				endif
			else
				if (l:start !=# l:col)
					" l:start was changed, and current char is not a number;
					" if this condition is never true, then l:start and l:end
					" were both already set to the correct values
					let l:end = l:curCol - 1
					break
				endif
			endif
		endwhile
		let l:curCol += 1
	else
		" number is under cursor
		" iterate backwards over all characters from 0 to l:curCol-1 in order to
		" find l:start
		let l:start = 0
		let l:curCol = l:col - 1
		" for l:ch in join(reverse(split(l:line[:l:curCol], '.\zs')))
		while (l:curCol >= 0)
			let l:ch = l:line[l:curCol]
			if (l:ch !~# '\d')
				" current char is not a number;
				" if this condition is never true, then l:start was set to the
				" correct value anyway
				let l:start = l:curCol + 1
				break
			endif
			let l:curCol -= 1
		endwhile
		" iterate forwards over all characters from l:curCol+1 to $ in order to
		" find l:end
		let l:end = len(l:line)
		let l:curCol = l:col + 1
		" for l:ch in l:line[l:curCol:]
		while l:curCol < l:end
			let l:ch = l:line[l:curCol]
			if (l:ch !~# '\d')
				" current char is not a number;
				" if this condition is never true, then l:end was set to the
				" correct value anyway
				let l:end = l:curCol - 1
				break
			endif
		endwhile
	endif
	" finally, just select the appropriate region on the line
	execute 'normal! '.l:start.'|v'.l:end.'|'
endfunction

My cursor was on the first if part and I pressed % to go to to the end, but it jumped to l:end. I think you might call search('\<end\>') or something along those lines, but maybe it should be search('[^:]\<end\>') for &ft ==# 'vim'since VimL can haveb:, l:, w:, g:, s:, t:, v:` (though I don't think that there is a v:end for anything) prefixes for variables.

Thanks!
dylnmc


post scriptum

To whom it might concern: please do not use or even read the above function. It does not work (because it fails to take into account virtual columns and it is just utterly terrible). Thank you, dylnmc

matchparen_deferred and neovim

Hi,

I am using NeoVim , version 0.2.0.
When using

let g:matchup_matchparen_deferred = 1

, commands like dw stop working on, at least, txt files. That is, if one types dw, the cursor moves one word to the right, instead of deleting the next one. Sometimes, if the d and w are typed fast enough, the command works as expected.

On tex files with the vimtex plugin loaded, the command dw behaves as expected.

This doesnt happen on Vim 8, so I am not sure if this is matchup falt.

Minimal example, using Vundle,

set nocompatible              " required by Vundle
filetype off                  " required by Vundle

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'
Plugin 'andymass/vim-matchup'

call vundle#end()             " required by Vundle
filetype plugin indent on     " required by Vundle

let g:matchup_matchparen_deferred = 1

thanks

Wrong XML tag matched and replaced

Using vim-matchup commit e3016e0
vim 8.1

let g:loaded_matchit = 1 " near the top of ~/.vim/vimrc
...
Plug 'andymass/vim-matchup' " install with vim-plug
...
" plugin vim-matchup {{{1
"To enable the experimental transmute module
let g:matchup_transmute_enabled = 1
"Deferred highlighting improves cursor movement performance
let g:matchup_matchparen_deferred = 1

Explain the issue

For the attached XML file, which consistently reproduces the problem on my system:

  1. :set ft=xml :syn on then put the curson on line 6, which is blank.
  2. Note that the <checkbox> tag on lines 7-12 is properly closing. We're going to show that either <checkbox> or </checkbox> are incorrectly changed to another tag when deleting a blank line.
  3. Delete blank line 6. This puts the cursor on line 7 (now 6) and highlights <checkbox> as well as </checkbox> on line 12 (now 11). I'm going to use new line numbers now.
  4. Press j to move to blank line 12
  5. Delete line 12.
  6. Note that </checkbox> has turned into </label>. Alternatively, note that <checkbox> has turned into <text>. In either case, it seems that vim-matchup is tricked into matching one of the tags of line 14.

Note: the attached file comes from a real project - it's a valid gtkdialog specification.
vim-matchup-20181230.xml.txt

Neovim CPU usage

This plugin caused CPU usage

neovim 0.2.2

After adding this plugin neovim always use CPU
screenshot from 2018-03-27 00-49-40

Profile output:

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
   70   0.072696   0.003727  airline#extensions#branch#get_head()
   70   0.068968   0.003924  airline#extensions#branch#head()
   70   0.047848   0.008579  <SNR>144_update_branch()
   70   0.032773   0.003150  <SNR>144_update_git_branch()
   70   0.029623   0.002470  fugitive#head()
  140   0.029335   0.017666  airline#extensions#ale#get()
   70   0.021974   0.006070  <SNR>72_repo_head()
   70   0.021736   0.014295  airline#extensions#hunks#get_hunks()
   70   0.020920   0.018225  airline#extensions#whitespace#check()
   70   0.017196   0.014387  <SNR>144_update_untracked()
   70   0.016022   0.001103  airline#extensions#ale#get_warning()
   70   0.015737             airline#check_mode()
   70   0.015471   0.001055  airline#extensions#ale#get_error()
  490   0.014244             airline#util#append()
  630   0.009749             airline#util#wrap()
  140   0.009622             <SNR>72_repo()
  140   0.009533   0.002630  ale#statusline#Count()
   70   0.008830   0.006783  <SNR>72_repo_head_ref()
   70   0.007441   0.004522  <SNR>142_get_hunks()
  140   0.007016             airline#util#shorten()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   70   0.020920   0.018225  airline#extensions#whitespace#check()
  140   0.029335   0.017666  airline#extensions#ale#get()
   70              0.015737  airline#check_mode()
   70   0.017196   0.014387  <SNR>144_update_untracked()
   70   0.021736   0.014295  airline#extensions#hunks#get_hunks()
  490              0.014244  airline#util#append()
  630              0.009749  airline#util#wrap()
  140              0.009622  <SNR>72_repo()
   70   0.047848   0.008579  <SNR>144_update_branch()
  140              0.007016  airline#util#shorten()
  140              0.006903  <SNR>225_GetCounts()
   70   0.008830   0.006783  <SNR>72_repo_head_ref()
   70              0.006496  <SNR>144_update_hg_branch()
   70   0.021974   0.006070  <SNR>72_repo_head()
   70              0.005438  airline#parts#ffenc()
   70              0.005251  airline#extensions#fugitiveline#bufname()
   70   0.006141   0.004569  airline#extensions#tagbar#currenttag()
   70   0.007441   0.004522  <SNR>142_get_hunks()
   70              0.004511  airline#parts#spell()
   70   0.068968   0.003924  airline#extensions#branch#head()

Wrong matching (HTML)

I was working with a very simple HTML when I noticed that the highlighting is not right & that also the transmute doesn't work, here is the HTML

<ul class="btn-group">
  <li>
  </li>
</ul>

and here is the issue:

wrong-match

and here are my settings:

let g:matchup_transmute_enabled = 1
let g:matchup_matchparen_deferred = 1

High CPU usage in macvim when using ignorecase and hlsearch

Explain the issue

when using vim-matchup and ignorecase and hlsearch set in the .vimrc (both must be set), I see high cpu usage (up to 100% cpu) when editing a ruby file (see attached example file) (might also happen in other formats, didn't check, but didn't happen in a small vimscript file)

  1. vim version:
vim --version
VIM - Vi IMproved 8.1 (2018 May 17, compiled May 31 2018 18:29:18)
macOS version
Included patches: 1-22
Compiled by Homebrew
Huge version with MacVim GUI.  Features included (+) or not (-):
+acl               +farsi             +mouse_netterm     +tag_binary
+arabic            +file_in_path      +mouse_sgr         +tag_old_static
+autocmd           +find_in_path      -mouse_sysmouse    -tag_any_white
-autoservername    +float             +mouse_urxvt       +tcl
+balloon_eval      +folding           +mouse_xterm       +termguicolors
+balloon_eval_term -footer            +multi_byte        +terminal
+browse            +fork()            +multi_lang        +terminfo
++builtin_terms    +fullscreen        -mzscheme          +termresponse
+byte_offset       -gettext           +netbeans_intg     +textobjects
+channel           -hangul_input      +num64             +timers
+cindent           +iconv             +odbeditor         +title
+clientserver      +insert_expand     +packages          +toolbar
+clipboard         +job               +path_extra        +transparency
+cmdline_compl     +jumplist          +perl              +user_commands
+cmdline_hist      +keymap            +persistent_undo   +vertsplit
+cmdline_info      +lambda            +postscript        +virtualedit
+comments          +langmap           +printer           +visual
+conceal           +libcall           +profile           +visualextra
+cryptv            +linebreak         -python            +viminfo
+cscope            +lispindent        +python3           +vreplace
+cursorbind        +listcmds          +quickfix          +wildignore
+cursorshape       +localmap          +reltime           +wildmenu
+dialog_con_gui    -lua               +rightleft         +windows
+diff              +menu              +ruby              +writebackup
+digraphs          +mksession         +scrollbind        -X11
+dnd               +modify_fname      +signs             -xfontset
-ebcdic            +mouse             +smartindent       +xim
+emacs_tags        +mouseshape        +startuptime       -xpm
+eval              +mouse_dec         +statusline        -xsmp
+ex_extra          -mouse_gpm         -sun_workshop      -xterm_clipboard
+extra_search      -mouse_jsbterm     +syntax            -xterm_save
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "$VIM/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/Applications/MacVim.app/Contents/Resources/vim"
Compilation: clang -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe  -DMACOS_X -DMACOS_X_DARWIN  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: clang   -L.             -L /BuildRoot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.Internal.sdk/usr/local/libressl/lib -L/BuildRoot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.Internal.sdk/usr/local/lib -L.             -L /BuildRoot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.Internal.sdk/usr/local/libressl/lib -L/BuildRoot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.Internal.sdk/usr/local/lib  -L/usr/local/lib -o Vim -framework Cocoa -framework Carbon       -lm  -lncurses -liconv -framework AppKit   -fstack-protector  -L/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE -lperl  -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin -lpython3.6m -framework CoreFoundation -F/System/Library/Frameworks -framework Tcl -framework CoreFoundation -framework Ruby 
  1. steps to reproduce.
    using the attached minimal .vimrc and the attached test.rb, use keyboard to run up and down the file and see the CPU skyrocket.

  2. Expected behavior
    smooth cursor behavior and low CPU usage.

  3. Observed behavior
    choppy cursor, high CPU

Minimal working example

(Tried to cut more of the code, but it seems that the length of the code is a factor in the CPU usage)

require 'yaml'
require 'aws-sdk'

class Time
  COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31].freeze

  class << self
    def days_in_month(month, year)
      if month == 2 && ::Date.gregorian_leap?(year)
        29
      else
        COMMON_YEAR_DAYS_IN_MONTH[month]
      end
    end
  end
end

module LoremIpsum 
  class Lorem < Ipsum 
    def test 
      lorem_ipsum = Aws::Credentials.new(@config[:lorem_ipsum][:dolor_sit], @config[:amet][:consectetur])
      @adipiscing = @config[:elit][:sed]
      @do = Aws::S3::Client.new(:region => @config[:eiusmod][:tempor], :credentials => lorem_ipsum)
      @incididunt = Aws::S3::Bucket.new(@adipiscing , client: @do)
      @ut = @config[:labore][:et]
      @dolore = /#{@config[:magna]}/
      @aliqua = /#{@config[:ut]}/
      @enim = @config[:ad] || false
      @minim = @config[:veniam].nil? ? :quis: @config[:nostrud].to_sym
      @exercitation = @config[:ullamco]
      @laboris = (@config[:nisi] || 0) * 60
      @ut = @config[:aliquip] || false
      @ex = @config[:ea] || false

      dolor = {:region =>            @config[:ex][:ea],
               :access_key_id =>     @config[:commodo][:consequat],
               :secret_access_key => @config[:duis][:aute]}
      @irure = Aws::S3::Client.new(dolor)

      @reprehenderit = @config[:in][:voluptate]
      @velit = Aws::S3::Bucket.new(@esse, client: @cillum)
      @dolore = @config[:eu][:fugiat]
      @nulla = @config[:pariatur]

      @excepteur = @config[:velit][:esse]
      @cillum = Aws::S3::Bucket.new(@dolore, client: @eu)
      @fugiat = @config[:nulla][:pariatur]

      if (@config[:excepteur])
        sint(@config[:occaecat])
      elsif (@config[:cupidatat])
        non(@config[:proident])
      else
        throw "sunt"
      end

      @in = Aws::EMR::Client.new(culpa)

      @qui = @config[:officia][:deserunt]

      @mollit = @config[:anim]

      @id = @config[:est][:laborum]
    end
  end
end

LoremIpsum::Lorem.test if __FILE__ == $0

Minimal vimrc file

Please provide a minimal vimrc file that reproduces the issue. The
following should often suffice:

set nocompatible

" load match-up
let &rtp  = '~/.vim/bundle/vim-matchup,' . &rtp
let &rtp .= ',~/.vim/bundle/vim-matchup/after'

" load other plugins, if necessary
" let &rtp = '~/path/to/other/plugin,' . &rtp

set ignorecase " Case insensitive search
set hlsearch   " Highlight search results

filetype plugin indent on
syntax enable

" match-up options go here

Add vim doc

An informative README file is good, but IMHO, it is much more important to write a good doc/vim-matchup.txt file to be read from inside vim. I think it should be rather quick to write one based on the current version of the README file.

Deferred timer fails when using FlyGrep

Explain the issue

After searching project with FlyGrep.vim,
and using let g:matchup_matchparen_deferred = 1, i get this error:
screenshot

Minimal working example

  • Open any project
  • run :FlyGrep
  • find something
  • press enter

Minimal vimrc file

Please provide a minimal vimrc file that reproduces the issue. The
following should often suffice:

set nocompatible

" load match-up
let &rtp  = '~/.vim/bundle/vim-matchup,' . &rtp
let &rtp .= ',~/.vim/bundle/vim-matchup/after'

" load other plugins, if necessary
let &rtp .= '~/path/to/FlyGrep.vim'

filetype plugin indent on
syntax enable

" match-up options go here
let g:matchup_matchparen_deferred = 1

When let g:matchup_matchparen_deferred = 1 is not set, everything works fine.

Note that i'm using neovim v0.3.2-dev

[fix] disable off-screen when scrolling with j/k

Please patch this, it will fix not showing off-screen when cursor just right on the screen edge. :)

  " disable off-screen when scrolling with j/k
  let l:scrolling = winheight(0) > 2*&scrolloff
        \ && (line('.') == line('w$')-&scrolloff+1
        \     || line('.') == line('w0')+&scrolloff-1)

Conditional compilation #ifdef and splitting if() then statement over two lines

I was trying out the features (a.1) jump between matching words (command %) and (a.2) jump to open and close words (commands [% and ]%) to jump, for example, from one if to the next elseif. However, I work with programs that contain #ifdef for conditional compilation. Also, sometimes if() then are split over two lines by means of the character &. In these cases, the commands %, [% or ]% seem not to be working.
Here is an example:

program ifElseIfElseProg
implicit none

   integer :: a = 100
 
   if( a == 10 ) then
  
      a = a + 1
#ifdef three_d
		 + 3
#endif      
   
   else if( a == 20 )
&  then
      print*, "Value of a is 20" 
  
   else if( a == 30 ) then
   
      print*, "Value of a is 30" 
  
   else
   
      print*, "None of the values is matching" 
      
   end if
   
   print*, "exact value of a is ", a
 
end program ifElseIfElseProg

[Bug] SQL keywords matching problem

Explain the issue

See the files content below.

  1. Steps to reproduce
  • Start vim with › HOME=$PWD MYVIMRC=$PWD/matchup_vimrc vim test.sql
  • Put cursor as drop or function in line 1, press %.
  1. Expected behavior
  • Nothing
  1. Observed behavior
  • Cusor jump to line 8 (return;).
  • Try again with the second function (line 3), cursor jump to returns at line 4.

Minimal working example

Please provide a minimal working example, e.g.,

-- file test.sql
drop function if exists dummy;

create or replace function dummy()
returns setof text as 
$$
begin
	return next 'something';
	return;
end
$$ language 'plpgsql';

Minimal vimrc file

" file matchup_vimrc
set nocompatible
let &rtp  = '~/.vim-plugged/vim-matchup/,' . &rtp
filetype plugin indent on
syntax enable

Outer most 2 braces are not matched in a file with more than 401 lines

The outer most 2 braces are not matched in the attached file using % from matchup
If one joins 2 lines (thus reducing the number of lines by 1) they match.

Another finding is that if one places the cursor on line 2 or on the penultimate line of this file there is a weird entry on the statusline.

In the case of the file with 2 lines joined this weird status line shows up if the cursor is on line 1, 2, the last or the penultimate line.
Matchup_Problem_File.txt

RFC: Convenience mapping I% for 1i% and A% for 1a%

I would like to easily select following vimscript function by growing the selection.

function! s:test()

    if l:x == 1
      call one()
    else
      call two()
    elseif " CURSOR
      call three()
    endif

    let l:str = "hello"

    return l:str

endfunction

Typingv1a%1a% requires only my left hand and the number 1 has to be pressed by my weak left pinky finger.

Also I would avoid counting the exact level of nested structures recognized by match-up which I might not recall exactly.
One could use genericallyv9a% to select the complete function as well without counting (assuming the maximum level of nested structures recognized by match words is at most 9; I guess this is for 99 percent the case). However, sometimes it would be nice to do this incrementally, for example when the function is a member function of a class.

Pressing vA%A% is quite handy; keeping the shift key pressed while pressing a5 (=A%) as often as you wish.

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.