mirror of
https://github.com/chenasraf/vim-matchup.git
synced 2026-05-18 01:38:57 +00:00
Improve delim skip, make minor changes to readme
This commit is contained in:
53
README.md
53
README.md
@@ -3,11 +3,14 @@
|
||||
:warning: warning :warning: this plugin is unfinished and under heavy
|
||||
active development. It is not ready for use yet!
|
||||
|
||||
match-up is a replacement for the venerable vim plugin
|
||||
[matchit.vim](http://ftp.vim.org/pub/vim/runtime/macros/matchit.txt).
|
||||
match-up is a replacement for the venerable vim plugin [matchit.vim]
|
||||
match-up aims to replicate all of matchit's features, fix a number of its
|
||||
deficiencies and bugs, and add a few totally new features. It also
|
||||
replaces the plugin matchparen, allowing matchit words to be highlighted.
|
||||
replaces the standard plugin [matchparen], allowing all of matchit's words
|
||||
to be highlighted along with the `matchpairs` (`(){}[]`).
|
||||
|
||||
[matchit.vim]: http://ftp.vim.org/pub/vim/runtime/macros/matchit.txt
|
||||
[matchparen]: http://ftp.vim.org/pub/vim/runtime/doc/pi_paren.txt
|
||||
|
||||
<img src='https://github.com/andymass/matchup.vim/wiki/images/teaser.jpg' width='300px' alt='and in this corner...'>
|
||||
|
||||
@@ -19,6 +22,8 @@ Contributions are welcome!
|
||||
* [Overview](#overview)
|
||||
* [Installation](#installation)
|
||||
* [Features](#features)
|
||||
* [FAQ](#faq)
|
||||
* [Interoperability](#interoperability)
|
||||
* [Development](#development)
|
||||
|
||||
## Overview
|
||||
@@ -49,20 +54,20 @@ Or use some other plugin manager:
|
||||
|
||||
## Features
|
||||
|
||||
| feature | __match-up__ | matchit | matchparen |
|
||||
| -------------------------------------- | ------------- | ------------- | ------------- |
|
||||
| (a.1) jump between matching constructs | :thumbsup: | :thumbsup: | :x: |
|
||||
| (a.2) jump to open, close | :thumbsup: | :question: | :x: |
|
||||
| (a.3) jump inside | :thumbsup: | :question: | :x: |
|
||||
| (b.1) full set of text objects | :thumbsup: | :x: | :x: |
|
||||
| (c.1) auto-insert open, close, and mid | :thumbsup: | :x: | :x: |
|
||||
| (c.2) auto-completion | :thumbsup: | :x: | :x: |
|
||||
| (c.3) parallel transmutations :star2: | :thumbsup: | :x: | :x: |
|
||||
| (c.4) split and join | :thumbsup: | :x: | :x: |
|
||||
| (d.1) highlight ()[]{} | :thumbsup: | :x: | :thumbsup: |
|
||||
| (d.2) highlight _all_ matches | :thumbsup: | :x: | :x: |
|
||||
| (e.1) modern, modular coding style | :thumbsup: | :x: | :x: |
|
||||
| (e.2) actively developed | :thumbsup: | :x: | :x: |
|
||||
| | feature | __match-up__ | matchit | matchparen |
|
||||
| ----- | -------------------------------- | ------------- | ------------- | ------------- |
|
||||
| (a.1) | jump between matching constructs | :thumbsup: | :thumbsup: | :x: |
|
||||
| (a.2) | jump to open, close | :thumbsup: | :question: | :x: |
|
||||
| (a.3) | jump inside | :thumbsup: | :question: | :x: |
|
||||
| (b.1) | full set of text objects | :thumbsup: | :x: | :x: |
|
||||
| (c.1) | auto-insert open, close, and mid | :thumbsup: | :x: | :x: |
|
||||
| (c.2) | auto-completion | :thumbsup: | :x: | :x: |
|
||||
| (c.3) | parallel transmutations :star2: | :thumbsup: | :x: | :x: |
|
||||
| (c.4) | split and join | :thumbsup: | :x: | :x: |
|
||||
| (d.1) | highlight ()[]{} | :thumbsup: | :x: | :thumbsup: |
|
||||
| (d.2) | highlight _all_ matches | :thumbsup: | :x: | :x: |
|
||||
| (e.1) | modern, modular coding style | :thumbsup: | :x: | :x: |
|
||||
| (e.2) | actively developed | :thumbsup: | :x: | :x: |
|
||||
|
||||
Legend: :thumbsup: supported. :construction: TODO, planned, or in progress.
|
||||
:question: poorly implemented, broken, or uncertain. :x: not possible.
|
||||
@@ -87,20 +92,20 @@ constructs 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.
|
||||
|
||||
- (a.1) jump between matching constructs
|
||||
#### (a.1) jump between matching constructs
|
||||
- `%` go forwards matching construct `[count]` times
|
||||
- `{count}%` forwards `{count}` times. Requires
|
||||
`let g:matchup_override_Npercent = 1`
|
||||
- `g%` go backwards matching construct `[count]` times
|
||||
|
||||
- (a.2) jump to open and close
|
||||
#### (a.2) jump to open and close
|
||||
- `[%` go to `[count]` previous unmatched open construct
|
||||
- `]%` go to `[count]` next unmatched close construct
|
||||
|
||||
- (a.3) jump inside
|
||||
#### (a.3) jump inside
|
||||
- `z%` go to inside nearest `[count]`th inner contained block.
|
||||
|
||||
- (b.1) full set of text objects
|
||||
#### (b.1) full set of text objects
|
||||
- `i%` the inside of an open to close block
|
||||
- `1i%` the inside of an any block
|
||||
- `{count}i%` If count is not 1, the inside open-to-close block
|
||||
@@ -203,9 +208,11 @@ as possible when submitting issues and pull requests.
|
||||
|
||||
## Interoperability
|
||||
|
||||
- Conflicts with end-wise
|
||||
- match-up is not compatible with [vimtex](https://github.com/lervag/vimtex)
|
||||
and will be disabled automatically when vimtex is detected.
|
||||
- the end-completion maps conflict with [vim-endwise](https://github.com/tpope/vim-endwise).
|
||||
- matchit.vim should not be loaded. If it is loaded, it must be loaded
|
||||
before match-up.
|
||||
before match-up (in this case, matchit is disabled).
|
||||
- match-up loads matchparen if it is not already loaded.
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
@@ -20,7 +20,7 @@ function! s:init_options()
|
||||
" see *cpo-M*
|
||||
|
||||
call s:init_option('matchup_motion_enabled', 1)
|
||||
call s:init_option('matchup_motion_cursor_end', 1) " xxx to implement
|
||||
call s:init_option('matchup_motion_cursor_end', 1)
|
||||
call s:init_option('matchup_motion_override_Npercent', 0)
|
||||
|
||||
call s:init_option('matchup_text_obj_enabled', 1)
|
||||
@@ -29,6 +29,9 @@ function! s:init_options()
|
||||
call s:init_option('matchup_transmute_enabled', 1)
|
||||
|
||||
call s:init_option('matchup_imap_enabled', 1)
|
||||
|
||||
call s:init_option('matchup_complete_enabled', 1)
|
||||
|
||||
endfunction
|
||||
|
||||
function! s:init_option(option, default)
|
||||
|
||||
@@ -286,9 +286,11 @@ function! s:get_delim(opts) " {{{1
|
||||
|
||||
let a:opts.cursorpos = l:cursorpos
|
||||
|
||||
" TODO XXX does this make any sense?
|
||||
if a:opts.direction !=# 'prev'
|
||||
let l:re .= '\%>'.(l:cursorpos).'c'
|
||||
" TODO XXX does this even make any sense?
|
||||
"
|
||||
" for current, we want to find matches that end after the cursor
|
||||
if a:opts.direction ==# 'current'
|
||||
let l:re .= '\%>'.(l:cursorpos).'c'
|
||||
endif
|
||||
|
||||
" let l:re .= '\%>'.(col('.')).'c'
|
||||
@@ -311,19 +313,25 @@ function! s:get_delim(opts) " {{{1
|
||||
\ : searchpos(l:re, 'bcnW', line('.'))
|
||||
if l:lnum == 0 | break | endif
|
||||
|
||||
" echo l:re l:lnum l:cnum | sleep 1
|
||||
" echo l:lnum l:cnum line('.')-s:stopline a:opts.direction | sleep 1
|
||||
"echo l:lnum l:re a:opts.direction ==# 'prev' | sleep 1
|
||||
" echo l:lnum l:cnum | sleep 1
|
||||
|
||||
" if invalid match, move cursor and keep looking
|
||||
" TODO this function should never be called
|
||||
" in 'current' mode, but we should be more explicit
|
||||
" if matchup#util#in_comment(l:lnum, l:cnum)
|
||||
" \ || matchup#util#in_string(l:lnum, l:cnum)
|
||||
|
||||
" XXX get rid of this..
|
||||
call matchup#pos#set_cursor([l:lnum, l:cnum])
|
||||
|
||||
" note: this function should never be called
|
||||
" in 'current' mode, but be explicit
|
||||
if a:opts.direction !=# 'current'
|
||||
\ && matchup#delim#skip(l:lnum, l:cnum)
|
||||
|
||||
" echo 'rejct'
|
||||
|
||||
" if invalid match, move cursor and keep looking
|
||||
call matchup#pos#set_cursor(a:opts.direction ==# 'next'
|
||||
\ ? matchup#pos#next(l:lnum, l:cnum)
|
||||
\ : matchup#pos#prev(l:lnum, l:cnum))
|
||||
@@ -728,7 +736,7 @@ function! s:get_matching_delims(down) dict " {{{1
|
||||
let l:open = self.augment.str
|
||||
endif
|
||||
|
||||
" echo 'op' l:open 'cl' l:close 're' l:re '|' self.groups 'a' self.augment
|
||||
echo '% op' l:open 'cl' l:close 're' l:re '|' self.groups 'a' self.augment
|
||||
|
||||
" turn \(\) into \%(\) for searchpairpos
|
||||
let l:open = s:remove_capture_groups(l:open)
|
||||
@@ -970,7 +978,7 @@ function! s:init_delim_lists() " {{{1
|
||||
" so we just disallow it.. (ref-2)
|
||||
|
||||
" get the groups like \(foo\) in the 'open' pattern
|
||||
let l:cg = s:get_delim_capture_groups(l:words[0])
|
||||
let l:cg = matchup#delim#get_capture_groups(l:words[0])
|
||||
|
||||
" if any of these contain \d raise a warning
|
||||
" and substitute it out (ref-2)
|
||||
@@ -1045,13 +1053,14 @@ function! s:init_delim_lists() " {{{1
|
||||
" turn things like \1 into \(...\)
|
||||
" replacement is guaranteed to exist and not contain \d
|
||||
let l:words_backref[l:i] = substitute(l:words_backref[l:i],
|
||||
\ s:notslash.'\\'.l:bref,
|
||||
\ g:matchup#re#backref,
|
||||
\ '\='''.l:cg[l:bref].str."'", '') " not global!!
|
||||
" \ s:notslash.'\\'.l:bref,
|
||||
|
||||
" echo '#'.l:i '%' '\'.l:bref l:words_backref[l:i] l:cg[l:bref]
|
||||
|
||||
let l:prev_max = max(keys(l:cg2))
|
||||
let l:cg2 = s:get_delim_capture_groups(l:words_backref[l:i])
|
||||
let l:cg2 = matchup#delim#get_capture_groups(l:words_backref[l:i])
|
||||
|
||||
" echo l:i '%' l:bref l:words_backref[l:i] l:cg2
|
||||
|
||||
@@ -1366,8 +1375,11 @@ function! s:init_delim_regexes_generator(list_name) " {{{1
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
function! s:get_delim_capture_groups(str) " {{{1
|
||||
let l:pat = s:notslash.'\zs\(\\(\|\\)\)'
|
||||
|
||||
function! matchup#delim#get_capture_groups(str, ...) " {{{1
|
||||
let l:allow_percent = a:0 ? a:1 : 0
|
||||
let l:pat = g:matchup#re#not_bslash . '\zs\('
|
||||
\ . (l:allow_percent ? '\\%(\|' : '') . '\\(\|\\)\)'
|
||||
|
||||
let l:start = 0
|
||||
|
||||
@@ -1379,7 +1391,7 @@ function! s:get_delim_capture_groups(str) " {{{1
|
||||
if l:match[1] < 0 | break | endif
|
||||
let l:start = l:match[2]
|
||||
|
||||
if l:match[0] ==# '\('
|
||||
if l:match[0] ==# '\(' || l:match[0] ==# '\%('
|
||||
let l:counter += 1
|
||||
call add(l:stack, l:counter)
|
||||
let l:brefs[l:counter] = {
|
||||
@@ -1412,12 +1424,12 @@ function! s:init_delim_skip() "{{{1
|
||||
" S:foo becomes (current syntax item) !~ foo
|
||||
" r:foo becomes (line before cursor) =~ foo
|
||||
" R:foo becomes (line before cursor) !~ foo
|
||||
let l:cursyn = "synIDattr(synID(line('.'),col('.'),1),'name')"
|
||||
let l:preline = "strpart(getline('.'),0,col('.'))"
|
||||
let l:cursyn = "synIDattr(synID(s:effline('.'),s:effcol('.'),1),'name')"
|
||||
let l:preline = "strpart(s:geteffline('.'),0,s:effcol('.'))"
|
||||
|
||||
if l:skip =~# '^[sSrR]:'
|
||||
let l:syn = strpart(l:skip, 2)
|
||||
|
||||
|
||||
let l:skip = {
|
||||
\ 's': l:cursyn."=~?'".l:syn."'",
|
||||
\ 'S': l:cursyn."!~?'".l:syn."'",
|
||||
@@ -1426,8 +1438,13 @@ function! s:init_delim_skip() "{{{1
|
||||
\}[l:skip[0]]
|
||||
endif
|
||||
|
||||
let l:skip = substitute(l:skip, '\<col\ze(',
|
||||
\ 's:effcol', 'g')
|
||||
for [l:pat, l:str] in [
|
||||
\ [ '\<col\ze(', 's:effcol' ],
|
||||
\ [ '\<line\ze(', 's:effline' ],
|
||||
\ [ '\<getline\ze(', 's:geteffline' ],
|
||||
\]
|
||||
let l:skip = substitute(l:skip, l:pat, l:str, 'g')
|
||||
endfor
|
||||
|
||||
return l:skip
|
||||
endfunction
|
||||
@@ -1445,13 +1462,27 @@ function! matchup#delim#skip(...) " {{{1
|
||||
\ || matchup#util#in_string(l:lnum, l:cnum)
|
||||
endif
|
||||
|
||||
" call s:set_effective_curpos(l:lnum, l:cnum)
|
||||
" call matchup#pos#set_cursor([l:lnum, l:cnum])
|
||||
|
||||
execute 'return (' b:matchup_delim_skip ')'
|
||||
endfunction
|
||||
|
||||
function! s:set_effective_curpos(lnum, cnum)
|
||||
endfunction
|
||||
|
||||
function! s:effcol(expr)
|
||||
return col(a:expr)
|
||||
endfunction
|
||||
|
||||
function! s:effline(expr)
|
||||
return line(a:expr)
|
||||
endfunction
|
||||
|
||||
function! s:geteffline(expr)
|
||||
return getline(a:expr)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:remove_capture_groups(re) "{{{1
|
||||
@@ -1482,6 +1513,9 @@ let s:not_bslash = '\v%(\\@<!%(\\\\)*)@<=\m'
|
||||
" xxx need to use this through code
|
||||
let s:backref = s:notslash.'\\'.'\(\d\)'
|
||||
|
||||
" whether we're behaving like in insert mode
|
||||
let s:insertmode = 0
|
||||
|
||||
let s:sidedict = {
|
||||
\ 'open' : ['open'],
|
||||
\ 'mid' : ['mid'],
|
||||
@@ -1505,3 +1539,4 @@ let s:types = {
|
||||
let &cpo = s:save_cpo
|
||||
|
||||
" vim: fdm=marker sw=2
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ function! s:matchparen.highlight() abort dict " {{{1
|
||||
if empty(l:corrlist) | return | endif
|
||||
|
||||
" echo l:corrlist
|
||||
echo map(copy(l:corrlist), 'v:val.rematch')
|
||||
"echo map(copy(l:corrlist), 'v:val.rematch')
|
||||
" echo map(copy(l:corrlist), 'v:val.lnum.",".v:val.cnum')
|
||||
" echo l:corrlist[0].class l:corrlist[1].class
|
||||
" \ l:corrlist[0].side l:corrlist[1].side
|
||||
|
||||
@@ -17,10 +17,11 @@ function! matchup#motion#init_module() " {{{1
|
||||
" <silent> XXX
|
||||
" todo make % vi compatible wrt yank (:h quote_number)
|
||||
|
||||
" the basic motions % and g%
|
||||
nnoremap <silent> <plug>(matchup-%)
|
||||
\ :<c-u>call matchup#motion#find_matching_pair(0, 1)<cr>
|
||||
\ :<c-u>call matchup#motion#find_matching_pair(0, 1)<cr>
|
||||
nnoremap <silent> <plug>(matchup-g%)
|
||||
\ :<c-u>call matchup#motion#find_matching_pair(0, 0)<cr>
|
||||
\ :<c-u>call matchup#motion#find_matching_pair(0, 0)<cr>
|
||||
|
||||
xnoremap <sid>(matchup-%)
|
||||
\ :<c-u>call matchup#motion#find_matching_pair(1, 1)<cr>
|
||||
|
||||
13
autoload/matchup/re.vim
Normal file
13
autoload/matchup/re.vim
Normal file
@@ -0,0 +1,13 @@
|
||||
" vim match-up - matchit replacement and more
|
||||
"
|
||||
" Maintainer: Andy Massimino
|
||||
" Email: a@normed.space
|
||||
"
|
||||
|
||||
let g:matchup#re#not_bslash = '\v%(\\@<!%(\\\\)*)@<=\m'
|
||||
|
||||
" 1 \1 \\1 \\\1 \\\\1 \\\\\1
|
||||
let g:matchup#re#backref = g:matchup#re#not_bslash.'\\'.'\(\d\)'
|
||||
|
||||
" vim: fdm=marker sw=2
|
||||
|
||||
Reference in New Issue
Block a user