Initial class construction

This commit is contained in:
João Narciso
2019-05-06 16:34:28 +02:00
parent 67f2d57e03
commit 431ff5f7d4
5813 changed files with 1622108 additions and 0 deletions

View File

@ -0,0 +1,62 @@
" cfilter.vim: Plugin to filter entries from a quickfix/location list
" Last Change: Aug 23, 2018
" Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
" Version: 1.1
"
" Commands to filter the quickfix list:
" :Cfilter[!] /{pat}/
" Create a new quickfix list from entries matching {pat} in the current
" quickfix list. Both the file name and the text of the entries are
" matched against {pat}. If ! is supplied, then entries not matching
" {pat} are used. The pattern can be optionally enclosed using one of
" the following characters: ', ", /. If the pattern is empty, then the
" last used search pattern is used.
" :Lfilter[!] /{pat}/
" Same as :Cfilter but operates on the current location list.
"
if exists("loaded_cfilter")
finish
endif
let loaded_cfilter = 1
func s:Qf_filter(qf, searchpat, bang)
if a:qf
let Xgetlist = function('getqflist')
let Xsetlist = function('setqflist')
let cmd = ':Cfilter' . a:bang
else
let Xgetlist = function('getloclist', [0])
let Xsetlist = function('setloclist', [0])
let cmd = ':Lfilter' . a:bang
endif
let firstchar = a:searchpat[0]
let lastchar = a:searchpat[-1:]
if firstchar == lastchar &&
\ (firstchar == '/' || firstchar == '"' || firstchar == "'")
let pat = a:searchpat[1:-2]
if pat == ''
" Use the last search pattern
let pat = @/
endif
else
let pat = a:searchpat
endif
if pat == ''
return
endif
if a:bang == '!'
let cond = 'v:val.text !~# pat && bufname(v:val.bufnr) !~# pat'
else
let cond = 'v:val.text =~# pat || bufname(v:val.bufnr) =~# pat'
endif
let items = filter(Xgetlist(), cond)
let title = cmd . ' /' . pat . '/'
call Xsetlist([], ' ', {'title' : title, 'items' : items})
endfunc
com! -nargs=+ -bang Cfilter call s:Qf_filter(1, <q-args>, <q-bang>)
com! -nargs=+ -bang Lfilter call s:Qf_filter(0, <q-args>, <q-bang>)

View File

@ -0,0 +1,72 @@
" Back to Qwerty keyboard after using Dvorak.
iunmap a
iunmap b
iunmap c
iunmap d
iunmap e
iunmap f
iunmap g
iunmap h
iunmap i
iunmap j
iunmap k
iunmap l
iunmap m
iunmap n
iunmap o
iunmap p
iunmap q
iunmap r
iunmap s
iunmap t
iunmap u
iunmap v
iunmap w
iunmap x
iunmap y
iunmap z
iunmap ;
iunmap '
iunmap "
iunmap ,
iunmap .
iunmap /
iunmap A
iunmap B
iunmap C
iunmap D
iunmap E
iunmap F
iunmap G
iunmap H
iunmap I
iunmap J
iunmap K
iunmap L
iunmap M
iunmap N
iunmap O
iunmap P
iunmap Q
iunmap R
iunmap S
iunmap T
iunmap U
iunmap V
iunmap W
iunmap X
iunmap Y
iunmap Z
iunmap <
iunmap >
iunmap ?
iunmap :
iunmap [
iunmap ]
iunmap {
iunmap }
iunmap -
iunmap _
iunmap =
iunmap +

View File

@ -0,0 +1,77 @@
" Dvorak keyboard, only in Insert mode.
"
" Change "inoremap" to "map!" to also use in Ex mode.
" Also change disable.vim then: "iunmap" to "unmap!".
"
" You may want to add a list of map's too.
inoremap a a
inoremap b x
inoremap c j
inoremap d e
inoremap e .
inoremap f u
inoremap g i
inoremap h d
inoremap i c
inoremap j h
inoremap k t
inoremap l n
inoremap m m
inoremap n b
inoremap o r
inoremap p l
inoremap q '
inoremap r p
inoremap s o
inoremap t y
inoremap u g
inoremap v k
inoremap w ,
inoremap x q
inoremap y f
inoremap z ;
inoremap ; s
inoremap ' -
inoremap " _
inoremap , w
inoremap . v
inoremap / z
inoremap A A
inoremap B X
inoremap C J
inoremap D E
inoremap E >
inoremap F U
inoremap G I
inoremap H D
inoremap I C
inoremap J H
inoremap K T
inoremap L N
inoremap M M
inoremap N B
inoremap O R
inoremap P L
inoremap Q "
inoremap R P
inoremap S O
inoremap T Y
inoremap U G
inoremap V K
inoremap W <
inoremap X Q
inoremap Y F
inoremap Z :
inoremap < W
inoremap > V
inoremap ? Z
inoremap : S
inoremap [ /
inoremap ] =
inoremap { ?
inoremap } +
inoremap - [
inoremap _ {
inoremap = ]
inoremap + }

View File

@ -0,0 +1,16 @@
" When using a dvorak keyboard this file may be of help to you.
" These mappings have been made by Lawrence Kesteloot <kesteloo@cs.unc.edu>.
" What they do is that the most often used keys, like hjkl, are put in a more
" easy to use position.
" It may take some time to learn using this.
if exists("g:loaded_dvorak_plugin")
finish
endif
let g:loaded_dvorak_plugin = 1
" Key to go into dvorak mode:
map ,d :runtime dvorak/enable.vim<CR>
" Key to get out of dvorak mode:
map ,q :runtime dvorak/disable.vim<CR>

View File

@ -0,0 +1,114 @@
" Vim Plugin: Edit the file with an existing Vim if possible
" Maintainer: Bram Moolenaar
" Last Change: 2016 Mar 28
" To use add ":packadd! editexisting" in your vimrc file.
" This plugin serves two purposes:
" 1. On startup, if we were invoked with one file name argument and the file
" is not modified then try to find another Vim instance that is editing
" this file. If there is one then bring it to the foreground and exit.
" 2. When a file is edited and a swap file exists for it, try finding that
" other Vim and bring it to the foreground. Requires Vim 7, because it
" uses the SwapExists autocommand event.
" Function that finds the Vim instance that is editing "filename" and brings
" it to the foreground.
func s:EditElsewhere(filename)
let fname_esc = substitute(a:filename, "'", "''", "g")
let servers = serverlist()
while servers != ''
" Get next server name in "servername"; remove it from "servers".
let i = match(servers, "\n")
if i == -1
let servername = servers
let servers = ''
else
let servername = strpart(servers, 0, i)
let servers = strpart(servers, i + 1)
endif
" Skip ourselves.
if servername ==? v:servername
continue
endif
" Check if this server is editing our file.
if remote_expr(servername, "bufloaded('" . fname_esc . "')")
" Yes, bring it to the foreground.
if has("win32")
call remote_foreground(servername)
endif
call remote_expr(servername, "foreground()")
if remote_expr(servername, "exists('*EditExisting')")
" Make sure the file is visible in a window (not hidden).
" If v:swapcommand exists and is set, send it to the server.
if exists("v:swapcommand")
let c = substitute(v:swapcommand, "'", "''", "g")
call remote_expr(servername, "EditExisting('" . fname_esc . "', '" . c . "')")
else
call remote_expr(servername, "EditExisting('" . fname_esc . "', '')")
endif
endif
if !(has('vim_starting') && has('gui_running') && has('gui_win32'))
" Tell the user what is happening. Not when the GUI is starting
" though, it would result in a message box.
echomsg "File is being edited by " . servername
sleep 2
endif
return 'q'
endif
endwhile
return ''
endfunc
" When the plugin is loaded and there is one file name argument: Find another
" Vim server that is editing this file right now.
if argc() == 1 && !&modified
if s:EditElsewhere(expand("%:p")) == 'q'
quit
endif
endif
" Setup for handling the situation that an existing swap file is found.
try
au! SwapExists * let v:swapchoice = s:EditElsewhere(expand("<afile>:p"))
catch
" Without SwapExists we don't do anything for ":edit" commands
endtry
" Function used on the server to make the file visible and possibly execute a
" command.
func! EditExisting(fname, command)
" Get the window number of the file in the current tab page.
let winnr = bufwinnr(a:fname)
if winnr <= 0
" Not found, look in other tab pages.
let bufnr = bufnr(a:fname)
for i in range(tabpagenr('$'))
if index(tabpagebuflist(i + 1), bufnr) >= 0
" Make this tab page the current one and find the window number.
exe 'tabnext ' . (i + 1)
let winnr = bufwinnr(a:fname)
break
endif
endfor
endif
if winnr > 0
exe winnr . "wincmd w"
elseif exists('*fnameescape')
exe "split " . fnameescape(a:fname)
else
exe "split " . escape(a:fname, " \t\n*?[{`$\\%#'\"|!<")
endif
if a:command != ''
exe "normal! " . a:command
endif
redraw
endfunc

View File

@ -0,0 +1,316 @@
" Function to left and right align text.
"
" Written by: Preben "Peppe" Guldberg <c928400@student.dtu.dk>
" Created: 980806 14:13 (or around that time anyway)
" Revised: 001103 00:36 (See "Revisions" below)
" function Justify( [ textwidth [, maxspaces [, indent] ] ] )
"
" Justify() will left and right align a line by filling in an
" appropriate amount of spaces. Extra spaces are added to existing
" spaces starting from the right side of the line. As an example, the
" following documentation has been justified.
"
" The function takes the following arguments:
" textwidth argument
" ------------------
" If not specified, the value of the 'textwidth' option is used. If
" 'textwidth' is zero a value of 80 is used.
"
" Additionally the arguments 'tw' and '' are accepted. The value of
" 'textwidth' will be used. These are handy, if you just want to specify
" the maxspaces argument.
" maxspaces argument
" ------------------
" If specified, alignment will only be done, if the longest space run
" after alignment is no longer than maxspaces.
"
" An argument of '' is accepted, should the user like to specify all
" arguments.
"
" To aid user defined commands, negative values are accepted aswell.
" Using a negative value specifies the default behaviour: any length of
" space runs will be used to justify the text.
" indent argument
" ---------------
" This argument specifies how a line should be indented. The default is
" to keep the current indentation.
"
" Negative values: Keep current amount of leading whitespace.
" Positive values: Indent all lines with leading whitespace using this
" amount of whitespace.
"
" Note that the value 0, needs to be quoted as a string. This value
" leads to a left flushed text.
"
" Additionally units of 'shiftwidth'/'sw' and 'tabstop'/'ts' may be
" added. In this case, if the value of indent is positive, the amount of
" whitespace to be added will be multiplied by the value of the
" 'shiftwidth' and 'tabstop' settings. If these units are used, the
" argument must be given as a string, eg. Justify('','','2sw').
"
" If the values of 'sw' or 'tw' are negative, they are treated as if
" they were 0, which means that the text is flushed left. There is no
" check if a negative number prefix is used to change the sign of a
" negative 'sw' or 'ts' value.
"
" As with the other arguments, '' may be used to get the default
" behaviour.
" Notes:
"
" If the line, adjusted for space runs and leading/trailing whitespace,
" is wider than the used textwidth, the line will be left untouched (no
" whitespace removed). This should be equivalent to the behaviour of
" :left, :right and :center.
"
" If the resulting line is shorter than the used textwidth it is left
" untouched.
"
" All space runs in the line are truncated before the alignment is
" carried out.
"
" If you have set 'noexpandtab', :retab! is used to replace space runs
" with whitespace using the value of 'tabstop'. This should be
" conformant with :left, :right and :center.
"
" If joinspaces is set, an extra space is added after '.', '?' and '!'.
" If 'cpooptions' include 'j', extra space is only added after '.'.
" (This may on occasion conflict with maxspaces.)
" Related mappings:
"
" Mappings that will align text using the current text width, using at
" most four spaces in a space run and keeping current indentation.
nmap _j :%call Justify('tw',4)<CR>
vmap _j :call Justify('tw',4)<CR>
"
" Mappings that will remove space runs and format lines (might be useful
" prior to aligning the text).
nmap ,gq :%s/\s\+/ /g<CR>gq1G
vmap ,gq :s/\s\+/ /g<CR>gvgq
" User defined command:
"
" The following is an ex command that works as a shortcut to the Justify
" function. Arguments to Justify() can be added after the command.
com! -range -nargs=* Justify <line1>,<line2>call Justify(<f-args>)
"
" The following commands are all equivalent:
"
" 1. Simplest use of Justify():
" :call Justify()
" :Justify
"
" 2. The _j mapping above via the ex command:
" :%Justify tw 4
"
" 3. Justify visualised text at 72nd column while indenting all
" previously indented text two shiftwidths
" :'<,'>call Justify(72,'','2sw')
" :'<,'>Justify 72 -1 2sw
"
" This documentation has been justified using the following command:
":se et|kz|1;/^" function Justify(/+,'z-g/^" /s/^" //|call Justify(70,3)|s/^/" /
" Revisions:
" 001103: If 'joinspaces' was set, calculations could be wrong.
" Tabs at start of line could also lead to errors.
" Use setline() instead of "exec 's/foo/bar/' - safer.
" Cleaned up the code a bit.
"
" Todo: Convert maps to the new script specific form
" Error function
function! Justify_error(message)
echohl Error
echo "Justify([tw, [maxspaces [, indent]]]): " . a:message
echohl None
endfunction
" Now for the real thing
function! Justify(...) range
if a:0 > 3
call Justify_error("Too many arguments (max 3)")
return 1
endif
" Set textwidth (accept 'tw' and '' as arguments)
if a:0 >= 1
if a:1 =~ '^\(tw\)\=$'
let tw = &tw
elseif a:1 =~ '^\d\+$'
let tw = a:1
else
call Justify_error("tw must be a number (>0), '' or 'tw'")
return 2
endif
else
let tw = &tw
endif
if tw == 0
let tw = 80
endif
" Set maximum number of spaces between WORDs
if a:0 >= 2
if a:2 == ''
let maxspaces = tw
elseif a:2 =~ '^-\d\+$'
let maxspaces = tw
elseif a:2 =~ '^\d\+$'
let maxspaces = a:2
else
call Justify_error("maxspaces must be a number or ''")
return 3
endif
else
let maxspaces = tw
endif
if maxspaces <= 1
call Justify_error("maxspaces should be larger than 1")
return 4
endif
" Set the indentation style (accept sw and ts units)
let indent_fix = ''
if a:0 >= 3
if (a:3 == '') || a:3 =~ '^-[1-9]\d*\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = -1
elseif a:3 =~ '^-\=0\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = 0
elseif a:3 =~ '^\d\+\(shiftwidth\|sw\|tabstop\|ts\)\=$'
let indent = substitute(a:3, '\D', '', 'g')
elseif a:3 =~ '^\(shiftwidth\|sw\|tabstop\|ts\)$'
let indent = 1
else
call Justify_error("indent: a number with 'sw'/'ts' unit")
return 5
endif
if indent >= 0
while indent > 0
let indent_fix = indent_fix . ' '
let indent = indent - 1
endwhile
let indent_sw = 0
if a:3 =~ '\(shiftwidth\|sw\)'
let indent_sw = &sw
elseif a:3 =~ '\(tabstop\|ts\)'
let indent_sw = &ts
endif
let indent_fix2 = ''
while indent_sw > 0
let indent_fix2 = indent_fix2 . indent_fix
let indent_sw = indent_sw - 1
endwhile
let indent_fix = indent_fix2
endif
else
let indent = -1
endif
" Avoid substitution reports
let save_report = &report
set report=1000000
" Check 'joinspaces' and 'cpo'
if &js == 1
if &cpo =~ 'j'
let join_str = '\(\. \)'
else
let join_str = '\([.!?!] \)'
endif
endif
let cur = a:firstline
while cur <= a:lastline
let str_orig = getline(cur)
let save_et = &et
set et
exec cur . "retab"
let &et = save_et
let str = getline(cur)
let indent_str = indent_fix
let indent_n = strlen(indent_str)
" Shall we remember the current indentation
if indent < 0
let indent_orig = matchstr(str_orig, '^\s*')
if strlen(indent_orig) > 0
let indent_str = indent_orig
let indent_n = strlen(matchstr(str, '^\s*'))
endif
endif
" Trim trailing, leading and running whitespace
let str = substitute(str, '\s\+$', '', '')
let str = substitute(str, '^\s\+', '', '')
let str = substitute(str, '\s\+', ' ', 'g')
let str_n = strdisplaywidth(str)
" Possible addition of space after punctuation
if exists("join_str")
let str = substitute(str, join_str, '\1 ', 'g')
endif
let join_n = strdisplaywidth(str) - str_n
" Can extraspaces be added?
" Note that str_n may be less than strlen(str) [joinspaces above]
if strdisplaywidth(str) <= tw - indent_n && str_n > 0
" How many spaces should be added
let s_add = tw - str_n - indent_n - join_n
let s_nr = strlen(substitute(str, '\S', '', 'g') ) - join_n
let s_dup = s_add / s_nr
let s_mod = s_add % s_nr
" Test if the changed line fits with tw
if 0 <= (str_n + (maxspaces - 1)*s_nr + indent_n) - tw
" Duplicate spaces
while s_dup > 0
let str = substitute(str, '\( \+\)', ' \1', 'g')
let s_dup = s_dup - 1
endwhile
" Add extra spaces from the end
while s_mod > 0
let str = substitute(str, '\(\(\s\+\S\+\)\{' . s_mod . '}\)$', ' \1', '')
let s_mod = s_mod - 1
endwhile
" Indent the line
if indent_n > 0
let str = substitute(str, '^', indent_str, '' )
endif
" Replace the line
call setline(cur, str)
" Convert to whitespace
if &et == 0
exec cur . 'retab!'
endif
endif " Change of line
endif " Possible change
let cur = cur + 1
endwhile
norm ^
let &report = save_report
endfunction
" EOF vim: tw=78 ts=8 sw=4 sts=4 noet ai

View File

@ -0,0 +1,754 @@
" matchit.vim: (global plugin) Extended "%" matching
" autload script of matchit plugin, see ../plugin/matchit.vim
" Last Change: 2019 Jan 28
let s:last_mps = ""
let s:last_words = ":"
let s:patBR = ""
let s:save_cpo = &cpo
set cpo&vim
" Auto-complete mappings: (not yet "ready for prime time")
" TODO Read :help write-plugin for the "right" way to let the user
" specify a key binding.
" let g:match_auto = '<C-]>'
" let g:match_autoCR = '<C-CR>'
" if exists("g:match_auto")
" execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
" endif
" if exists("g:match_autoCR")
" execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
" endif
" if exists("g:match_gthhoh")
" execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
" endif " gthhoh = "Get the heck out of here!"
let s:notslash = '\\\@1<!\%(\\\\\)*'
function s:RestoreOptions()
" In s:CleanUp(), :execute "set" restore_options .
let restore_options = ""
if get(b:, 'match_ignorecase', &ic) != &ic
let restore_options .= (&ic ? " " : " no") . "ignorecase"
let &ignorecase = b:match_ignorecase
endif
if &ve != ''
let restore_options = " ve=" . &ve . restore_options
set ve=
endif
return restore_options
endfunction
function matchit#Match_wrapper(word, forward, mode) range
let restore_options = s:RestoreOptions()
" If this function was called from Visual mode, make sure that the cursor
" is at the correct end of the Visual range:
if a:mode == "v"
execute "normal! gv\<Esc>"
elseif a:mode == "o" && mode(1) !~# '[vV]'
exe "norm! v"
endif
" In s:CleanUp(), we may need to check whether the cursor moved forward.
let startpos = [line("."), col(".")]
" Use default behavior if called with a count.
if v:count
exe "normal! " . v:count . "%"
return s:CleanUp(restore_options, a:mode, startpos)
end
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
if !exists("b:match_words") || b:match_words == ""
let match_words = ""
elseif b:match_words =~ ":"
let match_words = b:match_words
else
" Allow b:match_words = "GetVimMatchWords()" .
execute "let match_words =" b:match_words
endif
" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion!
if (match_words != s:last_words) || (&mps != s:last_mps)
\ || exists("b:match_debug")
let s:last_mps = &mps
" quote the special chars in 'matchpairs', replace [,:] with \| and then
" append the builtin pairs (/*, */, #if, #ifdef, #ifndef, #else, #elif,
" #endif)
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
" s:all = pattern with all the keywords
let match_words = match_words . (strlen(match_words) ? "," : "") . default
let s:last_words = match_words
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
" Just in case there are too many '\(...)' groups inside the pattern, make
" sure to use \%(...) groups, so that error E872 can be avoided
let s:all = substitute(s:all, '\\(', '\\%(', 'g')
let s:all = '\%(' . s:all . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
" Reconstruct the version with unresolved backrefs.
let s:patBR = substitute(match_words.',',
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let s:patBR = substitute(s:patBR, s:notslash.'\zs:\{2,}', ':', 'g')
endif
" Second step: set the following local variables:
" matchline = line on which the cursor started
" curcol = number of characters before match
" prefix = regexp for start of line to start of match
" suffix = regexp for end of match to end of line
" Require match to end on or after the cursor and prefer it to
" start on or before the cursor.
let matchline = getline(startpos[0])
if a:word != ''
" word given
if a:word !~ s:all
echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
return s:CleanUp(restore_options, a:mode, startpos)
endif
let matchline = a:word
let curcol = 0
let prefix = '^\%('
let suffix = '\)$'
" Now the case when "word" is not given
else " Find the match that ends on or after the cursor and set curcol.
let regexp = s:Wholematch(matchline, s:all, startpos[1]-1)
let curcol = match(matchline, regexp)
" If there is no match, give up.
if curcol == -1
return s:CleanUp(restore_options, a:mode, startpos)
endif
let endcol = matchend(matchline, regexp)
let suf = strlen(matchline) - endcol
let prefix = (curcol ? '^.*\%' . (curcol + 1) . 'c\%(' : '^\%(')
let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$' : '\)$')
endif
if exists("b:match_debug")
let b:match_match = matchstr(matchline, regexp)
let b:match_col = curcol+1
endif
" Third step: Find the group and single word that match, and the original
" (backref) versions of these. Then, resolve the backrefs.
" Set the following local variable:
" group = colon-separated list of patterns, one of which matches
" = ini:mid:fin or ini:fin
"
" Now, set group and groupBR to the matching group: 'if:endif' or
" 'while:endwhile' or whatever. A bit of a kluge: s:Choose() returns
" group . "," . groupBR, and we pick it apart.
let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, s:patBR)
let i = matchend(group, s:notslash . ",")
let groupBR = strpart(group, i)
let group = strpart(group, 0, i-1)
" Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
if s:do_BR " Do the hard part: resolve those backrefs!
let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
endif
if exists("b:match_debug")
let b:match_wholeBR = groupBR
let i = matchend(groupBR, s:notslash . ":")
let b:match_iniBR = strpart(groupBR, 0, i-1)
endif
" Fourth step: Set the arguments for searchpair().
let i = matchend(group, s:notslash . ":")
let j = matchend(group, '.*' . s:notslash . ":")
let ini = strpart(group, 0, i-1)
let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
let fin = strpart(group, j)
"Un-escape the remaining , and : characters.
let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
" searchpair() requires that these patterns avoid \(\) groups.
let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
" Set mid. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline =~ prefix . ini . suffix
let mid = ""
endif
" Set flag. This is optimized for readability, not micro-efficiency!
if a:forward && matchline =~ prefix . fin . suffix
\ || !a:forward && matchline !~ prefix . ini . suffix
let flag = "bW"
else
let flag = "W"
endif
" Set skip.
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
if exists("b:match_debug")
let b:match_ini = ini
let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
endif
" Fifth step: actually start moving the cursor and call searchpair().
" Later, :execute restore_cursor to get to the original screen.
let view = winsaveview()
call cursor(0, curcol + 1)
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = "0"
else
execute "if " . skip . "| let skip = '0' | endif"
endif
let sp_return = searchpair(ini, mid, fin, flag, skip)
let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
" Restore cursor position and original screen.
call winrestview(view)
normal! m'
if sp_return > 0
execute final_position
endif
return s:CleanUp(restore_options, a:mode, startpos, mid.'\|'.fin)
endfun
" Restore options and do some special handling for Operator-pending mode.
" The optional argument is the tail of the matching group.
fun! s:CleanUp(options, mode, startpos, ...)
if strlen(a:options)
execute "set" a:options
endif
" Open folds, if appropriate.
if a:mode != "o"
if &foldopen =~ "percent"
normal! zv
endif
" In Operator-pending mode, we want to include the whole match
" (for example, d%).
" This is only a problem if we end up moving in the forward direction.
elseif (a:startpos[0] < line(".")) ||
\ (a:startpos[0] == line(".") && a:startpos[1] < col("."))
if a:0
" Check whether the match is a single character. If not, move to the
" end of the match.
let matchline = getline(".")
let currcol = col(".")
let regexp = s:Wholematch(matchline, a:1, currcol-1)
let endcol = matchend(matchline, regexp)
if endcol > currcol " This is NOT off by one!
call cursor(0, endcol)
endif
endif " a:0
endif " a:mode != "o" && etc.
return 0
endfun
" Example (simplified HTML patterns): if
" a:groupBR = '<\(\k\+\)>:</\1>'
" a:prefix = '^.\{3}\('
" a:group = '<\(\k\+\)>:</\(\k\+\)>'
" a:suffix = '\).\{2}$'
" a:matchline = "123<tag>12" or "123</tag>12"
" then extract "tag" from a:matchline and return "<tag>:</tag>" .
fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
if a:matchline !~ a:prefix .
\ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
return a:group
endif
let i = matchend(a:groupBR, s:notslash . ':')
let ini = strpart(a:groupBR, 0, i-1)
let tailBR = strpart(a:groupBR, i)
let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
\ a:groupBR)
let i = matchend(word, s:notslash . ":")
let wordBR = strpart(word, i)
let word = strpart(word, 0, i-1)
" Now, a:matchline =~ a:prefix . word . a:suffix
if wordBR != ini
let table = s:Resolve(ini, wordBR, "table")
else
let table = ""
let d = 0
while d < 10
if tailBR =~ s:notslash . '\\' . d
let table = table . d
else
let table = table . "-"
endif
let d = d + 1
endwhile
endif
let d = 9
while d
if table[d] != "-"
let backref = substitute(a:matchline, a:prefix.word.a:suffix,
\ '\'.table[d], "")
" Are there any other characters that should be escaped?
let backref = escape(backref, '*,:')
execute s:Ref(ini, d, "start", "len")
let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
\ escape(backref, '\\&'), 'g')
endif
let d = d-1
endwhile
if exists("b:match_debug")
if s:do_BR
let b:match_table = table
let b:match_word = word
else
let b:match_table = ""
let b:match_word = ""
endif
endif
return ini . ":" . tailBR
endfun
" Input a comma-separated list of groups with backrefs, such as
" a:groups = '\(foo\):end\1,\(bar\):end\1'
" and return a comma-separated list of groups with backrefs replaced:
" return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
fun! s:ParseWords(groups)
let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
let parsed = ""
while groups =~ '[^,:]'
let i = matchend(groups, s:notslash . ':')
let j = matchend(groups, s:notslash . ',')
let ini = strpart(groups, 0, i-1)
let tail = strpart(groups, i, j-i-1) . ":"
let groups = strpart(groups, j)
let parsed = parsed . ini
let i = matchend(tail, s:notslash . ':')
while i != -1
" In 'if:else:endif', ini='if' and word='else' and then word='endif'.
let word = strpart(tail, 0, i-1)
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . ':')
let parsed = parsed . ":" . s:Resolve(ini, word, "word")
endwhile " Now, tail has been used up.
let parsed = parsed . ","
endwhile " groups =~ '[^,:]'
let parsed = substitute(parsed, ',$', '', '')
return parsed
endfun
" TODO I think this can be simplified and/or made more efficient.
" TODO What should I do if a:start is out of range?
" Return a regexp that matches all of a:string, such that
" matchstr(a:string, regexp) represents the match for a:pat that starts
" as close to a:start as possible, before being preferred to after, and
" ends after a:start .
" Usage:
" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
" let i = match(getline("."), regexp)
" let j = matchend(getline("."), regexp)
" let match = matchstr(getline("."), regexp)
fun! s:Wholematch(string, pat, start)
let group = '\%(' . a:pat . '\)'
let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
let len = strlen(a:string)
let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
if a:string !~ prefix . group . suffix
let prefix = ''
endif
return prefix . group . suffix
endfun
" No extra arguments: s:Ref(string, d) will
" find the d'th occurrence of '\(' and return it, along with everything up
" to and including the matching '\)'.
" One argument: s:Ref(string, d, "start") returns the index of the start
" of the d'th '\(' and any other argument returns the length of the group.
" Two arguments: s:Ref(string, d, "foo", "bar") returns a string to be
" executed, having the effect of
" :let foo = s:Ref(string, d, "start")
" :let bar = s:Ref(string, d, "len")
fun! s:Ref(string, d, ...)
let len = strlen(a:string)
if a:d == 0
let start = 0
else
let cnt = a:d
let match = a:string
while cnt
let cnt = cnt - 1
let index = matchend(match, s:notslash . '\\(')
if index == -1
return ""
endif
let match = strpart(match, index)
endwhile
let start = len - strlen(match)
if a:0 == 1 && a:1 == "start"
return start - 2
endif
let cnt = 1
while cnt
let index = matchend(match, s:notslash . '\\(\|\\)') - 1
if index == -2
return ""
endif
" Increment if an open, decrement if a ')':
let cnt = cnt + (match[index]=="(" ? 1 : -1) " ')'
let match = strpart(match, index+1)
endwhile
let start = start - 2
let len = len - start - strlen(match)
endif
if a:0 == 1
return len
elseif a:0 == 2
return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
else
return strpart(a:string, start, len)
endif
endfun
" Count the number of disjoint copies of pattern in string.
" If the pattern is a literal string and contains no '0' or '1' characters
" then s:Count(string, pattern, '0', '1') should be faster than
" s:Count(string, pattern).
fun! s:Count(string, pattern, ...)
let pat = escape(a:pattern, '\\')
if a:0 > 1
let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
let foo = substitute(a:string, pat, a:2, "g")
let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
return strlen(foo)
endif
let result = 0
let foo = a:string
let index = matchend(foo, pat)
while index != -1
let result = result + 1
let foo = strpart(foo, index)
let index = matchend(foo, pat)
endwhile
return result
endfun
" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'. That is, the first
" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
" indicates that all other instances of '\1' in target are to be replaced
" by '\3'. The hard part is dealing with nesting...
" Note that ":" is an illegal character for source and target,
" unless it is preceded by "\".
fun! s:Resolve(source, target, output)
let word = a:target
let i = matchend(word, s:notslash . '\\\d') - 1
let table = "----------"
while i != -2 " There are back references to be replaced.
let d = word[i]
let backref = s:Ref(a:source, d)
" The idea is to replace '\d' with backref. Before we do this,
" replace any \(\) groups in backref with :1, :2, ... if they
" correspond to the first, second, ... group already inserted
" into backref. Later, replace :1 with \1 and so on. The group
" number w+b within backref corresponds to the group number
" s within a:source.
" w = number of '\(' in word before the current one
let w = s:Count(
\ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
let b = 1 " number of the current '\(' in backref
let s = d " number of the current '\(' in a:source
while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
\ && s < 10
if table[s] == "-"
if w + b < 10
" let table[s] = w + b
let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
endif
let b = b + 1
let s = s + 1
else
execute s:Ref(backref, b, "start", "len")
let ref = strpart(backref, start, len)
let backref = strpart(backref, 0, start) . ":". table[s]
\ . strpart(backref, start+len)
let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
endif
endwhile
let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
let i = matchend(word, s:notslash . '\\\d') - 1
endwhile
let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
if a:output == "table"
return table
elseif a:output == "word"
return word
else
return table . word
endif
endfun
" Assume a:comma = ",". Then the format for a:patterns and a:1 is
" a:patterns = "<pat1>,<pat2>,..."
" a:1 = "<alt1>,<alt2>,..."
" If <patn> is the first pattern that matches a:string then return <patn>
" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
let i = matchend(tail, s:notslash . a:comma)
if a:0
let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
let j = matchend(alttail, s:notslash . a:comma)
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
while a:string !~ a:prefix . currpat . a:suffix
let tail = strpart(tail, i)
let i = matchend(tail, s:notslash . a:comma)
if i == -1
return -1
endif
let current = strpart(tail, 0, i-1)
if a:branch == ""
let currpat = current
else
let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
endif
if a:0
let alttail = strpart(alttail, j)
let j = matchend(alttail, s:notslash . a:comma)
endif
endwhile
if a:0
let current = current . a:comma . strpart(alttail, 0, j-1)
endif
return current
endfun
fun! matchit#Match_debug()
let b:match_debug = 1 " Save debugging information.
" pat = all of b:match_words with backrefs parsed
amenu &Matchit.&pat :echo b:match_pat<CR>
" match = bit of text that is recognized as a match
amenu &Matchit.&match :echo b:match_match<CR>
" curcol = cursor column of the start of the matching text
amenu &Matchit.&curcol :echo b:match_col<CR>
" wholeBR = matching group, original version
amenu &Matchit.wh&oleBR :echo b:match_wholeBR<CR>
" iniBR = 'if' piece, original version
amenu &Matchit.ini&BR :echo b:match_iniBR<CR>
" ini = 'if' piece, with all backrefs resolved from match
amenu &Matchit.&ini :echo b:match_ini<CR>
" tail = 'else\|endif' piece, with all backrefs resolved from match
amenu &Matchit.&tail :echo b:match_tail<CR>
" fin = 'endif' piece, with all backrefs resolved from match
amenu &Matchit.&word :echo b:match_word<CR>
" '\'.d in ini refers to the same thing as '\'.table[d] in word.
amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR>
endfun
" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
" Return a "mark" for the original position, so that
" let m = MultiMatch("bW", "n") ... call winrestview(m)
" will return to the original position. If there is a problem, do not
" move the cursor and return {}, unless a count is given, in which case
" go up or down as many levels as possible and again return {}.
" TODO This relies on the same patterns as % matching. It might be a good
" idea to give it its own matching patterns.
fun! matchit#MultiMatch(spflag, mode)
let restore_options = s:RestoreOptions()
let startpos = [line("."), col(".")]
" save v:count1 variable, might be reset from the restore_cursor command
let level = v:count1
if a:mode == "o" && mode(1) !~# '[vV]'
exe "norm! v"
endif
" First step: if not already done, set the script variables
" s:do_BR flag for whether there are backrefs
" s:pat parsed version of b:match_words
" s:all regexp based on s:pat and the default groups
" This part is copied and slightly modified from matchit#Match_wrapper().
if !exists("b:match_words") || b:match_words == ""
let match_words = ""
" Allow b:match_words = "GetVimMatchWords()" .
elseif b:match_words =~ ":"
let match_words = b:match_words
else
execute "let match_words =" b:match_words
endif
if (match_words != s:last_words) || (&mps != s:last_mps) ||
\ exists("b:match_debug")
let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
\ '\/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
let s:last_mps = &mps
let match_words = match_words . (strlen(match_words) ? "," : "") . default
let s:last_words = match_words
if match_words !~ s:notslash . '\\\d'
let s:do_BR = 0
let s:pat = match_words
else
let s:do_BR = 1
let s:pat = s:ParseWords(match_words)
endif
let s:all = '\%(' . substitute(s:pat, '[,:]\+', '\\|', 'g') . '\)'
if exists("b:match_debug")
let b:match_pat = s:pat
endif
" Reconstruct the version with unresolved backrefs.
let s:patBR = substitute(match_words.',',
\ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
let s:patBR = substitute(s:patBR, s:notslash.'\zs:\{2,}', ':', 'g')
endif
" Second step: figure out the patterns for searchpair()
" and save the screen, cursor position, and 'ignorecase'.
" - TODO: A lot of this is copied from matchit#Match_wrapper().
" - maybe even more functionality should be split off
" - into separate functions!
let openlist = split(s:pat . ',', s:notslash . '\zs:.\{-}' . s:notslash . ',')
let midclolist = split(',' . s:pat, s:notslash . '\zs,.\{-}' . s:notslash . ':')
call map(midclolist, {-> split(v:val, s:notslash . ':')})
let closelist = []
let middlelist = []
call map(midclolist, {i,v -> [extend(closelist, v[-1 : -1]),
\ extend(middlelist, v[0 : -2])]})
call map(openlist, {i,v -> v =~# s:notslash . '\\|' ? '\%(' . v . '\)' : v})
call map(middlelist, {i,v -> v =~# s:notslash . '\\|' ? '\%(' . v . '\)' : v})
call map(closelist, {i,v -> v =~# s:notslash . '\\|' ? '\%(' . v . '\)' : v})
let open = join(openlist, ',')
let middle = join(middlelist, ',')
let close = join(closelist, ',')
if exists("b:match_skip")
let skip = b:match_skip
elseif exists("b:match_comment") " backwards compatibility and testing!
let skip = "r:" . b:match_comment
else
let skip = 's:comment\|string'
endif
let skip = s:ParseSkip(skip)
let view = winsaveview()
" Third step: call searchpair().
" Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
let openpat = substitute(open, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g')
let openpat = substitute(openpat, ',', '\\|', 'g')
let closepat = substitute(close, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g')
let closepat = substitute(closepat, ',', '\\|', 'g')
let middlepat = substitute(middle, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g')
let middlepat = substitute(middlepat, ',', '\\|', 'g')
if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
let skip = '0'
else
try
execute "if " . skip . "| let skip = '0' | endif"
catch /^Vim\%((\a\+)\)\=:E363/
" We won't find anything, so skip searching, should keep Vim responsive.
return {}
endtry
endif
mark '
while level
if searchpair(openpat, middlepat, closepat, a:spflag, skip) < 1
call s:CleanUp(restore_options, a:mode, startpos)
return {}
endif
let level = level - 1
endwhile
" Restore options and return a string to restore the original position.
call s:CleanUp(restore_options, a:mode, startpos)
return view
endfun
" Search backwards for "if" or "while" or "<tag>" or ...
" and return "endif" or "endwhile" or "</tag>" or ... .
" For now, this uses b:match_words and the same script variables
" as matchit#Match_wrapper() . Later, it may get its own patterns,
" either from a buffer variable or passed as arguments.
" fun! s:Autocomplete()
" echo "autocomplete not yet implemented :-("
" if !exists("b:match_words") || b:match_words == ""
" return ""
" end
" let startpos = matchit#MultiMatch("bW")
"
" if startpos == ""
" return ""
" endif
" " - TODO: figure out whether 'if' or '<tag>' matched, and construct
" " - the appropriate closing.
" let matchline = getline(".")
" let curcol = col(".") - 1
" " - TODO: Change the s:all argument if there is a new set of match pats.
" let regexp = s:Wholematch(matchline, s:all, curcol)
" let suf = strlen(matchline) - matchend(matchline, regexp)
" let prefix = (curcol ? '^.\{' . curcol . '}\%(' : '^\%(')
" let suffix = (suf ? '\).\{' . suf . '}$' : '\)$')
" " Reconstruct the version with unresolved backrefs.
" let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
" let patBR = substitute(patBR, ':\{2,}', ':', "g")
" " Now, set group and groupBR to the matching group: 'if:endif' or
" " 'while:endwhile' or whatever.
" let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
" let i = matchend(group, s:notslash . ",")
" let groupBR = strpart(group, i)
" let group = strpart(group, 0, i-1)
" " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
" if s:do_BR
" let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
" endif
" " let g:group = group
"
" " - TODO: Construct the closing from group.
" let fake = "end" . expand("<cword>")
" execute startpos
" return fake
" endfun
" Close all open structures. "Get the heck out of here!"
" fun! s:Gthhoh()
" let close = s:Autocomplete()
" while strlen(close)
" put=close
" let close = s:Autocomplete()
" endwhile
" endfun
" Parse special strings as typical skip arguments for searchpair():
" s:foo becomes (current syntax item) =~ foo
" S:foo becomes (current syntax item) !~ foo
" r:foo becomes (line before cursor) =~ foo
" R:foo becomes (line before cursor) !~ foo
fun! s:ParseSkip(str)
let skip = a:str
if skip[1] == ":"
if skip[0] == "s"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "S"
let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
\ strpart(skip,2) . "'"
elseif skip[0] == "r"
let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
elseif skip[0] == "R"
let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
endif
endif
return skip
endfun
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:sts=2:sw=2:et:

View File

@ -0,0 +1,391 @@
*matchit.txt* Extended "%" matching
For instructions on installing this file, type
`:help matchit-install`
inside Vim.
For Vim version 8.1. Last change: 2019 Jan 28
VIM REFERENCE MANUAL by Benji Fisher et al
*matchit* *matchit.vim*
1. Extended matching with "%" |matchit-intro|
2. Activation |matchit-activate|
3. Configuration |matchit-configure|
4. Supporting a New Language |matchit-newlang|
5. Known Bugs and Limitations |matchit-bugs|
The functionality mentioned here is a plugin, see |add-plugin|.
This plugin is only available if 'compatible' is not set.
{Vi does not have any of this}
==============================================================================
1. Extended matching with "%" *matchit-intro*
*matchit-%*
% Cycle forward through matching groups, such as "if", "else", "endif",
as specified by |b:match_words|.
*g%* *v_g%* *o_g%*
g% Cycle backwards through matching groups, as specified by
|b:match_words|. For example, go from "if" to "endif" to "else".
*[%* *v_[%* *o_[%*
[% Go to [count] previous unmatched group, as specified by
|b:match_words|. Similar to |[{|.
*]%* *v_]%* *o_]%*
]% Go to [count] next unmatched group, as specified by
|b:match_words|. Similar to |]}|.
*v_a%*
a% In Visual mode, select the matching group, as specified by
|b:match_words|, containing the cursor. Similar to |v_a[|.
A [count] is ignored, and only the first character of the closing
pattern is selected.
In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
bracket, or paren to its match. This can be configured with the 'matchpairs'
option. The matchit plugin extends this in several ways:
You can match whole words, such as "if" and "endif", not just
single characters. You can also specify a |regular-expression|.
You can define groups with more than two words, such as "if",
"else", "endif". Banging on the "%" key will cycle from the "if" to
the first "else", the next "else", ..., the closing "endif", and back
to the opening "if". Nested structures are skipped. Using |g%| goes
in the reverse direction.
By default, words inside comments and strings are ignored, unless
the cursor is inside a comment or string when you type "%". If the
only thing you want to do is modify the behavior of "%" so that it
behaves this way, you do not have to define |b:match_words|, since the
script uses the 'matchpairs' option as well as this variable.
See |matchit-details| for details on what the script does, and |b:match_words|
for how to specify matching patterns.
MODES: *matchit-modes* *matchit-v_%* *matchit-o_%*
Mostly, % and related motions (|g%| and |[%| and |]%|) should just work like built-in
|motion| commands in |Operator-pending| and |Visual| modes (as of 8.1.648)
LANGUAGES: *matchit-languages*
Currently, the following languages are supported: Ada, ASP with VBS, Csh,
DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via
the default |filetype-plugin|s in the standard vim distribution.
To support a new language, see |matchit-newlang| below.
DETAILS: *matchit-details* *matchit-parse*
Here is an outline of what matchit.vim does each time you hit the "%" key. If
there are |backref|s in |b:match_words| then the first step is to produce a
version in which these back references have been eliminated; if there are no
|backref|s then this step is skipped. This step is called parsing. For
example, "\(foo\|bar\):end\1" is parsed to yield
"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are
nested groups. If debugging is turned on, the parsed version is saved as
|b:match_pat|.
*matchit-choose*
Next, the script looks for a word on the current line that matches the pattern
just constructed. It includes the patterns from the 'matchpairs' option.
The goal is to do what you expect, which turns out to be a little complicated.
The script follows these rules:
Insist on a match that ends on or after the cursor.
Prefer a match that includes the cursor position (that is, one that
starts on or before the cursor).
Prefer a match that starts as close to the cursor as possible.
If more than one pattern in |b:match_words| matches, choose the one
that is listed first.
Examples:
Suppose you >
:let b:match_words = '<:>,<tag>:</tag>'
< and hit "%" with the cursor on or before the "<" in "a <tag> is born".
The pattern '<' comes first, so it is preferred over '<tag>', which
also matches. If the cursor is on the "t", however, then '<tag>' is
preferred, because this matches a bit of text containing the cursor.
If the two groups of patterns were reversed then '<' would never be
preferred.
Suppose you >
:let b:match_words = 'if:end if'
< (Note the space!) and hit "%" with the cursor at the end of "end if".
Then "if" matches, which is probably not what you want, but if the
cursor starts on the "end " then "end if" is chosen. (You can avoid
this problem by using a more complicated pattern.)
If there is no match, the cursor does not move. (Before version 1.13 of the
script, it would fall back on the usual behavior of |%|). If debugging is
turned on, the matched bit of text is saved as |b:match_match| and the cursor
column of the start of the match is saved as |b:match_col|.
Next, the script looks through |b:match_words| (original and parsed versions)
for the group and pattern that match. If debugging is turned on, the group is
saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If
there are |backref|s then, in addition, the matching pattern is saved as
|b:match_word| and a table of translations is saved as |b:match_table|. If
there are |backref|s, these are determined from the matching pattern and
|b:match_match| and substituted into each pattern in the matching group.
The script decides whether to search forwards or backwards and chooses
arguments for the |searchpair()| function. Then, the cursor is moved to the
start of the match, and |searchpair()| is called. By default, matching
structures inside strings and comments are ignored. This can be changed by
setting |b:match_skip|.
==============================================================================
2. Activation *matchit-activate*
To use the matchit plugin add this line to your |vimrc|: >
packadd! matchit
The script should start working the next time you start Vim.
(Earlier versions of the script did nothing unless a |buffer-variable| named
|b:match_words| was defined. Even earlier versions contained autocommands
that set this variable for various file types. Now, |b:match_words| is
defined in many of the default |filetype-plugin|s instead.)
For a new language, you can add autocommands to the script or to your vimrc
file, but the recommended method is to add a line such as >
let b:match_words = '\<foo\>:\<bar\>'
to the |filetype-plugin| for your language. See |b:match_words| below for how
this variable is interpreted.
TROUBLESHOOTING *matchit-troubleshoot*
The script should work in most installations of Vim. It may not work if Vim
was compiled with a minimal feature set, for example if the |+syntax| option
was not enabled. If your Vim has support for syntax compiled in, but you do
not have |syntax| highlighting turned on, matchit.vim should work, but it may
fail to skip matching groups in comments and strings. If the |filetype|
mechanism is turned off, the |b:match_words| variable will probably not be
defined automatically.
==============================================================================
3. Configuration *matchit-configure*
There are several variables that govern the behavior of matchit.vim. Note
that these are variables local to the buffer, not options, so use |:let| to
define them, not |:set|. Some of these variables have values that matter; for
others, it only matters whether the variable has been defined. All of these
can be defined in the |filetype-plugin| or autocommand that defines
|b:match_words| or "on the fly."
The main variable is |b:match_words|. It is described in the section below on
supporting a new language.
*MatchError* *matchit-hl* *matchit-highlight*
MatchError is the highlight group for error messages from the script. By
default, it is linked to WarningMsg. If you do not want to be bothered by
error messages, you can define this to be something invisible. For example,
if you use the GUI version of Vim and your command line is normally white, you
can do >
:hi MatchError guifg=white guibg=white
<
*b:match_ignorecase*
If you >
:let b:match_ignorecase = 1
then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
are equivalent. If you >
:let b:match_ignorecase = 0
then matchit.vim treats "end" and "END" differently. (There will be no
b:match_infercase option unless someone requests it.)
*b:match_debug*
Define b:match_debug if you want debugging information to be saved. See
|matchit-debug|, below.
*b:match_skip*
If b:match_skip is defined, it is passed as the skip argument to
|searchpair()|. This controls when matching structures are skipped, or
ignored. By default, they are ignored inside comments and strings, as
determined by the |syntax| mechanism. (If syntax highlighting is turned off,
nothing is skipped.) You can set b:match_skip to a string, which evaluates to
a non-zero, numerical value if the match is to be skipped or zero if the match
should not be skipped. In addition, the following special values are
supported by matchit.vim:
s:foo becomes (current syntax item) =~ foo
S:foo becomes (current syntax item) !~ foo
r:foo becomes (line before cursor) =~ foo
R:foo becomes (line before cursor) !~ foo
(The "s" is meant to suggest "syntax", and the "r" is meant to suggest
"regular expression".)
Examples:
You can get the default behavior with >
:let b:match_skip = 's:comment\|string'
<
If you want to skip matching structures unless they are at the start
of the line (ignoring whitespace) then you can >
:let b:match_skip = 'R:^\s*'
< Do not do this if strings or comments can span several lines, since
the normal syntax checking will not be done if you set b:match_skip.
In LaTeX, since "%" is used as the comment character, you can >
:let b:match_skip = 'r:%'
< Unfortunately, this will skip anything after "\%", an escaped "%". To
allow for this, and also "\\%" (an escaped backslash followed by the
comment character) you can >
:let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
<
See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both
syntax and a regular expression.
==============================================================================
4. Supporting a New Language *matchit-newlang*
*b:match_words*
In order for matchit.vim to support a new language, you must define a suitable
pattern for |b:match_words|. You may also want to set some of the
|matchit-configure| variables, as described above. If your language has a
complicated syntax, or many keywords, you will need to know something about
Vim's |regular-expression|s.
The format for |b:match_words| is similar to that of the 'matchpairs' option:
it is a comma (,)-separated list of groups; each group is a colon(:)-separated
list of patterns (regular expressions). Commas and backslashes that are part
of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to
have only one group; the effect is undefined if a group has only one pattern.
A simple example is >
:let b:match_words = '\<if\>:\<endif\>,'
\ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if"
matches the end of "endif" but "\<if\>" does not.) Then banging on the "%"
key will bounce the cursor between "if" and the matching "endif"; and from
"while" to any matching "continue" or "break", then to the matching "endwhile"
and back to the "while". It is almost always easier to use |literal-string|s
(single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on.
Exception: If the ":" character does not appear in b:match_words, then it is
treated as an expression to be evaluated. For example, >
:let b:match_words = 'GetMatchWords()'
allows you to define a function. This can return a different string depending
on the current syntax, for example.
Once you have defined the appropriate value of |b:match_words|, you will
probably want to have this set automatically each time you edit the
appropriate file type. The recommended way to do this is by adding the
definition to a |filetype-plugin| file.
Tips: Be careful that your initial pattern does not match your final pattern.
See the example above for the use of word-boundary expressions. It is usually
better to use ".\{-}" (as many as necessary) instead of ".*" (as many as
possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>"
matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
"</tag>".
*matchit-spaces* *matchit-s:notend*
If "if" is to be paired with "end if" (Note the space!) then word boundaries
are not enough. Instead, define a regular expression s:notend that will match
anything but "end" and use it as follows: >
:let s:notend = '\%(\<end\s\+\)\@<!'
:let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
< *matchit-s:sol*
This is a simplified version of what is done for Ada. The s:notend is a
|script-variable|. Similarly, you may want to define a start-of-line regular
expression >
:let s:sol = '\%(^\|;\)\s*'
if keywords are only recognized after the start of a line or after a
semicolon (;), with optional white space.
*matchit-backref* *matchit-\1*
In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred
to as back references, or backrefs. For example, >
:let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note
that "\1" does not refer to the "\(h\)" in this example. If you have
"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1"
refers to everything and "\2" refers to "\(parentheses\)". If you use a
variable such as |s:notend| or |s:sol| in the previous paragraph then remember
to count any "\(" patterns in this variable. You do not have to count groups
defined by |\%(\)|.
It should be possible to resolve back references from any pattern in the
group. For example, >
:let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
would not work because "\2" cannot be determined from "morefoo" and "\1"
cannot be determined from "andbar". On the other hand, >
:let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
should work (and have the same effect as "foobar:barfoo:endfoobar"), although
this has not been thoroughly tested.
You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has
not been thouroughly tested in matchit.vim.) For example, if the keyword "if"
must occur at the start of the line, with optional white space, you might use
the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
at the start of the line. For another example, if HTML had only one tag then
one could >
:let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
so that "%" can bounce between matching "<" and ">" pairs or (starting on
"tag" or "/tag") between matching tags. Without the |\@<=|, the script would
bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
back to where you started.
DEBUGGING *matchit-debug* *:MatchDebug*
If you are having trouble figuring out the appropriate definition of
|b:match_words| then you can take advantage of the same information I use when
debugging the script. This is especially true if you are not sure whether
your patterns or my script are at fault! To make this more convenient, I have
made the command :MatchDebug, which defines the variable |b:match_debug| and
creates a Matchit menu. This menu makes it convenient to check the values of
the variables described below. You will probably also want to read
|matchit-details| above.
Defining the variable |b:match_debug| causes the script to set the following
variables, each time you hit the "%" key. Several of these are only defined
if |b:match_words| includes |backref|s.
*b:match_pat*
The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
*b:match_match*
The b:match_match variable is set to the bit of text that is recognized as a
match.
*b:match_col*
The b:match_col variable is set to the cursor column of the start of the
matching text.
*b:match_wholeBR*
The b:match_wholeBR variable is set to the comma-separated group of patterns
that matches, with |backref|s unparsed.
*b:match_iniBR*
The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
*b:match_ini*
The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
with |backref|s resolved from |b:match_match|.
*b:match_tail*
The b:match_tail variable is set to the remaining patterns in
|b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
*b:match_word*
The b:match_word variable is set to the pattern from |b:match_wholeBR| that
matches |b:match_match|.
*b:match_table*
The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
|b:match_word|.
==============================================================================
5. Known Bugs and Limitations *matchit-bugs*
Just because I know about a bug does not mean that it is on my todo list. I
try to respond to reports of bugs that cause real problems. If it does not
cause serious problems, or if there is a work-around, a bug may sit there for
a while. Moral: if a bug (known or not) bothers you, let me know.
It would be nice if "\0" were recognized as the entire pattern. That is, it
would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may
try to implement this in a future version. (This is not so easy to arrange as
you might think!)
==============================================================================
vim:tw=78:fo=tcq2:ft=help:

View File

@ -0,0 +1,50 @@
:MatchDebug matchit.txt /*:MatchDebug*
MatchError matchit.txt /*MatchError*
[% matchit.txt /*[%*
]% matchit.txt /*]%*
b:match_col matchit.txt /*b:match_col*
b:match_debug matchit.txt /*b:match_debug*
b:match_ignorecase matchit.txt /*b:match_ignorecase*
b:match_ini matchit.txt /*b:match_ini*
b:match_iniBR matchit.txt /*b:match_iniBR*
b:match_match matchit.txt /*b:match_match*
b:match_pat matchit.txt /*b:match_pat*
b:match_skip matchit.txt /*b:match_skip*
b:match_table matchit.txt /*b:match_table*
b:match_tail matchit.txt /*b:match_tail*
b:match_wholeBR matchit.txt /*b:match_wholeBR*
b:match_word matchit.txt /*b:match_word*
b:match_words matchit.txt /*b:match_words*
g% matchit.txt /*g%*
matchit matchit.txt /*matchit*
matchit-% matchit.txt /*matchit-%*
matchit-\1 matchit.txt /*matchit-\\1*
matchit-activate matchit.txt /*matchit-activate*
matchit-backref matchit.txt /*matchit-backref*
matchit-bugs matchit.txt /*matchit-bugs*
matchit-choose matchit.txt /*matchit-choose*
matchit-configure matchit.txt /*matchit-configure*
matchit-debug matchit.txt /*matchit-debug*
matchit-details matchit.txt /*matchit-details*
matchit-highlight matchit.txt /*matchit-highlight*
matchit-hl matchit.txt /*matchit-hl*
matchit-intro matchit.txt /*matchit-intro*
matchit-languages matchit.txt /*matchit-languages*
matchit-modes matchit.txt /*matchit-modes*
matchit-newlang matchit.txt /*matchit-newlang*
matchit-o_% matchit.txt /*matchit-o_%*
matchit-parse matchit.txt /*matchit-parse*
matchit-s:notend matchit.txt /*matchit-s:notend*
matchit-s:sol matchit.txt /*matchit-s:sol*
matchit-spaces matchit.txt /*matchit-spaces*
matchit-troubleshoot matchit.txt /*matchit-troubleshoot*
matchit-v_% matchit.txt /*matchit-v_%*
matchit.txt matchit.txt /*matchit.txt*
matchit.vim matchit.txt /*matchit.vim*
o_[% matchit.txt /*o_[%*
o_]% matchit.txt /*o_]%*
o_g% matchit.txt /*o_g%*
v_[% matchit.txt /*v_[%*
v_]% matchit.txt /*v_]%*
v_a% matchit.txt /*v_a%*
v_g% matchit.txt /*v_g%*

View File

@ -0,0 +1,92 @@
" matchit.vim: (global plugin) Extended "%" matching
" Maintainer: Christian Brabandt
" Version: 1.15
" Last Change: 2019 Jan 28
" Repository: https://github.com/chrisbra/matchit
" Previous URL:http://www.vim.org/script.php?script_id=39
" Previous Maintainer: Benji Fisher PhD <benji@member.AMS.org>
" Documentation:
" The documentation is in a separate file: ../doc/matchit.txt .
" Credits:
" Vim editor by Bram Moolenaar (Thanks, Bram!)
" Original script and design by Raul Segura Acevedo
" Support for comments by Douglas Potts
" Support for back references and other improvements by Benji Fisher
" Support for many languages by Johannes Zellner
" Suggestions for improvement, bug reports, and support for additional
" languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
" Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
" Debugging:
" If you'd like to try the built-in debugging commands...
" :MatchDebug to activate debugging for the current buffer
" This saves the values of several key script variables as buffer-local
" variables. See the MatchDebug() function, below, for details.
" TODO: I should think about multi-line patterns for b:match_words.
" This would require an option: how many lines to scan (default 1).
" This would be useful for Python, maybe also for *ML.
" TODO: Maybe I should add a menu so that people will actually use some of
" the features that I have implemented.
" TODO: Eliminate the MultiMatch function. Add yet another argument to
" Match_wrapper() instead.
" TODO: Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
" TODO: Make backrefs safer by using '\V' (very no-magic).
" TODO: Add a level of indirection, so that custom % scripts can use my
" work but extend it.
" Allow user to prevent loading and prevent duplicate loading.
if exists("g:loaded_matchit") || &cp
finish
endif
let g:loaded_matchit = 1
let s:save_cpo = &cpo
set cpo&vim
nnoremap <silent> <Plug>(MatchitNormalForward) :<C-U>call matchit#Match_wrapper('',1,'n')<CR>
nnoremap <silent> <Plug>(MatchitNormalBackward) :<C-U>call matchit#Match_wrapper('',0,'n')<CR>
vnoremap <silent> <Plug>(MatchitVisualForward) :<C-U>call matchit#Match_wrapper('',1,'v')<CR>m'gv``
vnoremap <silent> <Plug>(MatchitVisualBackward) :<C-U>call matchit#Match_wrapper('',0,'v')<CR>m'gv``
onoremap <silent> <Plug>(MatchitOperationForward) :<C-U>call matchit#Match_wrapper('',1,'o')<CR>
onoremap <silent> <Plug>(MatchitOperationBackward) :<C-U>call matchit#Match_wrapper('',0,'o')<CR>
nmap <silent> % <Plug>(MatchitNormalForward)
nmap <silent> g% <Plug>(MatchitNormalBackward)
xmap <silent> % <Plug>(MatchitVisualForward)
xmap <silent> g% <Plug>(MatchitVisualBackward)
omap <silent> % <Plug>(MatchitOperationForward)
omap <silent> g% <Plug>(MatchitOperationBackward)
" Analogues of [{ and ]} using matching patterns:
nnoremap <silent> <Plug>(MatchitNormalMultiBackward) :<C-U>call matchit#MultiMatch("bW", "n")<CR>
nnoremap <silent> <Plug>(MatchitNormalMultiForward) :<C-U>call matchit#MultiMatch("W", "n")<CR>
vnoremap <silent> <Plug>(MatchitVisualMultiBackward) :<C-U>call matchit#MultiMatch("bW", "n")<CR>m'gv``
vnoremap <silent> <Plug>(MatchitVisualMultiForward) :<C-U>call matchit#MultiMatch("W", "n")<CR>m'gv``
onoremap <silent> <Plug>(MatchitOperationMultiBackward) :<C-U>call matchit#MultiMatch("bW", "o")<CR>
onoremap <silent> <Plug>(MatchitOperationMultiForward) :<C-U>call matchit#MultiMatch("W", "o")<CR>
nmap <silent> [% <Plug>(MatchitNormalMultiBackward)
nmap <silent> ]% <Plug>(MatchitNormalMultiForward)
xmap <silent> [% <Plug>(MatchitVisualMultiBackward)
xmap <silent> ]% <Plug>(MatchitVisualMultiForward)
omap <silent> [% <Plug>(MatchitOperationMultiBackward)
omap <silent> ]% <Plug>(MatchitOperationMultiForward)
" text object:
vmap <silent> <Plug>(MatchitVisualTextObject) <Plug>(MatchitVisualMultiBackward)o<Plug>(MatchitVisualMultiForward)
xmap a% <Plug>(MatchitVisualTextObject)
" Call this function to turn on debugging information. Every time the main
" script is run, buffer variables will be saved. These can be used directly
" or viewed using the menu items below.
if !exists(":MatchDebug")
command! -nargs=0 MatchDebug call matchit#Match_debug()
endif
let &cpo = s:save_cpo
unlet s:save_cpo
" vim:sts=2:sw=2:et:

View File

@ -0,0 +1,94 @@
" When you're writing shell scripts and you are in doubt which test to use,
" which shell environment variables are defined, what the syntax of the case
" statement is, and you need to invoke 'man sh'?
"
" Your problems are over now!
"
" Attached is a Vim script file for turning gvim into a shell script editor.
" It may also be used as an example how to use menus in Vim.
"
" Written by: Lennart Schultz <les@dmi.min.dk>
imenu Stmts.for for in
do
doneki kk0elli
imenu Stmts.case case in
) ;;
esacbki k0elli
imenu Stmts.if if
then
fiki kk0elli
imenu Stmts.if-else if
then
else
fiki kki kk0elli
imenu Stmts.elif elif
then
ki kk0elli
imenu Stmts.while while
do
doneki kk0elli
imenu Stmts.break break
imenu Stmts.continue continue
imenu Stmts.function () {
}ki k0i
imenu Stmts.return return
imenu Stmts.return-true return 0
imenu Stmts.return-false return 1
imenu Stmts.exit exit
imenu Stmts.shift shift
imenu Stmts.trap trap
imenu Test.existence [ -e ]hi
imenu Test.existence - file [ -f ]hi
imenu Test.existence - file (not empty) [ -s ]hi
imenu Test.existence - directory [ -d ]hi
imenu Test.existence - executable [ -x ]hi
imenu Test.existence - readable [ -r ]hi
imenu Test.existence - writable [ -w ]hi
imenu Test.String is empty [ x = "x$" ]hhi
imenu Test.String is not empty [ x != "x$" ]hhi
imenu Test.Strings is equal [ "" = "" ]hhhhhhhi
imenu Test.Strings is not equal [ "" != "" ]hhhhhhhhi
imenu Test.Values is greater than [ -gt ]hhhhhhi
imenu Test.Values is greater equal [ -ge ]hhhhhhi
imenu Test.Values is equal [ -eq ]hhhhhhi
imenu Test.Values is not equal [ -ne ]hhhhhhi
imenu Test.Values is less than [ -lt ]hhhhhhi
imenu Test.Values is less equal [ -le ]hhhhhhi
imenu ParmSub.Substitute word if parm not set ${:-}hhi
imenu ParmSub.Set parm to word if not set ${:=}hhi
imenu ParmSub.Substitute word if parm set else nothing ${:+}hhi
imenu ParmSub.If parm not set print word and exit ${:?}hhi
imenu SpShVars.Number of positional parameters ${#}
imenu SpShVars.All positional parameters (quoted spaces) ${*}
imenu SpShVars.All positional parameters (unquoted spaces) ${@}
imenu SpShVars.Flags set ${-}
imenu SpShVars.Return code of last command ${?}
imenu SpShVars.Process number of this shell ${$}
imenu SpShVars.Process number of last background command ${!}
imenu Environ.HOME ${HOME}
imenu Environ.PATH ${PATH}
imenu Environ.CDPATH ${CDPATH}
imenu Environ.MAIL ${MAIL}
imenu Environ.MAILCHECK ${MAILCHECK}
imenu Environ.PS1 ${PS1}
imenu Environ.PS2 ${PS2}
imenu Environ.IFS ${IFS}
imenu Environ.SHACCT ${SHACCT}
imenu Environ.SHELL ${SHELL}
imenu Environ.LC_CTYPE ${LC_CTYPE}
imenu Environ.LC_MESSAGES ${LC_MESSAGES}
imenu Builtins.cd cd
imenu Builtins.echo echo
imenu Builtins.eval eval
imenu Builtins.exec exec
imenu Builtins.export export
imenu Builtins.getopts getopts
imenu Builtins.hash hash

View File

@ -0,0 +1,22 @@
" These macros swap the left and right mouse buttons (for left handed)
" Don't forget to do ":set mouse=a" or the mouse won't work at all
noremap <LeftMouse> <RightMouse>
noremap <2-LeftMouse> <2-RightMouse>
noremap <3-LeftMouse> <3-RightMouse>
noremap <4-LeftMouse> <4-RightMouse>
noremap <LeftDrag> <RightDrag>
noremap <LeftRelease> <RightRelease>
noremap <RightMouse> <LeftMouse>
noremap <2-RightMouse> <2-LeftMouse>
noremap <3-RightMouse> <3-LeftMouse>
noremap <4-RightMouse> <4-LeftMouse>
noremap <RightDrag> <LeftDrag>
noremap <RightRelease> <LeftRelease>
noremap g<LeftMouse> <C-RightMouse>
noremap g<RightMouse> <C-LeftMouse>
noremap! <LeftMouse> <RightMouse>
noremap! <LeftDrag> <RightDrag>
noremap! <LeftRelease> <RightRelease>
noremap! <RightMouse> <LeftMouse>
noremap! <RightDrag> <LeftDrag>
noremap! <RightRelease> <LeftRelease>

File diff suppressed because it is too large Load Diff