made the pack completely portable and wrote relevent bat files to go with it
This commit is contained in:
72
gitportable/usr/share/vim/vim91/pack/dist/opt/cfilter/plugin/cfilter.vim
vendored
Normal file
72
gitportable/usr/share/vim/vim91/pack/dist/opt/cfilter/plugin/cfilter.vim
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
vim9script
|
||||
|
||||
# cfilter.vim: Plugin to filter entries from a quickfix/location list
|
||||
# Last Change: August 16, 2023
|
||||
# Maintainer: Yegappan Lakshmanan (yegappan AT yahoo DOT com)
|
||||
# Version: 2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
def Qf_filter(qf: bool, searchpat: string, bang: string)
|
||||
var Xgetlist: func
|
||||
var Xsetlist: func
|
||||
var cmd: string
|
||||
var firstchar: string
|
||||
var lastchar: string
|
||||
var pat: string
|
||||
var title: string
|
||||
var Cond: func
|
||||
var items: list<any>
|
||||
|
||||
if qf
|
||||
Xgetlist = function('getqflist')
|
||||
Xsetlist = function('setqflist')
|
||||
cmd = $':Cfilter{bang}'
|
||||
else
|
||||
Xgetlist = function('getloclist', [0])
|
||||
Xsetlist = function('setloclist', [0])
|
||||
cmd = $':Lfilter{bang}'
|
||||
endif
|
||||
|
||||
firstchar = searchpat[0]
|
||||
lastchar = searchpat[-1 :]
|
||||
if firstchar == lastchar &&
|
||||
(firstchar == '/' || firstchar == '"' || firstchar == "'")
|
||||
pat = searchpat[1 : -2]
|
||||
if pat == ''
|
||||
# Use the last search pattern
|
||||
pat = @/
|
||||
endif
|
||||
else
|
||||
pat = searchpat
|
||||
endif
|
||||
|
||||
if pat == ''
|
||||
return
|
||||
endif
|
||||
|
||||
if bang == '!'
|
||||
Cond = (_, val) => val.text !~# pat && bufname(val.bufnr) !~# pat
|
||||
else
|
||||
Cond = (_, val) => val.text =~# pat || bufname(val.bufnr) =~# pat
|
||||
endif
|
||||
|
||||
items = filter(Xgetlist(), Cond)
|
||||
title = $'{cmd} /{pat}/'
|
||||
Xsetlist([], ' ', {title: title, items: items})
|
||||
enddef
|
||||
|
||||
command! -nargs=+ -bang Cfilter Qf_filter(true, <q-args>, <q-bang>)
|
||||
command! -nargs=+ -bang Lfilter Qf_filter(false, <q-args>, <q-bang>)
|
||||
|
||||
# vim: shiftwidth=2 sts=2 expandtab
|
||||
78
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/autoload/comment.vim
vendored
Normal file
78
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/autoload/comment.vim
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
vim9script
|
||||
|
||||
# Maintainer: Maxim Kim <habamax@gmail.com>
|
||||
# Last Update: 2024 Oct 05
|
||||
#
|
||||
# Toggle comments
|
||||
# Usage:
|
||||
# Add following mappings to vimrc:
|
||||
# import autoload 'dist/comment.vim'
|
||||
# nnoremap <silent> <expr> gc comment.Toggle()
|
||||
# xnoremap <silent> <expr> gc comment.Toggle()
|
||||
# nnoremap <silent> <expr> gcc comment.Toggle() .. '_'
|
||||
# nnoremap <silent> <expr> gC comment.Toggle() .. '$'
|
||||
export def Toggle(...args: list<string>): string
|
||||
if len(args) == 0
|
||||
&opfunc = matchstr(expand('<stack>'), '[^. ]*\ze[')
|
||||
return 'g@'
|
||||
endif
|
||||
if empty(&cms) || !&ma | return '' | endif
|
||||
var cms = substitute(substitute(&cms, '\S\zs%s\s*', ' %s', ''), '%s\ze\S', '%s ', '')
|
||||
var [lnum1, lnum2] = [line("'["), line("']")]
|
||||
var cms_l = split(escape(cms, '*.'), '\s*%s\s*')
|
||||
|
||||
var first_col = indent(lnum1)
|
||||
var start_col = getpos("'[")[2] - 1
|
||||
if len(cms_l) == 1 && lnum1 == lnum2 && first_col < start_col
|
||||
var line_start = getline(lnum1)[0 : start_col - 1]
|
||||
var line_end = getline(lnum1)[start_col : -1]
|
||||
line_end = line_end =~ $'^\s*{cms_l[0]}' ?
|
||||
\ substitute(line_end, $'^\s*\zs{cms_l[0]}\s\ze\s*', line_end =~ '^\s' ? ' ' : '', '') :
|
||||
\ printf(substitute(cms, '%s\@!', '%%', ''), line_end)
|
||||
setline(lnum1, line_start .. line_end)
|
||||
return ''
|
||||
endif
|
||||
|
||||
if len(cms_l) == 0 | return '' | endif
|
||||
if len(cms_l) == 1 | call add(cms_l, '') | endif
|
||||
var comment = false
|
||||
var indent_spaces = false
|
||||
var indent_tabs = false
|
||||
var indent_min = indent(lnum1)
|
||||
var indent_start = matchstr(getline(lnum1), '^\s*')
|
||||
for lnum in range(lnum1, lnum2)
|
||||
if getline(lnum) =~ '^\s*$' | continue | endif
|
||||
var indent_str = matchstr(getline(lnum), '^\s*')
|
||||
if indent_min > indent(lnum)
|
||||
indent_min = indent(lnum)
|
||||
indent_start = indent_str
|
||||
endif
|
||||
indent_spaces = indent_spaces || (stridx(indent_str, ' ') != -1)
|
||||
indent_tabs = indent_tabs || (stridx(indent_str, "\t") != -1)
|
||||
if getline(lnum) !~ $'^\s*{cms_l[0]}.*{cms_l[1]}$'
|
||||
comment = true
|
||||
endif
|
||||
endfor
|
||||
var mixed_indent = indent_spaces && indent_tabs
|
||||
var lines = []
|
||||
var line = ''
|
||||
for lnum in range(lnum1, lnum2)
|
||||
if getline(lnum) =~ '^\s*$'
|
||||
line = getline(lnum)
|
||||
elseif comment
|
||||
if exists("g:comment_first_col") || exists("b:comment_first_col")
|
||||
line = printf(substitute(cms, '%s\@!', '%%', 'g'), getline(lnum))
|
||||
else
|
||||
# consider different whitespace indenting
|
||||
var indent_current = mixed_indent ? matchstr(getline(lnum), '^\s*') : indent_start
|
||||
line = printf(indent_current .. substitute(cms, '%s\@!', '%%', 'g'),
|
||||
strpart(getline(lnum), strlen(indent_current)))
|
||||
endif
|
||||
else
|
||||
line = substitute(getline(lnum), $'^\s*\zs{cms_l[0]} \?\| \?{cms_l[1]}$', '', 'g')
|
||||
endif
|
||||
add(lines, line)
|
||||
endfor
|
||||
noautocmd keepjumps setline(lnum1, lines)
|
||||
return ''
|
||||
enddef
|
||||
80
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/doc/comment.txt
vendored
Normal file
80
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/doc/comment.txt
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
*comment.txt* For Vim version 9.1. Last change: 2024 Oct 01
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL
|
||||
|
||||
Commenting and un-commenting text.
|
||||
|
||||
==============================================================================
|
||||
|
||||
See |comment-install| on how to activate this package.
|
||||
|
||||
The comment.vim package, allows to toggle comments for a single line, a range
|
||||
of lines or a selected text object. It defines the following mappings:
|
||||
|
||||
*o_gc*
|
||||
gc{motion} to toggle comments for the selected motion
|
||||
*v_gc*
|
||||
{Visual}gc to comment/uncomment the highlighted lines.
|
||||
|
||||
Since gc operates on a motion, it can be used with any motion, for example _
|
||||
to comment the current line, or ip to comment the current paragraph.
|
||||
A default mapping `gcc` to `gc_` is defined:
|
||||
*gcc*
|
||||
gcc to comment/uncomment current line
|
||||
|
||||
To comment the rest of the line by `gC` whenever the filetype plugin
|
||||
supports it (that is, whenever the comment marker precedes the code) and fall
|
||||
back to `gcc` otherwise, add the following mapping to your vimrc: >
|
||||
|
||||
nnoremap <silent> <expr> gC comment#Toggle() .. '$'
|
||||
<
|
||||
Note: using `gC` may not always result in valid comment markers depending on
|
||||
the language used.
|
||||
|
||||
This plugin uses the buffer-local 'commentstring' option value to add or remove
|
||||
comment markers to the selected lines. Whether it will comment or un-comment
|
||||
depends on the first line of the range of lines to act upon. When it matches
|
||||
a comment marker, the line will be un-commented, if it doesn't, the line will
|
||||
be commented out. Blank and empty lines are ignored.
|
||||
|
||||
The value of 'commentstring' is the same for the entire buffer and determined
|
||||
by its filetype (|filetypes|). To adapt it within the buffer for embedded
|
||||
languages, you can use a plug-in such as
|
||||
https://github.com/suy/vim-context-commentstring.
|
||||
|
||||
The comment marker will always be padded with blanks whether or not the
|
||||
'commentstring' value contains whitespace around "%s".
|
||||
|
||||
If the mapping does not seem to work (or uses wrong comment markers), it might
|
||||
be because of several reasons:
|
||||
- the filetype is not detected by Vim, see |new-filetype|,
|
||||
- filetype plugins are not enabled, see |:filetype-plugin-on| or
|
||||
- the filetype plugin does not set the (correct) 'commentstring' option.
|
||||
|
||||
You can simply configure this using the following autocommand (e.g. for legacy
|
||||
Vim script): >
|
||||
|
||||
autocmd Filetype vim :setlocal commentstring="%s
|
||||
|
||||
This example sets the " as start of a comment for legacy Vim script. For Vim9
|
||||
script, you would instead use the "#" char: >
|
||||
|
||||
autocmd Filetype vim :setlocal commentstring=#\ %s
|
||||
|
||||
==============================================================================
|
||||
Options:
|
||||
|
||||
*g:comment_first_col*
|
||||
*b:comment_first_col*
|
||||
By default comment chars are added in front of the line, i.e. if the line
|
||||
was indented, commented line would stay indented as well.
|
||||
|
||||
However some filetypes require a comment char on the first column, use this option
|
||||
to change default behaviour.
|
||||
|
||||
Use g:comment_first_col to change it globally or b:comment_first_col to
|
||||
target specific filetype(s).
|
||||
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:fo=tcq2:ft=help:
|
||||
6
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/doc/tags
vendored
Normal file
6
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/doc/tags
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
b:comment_first_col comment.txt /*b:comment_first_col*
|
||||
comment.txt comment.txt /*comment.txt*
|
||||
g:comment_first_col comment.txt /*g:comment_first_col*
|
||||
gcc comment.txt /*gcc*
|
||||
o_gc comment.txt /*o_gc*
|
||||
v_gc comment.txt /*v_gc*
|
||||
9
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/plugin/comment.vim
vendored
Normal file
9
gitportable/usr/share/vim/vim91/pack/dist/opt/comment/plugin/comment.vim
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
vim9script
|
||||
|
||||
# Maintainer: Maxim Kim <habamax@gmail.com>
|
||||
# Last Update: 2024-04-26
|
||||
|
||||
import autoload 'comment.vim'
|
||||
nnoremap <silent> <expr> gc comment.Toggle()
|
||||
xnoremap <silent> <expr> gc comment.Toggle()
|
||||
nnoremap <silent> <expr> gcc comment.Toggle() .. '_'
|
||||
72
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/dvorak/disable.vim
vendored
Normal file
72
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/dvorak/disable.vim
vendored
Normal 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 +
|
||||
77
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/dvorak/enable.vim
vendored
Normal file
77
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/dvorak/enable.vim
vendored
Normal 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 + }
|
||||
16
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/plugin/dvorak.vim
vendored
Normal file
16
gitportable/usr/share/vim/vim91/pack/dist/opt/dvorak/plugin/dvorak.vim
vendored
Normal 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>
|
||||
118
gitportable/usr/share/vim/vim91/pack/dist/opt/editexisting/plugin/editexisting.vim
vendored
Normal file
118
gitportable/usr/share/vim/vim91/pack/dist/opt/editexisting/plugin/editexisting.vim
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
" Vim Plugin: Edit the file with an existing Vim if possible
|
||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||
" Last Change: 2023 Aug 13
|
||||
|
||||
" 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.
|
||||
try
|
||||
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
|
||||
catch /^Vim\%((\a\+)\)\=:E241:/
|
||||
" Unable to send to this server, ignore it.
|
||||
endtry
|
||||
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
|
||||
27
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/.editorconfig
vendored
Normal file
27
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/.editorconfig
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
max_line_length = 80
|
||||
|
||||
[*.{vim,sh}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 80
|
||||
|
||||
[*.rb]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 120
|
||||
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{bat,vbs,ps1}]
|
||||
end_of_line = CRLF
|
||||
6
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/CONTRIBUTORS
vendored
Normal file
6
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/CONTRIBUTORS
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
Contributors to the EditorConfig Vim Plugin:
|
||||
|
||||
Hong Xu
|
||||
Trey Hunner
|
||||
Kent Frazier
|
||||
Chris White
|
||||
26
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/LICENSE
vendored
Normal file
26
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/LICENSE
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
Unless otherwise stated, all files are distributed under the Simplified BSD
|
||||
license included below.
|
||||
|
||||
Copyright (c) 2011-2019 EditorConfig Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
53
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/LICENSE.PSF
vendored
Normal file
53
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/LICENSE.PSF
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
Some code in editorconfig-vim is derived from code licensed under the
|
||||
PSF license. The following is the text of that license, retrieved 2019-05-05
|
||||
from https://docs.python.org/2.6/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python
|
||||
|
||||
PSF LICENSE AGREEMENT FOR PYTHON 2.6.9
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
(``PSF''), and the Individual or Organization (``Licensee'') accessing and
|
||||
otherwise using Python 2.6.9 software in source or binary form and its
|
||||
associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python 2.6.9
|
||||
alone or in any derivative version, provided, however, that PSF's
|
||||
License Agreement and PSF's notice of copyright, i.e., ``Copyright (c)
|
||||
2001-2010 Python Software Foundation; All Rights Reserved'' are
|
||||
retained in Python 2.6.9 alone or in any derivative version prepared
|
||||
by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python 2.6.9 or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python 2.6.9.
|
||||
|
||||
4. PSF is making Python 2.6.9 available to Licensee on an ``AS IS''
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
|
||||
BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY
|
||||
REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY
|
||||
PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.6.9 WILL NOT INFRINGE
|
||||
ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
2.6.9 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.6.9,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python 2.6.9, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
|
||||
# vi: set ft=:
|
||||
148
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/README.md
vendored
Normal file
148
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/README.md
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
# EditorConfig Vim Plugin
|
||||
|
||||
[](https://travis-ci.org/editorconfig/editorconfig-vim)
|
||||
[](https://ci.appveyor.com/project/cxw42/editorconfig-vim)
|
||||
|
||||
This is an [EditorConfig][] plugin for Vim. This plugin can be found on both
|
||||
[GitHub][] and [Vim online][].
|
||||
|
||||
## Installation
|
||||
|
||||
To install this plugin, you can use one of the following ways:
|
||||
|
||||
### Install with the archive
|
||||
|
||||
Download the [archive][] and extract it into your Vim runtime directory
|
||||
(`~/.vim` on UNIX/Linux and `$VIM_INSTALLATION_FOLDER\vimfiles` on windows).
|
||||
You should have 4 sub-directories in this runtime directory now: "autoload",
|
||||
"doc", "ftdetect" and "plugin".
|
||||
|
||||
### Install as Vim8 plugin
|
||||
|
||||
Install as a Vim 8 plugin. Note `local` can be any name, but some path
|
||||
element must be present. On Windows, instead of `~/.vim` use
|
||||
`$VIM_INSTALLATION_FOLDER\vimfiles`.
|
||||
```shell
|
||||
mkdir -p ~/.vim/pack/local/start
|
||||
cd ~/.vim/pack/local/start
|
||||
git clone https://github.com/editorconfig/editorconfig-vim.git
|
||||
```
|
||||
|
||||
### Install with [pathogen][]
|
||||
|
||||
Use pathogen (the git repository of this plugin is
|
||||
https://github.com/editorconfig/editorconfig-vim.git)
|
||||
|
||||
### Install with [Vundle][]
|
||||
|
||||
Use Vundle by adding to your `.vimrc` Vundle plugins section:
|
||||
|
||||
```viml
|
||||
Plugin 'editorconfig/editorconfig-vim'
|
||||
```
|
||||
|
||||
Then call `:PluginInstall`.
|
||||
|
||||
### Install with [vim-plug][]
|
||||
|
||||
Use vim-plug by adding to your `.vimrc` in your plugin section:
|
||||
|
||||
```viml
|
||||
Plug 'editorconfig/editorconfig-vim'
|
||||
```
|
||||
|
||||
Source your `.vimrc` by calling `:source $MYVIMRC`.
|
||||
|
||||
Then call `:PlugInstall`.
|
||||
|
||||
### No external editorconfig core library is required
|
||||
|
||||
Previous versions of this plugin also required a Python "core".
|
||||
The core included the code to parse `.editorconfig` files.
|
||||
This plugin **includes** the core, so you don't need to download the
|
||||
core separately.
|
||||
|
||||
## Supported properties
|
||||
|
||||
The EditorConfig Vim plugin supports the following EditorConfig [properties][]:
|
||||
|
||||
* `indent_style`
|
||||
* `indent_size`
|
||||
* `tab_width`
|
||||
* `end_of_line`
|
||||
* `charset`
|
||||
* `insert_final_newline` (Feature `+fixendofline`, available on Vim 7.4.785+,
|
||||
or [PreserveNoEOL][] is required for this property)
|
||||
* `trim_trailing_whitespace`
|
||||
* `max_line_length`
|
||||
* `root` (only used by EditorConfig core)
|
||||
|
||||
## Selected Options
|
||||
|
||||
The supported options are documented in [editorconfig.txt][]
|
||||
and can be viewed by executing the following: `:help editorconfig`. You may
|
||||
need to execute `:helptags ALL` so that Vim is aware of editorconfig.txt.
|
||||
|
||||
### Excluded patterns
|
||||
|
||||
To ensure that this plugin works well with [Tim Pope's fugitive][], use the
|
||||
following patterns array:
|
||||
|
||||
```viml
|
||||
let g:EditorConfig_exclude_patterns = ['fugitive://.*']
|
||||
```
|
||||
|
||||
If you wanted to avoid loading EditorConfig for any remote files over ssh:
|
||||
|
||||
```viml
|
||||
let g:EditorConfig_exclude_patterns = ['scp://.*']
|
||||
```
|
||||
|
||||
Of course these two items could be combined into the following:
|
||||
|
||||
```viml
|
||||
let g:EditorConfig_exclude_patterns = ['fugitive://.*', 'scp://.*']
|
||||
```
|
||||
|
||||
### Disable for a specific filetype
|
||||
|
||||
You can disable this plugin for a specific buffer by setting
|
||||
`b:EditorConfig_disable`. Therefore, you can disable the
|
||||
plugin for all buffers of a specific filetype. For example, to disable
|
||||
EditorConfig for all git commit messages (filetype `gitcommit`):
|
||||
|
||||
```viml
|
||||
au FileType gitcommit let b:EditorConfig_disable = 1
|
||||
```
|
||||
|
||||
### Disable rules
|
||||
|
||||
In very rare cases,
|
||||
you might need to override some project-specific EditorConfig rules in global
|
||||
or local vimrc in some cases, e.g., to resolve conflicts of trailing whitespace
|
||||
trimming and buffer autosaving. This is not recommended, but you can:
|
||||
|
||||
```viml
|
||||
let g:EditorConfig_disable_rules = ['trim_trailing_whitespace']
|
||||
```
|
||||
|
||||
You are able to disable any supported EditorConfig properties.
|
||||
|
||||
## Bugs and Feature Requests
|
||||
|
||||
Feel free to submit bugs, feature requests, and other issues to the
|
||||
[issue tracker][]. Be sure you have read the [contribution guidelines][]!
|
||||
|
||||
[EditorConfig]: http://editorconfig.org
|
||||
[GitHub]: https://github.com/editorconfig/editorconfig-vim
|
||||
[PreserveNoEOL]: http://www.vim.org/scripts/script.php?script_id=4550
|
||||
[Tim Pope's fugitive]: https://github.com/tpope/vim-fugitive
|
||||
[Vim online]: http://www.vim.org/scripts/script.php?script_id=3934
|
||||
[Vundle]: https://github.com/gmarik/Vundle.vim
|
||||
[archive]: https://github.com/editorconfig/editorconfig-vim/archive/master.zip
|
||||
[contribution guidelines]: https://github.com/editorconfig/editorconfig/blob/master/CONTRIBUTING.md#submitting-an-issue
|
||||
[issue tracker]: https://github.com/editorconfig/editorconfig-vim/issues
|
||||
[pathogen]: https://github.com/tpope/vim-pathogen
|
||||
[properties]: http://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties
|
||||
[editorconfig.txt]: https://github.com/editorconfig/editorconfig-vim/blob/master/doc/editorconfig.txt
|
||||
[vim-plug]: https://github.com/junegunn/vim-plug
|
||||
60
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig.vim
vendored
Normal file
60
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig.vim
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
" autoload/editorconfig.vim: EditorConfig native Vim script plugin
|
||||
" Copyright (c) 2011-2019 EditorConfig Team
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE.
|
||||
"
|
||||
|
||||
if v:version < 700
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" {{{1 variables
|
||||
let s:hook_list = []
|
||||
|
||||
function! editorconfig#AddNewHook(func) " {{{1
|
||||
" Add a new hook
|
||||
|
||||
call add(s:hook_list, a:func)
|
||||
endfunction
|
||||
|
||||
function! editorconfig#ApplyHooks(config) abort " {{{1
|
||||
" apply hooks
|
||||
|
||||
for Hook in s:hook_list
|
||||
let l:hook_ret = Hook(a:config)
|
||||
|
||||
if type(l:hook_ret) != type(0) && l:hook_ret != 0
|
||||
" TODO print some debug info here
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vim: fdm=marker fdc=3
|
||||
147
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core.vim
vendored
Normal file
147
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core.vim
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
" autoload/editorconfig_core.vim: top-level functions for
|
||||
" editorconfig-core-vimscript and editorconfig-vim.
|
||||
|
||||
" Copyright (c) 2018-2020 EditorConfig Team, including Chris White {{{1
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE. }}}1
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Variables {{{1
|
||||
|
||||
" Note: we create this variable in every script that accesses it. Normally, I
|
||||
" would put this in plugin/editorconfig.vim. However, in some of my tests,
|
||||
" the command-line testing environment did not load plugin/* in the normal
|
||||
" way. Therefore, I do the check everywhere so I don't have to special-case
|
||||
" the command line.
|
||||
|
||||
if !exists('g:editorconfig_core_vimscript_debug')
|
||||
let g:editorconfig_core_vimscript_debug = 0
|
||||
endif
|
||||
" }}}1
|
||||
|
||||
" The latest version of the specification that we support.
|
||||
" See discussion at https://github.com/editorconfig/editorconfig/issues/395
|
||||
function! editorconfig_core#version()
|
||||
return [0,13,0]
|
||||
endfunction
|
||||
|
||||
" === CLI =============================================================== {{{1
|
||||
|
||||
" For use from the command line. Output settings for in_name to
|
||||
" the buffer named out_name. If an optional argument is provided, it is the
|
||||
" name of the config file to use (default '.editorconfig').
|
||||
" TODO support multiple files
|
||||
"
|
||||
" filename (if any)
|
||||
" @param names {Dictionary} The names of the files to use for this run
|
||||
" - output [required] Where the editorconfig settings should be written
|
||||
" - target [required] A string or list of strings to process. Each
|
||||
" must be a full path.
|
||||
" - dump [optional] If present, write debug info to this file
|
||||
" @param job {Dictionary} What to do - same format as the input of
|
||||
" editorconfig_core#handler#get_configurations(),
|
||||
" except without the target member.
|
||||
|
||||
function! editorconfig_core#currbuf_cli(names, job) " out_name, in_name, ...
|
||||
let l:output = []
|
||||
|
||||
" Preprocess the job
|
||||
let l:job = deepcopy(a:job)
|
||||
|
||||
if has_key(l:job, 'version') " string to list
|
||||
let l:ver = split(editorconfig_core#util#strip(l:job.version), '\v\.')
|
||||
for l:idx in range(len(l:ver))
|
||||
let l:ver[l:idx] = str2nr(l:ver[l:idx])
|
||||
endfor
|
||||
|
||||
let l:job.version = l:ver
|
||||
endif
|
||||
|
||||
" TODO provide version output from here instead of the shell script
|
||||
" if string(a:names) ==? 'version'
|
||||
" return
|
||||
" endif
|
||||
"
|
||||
if type(a:names) != type({}) || type(a:job) != type({})
|
||||
throw 'Need two Dictionary arguments'
|
||||
endif
|
||||
|
||||
if has_key(a:names, 'dump')
|
||||
execute 'redir! > ' . fnameescape(a:names.dump)
|
||||
echom 'Names: ' . string(a:names)
|
||||
echom 'Job: ' . string(l:job)
|
||||
let g:editorconfig_core_vimscript_debug = 1
|
||||
endif
|
||||
|
||||
if type(a:names['target']) == type([])
|
||||
let l:targets = a:names.target
|
||||
else
|
||||
let l:targets = [a:names.target]
|
||||
endif
|
||||
|
||||
for l:target in l:targets
|
||||
|
||||
" Pre-process quoting weirdness so we are more flexible in the face
|
||||
" of CMake+CTest+BAT+Powershell quoting.
|
||||
|
||||
" Permit wrapping in double-quotes
|
||||
let l:target = substitute(l:target, '\v^"(.*)"$', '\1', '')
|
||||
|
||||
" Permit empty ('') entries in l:targets
|
||||
if strlen(l:target)<1
|
||||
continue
|
||||
endif
|
||||
|
||||
if has_key(a:names, 'dump')
|
||||
echom 'Trying: ' . string(l:target)
|
||||
endif
|
||||
|
||||
let l:job.target = l:target
|
||||
let l:options = editorconfig_core#handler#get_configurations(l:job)
|
||||
|
||||
if has_key(a:names, 'dump')
|
||||
echom 'editorconfig_core#currbuf_cli result: ' . string(l:options)
|
||||
endif
|
||||
|
||||
if len(l:targets) > 1
|
||||
let l:output += [ '[' . l:target . ']' ]
|
||||
endif
|
||||
|
||||
for [ l:key, l:value ] in items(l:options)
|
||||
let l:output += [ l:key . '=' . l:value ]
|
||||
endfor
|
||||
|
||||
endfor "foreach target
|
||||
|
||||
" Write the output file
|
||||
call writefile(l:output, a:names.output)
|
||||
endfunction "editorconfig_core#currbuf_cli
|
||||
|
||||
" }}}1
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vi: set fdm=marker fo-=ro:
|
||||
467
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/fnmatch.vim
vendored
Normal file
467
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/fnmatch.vim
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
" autoload/editorconfig_core/fnmatch.vim: Globbing for
|
||||
" editorconfig-vim. Ported from the Python core's fnmatch.py.
|
||||
|
||||
" Copyright (c) 2012-2019 EditorConfig Team {{{1
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE. }}}1
|
||||
|
||||
"Filename matching with shell patterns.
|
||||
"
|
||||
"fnmatch(FILENAME, PATH, PATTERN) matches according to the local convention.
|
||||
"fnmatchcase(FILENAME, PATH, PATTERN) always takes case in account.
|
||||
"
|
||||
"The functions operate by translating the pattern into a regular
|
||||
"expression. They cache the compiled regular expressions for speed.
|
||||
"
|
||||
"The function translate(PATTERN) returns a regular expression
|
||||
"corresponding to PATTERN. (It does not compile it.)
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" variables {{{1
|
||||
if !exists('g:editorconfig_core_vimscript_debug')
|
||||
let g:editorconfig_core_vimscript_debug = 0
|
||||
endif
|
||||
" }}}1
|
||||
" === Regexes =========================================================== {{{1
|
||||
let s:LEFT_BRACE = '\v[\\]@8<!\{'
|
||||
" 8 is an arbitrary byte-count limit to the lookbehind (micro-optimization)
|
||||
"LEFT_BRACE = re.compile(
|
||||
" r"""
|
||||
"
|
||||
" (?<! \\ ) # Not preceded by "\"
|
||||
"
|
||||
" \{ # "{"
|
||||
"
|
||||
" """, re.VERBOSE
|
||||
")
|
||||
|
||||
let s:RIGHT_BRACE = '\v[\\]@8<!\}'
|
||||
" 8 is an arbitrary byte-count limit to the lookbehind (micro-optimization)
|
||||
"RIGHT_BRACE = re.compile(
|
||||
" r"""
|
||||
"
|
||||
" (?<! \\ ) # Not preceded by "\"
|
||||
"
|
||||
" \} # "}"
|
||||
"
|
||||
" """, re.VERBOSE
|
||||
")
|
||||
|
||||
let s:NUMERIC_RANGE = '\v([+-]?\d+)' . '\.\.' . '([+-]?\d+)'
|
||||
"NUMERIC_RANGE = re.compile(
|
||||
" r"""
|
||||
" ( # Capture a number
|
||||
" [+-] ? # Zero or one "+" or "-" characters
|
||||
" \d + # One or more digits
|
||||
" )
|
||||
"
|
||||
" \.\. # ".."
|
||||
"
|
||||
" ( # Capture a number
|
||||
" [+-] ? # Zero or one "+" or "-" characters
|
||||
" \d + # One or more digits
|
||||
" )
|
||||
" """, re.VERBOSE
|
||||
")
|
||||
|
||||
" }}}1
|
||||
" === Internal functions ================================================ {{{1
|
||||
|
||||
" Dump the bytes of a:text. For debugging use.
|
||||
function! s:dump_bytes(text)
|
||||
let l:idx=0
|
||||
while l:idx < strlen(a:text)
|
||||
let l:byte_val = char2nr(a:text[l:idx])
|
||||
echom printf('%10s%-5d%02x %s', '', l:idx, l:byte_val,
|
||||
\ a:text[l:idx])
|
||||
let l:idx+=1
|
||||
endwhile
|
||||
endfunction "s:dump_bytes
|
||||
|
||||
" Dump the characters of a:text and their codepoints. For debugging use.
|
||||
function! s:dump_chars(text)
|
||||
let l:chars = split(a:text, '\zs')
|
||||
let l:idx = 0
|
||||
let l:out1 = ''
|
||||
let l:out2 = ''
|
||||
while l:idx < len(l:chars)
|
||||
let l:char = l:chars[l:idx]
|
||||
let l:out1 .= printf('%5s', l:char)
|
||||
let l:out2 .= printf('%5x', char2nr(l:char))
|
||||
let l:idx+=1
|
||||
endwhile
|
||||
|
||||
echom l:out1
|
||||
echom l:out2
|
||||
endfunction "s:dump_chars
|
||||
|
||||
" }}}1
|
||||
" === Translating globs to patterns ===================================== {{{1
|
||||
|
||||
" Used by s:re_escape: backslash-escape any character below U+0080;
|
||||
" replace all others with a %U escape.
|
||||
" See https://vi.stackexchange.com/a/19617/1430 by yours truly
|
||||
" (https://vi.stackexchange.com/users/1430/cxw).
|
||||
unlockvar s:replacement_expr
|
||||
let s:replacement_expr =
|
||||
\ '\=' .
|
||||
\ '((char2nr(submatch(1)) >= 128) ? ' .
|
||||
\ 'printf("%%U%08x", char2nr(submatch(1))) : ' .
|
||||
\ '("\\" . submatch(1))' .
|
||||
\ ')'
|
||||
lockvar s:replacement_expr
|
||||
|
||||
" Escaper for very-magic regexes
|
||||
function! s:re_escape(text)
|
||||
return substitute(a:text, '\v([^0-9a-zA-Z_])', s:replacement_expr, 'g')
|
||||
endfunction
|
||||
|
||||
"def translate(pat, nested=0):
|
||||
" Translate a shell PATTERN to a regular expression.
|
||||
" There is no way to quote meta-characters.
|
||||
function! editorconfig_core#fnmatch#translate(pat, ...)
|
||||
let l:nested = 0
|
||||
if a:0
|
||||
let l:nested = a:1
|
||||
endif
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom '- fnmatch#translate: pattern ' . a:pat
|
||||
echom printf(
|
||||
\ '- %d chars', strlen(substitute(a:pat, ".", "x", "g")))
|
||||
call s:dump_chars(a:pat)
|
||||
endif
|
||||
|
||||
let l:pat = a:pat " TODO remove if we wind up not needing this
|
||||
|
||||
" Note: the Python sets MULTILINE and DOTALL, but Vim has \_.
|
||||
" instead of DOTALL, and \_^ / \_$ instead of MULTILINE.
|
||||
|
||||
let l:is_escaped = 0
|
||||
|
||||
" Find out whether the pattern has balanced braces.
|
||||
let l:left_braces=[]
|
||||
let l:right_braces=[]
|
||||
call substitute(l:pat, s:LEFT_BRACE, '\=add(l:left_braces, 1)', 'g')
|
||||
call substitute(l:pat, s:RIGHT_BRACE, '\=add(l:right_braces, 1)', 'g')
|
||||
" Thanks to http://jeromebelleman.gitlab.io/posts/productivity/vimsub/
|
||||
let l:matching_braces = (len(l:left_braces) == len(l:right_braces))
|
||||
|
||||
" Unicode support (#2). Indexing l:pat[l:index] returns bytes, per
|
||||
" https://github.com/neovim/neovim/issues/68#issue-28114985 .
|
||||
" Instead, use split() per vimdoc to break the input string into an
|
||||
" array of *characters*, and process that.
|
||||
let l:characters = split(l:pat, '\zs')
|
||||
|
||||
let l:index = 0 " character index
|
||||
let l:length = len(l:characters)
|
||||
let l:brace_level = 0
|
||||
let l:in_brackets = 0
|
||||
|
||||
let l:result = ''
|
||||
let l:numeric_groups = []
|
||||
while l:index < l:length
|
||||
let l:current_char = l:characters[l:index]
|
||||
let l:index += 1
|
||||
|
||||
" if g:editorconfig_core_vimscript_debug
|
||||
" echom ' - fnmatch#translate: ' . l:current_char . '@' .
|
||||
" \ (l:index-1) . '; result ' . l:result
|
||||
" endif
|
||||
|
||||
if l:current_char ==# '*'
|
||||
let l:pos = l:index
|
||||
if l:pos < l:length && l:characters[l:pos] ==# '*'
|
||||
let l:result .= '\_.*'
|
||||
let l:index += 1 " skip the second star
|
||||
else
|
||||
let l:result .= '[^/]*'
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# '?'
|
||||
let l:result .= '\_[^/]'
|
||||
|
||||
elseif l:current_char ==# '['
|
||||
if l:in_brackets
|
||||
let l:result .= '\['
|
||||
else
|
||||
let l:pos = l:index
|
||||
let l:has_slash = 0
|
||||
while l:pos < l:length && l:characters[l:pos] != ']'
|
||||
if l:characters[l:pos] ==# '/' && l:characters[l:pos-1] !=# '\'
|
||||
let has_slash = 1
|
||||
break
|
||||
endif
|
||||
let l:pos += 1
|
||||
endwhile
|
||||
if l:has_slash
|
||||
" POSIX IEEE 1003.1-2017 sec. 2.13.3: '/' cannot occur
|
||||
" in a bracket expression, so [/] matches a literal
|
||||
" three-character string '[' . '/' . ']'.
|
||||
let l:result .= '\['
|
||||
\ . s:re_escape(join(l:characters[l:index : l:pos-1], ''))
|
||||
\ . '\/'
|
||||
" escape the slash
|
||||
let l:index = l:pos + 1
|
||||
" resume after the slash
|
||||
else
|
||||
if l:index < l:length && l:characters[l:index] =~# '\v%(\^|\!)'
|
||||
let l:index += 1
|
||||
let l:result .= '[^'
|
||||
else
|
||||
let l:result .= '['
|
||||
endif
|
||||
let l:in_brackets = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# '-'
|
||||
if l:in_brackets
|
||||
let l:result .= l:current_char
|
||||
else
|
||||
let l:result .= '\' . l:current_char
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# ']'
|
||||
if l:in_brackets && !l:is_escaped
|
||||
let l:result .= ']'
|
||||
let l:in_brackets = 0
|
||||
elseif l:is_escaped
|
||||
let l:result .= '\]'
|
||||
let l:is_escaped = 0
|
||||
else
|
||||
let l:result .= '\]'
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# '{'
|
||||
let l:pos = l:index
|
||||
let l:has_comma = 0
|
||||
while l:pos < l:length && (l:characters[l:pos] !=# '}' || l:is_escaped)
|
||||
if l:characters[l:pos] ==# ',' && ! l:is_escaped
|
||||
let l:has_comma = 1
|
||||
break
|
||||
endif
|
||||
let l:is_escaped = l:characters[l:pos] ==# '\' && ! l:is_escaped
|
||||
let l:pos += 1
|
||||
endwhile
|
||||
if ! l:has_comma && l:pos < l:length
|
||||
let l:num_range =
|
||||
\ matchlist(join(l:characters[l:index : l:pos-1], ''),
|
||||
\ s:NUMERIC_RANGE)
|
||||
if len(l:num_range) > 0 " Remember the ranges
|
||||
call add(l:numeric_groups, [ 0+l:num_range[1], 0+l:num_range[2] ])
|
||||
let l:result .= '([+-]?\d+)'
|
||||
else
|
||||
let l:inner_xlat = editorconfig_core#fnmatch#translate(
|
||||
\ join(l:characters[l:index : l:pos-1], ''), 1)
|
||||
let l:inner_result = l:inner_xlat[0]
|
||||
let l:inner_groups = l:inner_xlat[1]
|
||||
let l:result .= '\{' . l:inner_result . '\}'
|
||||
let l:numeric_groups += l:inner_groups
|
||||
endif
|
||||
let l:index = l:pos + 1
|
||||
elseif l:matching_braces
|
||||
let l:result .= '%('
|
||||
let l:brace_level += 1
|
||||
else
|
||||
let l:result .= '\{'
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# ','
|
||||
if l:brace_level > 0 && ! l:is_escaped
|
||||
let l:result .= '|'
|
||||
else
|
||||
let l:result .= '\,'
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# '}'
|
||||
if l:brace_level > 0 && ! l:is_escaped
|
||||
let l:result .= ')'
|
||||
let l:brace_level -= 1
|
||||
else
|
||||
let l:result .= '\}'
|
||||
endif
|
||||
|
||||
elseif l:current_char ==# '/'
|
||||
if join(l:characters[l:index : (l:index + 2)], '') ==# '**/'
|
||||
let l:result .= '%(/|/\_.*/)'
|
||||
let l:index += 3
|
||||
else
|
||||
let l:result .= '\/'
|
||||
endif
|
||||
|
||||
elseif l:current_char != '\'
|
||||
let l:result .= s:re_escape(l:current_char)
|
||||
endif
|
||||
|
||||
if l:current_char ==# '\'
|
||||
if l:is_escaped
|
||||
let l:result .= s:re_escape(l:current_char)
|
||||
endif
|
||||
let l:is_escaped = ! l:is_escaped
|
||||
else
|
||||
let l:is_escaped = 0
|
||||
endif
|
||||
|
||||
endwhile
|
||||
|
||||
if ! l:nested
|
||||
let l:result .= '\_$'
|
||||
endif
|
||||
|
||||
return [l:result, l:numeric_groups]
|
||||
endfunction " #editorconfig_core#fnmatch#translate
|
||||
|
||||
let s:_cache = {}
|
||||
function! s:cached_translate(pat)
|
||||
if ! has_key(s:_cache, a:pat)
|
||||
"regex = re.compile(res)
|
||||
let s:_cache[a:pat] =
|
||||
\ editorconfig_core#fnmatch#translate(a:pat)
|
||||
" we don't compile the regex
|
||||
endif
|
||||
return s:_cache[a:pat]
|
||||
endfunction " cached_translate
|
||||
|
||||
" }}}1
|
||||
" === Matching functions ================================================ {{{1
|
||||
|
||||
function! editorconfig_core#fnmatch#fnmatch(name, path, pattern)
|
||||
"def fnmatch(name, pat):
|
||||
" """Test whether FILENAME matches PATH/PATTERN.
|
||||
"
|
||||
" Patterns are Unix shell style:
|
||||
"
|
||||
" - ``*`` matches everything except path separator
|
||||
" - ``**`` matches everything
|
||||
" - ``?`` matches any single character
|
||||
" - ``[seq]`` matches any character in seq
|
||||
" - ``[!seq]`` matches any char not in seq
|
||||
" - ``{s1,s2,s3}`` matches any of the strings given (separated by commas)
|
||||
"
|
||||
" An initial period in FILENAME is not special.
|
||||
" Both FILENAME and PATTERN are first case-normalized
|
||||
" if the operating system requires it.
|
||||
" If you don't want this, use fnmatchcase(FILENAME, PATTERN).
|
||||
" """
|
||||
"
|
||||
" Note: This throws away the backslash in '\.txt' on Cygwin, but that
|
||||
" makes sense since it's Windows under the hood.
|
||||
" We don't care about shellslash since we're going to change backslashes
|
||||
" to slashes in just a moment anyway.
|
||||
let l:localname = fnamemodify(a:name, ':p')
|
||||
|
||||
if editorconfig_core#util#is_win() " normalize
|
||||
let l:localname = substitute(tolower(l:localname), '\v\\', '/', 'g')
|
||||
let l:path = substitute(tolower(a:path), '\v\\', '/', 'g')
|
||||
let l:pattern = tolower(a:pattern)
|
||||
else
|
||||
let l:localname = l:localname
|
||||
let l:path = a:path
|
||||
let l:pattern = a:pattern
|
||||
endif
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom '- fnmatch#fnmatch testing <' . l:localname . '> against <' .
|
||||
\ l:pattern . '> wrt <' . l:path . '>'
|
||||
endif
|
||||
|
||||
return editorconfig_core#fnmatch#fnmatchcase(l:localname, l:path, l:pattern)
|
||||
endfunction " fnmatch
|
||||
|
||||
function! editorconfig_core#fnmatch#fnmatchcase(name, path, pattern)
|
||||
"def fnmatchcase(name, pat):
|
||||
" """Test whether FILENAME matches PATH/PATTERN, including case.
|
||||
"
|
||||
" This is a version of fnmatch() which doesn't case-normalize
|
||||
" its arguments.
|
||||
" """
|
||||
"
|
||||
let [regex, num_groups] = s:cached_translate(a:pattern)
|
||||
|
||||
let l:escaped_path = s:re_escape(a:path)
|
||||
let l:regex = '\v' . l:escaped_path . l:regex
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom '- fnmatch#fnmatchcase: regex ' . l:regex
|
||||
call s:dump_chars(l:regex)
|
||||
echom '- fnmatch#fnmatchcase: checking ' . a:name
|
||||
call s:dump_chars(a:name)
|
||||
endif
|
||||
|
||||
let l:match_groups = matchlist(a:name, l:regex)[1:] " [0] = full match
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom printf(' Got %d matches', len(l:match_groups))
|
||||
endif
|
||||
|
||||
if len(l:match_groups) == 0
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Check numeric ranges
|
||||
let pattern_matched = 1
|
||||
for l:idx in range(0,len(l:match_groups))
|
||||
let l:num = l:match_groups[l:idx]
|
||||
if l:num ==# ''
|
||||
break
|
||||
endif
|
||||
|
||||
let [min_num, max_num] = num_groups[l:idx]
|
||||
if (min_num > (0+l:num)) || ((0+l:num) > max_num)
|
||||
let pattern_matched = 0
|
||||
break
|
||||
endif
|
||||
|
||||
" Reject leading zeros without sign. This is very odd ---
|
||||
" see editorconfig/editorconfig#371.
|
||||
if match(l:num, '\v^0') != -1
|
||||
let pattern_matched = 0
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom '- fnmatch#fnmatchcase: ' . (pattern_matched ? 'matched' : 'did not match')
|
||||
endif
|
||||
|
||||
return pattern_matched
|
||||
endfunction " fnmatchcase
|
||||
|
||||
" }}}1
|
||||
" === Copyright notices ================================================= {{{1
|
||||
" Based on code from fnmatch.py file distributed with Python 2.6.
|
||||
" Portions Copyright (c) 2001-2010 Python Software Foundation;
|
||||
" All Rights Reserved. Licensed under PSF License (see LICENSE.PSF file).
|
||||
"
|
||||
" Changes to original fnmatch:
|
||||
"
|
||||
" - translate function supports ``*`` and ``**`` similarly to fnmatch C library
|
||||
" }}}1
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vi: set fdm=marker:
|
||||
183
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim
vendored
Normal file
183
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/handler.vim
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
" autoload/editorconfig_core/handler.vim: Main worker for
|
||||
" editorconfig-core-vimscript and editorconfig-vim.
|
||||
" Modified from the Python core's handler.py.
|
||||
|
||||
" Copyright (c) 2012-2019 EditorConfig Team {{{1
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE. }}}1
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" Return full filepath for filename in each directory in and above path. {{{1
|
||||
" Input path must be an absolute path.
|
||||
" TODO shellslash/shellescape?
|
||||
function! s:get_filenames(path, config_filename)
|
||||
let l:path = a:path
|
||||
let l:path_list = []
|
||||
while 1
|
||||
call add(l:path_list, editorconfig_core#util#path_join(l:path, a:config_filename))
|
||||
let l:newpath = fnamemodify(l:path, ':h')
|
||||
if l:path ==? l:newpath || !strlen(l:path)
|
||||
break
|
||||
endif
|
||||
let l:path = l:newpath
|
||||
endwhile
|
||||
return l:path_list
|
||||
endfunction " get_filenames
|
||||
|
||||
" }}}1
|
||||
" === Main ============================================================== {{{1
|
||||
|
||||
" Find EditorConfig files and return all options matching target_filename.
|
||||
" Throws on failure.
|
||||
" @param job {Dictionary} required 'target'; optional 'config' and 'version'
|
||||
function! editorconfig_core#handler#get_configurations(job)
|
||||
" TODO? support VERSION checks?
|
||||
|
||||
" Special exceptions that may be raised by this function include:
|
||||
" - ``VersionError``: self.version is invalid EditorConfig version
|
||||
" - ``PathError``: self.filepath is not a valid absolute filepath
|
||||
" - ``ParsingError``: improperly formatted EditorConfig file found
|
||||
|
||||
let l:job = deepcopy(a:job)
|
||||
if has_key(l:job, 'config')
|
||||
let l:config_filename = l:job.config
|
||||
else
|
||||
let l:config_filename = '.editorconfig'
|
||||
let l:job.config = l:config_filename
|
||||
endif
|
||||
|
||||
if has_key(l:job, 'version')
|
||||
let l:version = l:job.version
|
||||
else
|
||||
let l:version = editorconfig_core#version()
|
||||
let l:job.version = l:version
|
||||
endif
|
||||
|
||||
let l:target_filename = l:job.target
|
||||
|
||||
"echom 'Beginning job ' . string(l:job)
|
||||
if !s:check_assertions(l:job)
|
||||
throw "Assertions failed"
|
||||
endif
|
||||
|
||||
let l:fullpath = fnamemodify(l:target_filename,':p')
|
||||
let l:path = fnamemodify(l:fullpath, ':h')
|
||||
let l:conf_files = s:get_filenames(l:path, l:config_filename)
|
||||
|
||||
" echom 'fullpath ' . l:fullpath
|
||||
" echom 'path ' . l:path
|
||||
|
||||
let l:retval = {}
|
||||
|
||||
" Attempt to find and parse every EditorConfig file in filetree
|
||||
for l:conf_fn in l:conf_files
|
||||
"echom 'Trying ' . l:conf_fn
|
||||
let l:parsed = editorconfig_core#ini#read_ini_file(l:conf_fn, l:target_filename)
|
||||
if !has_key(l:parsed, 'options')
|
||||
continue
|
||||
endif
|
||||
" echom ' Has options'
|
||||
|
||||
" Merge new EditorConfig file's options into current options
|
||||
let l:old_options = l:retval
|
||||
let l:retval = l:parsed.options
|
||||
" echom 'Old options ' . string(l:old_options)
|
||||
" echom 'New options ' . string(l:retval)
|
||||
call extend(l:retval, l:old_options, 'force')
|
||||
|
||||
" Stop parsing if parsed file has a ``root = true`` option
|
||||
if l:parsed.root
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
call s:preprocess_values(l:job, l:retval)
|
||||
return l:retval
|
||||
endfunction " get_configurations
|
||||
|
||||
function! s:check_assertions(job)
|
||||
" TODO
|
||||
" """Raise error if filepath or version have invalid values"""
|
||||
|
||||
" # Raise ``PathError`` if filepath isn't an absolute path
|
||||
" if not os.path.isabs(self.filepath):
|
||||
" raise PathError("Input file must be a full path name.")
|
||||
|
||||
" Throw if version specified is greater than current
|
||||
let l:v = a:job.version
|
||||
let l:us = editorconfig_core#version()
|
||||
" echom 'Comparing requested version ' . string(l:v) .
|
||||
" \ ' to our version ' . string(l:us)
|
||||
if l:v[0] > l:us[0] || l:v[1] > l:us[1] || l:v[2] > l:us[2]
|
||||
throw 'Required version ' . string(l:v) .
|
||||
\ ' is greater than the current version ' . string(l:us)
|
||||
endif
|
||||
|
||||
return 1 " All OK if we got here
|
||||
endfunction " check_assertions
|
||||
|
||||
" }}}1
|
||||
|
||||
" Preprocess option values for consumption by plugins. {{{1
|
||||
" Modifies its argument in place.
|
||||
function! s:preprocess_values(job, opts)
|
||||
|
||||
" Lowercase option value for certain options
|
||||
for l:name in ['end_of_line', 'indent_style', 'indent_size',
|
||||
\ 'insert_final_newline', 'trim_trailing_whitespace',
|
||||
\ 'charset']
|
||||
if has_key(a:opts, l:name)
|
||||
let a:opts[l:name] = tolower(a:opts[l:name])
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Set indent_size to "tab" if indent_size is unspecified and
|
||||
" indent_style is set to "tab", provided we are at least v0.10.0.
|
||||
if get(a:opts, 'indent_style', '') ==? "tab" &&
|
||||
\ !has_key(a:opts, 'indent_size') &&
|
||||
\ ( a:job.version[0]>0 || a:job.version[1] >=10 )
|
||||
let a:opts['indent_size'] = 'tab'
|
||||
endif
|
||||
|
||||
" Set tab_width to indent_size if indent_size is specified and
|
||||
" tab_width is unspecified
|
||||
if has_key(a:opts, 'indent_size') && !has_key(a:opts, 'tab_width') &&
|
||||
\ get(a:opts, 'indent_size', '') !=? "tab"
|
||||
let a:opts['tab_width'] = a:opts['indent_size']
|
||||
endif
|
||||
|
||||
" Set indent_size to tab_width if indent_size is "tab"
|
||||
if has_key(a:opts, 'indent_size') && has_key(a:opts, 'tab_width') &&
|
||||
\ get(a:opts, 'indent_size', '') ==? "tab"
|
||||
let a:opts['indent_size'] = a:opts['tab_width']
|
||||
endif
|
||||
endfunction " preprocess_values
|
||||
|
||||
" }}}1
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vi: set fdm=marker fdl=1:
|
||||
264
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim
vendored
Normal file
264
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/ini.vim
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
" autoload/editorconfig_core/ini.vim: Config-file parser for
|
||||
" editorconfig-core-vimscript and editorconfig-vim.
|
||||
" Modified from the Python core's ini.py.
|
||||
|
||||
" Copyright (c) 2012-2019 EditorConfig Team {{{2
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE. }}}2
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" variables {{{2
|
||||
if !exists('g:editorconfig_core_vimscript_debug')
|
||||
let g:editorconfig_core_vimscript_debug = 0
|
||||
endif
|
||||
" }}}2
|
||||
" === Constants, including regexes ====================================== {{{2
|
||||
" Regular expressions for parsing section headers and options.
|
||||
" Allow ``]`` and escaped ``;`` and ``#`` characters in section headers.
|
||||
" In fact, allow \ to escape any single character - it needs to cover at
|
||||
" least \ * ? [ ! ] { }.
|
||||
unlockvar s:SECTCRE s:OPTCRE s:MAX_SECTION_NAME s:MAX_PROPERTY_NAME s:MAX_PROPERTY_VALUE
|
||||
let s:SECTCRE = '\v^\s*\[(%([^\\#;]|\\.)+)\]'
|
||||
|
||||
" Regular expression for parsing option name/values.
|
||||
" Allow any amount of whitespaces, followed by separator
|
||||
" (either ``:`` or ``=``), followed by any amount of whitespace and then
|
||||
" any characters to eol
|
||||
let s:OPTCRE = '\v\s*([^:=[:space:]][^:=]*)\s*([:=])\s*(.*)$'
|
||||
|
||||
let s:MAX_SECTION_NAME = 4096
|
||||
let s:MAX_PROPERTY_NAME = 1024
|
||||
let s:MAX_PROPERTY_VALUE = 4096
|
||||
|
||||
lockvar s:SECTCRE s:OPTCRE s:MAX_SECTION_NAME s:MAX_PROPERTY_NAME s:MAX_PROPERTY_VALUE
|
||||
|
||||
" }}}2
|
||||
" === Main ============================================================== {{{1
|
||||
|
||||
" Read \p config_filename and return the options applicable to
|
||||
" \p target_filename. This is the main entry point in this file.
|
||||
function! editorconfig_core#ini#read_ini_file(config_filename, target_filename)
|
||||
if !filereadable(a:config_filename)
|
||||
return {}
|
||||
endif
|
||||
|
||||
try
|
||||
let l:lines = readfile(a:config_filename)
|
||||
if &encoding !=? 'utf-8'
|
||||
" strip BOM
|
||||
if len(l:lines) > 0 && l:lines[0][:2] ==# "\xEF\xBB\xBF"
|
||||
let l:lines[0] = l:lines[0][3:]
|
||||
endif
|
||||
" convert from UTF-8 to 'encoding'
|
||||
call map(l:lines, 'iconv(v:val, "utf-8", &encoding)')
|
||||
endif
|
||||
let result = s:parse(a:config_filename, a:target_filename, l:lines)
|
||||
catch
|
||||
" rethrow, but with a prefix since throw 'Vim...' fails.
|
||||
throw 'Could not read editorconfig file at ' . v:throwpoint . ': ' . string(v:exception)
|
||||
endtry
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:parse(config_filename, target_filename, lines)
|
||||
" Parse a sectioned setup file.
|
||||
" The sections in setup file contains a title line at the top,
|
||||
" indicated by a name in square brackets (`[]'), plus key/value
|
||||
" options lines, indicated by `name: value' format lines.
|
||||
" Continuations are represented by an embedded newline then
|
||||
" leading whitespace. Blank lines, lines beginning with a '#',
|
||||
" and just about everything else are ignored.
|
||||
|
||||
let l:in_section = 0
|
||||
let l:matching_section = 0
|
||||
let l:optname = ''
|
||||
let l:lineno = 0
|
||||
let l:e = [] " Errors, if any
|
||||
|
||||
let l:options = {} " Options applicable to this file
|
||||
let l:is_root = 0 " Whether a:config_filename declares root=true
|
||||
|
||||
while 1
|
||||
if l:lineno == len(a:lines)
|
||||
break
|
||||
endif
|
||||
|
||||
let l:line = a:lines[l:lineno]
|
||||
let l:lineno = l:lineno + 1
|
||||
|
||||
" comment or blank line?
|
||||
if editorconfig_core#util#strip(l:line) ==# ''
|
||||
continue
|
||||
endif
|
||||
if l:line =~# '\v^[#;]'
|
||||
continue
|
||||
endif
|
||||
|
||||
" is it a section header?
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom "Header? <" . l:line . ">"
|
||||
endif
|
||||
|
||||
let l:mo = matchlist(l:line, s:SECTCRE)
|
||||
if len(l:mo)
|
||||
let l:sectname = l:mo[1]
|
||||
let l:in_section = 1
|
||||
if strlen(l:sectname) > s:MAX_SECTION_NAME
|
||||
" Section name too long => ignore the section
|
||||
let l:matching_section = 0
|
||||
else
|
||||
let l:matching_section = s:matches_filename(
|
||||
\ a:config_filename, a:target_filename, l:sectname)
|
||||
endif
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom 'In section ' . l:sectname . ', which ' .
|
||||
\ (l:matching_section ? 'matches' : 'does not match')
|
||||
\ ' file ' . a:target_filename . ' (config ' .
|
||||
\ a:config_filename . ')'
|
||||
endif
|
||||
|
||||
" So sections can't start with a continuation line
|
||||
let l:optname = ''
|
||||
|
||||
" Is it an option line?
|
||||
else
|
||||
let l:mo = matchlist(l:line, s:OPTCRE)
|
||||
if len(l:mo)
|
||||
let l:optname = mo[1]
|
||||
let l:optval = mo[3]
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom printf('Saw raw opt <%s>=<%s>', l:optname, l:optval)
|
||||
endif
|
||||
|
||||
let l:optval = editorconfig_core#util#strip(l:optval)
|
||||
" allow empty values
|
||||
if l:optval ==? '""'
|
||||
let l:optval = ''
|
||||
endif
|
||||
let l:optname = s:optionxform(l:optname)
|
||||
if !l:in_section && optname ==? 'root'
|
||||
let l:is_root = (optval ==? 'true')
|
||||
endif
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom printf('Saw opt <%s>=<%s>', l:optname, l:optval)
|
||||
endif
|
||||
|
||||
if l:matching_section &&
|
||||
\ strlen(l:optname) <= s:MAX_PROPERTY_NAME &&
|
||||
\ strlen(l:optval) <= s:MAX_PROPERTY_VALUE
|
||||
let l:options[l:optname] = l:optval
|
||||
endif
|
||||
else
|
||||
" a non-fatal parsing error occurred. set up the
|
||||
" exception but keep going. the exception will be
|
||||
" raised at the end of the file and will contain a
|
||||
" list of all bogus lines
|
||||
call add(e, "Parse error in '" . a:config_filename . "' at line " .
|
||||
\ l:lineno . ": '" . l:line . "'")
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
|
||||
" if any parsing errors occurred, raise an exception
|
||||
if len(l:e)
|
||||
throw string(l:e)
|
||||
endif
|
||||
|
||||
return {'root': l:is_root, 'options': l:options}
|
||||
endfunction!
|
||||
|
||||
" }}}1
|
||||
" === Helpers =========================================================== {{{1
|
||||
|
||||
" Preprocess option names
|
||||
function! s:optionxform(optionstr)
|
||||
let l:result = substitute(a:optionstr, '\v\s+$', '', 'g') " rstrip
|
||||
return tolower(l:result)
|
||||
endfunction
|
||||
|
||||
" Return true if \p glob matches \p target_filename
|
||||
function! s:matches_filename(config_filename, target_filename, glob)
|
||||
" config_dirname = normpath(dirname(config_filename)).replace(sep, '/')
|
||||
let l:config_dirname = fnamemodify(a:config_filename, ':p:h') . '/'
|
||||
|
||||
if editorconfig_core#util#is_win()
|
||||
" Regardless of whether shellslash is set, make everything slashes
|
||||
let l:config_dirname =
|
||||
\ tolower(substitute(l:config_dirname, '\v\\', '/', 'g'))
|
||||
endif
|
||||
|
||||
let l:glob = substitute(a:glob, '\v\\([#;])', '\1', 'g')
|
||||
|
||||
" Take account of the path to the editorconfig file.
|
||||
" editorconfig-core-c/src/lib/editorconfig.c says:
|
||||
" "Pattern would be: /dir/of/editorconfig/file[double_star]/[section] if
|
||||
" section does not contain '/', or /dir/of/editorconfig/file[section]
|
||||
" if section starts with a '/', or /dir/of/editorconfig/file/[section] if
|
||||
" section contains '/' but does not start with '/'."
|
||||
|
||||
if stridx(l:glob, '/') != -1 " contains a slash
|
||||
if l:glob[0] ==# '/'
|
||||
let l:glob = l:glob[1:] " trim leading slash
|
||||
endif
|
||||
" This will be done by fnmatch
|
||||
" let l:glob = l:config_dirname . l:glob
|
||||
else " does not contain a slash
|
||||
let l:config_dirname = l:config_dirname[:-2]
|
||||
" Trim trailing slash
|
||||
let l:glob = '**/' . l:glob
|
||||
endif
|
||||
|
||||
if g:editorconfig_core_vimscript_debug
|
||||
echom '- ini#matches_filename: checking <' . a:target_filename .
|
||||
\ '> against <' . l:glob . '> with respect to config file <' .
|
||||
\ a:config_filename . '>'
|
||||
echom '- ini#matches_filename: config_dirname is ' . l:config_dirname
|
||||
endif
|
||||
|
||||
return editorconfig_core#fnmatch#fnmatch(a:target_filename,
|
||||
\ l:config_dirname, l:glob)
|
||||
endfunction " matches_filename
|
||||
|
||||
" }}}1
|
||||
" === Copyright notices ================================================= {{{2
|
||||
" Based on code from ConfigParser.py file distributed with Python 2.6.
|
||||
" Portions Copyright (c) 2001-2010 Python Software Foundation;
|
||||
" All Rights Reserved. Licensed under PSF License (see LICENSE.PSF file).
|
||||
"
|
||||
" Changes to original ConfigParser:
|
||||
"
|
||||
" - Special characters can be used in section names
|
||||
" - Octothorpe can be used for comments (not just at beginning of line)
|
||||
" - Only track INI options in sections that match target filename
|
||||
" - Stop parsing files with when ``root = true`` is found
|
||||
" }}}2
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vi: set fdm=marker fdl=1:
|
||||
84
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/util.vim
vendored
Normal file
84
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/autoload/editorconfig_core/util.vim
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
" util.vim: part of editorconfig-core-vimscript and editorconfig-vim.
|
||||
" Copyright (c) 2018-2019 EditorConfig Team, including Chris White {{{1
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE. }}}1
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" A verbatim copy of ingo#fs#path#Separator() {{{1
|
||||
" from https://github.com/vim-scripts/ingo-library/blob/558132e2221db3af26dc2f2c6756d092d48a459f/autoload/ingo/fs/path.vim
|
||||
" distributed under the Vim license.
|
||||
function! editorconfig_core#util#Separator()
|
||||
return (exists('+shellslash') && ! &shellslash ? '\' : '/')
|
||||
endfunction " }}}1
|
||||
|
||||
" path_join(): ('a','b')->'a/b'; ('a/','b')->'a/b'. {{{1
|
||||
function! editorconfig_core#util#path_join(a, b)
|
||||
" TODO shellescape/shellslash?
|
||||
"echom 'Joining <' . a:a . '> and <' . a:b . '>'
|
||||
"echom 'Length is ' . strlen(a:a)
|
||||
"echom 'Last char is ' . char2nr(a:a[-1])
|
||||
if a:a !~# '\v%(\/|\\)$'
|
||||
return a:a . editorconfig_core#util#Separator() . a:b
|
||||
else
|
||||
return a:a . a:b
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
" is_win() by xolox {{{1
|
||||
" The following function is modified from
|
||||
" https://github.com/xolox/vim-misc/blob/master/autoload/xolox/misc/os.vim
|
||||
" Copyright (c) 2015 Peter Odding <peter@peterodding.com>
|
||||
"
|
||||
" Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
" of this software and associated documentation files (the "Software"), to deal
|
||||
" in the Software without restriction, including without limitation the rights
|
||||
" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
" copies of the Software, and to permit persons to whom the Software is
|
||||
" furnished to do so, subject to the following conditions:
|
||||
"
|
||||
" The above copyright notice and this permission notice shall be included in all
|
||||
" copies or substantial portions of the Software.
|
||||
"
|
||||
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
" SOFTWARE.
|
||||
function! editorconfig_core#util#is_win()
|
||||
" Returns 1 (true) when on Microsoft Windows, 0 (false) otherwise.
|
||||
return has('win16') || has('win32') || has('win64')
|
||||
endfunction " }}}1
|
||||
|
||||
" strip() {{{1
|
||||
function! editorconfig_core#util#strip(s)
|
||||
return substitute(a:s, '\v^\s+|\s+$','','g')
|
||||
endfunction " }}}1
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vi: set fdm=marker:
|
||||
238
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/doc/editorconfig.txt
vendored
Normal file
238
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/doc/editorconfig.txt
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
*editorconfig.txt* EditorConfig plugin for vim.
|
||||
|
||||
File: editorconfig.txt
|
||||
Version: 1.1.1
|
||||
Maintainer: EditorConfig Team <http://editorconfig.org>
|
||||
Description: EditorConfig vim plugin
|
||||
|
||||
CONTENTS~
|
||||
*editorconfig-contents*
|
||||
----------------------------------------------------------------------------
|
||||
1. Overview |editorconfig-overview|
|
||||
2. Installation |editorconfig-installation|
|
||||
3. Commands |editorconfig-commands|
|
||||
4. Settings |editorconfig-settings|
|
||||
5. Advanced |editorconfig-advanced|
|
||||
6. License |editorconfig-license|
|
||||
|
||||
|
||||
OVERVIEW~
|
||||
*editorconfig-overview*
|
||||
----------------------------------------------------------------------------
|
||||
This is the EditorConfig plugin for vim.
|
||||
|
||||
|
||||
INSTALLATION~
|
||||
*editorconfig-installation*
|
||||
----------------------------------------------------------------------------
|
||||
Follow the instructions in the README.md file to install this plugin.
|
||||
|
||||
COMMANDS~
|
||||
*editorconfig-commands*
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
*:EditorConfigReload*
|
||||
Command:
|
||||
:EditorConfigReload
|
||||
|
||||
Reload the EditorConfig conf files. When `.editorconfig` files are modified,
|
||||
this command could prevent you to reload the current edited file to load the
|
||||
new configuration.
|
||||
|
||||
SETTINGS~
|
||||
*editorconfig-settings*
|
||||
----------------------------------------------------------------------------
|
||||
*g:EditorConfig_core_mode*
|
||||
Specify the mode of EditorConfig core. Generally it is OK to leave this option
|
||||
empty. Currently, the supported modes are "vim_core" (default) and
|
||||
"external_command".
|
||||
|
||||
vim_core: Use the included Vim script EditorConfig Core.
|
||||
external_command: Run external EditorConfig Core.
|
||||
|
||||
If "g:EditorConfig_core_mode" is not specified, this plugin will automatically
|
||||
choose "vim_core".
|
||||
|
||||
If you choose "external_command" mode, you must also set
|
||||
|g:EditorConfig_exec_path|.
|
||||
|
||||
Changes to "g:EditorConfig_core_mode" will not take effect until Vim
|
||||
is restarted.
|
||||
|
||||
*b:EditorConfig_disable*
|
||||
This is a buffer-local variable that disables the EditorConfig plugin for a
|
||||
single buffer.
|
||||
|
||||
Example: Disable EditorConfig for the current buffer:
|
||||
>
|
||||
let b:EditorConfig_disable = 1
|
||||
<
|
||||
Example: Disable EditorConfig for all git commit messages:
|
||||
>
|
||||
au FileType gitcommit let b:EditorConfig_disable = 1
|
||||
<
|
||||
|
||||
*g:EditorConfig_exclude_patterns*
|
||||
This is a list contains file path patterns which will be ignored by
|
||||
EditorConfig plugin. When the path of the opened buffer (i.e.
|
||||
"expand('%:p')") matches any of the patterns in the list, EditorConfig will
|
||||
not load for this file. The default is an empty list.
|
||||
|
||||
Example: Avoid loading EditorConfig for any remote files over ssh
|
||||
>
|
||||
let g:EditorConfig_exclude_patterns = ['scp://.*']
|
||||
<
|
||||
|
||||
*g:EditorConfig_exec_path*
|
||||
The file path to the EditorConfig core executable. You can set this value in
|
||||
your |vimrc| like this:
|
||||
>
|
||||
let g:EditorConfig_exec_path = 'Path to your EditorConfig Core executable'
|
||||
<
|
||||
The default value is empty.
|
||||
|
||||
If "g:EditorConfig_exec_path" is not set, the plugin will use the "vim_core"
|
||||
mode regardless of the setting of |g:EditorConfig_core_mode|.
|
||||
|
||||
Changes to "g:EditorConfig_exec_path" will not take effect until Vim
|
||||
is restarted.
|
||||
|
||||
*g:EditorConfig_max_line_indicator*
|
||||
The way to show the line where the maximal length is reached. Accepted values
|
||||
are "line", "fill", "exceeding" and "fillexceeding", otherwise there will be
|
||||
no max line indicator.
|
||||
|
||||
"line": the right column of the max line length column will be
|
||||
highlighted on all lines, by adding +1 to 'colorcolumn'.
|
||||
|
||||
"fill": all the columns to the right of the max line length
|
||||
column will be highlighted on all lines, by setting
|
||||
'colorcolumn' to a list starting from "max_line_length +
|
||||
1" to the number of columns on the screen.
|
||||
|
||||
"exceeding": the right column of the max line length column will be
|
||||
highlighted on lines that exceed the max line length, by
|
||||
adding a match for the ColorColumn group.
|
||||
|
||||
"fillexceeding": all the columns to the right of the max line length
|
||||
column will be highlighted on lines that exceed the max
|
||||
line length, by adding a match for the ColorColumn group.
|
||||
|
||||
"none": no max line length indicator will be shown. Recommended
|
||||
when you do not want any indicator to be shown, but any
|
||||
value other than those listed above also work as "none".
|
||||
|
||||
To set this option, add any of the following lines to your |vimrc| file:
|
||||
>
|
||||
let g:EditorConfig_max_line_indicator = "line"
|
||||
let g:EditorConfig_max_line_indicator = "fill"
|
||||
let g:EditorConfig_max_line_indicator = "exceeding"
|
||||
let g:EditorConfig_max_line_indicator = "fillexceeding"
|
||||
let g:EditorConfig_max_line_indicator = "none"
|
||||
<
|
||||
The default value is "line".
|
||||
|
||||
*g:EditorConfig_enable_for_new_buf*
|
||||
Set this to 1 if you want EditorConfig plugin to set options
|
||||
for new empty buffers too.
|
||||
Path to .editorconfig will be determined based on CWD (see |getcwd()|)
|
||||
>
|
||||
let g:EditorConfig_enable_for_new_buf = 1
|
||||
<
|
||||
This option defaults to 0.
|
||||
|
||||
*g:EditorConfig_preserve_formatoptions*
|
||||
Set this to 1 if you don't want your formatoptions modified when
|
||||
max_line_length is set:
|
||||
>
|
||||
let g:EditorConfig_preserve_formatoptions = 1
|
||||
<
|
||||
This option defaults to 0.
|
||||
|
||||
*g:EditorConfig_softtabstop_space*
|
||||
When spaces are used for indent, Vim's 'softtabstop' feature will make the
|
||||
backspace key delete one indent level. If you turn off that feature (by
|
||||
setting the option to 0), only a single space will be deleted.
|
||||
This option defaults to 1, which enables 'softtabstop' and uses the
|
||||
'shiftwidth' value for it. You can also set this to -1 to automatically follow
|
||||
the current 'shiftwidth' value (since Vim 7.3.693). Or set this to [] if
|
||||
EditorConfig should not touch 'softtabstop' at all.
|
||||
|
||||
*g:EditorConfig_softtabstop_tab*
|
||||
When tabs are used for indent, Vim's 'softtabstop' feature only applies to
|
||||
backspacing over existing runs of spaces.
|
||||
This option defaults to 1, so backspace will delete one indent level worth of
|
||||
spaces; -1 does the same but automatically follows the current 'shiftwidth'
|
||||
value. Set this to 0 to have backspace delete just a single space character.
|
||||
Or set this to [] if EditorConfig should not touch 'softtabstop' at all.
|
||||
|
||||
*g:EditorConfig_verbose*
|
||||
Set this to 1 if you want debug info printed:
|
||||
>
|
||||
let g:EditorConfig_verbose = 1
|
||||
<
|
||||
|
||||
ADVANCED~
|
||||
*editorconfig-advanced*
|
||||
----------------------------------------------------------------------------
|
||||
*editorconfig-hook*
|
||||
*EditorConfig#AddNewHook()*
|
||||
While this plugin offers several builtin supported properties (as mentioned
|
||||
here: https://github.com/editorconfig/editorconfig-vim#supported-properties),
|
||||
we are also able to add our own hooks to support additional EditorConfig
|
||||
properties, including those not in the EditorConfig standard. For example, we
|
||||
are working on an Objective-C project, and all our "*.m" files should be
|
||||
Objective-C source files. However, vim sometimes detect "*.m" files as MATLAB
|
||||
source files, which causes incorrect syntax highlighting, code indentation,
|
||||
etc. To solve the case, we could write the following code into the |vimrc|
|
||||
file:
|
||||
>
|
||||
function! FiletypeHook(config)
|
||||
if has_key(a:config, 'vim_filetype')
|
||||
let &filetype = a:config['vim_filetype']
|
||||
endif
|
||||
|
||||
return 0 " Return 0 to show no error happened
|
||||
endfunction
|
||||
|
||||
call editorconfig#AddNewHook(function('FiletypeHook'))
|
||||
<
|
||||
And add the following code to your .editorconfig file:
|
||||
>
|
||||
[*.m]
|
||||
vim_filetype = objc
|
||||
<
|
||||
Then try to open an Objective-C file, you will find the |filetype| is set to
|
||||
"objc".
|
||||
|
||||
License~
|
||||
*editorconfig-license*
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
License:
|
||||
Copyright (c) 2011-2019 EditorConfig Team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
vim:ft=help:tw=78:cc=
|
||||
21
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/doc/tags
vendored
Normal file
21
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/doc/tags
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
:EditorConfigReload editorconfig.txt /*:EditorConfigReload*
|
||||
EditorConfig#AddNewHook() editorconfig.txt /*EditorConfig#AddNewHook()*
|
||||
b:EditorConfig_disable editorconfig.txt /*b:EditorConfig_disable*
|
||||
editorconfig-advanced editorconfig.txt /*editorconfig-advanced*
|
||||
editorconfig-commands editorconfig.txt /*editorconfig-commands*
|
||||
editorconfig-contents editorconfig.txt /*editorconfig-contents*
|
||||
editorconfig-hook editorconfig.txt /*editorconfig-hook*
|
||||
editorconfig-installation editorconfig.txt /*editorconfig-installation*
|
||||
editorconfig-license editorconfig.txt /*editorconfig-license*
|
||||
editorconfig-overview editorconfig.txt /*editorconfig-overview*
|
||||
editorconfig-settings editorconfig.txt /*editorconfig-settings*
|
||||
editorconfig.txt editorconfig.txt /*editorconfig.txt*
|
||||
g:EditorConfig_core_mode editorconfig.txt /*g:EditorConfig_core_mode*
|
||||
g:EditorConfig_enable_for_new_buf editorconfig.txt /*g:EditorConfig_enable_for_new_buf*
|
||||
g:EditorConfig_exclude_patterns editorconfig.txt /*g:EditorConfig_exclude_patterns*
|
||||
g:EditorConfig_exec_path editorconfig.txt /*g:EditorConfig_exec_path*
|
||||
g:EditorConfig_max_line_indicator editorconfig.txt /*g:EditorConfig_max_line_indicator*
|
||||
g:EditorConfig_preserve_formatoptions editorconfig.txt /*g:EditorConfig_preserve_formatoptions*
|
||||
g:EditorConfig_softtabstop_space editorconfig.txt /*g:EditorConfig_softtabstop_space*
|
||||
g:EditorConfig_softtabstop_tab editorconfig.txt /*g:EditorConfig_softtabstop_tab*
|
||||
g:EditorConfig_verbose editorconfig.txt /*g:EditorConfig_verbose*
|
||||
1
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/ftdetect/editorconfig.vim
vendored
Normal file
1
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/ftdetect/editorconfig.vim
vendored
Normal file
@@ -0,0 +1 @@
|
||||
autocmd BufNewFile,BufRead .editorconfig setfiletype dosini
|
||||
3
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/mkzip.sh
vendored
Normal file
3
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/mkzip.sh
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
zip -r editorconfig-vim-$*.zip autoload/* doc/* ftdetect/* plugin/*
|
||||
614
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/plugin/editorconfig.vim
vendored
Normal file
614
gitportable/usr/share/vim/vim91/pack/dist/opt/editorconfig/plugin/editorconfig.vim
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
" plugin/editorconfig.vim: EditorConfig native Vim script plugin file
|
||||
" Copyright (c) 2011-2019 EditorConfig Team
|
||||
" All rights reserved.
|
||||
"
|
||||
" Redistribution and use in source and binary forms, with or without
|
||||
" modification, are permitted provided that the following conditions are met:
|
||||
"
|
||||
" 1. Redistributions of source code must retain the above copyright notice,
|
||||
" this list of conditions and the following disclaimer.
|
||||
" 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
" this list of conditions and the following disclaimer in the documentation
|
||||
" and/or other materials provided with the distribution.
|
||||
"
|
||||
" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
" POSSIBILITY OF SUCH DAMAGE.
|
||||
"
|
||||
|
||||
" check for Vim versions and duplicate script loading.
|
||||
if v:version < 700 || exists("g:loaded_EditorConfig")
|
||||
finish
|
||||
endif
|
||||
let g:loaded_EditorConfig = 1
|
||||
|
||||
let s:saved_cpo = &cpo
|
||||
set cpo&vim
|
||||
|
||||
" variables {{{1
|
||||
|
||||
" Make sure the globals all exist
|
||||
if !exists('g:EditorConfig_exec_path')
|
||||
let g:EditorConfig_exec_path = ''
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_verbose')
|
||||
let g:EditorConfig_verbose = 0
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_preserve_formatoptions')
|
||||
let g:EditorConfig_preserve_formatoptions = 0
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_max_line_indicator')
|
||||
let g:EditorConfig_max_line_indicator = 'line'
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_exclude_patterns')
|
||||
let g:EditorConfig_exclude_patterns = []
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_disable_rules')
|
||||
let g:EditorConfig_disable_rules = []
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_enable_for_new_buf')
|
||||
let g:EditorConfig_enable_for_new_buf = 0
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_softtabstop_space')
|
||||
let g:EditorConfig_softtabstop_space = 1
|
||||
endif
|
||||
|
||||
if !exists('g:EditorConfig_softtabstop_tab')
|
||||
let g:EditorConfig_softtabstop_tab = 1
|
||||
endif
|
||||
|
||||
" Copy some of the globals into script variables --- changes to these
|
||||
" globals won't affect the plugin until the plugin is reloaded.
|
||||
if exists('g:EditorConfig_core_mode') && !empty(g:EditorConfig_core_mode)
|
||||
let s:editorconfig_core_mode = g:EditorConfig_core_mode
|
||||
else
|
||||
let s:editorconfig_core_mode = ''
|
||||
endif
|
||||
|
||||
if exists('g:EditorConfig_exec_path') && !empty(g:EditorConfig_exec_path)
|
||||
let s:editorconfig_exec_path = g:EditorConfig_exec_path
|
||||
else
|
||||
let s:editorconfig_exec_path = ''
|
||||
endif
|
||||
|
||||
let s:initialized = 0
|
||||
|
||||
" }}}1
|
||||
|
||||
" shellslash handling {{{1
|
||||
function! s:DisableShellSlash(bufnr) " {{{2
|
||||
" disable shellslash for proper escaping of Windows paths
|
||||
|
||||
" In Windows, 'shellslash' also changes the behavior of 'shellescape'.
|
||||
" It makes 'shellescape' behave like in UNIX environment. So ':setl
|
||||
" noshellslash' before evaluating 'shellescape' and restore the
|
||||
" settings afterwards when 'shell' does not contain 'sh' somewhere.
|
||||
let l:shell = getbufvar(a:bufnr, '&shell')
|
||||
if has('win32') && empty(matchstr(l:shell, 'sh'))
|
||||
let s:old_shellslash = getbufvar(a:bufnr, '&shellslash')
|
||||
setbufvar(a:bufnr, '&shellslash', 0)
|
||||
endif
|
||||
endfunction " }}}2
|
||||
|
||||
function! s:ResetShellSlash(bufnr) " {{{2
|
||||
" reset shellslash to the user-set value, if any
|
||||
if exists('s:old_shellslash')
|
||||
setbufvar(a:bufnr, '&shellslash', s:old_shellslash)
|
||||
unlet! s:old_shellslash
|
||||
endif
|
||||
endfunction " }}}2
|
||||
" }}}1
|
||||
|
||||
" Mode initialization functions {{{1
|
||||
|
||||
function! s:InitializeVimCore()
|
||||
" Initialize vim core. Returns 1 on failure; 0 on success
|
||||
" At the moment, all we need to do is to check that it is installed.
|
||||
try
|
||||
let l:vim_core_ver = editorconfig_core#version()
|
||||
catch
|
||||
return 1
|
||||
endtry
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:InitializeExternalCommand()
|
||||
" Initialize external_command mode
|
||||
|
||||
if empty(s:editorconfig_exec_path)
|
||||
echo 'Please specify a g:EditorConfig_exec_path'
|
||||
return 1
|
||||
endif
|
||||
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Checking for external command ' . s:editorconfig_exec_path . ' ...'
|
||||
endif
|
||||
|
||||
if !executable(s:editorconfig_exec_path)
|
||||
echo 'File ' . s:editorconfig_exec_path . ' is not executable.'
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
" }}}1
|
||||
|
||||
function! s:Initialize() " Initialize the plugin. {{{1
|
||||
" Returns truthy on error, falsy on success.
|
||||
|
||||
if empty(s:editorconfig_core_mode)
|
||||
let s:editorconfig_core_mode = 'vim_core' " Default core choice
|
||||
endif
|
||||
|
||||
if s:editorconfig_core_mode ==? 'external_command'
|
||||
if s:InitializeExternalCommand()
|
||||
echohl WarningMsg
|
||||
echo 'EditorConfig: Failed to initialize external_command mode. ' .
|
||||
\ 'Falling back to vim_core mode.'
|
||||
echohl None
|
||||
let s:editorconfig_core_mode = 'vim_core'
|
||||
endif
|
||||
endif
|
||||
|
||||
if s:editorconfig_core_mode ==? 'vim_core'
|
||||
if s:InitializeVimCore()
|
||||
echohl ErrorMsg
|
||||
echo 'EditorConfig: Failed to initialize vim_core mode. ' .
|
||||
\ 'The plugin will not function.'
|
||||
echohl None
|
||||
return 1
|
||||
endif
|
||||
|
||||
elseif s:editorconfig_core_mode ==? 'external_command'
|
||||
" Nothing to do here, but this elseif is required to avoid
|
||||
" external_command falling into the else clause.
|
||||
|
||||
else " neither external_command nor vim_core
|
||||
echohl ErrorMsg
|
||||
echo "EditorConfig: I don't know how to use mode " . s:editorconfig_core_mode
|
||||
echohl None
|
||||
return 1
|
||||
endif
|
||||
|
||||
let s:initialized = 1
|
||||
return 0
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:GetFilenames(path, filename) " {{{1
|
||||
" Yield full filepath for filename in each directory in and above path
|
||||
|
||||
let l:path_list = []
|
||||
let l:path = a:path
|
||||
while 1
|
||||
let l:path_list += [l:path . '/' . a:filename]
|
||||
let l:newpath = fnamemodify(l:path, ':h')
|
||||
if l:path == l:newpath
|
||||
break
|
||||
endif
|
||||
let l:path = l:newpath
|
||||
endwhile
|
||||
return l:path_list
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:UseConfigFiles(from_autocmd) abort " Apply config to the current buffer {{{1
|
||||
" from_autocmd is truthy if called from an autocmd, falsy otherwise.
|
||||
|
||||
" Get the properties of the buffer we are working on
|
||||
if a:from_autocmd
|
||||
let l:bufnr = str2nr(expand('<abuf>'))
|
||||
let l:buffer_name = expand('<afile>:p')
|
||||
let l:buffer_path = expand('<afile>:p:h')
|
||||
else
|
||||
let l:bufnr = bufnr('%')
|
||||
let l:buffer_name = expand('%:p')
|
||||
let l:buffer_path = expand('%:p:h')
|
||||
endif
|
||||
call setbufvar(l:bufnr, 'editorconfig_tried', 1)
|
||||
|
||||
" Only process normal buffers (do not treat help files as '.txt' files)
|
||||
" When starting Vim with a directory, the buftype might not yet be set:
|
||||
" Therefore, also check if buffer_name is a directory.
|
||||
if index(['', 'acwrite'], &buftype) == -1 || isdirectory(l:buffer_name)
|
||||
return
|
||||
endif
|
||||
|
||||
if empty(l:buffer_name)
|
||||
if g:EditorConfig_enable_for_new_buf
|
||||
let l:buffer_name = getcwd() . "/."
|
||||
else
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Skipping EditorConfig for unnamed buffer'
|
||||
endif
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
if getbufvar(l:bufnr, 'EditorConfig_disable', 0)
|
||||
if g:EditorConfig_verbose
|
||||
echo 'EditorConfig disabled --- skipping buffer "' . l:buffer_name . '"'
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
" Ignore specific patterns
|
||||
for pattern in g:EditorConfig_exclude_patterns
|
||||
if l:buffer_name =~ pattern
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Skipping EditorConfig for buffer "' . l:buffer_name .
|
||||
\ '" based on pattern "' . pattern . '"'
|
||||
endif
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Check if any .editorconfig does exist
|
||||
let l:conf_files = s:GetFilenames(l:buffer_path, '.editorconfig')
|
||||
let l:conf_found = 0
|
||||
for conf_file in conf_files
|
||||
if filereadable(conf_file)
|
||||
let l:conf_found = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if !l:conf_found
|
||||
return
|
||||
endif
|
||||
|
||||
if !s:initialized
|
||||
if s:Initialize()
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Applying EditorConfig ' . s:editorconfig_core_mode .
|
||||
\ ' on file "' . l:buffer_name . '"'
|
||||
endif
|
||||
|
||||
if s:editorconfig_core_mode ==? 'vim_core'
|
||||
if s:UseConfigFiles_VimCore(l:bufnr, l:buffer_name) == 0
|
||||
call setbufvar(l:bufnr, 'editorconfig_applied', 1)
|
||||
endif
|
||||
elseif s:editorconfig_core_mode ==? 'external_command'
|
||||
call s:UseConfigFiles_ExternalCommand(l:bufnr, l:buffer_name)
|
||||
call setbufvar(l:bufnr, 'editorconfig_applied', 1)
|
||||
else
|
||||
echohl Error |
|
||||
\ echo "Unknown EditorConfig Core: " .
|
||||
\ s:editorconfig_core_mode |
|
||||
\ echohl None
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
" Custom commands, and autoloading {{{1
|
||||
|
||||
" Autocommands, and function to enable/disable the plugin {{{2
|
||||
function! s:EditorConfigEnable(should_enable)
|
||||
augroup editorconfig
|
||||
autocmd!
|
||||
if a:should_enable
|
||||
autocmd BufNewFile,BufReadPost,BufFilePost * call s:UseConfigFiles(1)
|
||||
autocmd VimEnter,BufNew * call s:UseConfigFiles(1)
|
||||
endif
|
||||
augroup END
|
||||
endfunction
|
||||
|
||||
" }}}2
|
||||
|
||||
" Commands {{{2
|
||||
command! EditorConfigEnable call s:EditorConfigEnable(1)
|
||||
command! EditorConfigDisable call s:EditorConfigEnable(0)
|
||||
|
||||
command! EditorConfigReload call s:UseConfigFiles(0) " Reload EditorConfig files
|
||||
" }}}2
|
||||
|
||||
" On startup, enable the autocommands
|
||||
call s:EditorConfigEnable(1)
|
||||
|
||||
" }}}1
|
||||
|
||||
" UseConfigFiles function for different modes {{{1
|
||||
|
||||
function! s:UseConfigFiles_VimCore(bufnr, target)
|
||||
" Use the vimscript EditorConfig core
|
||||
try
|
||||
let l:config = editorconfig_core#handler#get_configurations(
|
||||
\ { 'target': a:target } )
|
||||
call s:ApplyConfig(a:bufnr, l:config)
|
||||
return 0 " success
|
||||
catch
|
||||
return 1 " failure
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:UseConfigFiles_ExternalCommand(bufnr, target)
|
||||
" Use external EditorConfig core (e.g., the C core)
|
||||
|
||||
call s:DisableShellSlash(a:bufnr)
|
||||
let l:exec_path = shellescape(s:editorconfig_exec_path)
|
||||
call s:ResetShellSlash(a:bufnr)
|
||||
|
||||
call s:SpawnExternalParser(a:bufnr, l:exec_path, a:target)
|
||||
endfunction
|
||||
|
||||
function! s:SpawnExternalParser(bufnr, cmd, target) " {{{2
|
||||
" Spawn external EditorConfig. Used by s:UseConfigFiles_ExternalCommand()
|
||||
|
||||
let l:cmd = a:cmd
|
||||
|
||||
if empty(l:cmd)
|
||||
throw 'No cmd provided'
|
||||
endif
|
||||
|
||||
let l:config = {}
|
||||
|
||||
call s:DisableShellSlash(a:bufnr)
|
||||
let l:cmd = l:cmd . ' ' . shellescape(a:target)
|
||||
call s:ResetShellSlash(a:bufnr)
|
||||
|
||||
let l:parsing_result = split(system(l:cmd), '\v[\r\n]+')
|
||||
|
||||
" if editorconfig core's exit code is not zero, give out an error
|
||||
" message
|
||||
if v:shell_error != 0
|
||||
echohl ErrorMsg
|
||||
echo 'Failed to execute "' . l:cmd . '". Exit code: ' .
|
||||
\ v:shell_error
|
||||
echo ''
|
||||
echo 'Message:'
|
||||
echo l:parsing_result
|
||||
echohl None
|
||||
return
|
||||
endif
|
||||
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Output from EditorConfig core executable:'
|
||||
echo l:parsing_result
|
||||
endif
|
||||
|
||||
for one_line in l:parsing_result
|
||||
let l:eq_pos = stridx(one_line, '=')
|
||||
|
||||
if l:eq_pos == -1 " = is not found. Skip this line
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:eq_left = strpart(one_line, 0, l:eq_pos)
|
||||
if l:eq_pos + 1 < strlen(one_line)
|
||||
let l:eq_right = strpart(one_line, l:eq_pos + 1)
|
||||
else
|
||||
let l:eq_right = ''
|
||||
endif
|
||||
|
||||
let l:config[l:eq_left] = l:eq_right
|
||||
endfor
|
||||
|
||||
call s:ApplyConfig(a:bufnr, l:config)
|
||||
endfunction " }}}2
|
||||
|
||||
" }}}1
|
||||
|
||||
" Set the buffer options {{{1
|
||||
function! s:SetCharset(bufnr, charset) abort " apply config['charset']
|
||||
|
||||
" Remember the buffer's state so we can set `nomodifed` at the end
|
||||
" if appropriate.
|
||||
let l:orig_fenc = getbufvar(a:bufnr, "&fileencoding")
|
||||
let l:orig_enc = getbufvar(a:bufnr, "&encoding")
|
||||
let l:orig_modified = getbufvar(a:bufnr, "&modified")
|
||||
|
||||
if a:charset == "utf-8"
|
||||
call setbufvar(a:bufnr, '&fileencoding', 'utf-8')
|
||||
call setbufvar(a:bufnr, '&bomb', 0)
|
||||
elseif a:charset == "utf-8-bom"
|
||||
call setbufvar(a:bufnr, '&fileencoding', 'utf-8')
|
||||
call setbufvar(a:bufnr, '&bomb', 1)
|
||||
elseif a:charset == "latin1"
|
||||
call setbufvar(a:bufnr, '&fileencoding', 'latin1')
|
||||
call setbufvar(a:bufnr, '&bomb', 0)
|
||||
elseif a:charset == "utf-16be"
|
||||
call setbufvar(a:bufnr, '&fileencoding', 'utf-16be')
|
||||
call setbufvar(a:bufnr, '&bomb', 1)
|
||||
elseif a:charset == "utf-16le"
|
||||
call setbufvar(a:bufnr, '&fileencoding', 'utf-16le')
|
||||
call setbufvar(a:bufnr, '&bomb', 1)
|
||||
endif
|
||||
|
||||
let l:new_fenc = getbufvar(a:bufnr, "&fileencoding")
|
||||
|
||||
" If all we did was change the fileencoding from the default to a copy
|
||||
" of the default, we didn't actually modify the file.
|
||||
if !l:orig_modified && (l:orig_fenc ==# '') && (l:new_fenc ==# l:orig_enc)
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Setting nomodified on buffer ' . a:bufnr
|
||||
endif
|
||||
call setbufvar(a:bufnr, '&modified', 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ApplyConfig(bufnr, config) abort
|
||||
if g:EditorConfig_verbose
|
||||
echo 'Options: ' . string(a:config)
|
||||
endif
|
||||
|
||||
if s:IsRuleActive('indent_style', a:config)
|
||||
if a:config["indent_style"] == "tab"
|
||||
call setbufvar(a:bufnr, '&expandtab', 0)
|
||||
elseif a:config["indent_style"] == "space"
|
||||
call setbufvar(a:bufnr, '&expandtab', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
if s:IsRuleActive('tab_width', a:config)
|
||||
let l:tabstop = str2nr(a:config["tab_width"])
|
||||
call setbufvar(a:bufnr, '&tabstop', l:tabstop)
|
||||
else
|
||||
" Grab the current ts so we can use it below
|
||||
let l:tabstop = getbufvar(a:bufnr, '&tabstop')
|
||||
endif
|
||||
|
||||
if s:IsRuleActive('indent_size', a:config)
|
||||
" if indent_size is 'tab', set shiftwidth to tabstop;
|
||||
" if indent_size is a positive integer, set shiftwidth to the integer
|
||||
" value
|
||||
if a:config["indent_size"] == "tab"
|
||||
call setbufvar(a:bufnr, '&shiftwidth', l:tabstop)
|
||||
if type(g:EditorConfig_softtabstop_tab) != type([])
|
||||
call setbufvar(a:bufnr, '&softtabstop',
|
||||
\ g:EditorConfig_softtabstop_tab > 0 ?
|
||||
\ l:tabstop : g:EditorConfig_softtabstop_tab)
|
||||
endif
|
||||
else
|
||||
let l:indent_size = str2nr(a:config["indent_size"])
|
||||
if l:indent_size > 0
|
||||
call setbufvar(a:bufnr, '&shiftwidth', l:indent_size)
|
||||
if type(g:EditorConfig_softtabstop_space) != type([])
|
||||
call setbufvar(a:bufnr, '&softtabstop',
|
||||
\ g:EditorConfig_softtabstop_space > 0 ?
|
||||
\ l:indent_size : g:EditorConfig_softtabstop_space)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if s:IsRuleActive('end_of_line', a:config) &&
|
||||
\ getbufvar(a:bufnr, '&modifiable')
|
||||
if a:config["end_of_line"] == "lf"
|
||||
call setbufvar(a:bufnr, '&fileformat', 'unix')
|
||||
elseif a:config["end_of_line"] == "crlf"
|
||||
call setbufvar(a:bufnr, '&fileformat', 'dos')
|
||||
elseif a:config["end_of_line"] == "cr"
|
||||
call setbufvar(a:bufnr, '&fileformat', 'mac')
|
||||
endif
|
||||
endif
|
||||
|
||||
if s:IsRuleActive('charset', a:config) &&
|
||||
\ getbufvar(a:bufnr, '&modifiable')
|
||||
call s:SetCharset(a:bufnr, a:config["charset"])
|
||||
endif
|
||||
|
||||
augroup editorconfig_trim_trailing_whitespace
|
||||
autocmd! BufWritePre <buffer>
|
||||
if s:IsRuleActive('trim_trailing_whitespace', a:config) &&
|
||||
\ get(a:config, 'trim_trailing_whitespace', 'false') ==# 'true'
|
||||
execute 'autocmd BufWritePre <buffer=' . a:bufnr . '> call s:TrimTrailingWhitespace()'
|
||||
endif
|
||||
augroup END
|
||||
|
||||
if s:IsRuleActive('insert_final_newline', a:config)
|
||||
if exists('+fixendofline')
|
||||
if a:config["insert_final_newline"] == "false"
|
||||
call setbufvar(a:bufnr, '&fixendofline', 0)
|
||||
else
|
||||
call setbufvar(a:bufnr, '&fixendofline', 1)
|
||||
endif
|
||||
elseif exists(':SetNoEOL') == 2
|
||||
if a:config["insert_final_newline"] == "false"
|
||||
silent! SetNoEOL " Use the PreserveNoEOL plugin to accomplish it
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
" highlight the columns following max_line_length
|
||||
if s:IsRuleActive('max_line_length', a:config) &&
|
||||
\ a:config['max_line_length'] != 'off'
|
||||
let l:max_line_length = str2nr(a:config['max_line_length'])
|
||||
|
||||
if l:max_line_length >= 0
|
||||
call setbufvar(a:bufnr, '&textwidth', l:max_line_length)
|
||||
if g:EditorConfig_preserve_formatoptions == 0
|
||||
" setlocal formatoptions+=tc
|
||||
let l:fo = getbufvar(a:bufnr, '&formatoptions')
|
||||
if l:fo !~# 't'
|
||||
let l:fo .= 't'
|
||||
endif
|
||||
if l:fo !~# 'c'
|
||||
let l:fo .= 'c'
|
||||
endif
|
||||
call setbufvar(a:bufnr, '&formatoptions', l:fo)
|
||||
endif
|
||||
endif
|
||||
|
||||
if exists('+colorcolumn')
|
||||
if l:max_line_length > 0
|
||||
if g:EditorConfig_max_line_indicator == 'line'
|
||||
" setlocal colorcolumn+=+1
|
||||
let l:cocol = getbufvar(a:bufnr, '&colorcolumn')
|
||||
if !empty(l:cocol)
|
||||
let l:cocol .= ','
|
||||
endif
|
||||
let l:cocol .= '+1'
|
||||
call setbufvar(a:bufnr, '&colorcolumn', l:cocol)
|
||||
elseif g:EditorConfig_max_line_indicator == 'fill' &&
|
||||
\ l:max_line_length < getbufvar(a:bufnr, '&columns')
|
||||
" Fill only if the columns of screen is large enough
|
||||
call setbufvar(a:bufnr, '&colorcolumn',
|
||||
\ join(range(l:max_line_length+1,
|
||||
\ getbufvar(a:bufnr, '&columns')),
|
||||
\ ','))
|
||||
elseif g:EditorConfig_max_line_indicator == 'exceeding'
|
||||
call setbufvar(a:bufnr, '&colorcolumn', '')
|
||||
for l:match in getmatches()
|
||||
if get(l:match, 'group', '') == 'ColorColumn'
|
||||
call matchdelete(get(l:match, 'id'))
|
||||
endif
|
||||
endfor
|
||||
call matchadd('ColorColumn',
|
||||
\ '\%' . (l:max_line_length + 1) . 'v.', 100)
|
||||
elseif g:EditorConfig_max_line_indicator == 'fillexceeding'
|
||||
let &l:colorcolumn = ''
|
||||
for l:match in getmatches()
|
||||
if get(l:match, 'group', '') == 'ColorColumn'
|
||||
call matchdelete(get(l:match, 'id'))
|
||||
endif
|
||||
endfor
|
||||
call matchadd('ColorColumn',
|
||||
\ '\%'. (l:max_line_length + 1) . 'v.\+', -1)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
call editorconfig#ApplyHooks(a:config)
|
||||
endfunction
|
||||
|
||||
" }}}1
|
||||
|
||||
function! s:TrimTrailingWhitespace() " {{{1
|
||||
" Called from within a buffer-specific autocmd, so we can use '%'
|
||||
if getbufvar('%', '&modifiable')
|
||||
" don't lose user position when trimming trailing whitespace
|
||||
let s:view = winsaveview()
|
||||
try
|
||||
silent! keeppatterns keepjumps %s/\s\+$//e
|
||||
finally
|
||||
call winrestview(s:view)
|
||||
endtry
|
||||
endif
|
||||
endfunction " }}}1
|
||||
|
||||
function! s:IsRuleActive(name, config) " {{{1
|
||||
return index(g:EditorConfig_disable_rules, a:name) < 0 &&
|
||||
\ has_key(a:config, a:name)
|
||||
endfunction "}}}1
|
||||
|
||||
let &cpo = s:saved_cpo
|
||||
unlet! s:saved_cpo
|
||||
|
||||
" vim: fdm=marker fdc=3
|
||||
953
gitportable/usr/share/vim/vim91/pack/dist/opt/helptoc/autoload/helptoc.vim
vendored
Normal file
953
gitportable/usr/share/vim/vim91/pack/dist/opt/helptoc/autoload/helptoc.vim
vendored
Normal file
@@ -0,0 +1,953 @@
|
||||
vim9script noclear
|
||||
|
||||
# Config {{{1
|
||||
|
||||
var SHELL_PROMPT: string = ''
|
||||
|
||||
def UpdateUserSettings() #{{{2
|
||||
var new_prompt: string = g:
|
||||
->get('helptoc', {})
|
||||
->get('shell_prompt', '^\w\+@\w\+:\f\+\$\s')
|
||||
if new_prompt != SHELL_PROMPT
|
||||
SHELL_PROMPT = new_prompt
|
||||
# invalidate cache: user config has changed
|
||||
unlet! b:toc
|
||||
endif
|
||||
enddef
|
||||
|
||||
UpdateUserSettings()
|
||||
|
||||
# Init {{{1
|
||||
|
||||
const HELP_TEXT: list<string> =<< trim END
|
||||
normal commands in help window
|
||||
──────────────────────────────
|
||||
? hide this help window
|
||||
<C-J> scroll down one line
|
||||
<C-K> scroll up one line
|
||||
|
||||
normal commands in TOC menu
|
||||
───────────────────────────
|
||||
j select next entry
|
||||
k select previous entry
|
||||
J same as j, and jump to corresponding line in main buffer
|
||||
K same as k, and jump to corresponding line in main buffer
|
||||
c select nearest entry from cursor position in main buffer
|
||||
g select first entry
|
||||
G select last entry
|
||||
H collapse one level
|
||||
L expand one level
|
||||
p print selected entry on command-line
|
||||
|
||||
P same as p but automatically, whenever selection changes
|
||||
press multiple times to toggle feature on/off
|
||||
|
||||
q quit menu
|
||||
z redraw menu with selected entry at center
|
||||
+ increase width of popup menu
|
||||
- decrease width of popup menu
|
||||
/ look for given text with fuzzy algorithm
|
||||
? show help window
|
||||
|
||||
<C-D> scroll down half a page
|
||||
<C-U> scroll up half a page
|
||||
<PageUp> scroll down a whole page
|
||||
<PageDown> scroll up a whole page
|
||||
<Home> select first entry
|
||||
<End> select last entry
|
||||
|
||||
title meaning
|
||||
─────────────
|
||||
example: 12/34 (5/6)
|
||||
broken down:
|
||||
|
||||
12 index of selected entry
|
||||
34 index of last entry
|
||||
5 index of deepest level currently visible
|
||||
6 index of maximum possible level
|
||||
|
||||
tip
|
||||
───
|
||||
after inserting a pattern to look for with the / command,
|
||||
if you press <Esc> instead of <CR>, you can then get
|
||||
more context for each remaining entry by pressing J or K
|
||||
END
|
||||
|
||||
const MATCH_ENTRY: dict<dict<func: bool>> = {
|
||||
help: {},
|
||||
|
||||
man: {
|
||||
1: (line: string, _): bool => line =~ '^\S',
|
||||
2: (line: string, _): bool => line =~ '^\%( \{3\}\)\=\S',
|
||||
3: (line: string, _): bool => line =~ '^\s\+\(\%(+\|-\)\S\+,\s\+\)*\%(+\|-\)\S\+',
|
||||
},
|
||||
|
||||
markdown: {
|
||||
1: (line: string, nextline: string): bool =>
|
||||
(line =~ '^#[^#]' || nextline =~ '^=\+$') && line =~ '\w',
|
||||
2: (line: string, nextline: string): bool =>
|
||||
(line =~ '^##[^#]' || nextline =~ '^-\+$') && line =~ '\w',
|
||||
3: (line: string, _): bool => line =~ '^###[^#]',
|
||||
4: (line: string, _): bool => line =~ '^####[^#]',
|
||||
5: (line: string, _): bool => line =~ '^#####[^#]',
|
||||
6: (line: string, _): bool => line =~ '^######[^#]',
|
||||
},
|
||||
|
||||
terminal: {
|
||||
1: (line: string, _): bool => line =~ SHELL_PROMPT,
|
||||
}
|
||||
}
|
||||
|
||||
const HELP_RULERS: dict<string> = {
|
||||
'=': '^=\{40,}$',
|
||||
'-': '^-\{40,}',
|
||||
}
|
||||
const HELP_RULER: string = HELP_RULERS->values()->join('\|')
|
||||
|
||||
# the regex is copied from the help syntax plugin
|
||||
const HELP_TAG: string = '\*[#-)!+-~]\+\*\%(\s\|$\)\@='
|
||||
|
||||
# Adapted from `$VIMRUNTIME/syntax/help.vim`.{{{
|
||||
#
|
||||
# The original regex is:
|
||||
#
|
||||
# ^[-A-Z .][-A-Z0-9 .()_]*\ze\(\s\+\*\|$\)
|
||||
#
|
||||
# Allowing a space or a hyphen at the start can give false positives, and is
|
||||
# useless, so we don't allow them.
|
||||
#}}}
|
||||
const HELP_HEADLINE: string = '^\C[A-Z.][-A-Z0-9 .()_]*\%(\s\+\*+\@!\|$\)'
|
||||
# ^--^
|
||||
# To prevent some false positives under `:help feature-list`.
|
||||
|
||||
var lvls: dict<number>
|
||||
def InitHelpLvls()
|
||||
lvls = {
|
||||
'*01.1*': 0,
|
||||
'1.': 0,
|
||||
'1.2': 0,
|
||||
'1.2.3': 0,
|
||||
'header ~': 0,
|
||||
HEADLINE: 0,
|
||||
tag: 0,
|
||||
}
|
||||
enddef
|
||||
|
||||
const AUGROUP: string = 'HelpToc'
|
||||
var fuzzy_entries: list<dict<any>>
|
||||
var help_winid: number
|
||||
var print_entry: bool
|
||||
var selected_entry_match: number
|
||||
|
||||
# Interface {{{1
|
||||
export def Open() #{{{2
|
||||
var type: string = GetType()
|
||||
if !MATCH_ENTRY->has_key(type)
|
||||
return
|
||||
endif
|
||||
if type == 'terminal' && win_gettype() == 'popup'
|
||||
# trying to deal with a popup menu on top of a popup terminal seems
|
||||
# too tricky for now
|
||||
echomsg 'does not work in a popup window; only in a regular window'
|
||||
return
|
||||
endif
|
||||
|
||||
UpdateUserSettings()
|
||||
|
||||
# invalidate the cache if the buffer's contents has changed
|
||||
if exists('b:toc') && &filetype != 'man'
|
||||
if b:toc.changedtick != b:changedtick
|
||||
# in a terminal buffer, `b:changedtick` does not change
|
||||
|| type == 'terminal' && line('$') > b:toc.linecount
|
||||
unlet! b:toc
|
||||
endif
|
||||
endif
|
||||
|
||||
if !exists('b:toc')
|
||||
SetToc()
|
||||
endif
|
||||
|
||||
var winpos: list<number> = winnr()->win_screenpos()
|
||||
var height: number = winheight(0) - 2
|
||||
var width: number = winwidth(0)
|
||||
b:toc.width = b:toc.width ?? width / 3
|
||||
# the popup needs enough space to display the help message in its title
|
||||
if b:toc.width < 30
|
||||
b:toc.width = 30
|
||||
endif
|
||||
# Is `popup_menu()` OK with a list of dictionaries?{{{
|
||||
#
|
||||
# Yes, see `:help popup_create-arguments`.
|
||||
# Although, it expects dictionaries with the keys `text` and `props`.
|
||||
# But we use dictionaries with the keys `text` and `lnum`.
|
||||
# IOW, we abuse the feature which lets us use text properties in a popup.
|
||||
#}}}
|
||||
var winid: number = GetTocEntries()
|
||||
->popup_menu({
|
||||
line: winpos[0],
|
||||
col: winpos[1] + width - 1,
|
||||
pos: 'topright',
|
||||
scrollbar: false,
|
||||
highlight: type == 'terminal' ? 'Terminal' : 'Normal',
|
||||
border: [],
|
||||
borderchars: ['─', '│', '─', '│', '┌', '┐', '┘', '└'],
|
||||
minheight: height,
|
||||
maxheight: height,
|
||||
minwidth: b:toc.width,
|
||||
maxwidth: b:toc.width,
|
||||
filter: Filter,
|
||||
callback: Callback,
|
||||
})
|
||||
Win_execute(winid, [$'ownsyntax {&filetype}', '&l:conceallevel = 3'])
|
||||
# In a help file, we might reduce some noisy tags to a trailing asterisk.
|
||||
# Hide those.
|
||||
if type == 'help'
|
||||
matchadd('Conceal', '\*$', 0, -1, {window: winid})
|
||||
endif
|
||||
SelectNearestEntryFromCursor(winid)
|
||||
|
||||
# can't set the title before jumping to the relevant line, otherwise the
|
||||
# indicator in the title might be wrong
|
||||
SetTitle(winid)
|
||||
enddef
|
||||
#}}}1
|
||||
# Core {{{1
|
||||
def SetToc() #{{{2
|
||||
var toc: dict<any> = {entries: []}
|
||||
var type: string = GetType()
|
||||
toc.changedtick = b:changedtick
|
||||
if !toc->has_key('width')
|
||||
toc.width = 0
|
||||
endif
|
||||
# We cache the toc in `b:toc` to get better performance.{{{
|
||||
#
|
||||
# Without caching, when we press `H`, `L`, `H`, `L`, ... quickly for a few
|
||||
# seconds, there is some lag if we then try to move with `j` and `k`.
|
||||
# This can only be perceived in big man pages like with `:Man ffmpeg-all`.
|
||||
#}}}
|
||||
b:toc = toc
|
||||
|
||||
if type == 'help'
|
||||
SetTocHelp()
|
||||
return
|
||||
endif
|
||||
|
||||
if type == 'terminal'
|
||||
b:toc.linecount = line('$')
|
||||
endif
|
||||
|
||||
var curline: string = getline(1)
|
||||
var nextline: string
|
||||
var lvl_and_test: list<list<any>> = MATCH_ENTRY
|
||||
->get(type, {})
|
||||
->items()
|
||||
->sort((l: list<any>, ll: list<any>): number => l[0]->str2nr() - ll[0]->str2nr())
|
||||
|
||||
for lnum: number in range(1, line('$'))
|
||||
nextline = getline(lnum + 1)
|
||||
for [lvl: string, IsEntry: func: bool] in lvl_and_test
|
||||
if IsEntry(curline, nextline)
|
||||
b:toc.entries->add({
|
||||
lnum: lnum,
|
||||
lvl: lvl->str2nr(),
|
||||
text: curline,
|
||||
})
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
curline = nextline
|
||||
endfor
|
||||
|
||||
InitMaxAndCurLvl()
|
||||
enddef
|
||||
|
||||
def SetTocHelp() #{{{2
|
||||
var main_ruler: string
|
||||
for line: string in getline(1, '$')
|
||||
if line =~ HELP_RULER
|
||||
main_ruler = line =~ '=' ? HELP_RULERS['='] : HELP_RULERS['-']
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
var prevline: string
|
||||
var curline: string = getline(1)
|
||||
var nextline: string
|
||||
var in_list: bool
|
||||
var last_numbered_entry: number
|
||||
InitHelpLvls()
|
||||
for lnum: number in range(1, line('$'))
|
||||
nextline = getline(lnum + 1)
|
||||
|
||||
if main_ruler != '' && curline =~ main_ruler
|
||||
last_numbered_entry = 0
|
||||
# The information gathered in `lvls` might not be applicable to all
|
||||
# the main sections of a help file. Let's reset it whenever we find
|
||||
# a ruler.
|
||||
InitHelpLvls()
|
||||
endif
|
||||
|
||||
# Do not assume that a list ends on an empty line.
|
||||
# See the list at `:help gdb` for a counter-example.
|
||||
if in_list
|
||||
&& curline !~ '^\d\+.\s'
|
||||
&& curline !~ '^\s*$'
|
||||
&& curline !~ '^[< \t]'
|
||||
in_list = false
|
||||
endif
|
||||
|
||||
if prevline =~ '^\d\+\.\s'
|
||||
&& curline !~ '^\s*$'
|
||||
&& curline !~ $'^\s*{HELP_TAG}'
|
||||
in_list = true
|
||||
endif
|
||||
|
||||
# 1.
|
||||
if prevline =~ '^\d\+\.\s'
|
||||
# let's assume that the start of a main entry is always followed by an
|
||||
# empty line, or a line starting with a tag
|
||||
&& (curline =~ '^>\=\s*$' || curline =~ $'^\s*{HELP_TAG}')
|
||||
# ignore a numbered line in a list
|
||||
&& !in_list
|
||||
var current_numbered_entry: number = prevline
|
||||
->matchstr('^\d\+\ze\.\s')
|
||||
->str2nr()
|
||||
if current_numbered_entry > last_numbered_entry
|
||||
AddEntryInTocHelp('1.', lnum - 1, prevline)
|
||||
last_numbered_entry = prevline
|
||||
->matchstr('^\d\+\ze\.\s')
|
||||
->str2nr()
|
||||
endif
|
||||
endif
|
||||
|
||||
# 1.2
|
||||
if curline =~ '^\d\+\.\d\+\s'
|
||||
if curline =~ $'\%({HELP_TAG}\s*\|\~\)$'
|
||||
|| (prevline =~ $'^\s*{HELP_TAG}' || nextline =~ $'^\s*{HELP_TAG}')
|
||||
|| (prevline =~ HELP_RULER || nextline =~ HELP_RULER)
|
||||
|| (prevline =~ '^\s*$' && nextline =~ '^\s*$')
|
||||
AddEntryInTocHelp('1.2', lnum, curline)
|
||||
endif
|
||||
# 1.2.3
|
||||
elseif curline =~ '^\s\=\d\+\.\d\+\.\d\+\s'
|
||||
AddEntryInTocHelp('1.2.3', lnum, curline)
|
||||
endif
|
||||
|
||||
# HEADLINE
|
||||
if curline =~ HELP_HEADLINE
|
||||
&& curline !~ '^CTRL-'
|
||||
&& prevline->IsSpecialHelpLine()
|
||||
&& (nextline->IsSpecialHelpLine() || nextline =~ '^\s*(\|^\t\|^N[oO][tT][eE]:')
|
||||
AddEntryInTocHelp('HEADLINE', lnum, curline)
|
||||
endif
|
||||
|
||||
# header ~
|
||||
if curline =~ '\~$'
|
||||
&& curline =~ '\w'
|
||||
&& curline !~ '^[ \t<]\|\t\|---+---\|^NOTE:'
|
||||
&& curline !~ '^\d\+\.\%(\d\+\%(\.\d\+\)\=\)\=\s'
|
||||
&& prevline !~ $'^\s*{HELP_TAG}'
|
||||
&& prevline !~ '\~$'
|
||||
&& nextline !~ '\~$'
|
||||
AddEntryInTocHelp('header ~', lnum, curline)
|
||||
endif
|
||||
|
||||
# *some_tag*
|
||||
if curline =~ HELP_TAG
|
||||
AddEntryInTocHelp('tag', lnum, curline)
|
||||
endif
|
||||
|
||||
# In the Vim user manual, a main section is a special case.{{{
|
||||
#
|
||||
# It's not a simple numbered section:
|
||||
#
|
||||
# 01.1
|
||||
#
|
||||
# It's used as a tag:
|
||||
#
|
||||
# *01.1* Two manuals
|
||||
# ^ ^
|
||||
#}}}
|
||||
if prevline =~ main_ruler && curline =~ '^\*\d\+\.\d\+\*'
|
||||
AddEntryInTocHelp('*01.1*', lnum, curline)
|
||||
endif
|
||||
|
||||
[prevline, curline] = [curline, nextline]
|
||||
endfor
|
||||
|
||||
# let's ignore the tag on the first line (not really interesting)
|
||||
if b:toc.entries->get(0, {})->get('lnum') == 1
|
||||
b:toc.entries->remove(0)
|
||||
endif
|
||||
|
||||
# let's also ignore anything before the first `1.` line
|
||||
var i: number = b:toc.entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>) => entry.text)
|
||||
->match('^\s*1\.\s')
|
||||
if i > 0
|
||||
b:toc.entries->remove(0, i - 1)
|
||||
endif
|
||||
|
||||
InitMaxAndCurLvl()
|
||||
|
||||
# set level of tag entries to the deepest level
|
||||
var has_tag: bool = b:toc.entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>) => entry.text)
|
||||
->match(HELP_TAG) >= 0
|
||||
if has_tag
|
||||
++b:toc.maxlvl
|
||||
endif
|
||||
b:toc.entries
|
||||
->map((_, entry: dict<any>) => entry.lvl == 0
|
||||
? entry->extend({lvl: b:toc.maxlvl})
|
||||
: entry)
|
||||
|
||||
# fix indentation
|
||||
var min_lvl: number = b:toc.entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>) => entry.lvl)
|
||||
->min()
|
||||
for entry: dict<any> in b:toc.entries
|
||||
entry.text = entry.text
|
||||
->substitute('^\s*', () => repeat(' ', (entry.lvl - min_lvl) * 3), '')
|
||||
endfor
|
||||
enddef
|
||||
|
||||
def AddEntryInTocHelp(type: string, lnum: number, line: string) #{{{2
|
||||
# don't add a duplicate entry
|
||||
if lnum == b:toc.entries->get(-1, {})->get('lnum')
|
||||
# For a numbered line containing a tag, *do* add an entry.
|
||||
# But only for its numbered prefix, not for its tag.
|
||||
# The former is the line's most meaningful representation.
|
||||
if b:toc.entries->get(-1, {})->get('type') == 'tag'
|
||||
b:toc.entries->remove(-1)
|
||||
else
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
var text: string = line
|
||||
if type == 'tag'
|
||||
var tags: list<string>
|
||||
text->substitute(HELP_TAG, () => !!tags->add(submatch(0)), 'g')
|
||||
text = tags
|
||||
# we ignore errors and warnings because those are meaningless in
|
||||
# a TOC where no context is available
|
||||
->filter((_, tag: string) => tag !~ '\*[EW]\d\+\*')
|
||||
->join()
|
||||
if text !~ HELP_TAG
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
var maxlvl: number = lvls->values()->max()
|
||||
if type == 'tag'
|
||||
lvls[type] = 0
|
||||
elseif type == '1.2'
|
||||
lvls[type] = lvls[type] ?? lvls->get('1.', maxlvl) + 1
|
||||
elseif type == '1.2.3'
|
||||
lvls[type] = lvls[type] ?? lvls->get('1.2', maxlvl) + 1
|
||||
else
|
||||
lvls[type] = lvls[type] ?? maxlvl + 1
|
||||
endif
|
||||
|
||||
# Ignore noisy tags.{{{
|
||||
#
|
||||
# 14. Linking groups *:hi-link* *:highlight-link* *E412* *E413*
|
||||
# ^----------------------------------------^
|
||||
# ^\s*\d\+\.\%(\d\+\.\=\)*\s\+.\{-}\zs\*.*
|
||||
# ---
|
||||
#
|
||||
# We don't use conceal because then, `matchfuzzypos()` could match concealed
|
||||
# characters, which would be confusing.
|
||||
#}}}
|
||||
# MAKING YOUR OWN SYNTAX FILES *mysyntaxfile*
|
||||
# ^------------^
|
||||
# ^\s*[A-Z].\{-}\*\zs.*
|
||||
#
|
||||
var after_HEADLINE: string = '^\s*[A-Z].\{-}\*\zs.*'
|
||||
# 14. Linking groups *:hi-link* *:highlight-link* *E412* *E413*
|
||||
# ^----------------------------------------^
|
||||
# ^\s*\d\+\.\%(\d\+\.\=\)*\s\+.\{-}\*\zs.*
|
||||
var after_numbered: string = '^\s*\d\+\.\%(\d\+\.\=\)*\s\+.\{-}\*\zs.*'
|
||||
# 01.3 Using the Vim tutor *tutor* *vimtutor*
|
||||
# ^----------------^
|
||||
var after_numbered_tutor: string = '^\*\d\+\.\%(\d\+\.\=\)*.\{-}\t\*\zs.*'
|
||||
var noisy_tags: string = $'{after_HEADLINE}\|{after_numbered}\|{after_numbered_tutor}'
|
||||
text = text->substitute(noisy_tags, '', '')
|
||||
# We don't remove the trailing asterisk, because the help syntax plugin
|
||||
# might need it to highlight some headlines.
|
||||
|
||||
b:toc.entries->add({
|
||||
lnum: lnum,
|
||||
lvl: lvls[type],
|
||||
text: text,
|
||||
type: type,
|
||||
})
|
||||
enddef
|
||||
|
||||
def InitMaxAndCurLvl() #{{{2
|
||||
b:toc.maxlvl = b:toc.entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>) => entry.lvl)
|
||||
->max()
|
||||
b:toc.curlvl = b:toc.maxlvl
|
||||
enddef
|
||||
|
||||
def Popup_settext(winid: number, entries: list<dict<any>>) #{{{2
|
||||
var text: list<any>
|
||||
# When we fuzzy search the toc, the dictionaries in `entries` contain a
|
||||
# `props` key, to highlight each matched character individually.
|
||||
# We don't want to process those dictionaries further.
|
||||
# The processing should already have been done by the caller.
|
||||
if entries->get(0, {})->has_key('props')
|
||||
text = entries
|
||||
else
|
||||
text = entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>): string => entry.text)
|
||||
endif
|
||||
popup_settext(winid, text)
|
||||
SetTitle(winid)
|
||||
redraw
|
||||
enddef
|
||||
|
||||
def SetTitle(winid: number) #{{{2
|
||||
var curlnum: number
|
||||
var lastlnum: number = line('$', winid)
|
||||
var is_empty: bool = lastlnum == 1
|
||||
&& winid->winbufnr()->getbufoneline(1) == ''
|
||||
if is_empty
|
||||
[curlnum, lastlnum] = [0, 0]
|
||||
else
|
||||
curlnum = line('.', winid)
|
||||
endif
|
||||
var newtitle: string = printf(' %*d/%d (%d/%d)',
|
||||
len(lastlnum), curlnum,
|
||||
lastlnum,
|
||||
b:toc.curlvl,
|
||||
b:toc.maxlvl,
|
||||
)
|
||||
|
||||
var width: number = winid->popup_getoptions().minwidth
|
||||
newtitle = printf('%s%*s',
|
||||
newtitle,
|
||||
width - newtitle->strlen(),
|
||||
'press ? for help ')
|
||||
|
||||
popup_setoptions(winid, {title: newtitle})
|
||||
enddef
|
||||
|
||||
def SelectNearestEntryFromCursor(winid: number) #{{{2
|
||||
var lnum: number = line('.')
|
||||
var firstline: number = b:toc.entries
|
||||
->copy()
|
||||
->filter((_, line: dict<any>): bool => line.lvl <= b:toc.curlvl && line.lnum <= lnum)
|
||||
->len()
|
||||
if firstline == 0
|
||||
return
|
||||
endif
|
||||
Win_execute(winid, $'normal! {firstline}Gzz')
|
||||
enddef
|
||||
|
||||
def Filter(winid: number, key: string): bool #{{{2
|
||||
# support various normal commands for moving/scrolling
|
||||
if [
|
||||
'j', 'J', 'k', 'K', "\<Down>", "\<Up>", "\<C-N>", "\<C-P>",
|
||||
"\<C-D>", "\<C-U>",
|
||||
"\<PageUp>", "\<PageDown>",
|
||||
'g', 'G', "\<Home>", "\<End>",
|
||||
'z'
|
||||
]->index(key) >= 0
|
||||
var scroll_cmd: string = {
|
||||
J: 'j',
|
||||
K: 'k',
|
||||
g: '1G',
|
||||
"\<Home>": '1G',
|
||||
"\<End>": 'G',
|
||||
z: 'zz'
|
||||
}->get(key, key)
|
||||
|
||||
var old_lnum: number = line('.', winid)
|
||||
Win_execute(winid, $'normal! {scroll_cmd}')
|
||||
var new_lnum: number = line('.', winid)
|
||||
|
||||
if print_entry
|
||||
PrintEntry(winid)
|
||||
endif
|
||||
|
||||
# wrap around the edges
|
||||
if new_lnum == old_lnum
|
||||
scroll_cmd = {
|
||||
j: '1G',
|
||||
J: '1G',
|
||||
k: 'G',
|
||||
K: 'G',
|
||||
"\<Down>": '1G',
|
||||
"\<Up>": 'G',
|
||||
"\<C-N>": '1G',
|
||||
"\<C-P>": 'G',
|
||||
}->get(key, '')
|
||||
if !scroll_cmd->empty()
|
||||
Win_execute(winid, $'normal! {scroll_cmd}')
|
||||
endif
|
||||
endif
|
||||
|
||||
# move the cursor to the corresponding line in the main buffer
|
||||
if key == 'J' || key == 'K'
|
||||
var lnum: number = GetBufLnum(winid)
|
||||
execute $'normal! 0{lnum}zt'
|
||||
# install a match in the regular buffer to highlight the position of
|
||||
# the entry in the latter
|
||||
MatchDelete()
|
||||
selected_entry_match = matchaddpos('IncSearch', [lnum], 0, -1)
|
||||
endif
|
||||
SetTitle(winid)
|
||||
|
||||
return true
|
||||
|
||||
elseif key == 'c'
|
||||
SelectNearestEntryFromCursor(winid)
|
||||
return true
|
||||
|
||||
# when we press `p`, print the selected line (useful when it's truncated)
|
||||
elseif key == 'p'
|
||||
PrintEntry(winid)
|
||||
return true
|
||||
|
||||
# same thing, but automatically
|
||||
elseif key == 'P'
|
||||
print_entry = !print_entry
|
||||
if print_entry
|
||||
PrintEntry(winid)
|
||||
else
|
||||
echo ''
|
||||
endif
|
||||
return true
|
||||
|
||||
elseif key == 'q'
|
||||
popup_close(winid, -1)
|
||||
return true
|
||||
|
||||
elseif key == '?'
|
||||
ToggleHelp(winid)
|
||||
return true
|
||||
|
||||
# scroll help window
|
||||
elseif key == "\<C-J>" || key == "\<C-K>"
|
||||
var scroll_cmd: string = {"\<C-J>": 'j', "\<C-K>": 'k'}->get(key, key)
|
||||
if scroll_cmd == 'j' && line('.', help_winid) == line('$', help_winid)
|
||||
scroll_cmd = '1G'
|
||||
elseif scroll_cmd == 'k' && line('.', help_winid) == 1
|
||||
scroll_cmd = 'G'
|
||||
endif
|
||||
Win_execute(help_winid, $'normal! {scroll_cmd}')
|
||||
return true
|
||||
|
||||
# increase/decrease the popup's width
|
||||
elseif key == '+' || key == '-'
|
||||
var width: number = winid->popup_getoptions().minwidth
|
||||
if key == '-' && width == 1
|
||||
|| key == '+' && winid->popup_getpos().col == 1
|
||||
return true
|
||||
endif
|
||||
width = width + (key == '+' ? 1 : -1)
|
||||
# remember the last width if we close and re-open the TOC later
|
||||
b:toc.width = width
|
||||
popup_setoptions(winid, {minwidth: width, maxwidth: width})
|
||||
return true
|
||||
|
||||
elseif key == 'H' && b:toc.curlvl > 1
|
||||
|| key == 'L' && b:toc.curlvl < b:toc.maxlvl
|
||||
CollapseOrExpand(winid, key)
|
||||
return true
|
||||
|
||||
elseif key == '/'
|
||||
# This is probably what the user expect if they've started a first fuzzy
|
||||
# search, press Escape, then start a new one.
|
||||
DisplayNonFuzzyToc(winid)
|
||||
|
||||
[{
|
||||
group: AUGROUP,
|
||||
event: 'CmdlineChanged',
|
||||
pattern: '@',
|
||||
cmd: $'FuzzySearch({winid})',
|
||||
replace: true,
|
||||
}, {
|
||||
group: AUGROUP,
|
||||
event: 'CmdlineLeave',
|
||||
pattern: '@',
|
||||
cmd: 'TearDown()',
|
||||
replace: true,
|
||||
}]->autocmd_add()
|
||||
|
||||
# Need to evaluate `winid` right now with an `eval`'ed and `execute()`'ed heredoc because:{{{
|
||||
#
|
||||
# - the mappings can only access the script-local namespace
|
||||
# - `winid` is in the function namespace; not in the script-local one
|
||||
#}}}
|
||||
var input_mappings: list<string> =<< trim eval END
|
||||
cnoremap <buffer><nowait> <Down> <ScriptCmd>Filter({winid}, 'j')<CR>
|
||||
cnoremap <buffer><nowait> <Up> <ScriptCmd>Filter({winid}, 'k')<CR>
|
||||
cnoremap <buffer><nowait> <C-N> <ScriptCmd>Filter({winid}, 'j')<CR>
|
||||
cnoremap <buffer><nowait> <C-P> <ScriptCmd>Filter({winid}, 'k')<CR>
|
||||
END
|
||||
input_mappings->execute()
|
||||
|
||||
var look_for: string
|
||||
try
|
||||
popup_setoptions(winid, {mapping: true})
|
||||
look_for = input('look for: ', '', $'custom,{Complete->string()}') | redraw | echo ''
|
||||
catch /Vim:Interrupt/
|
||||
TearDown()
|
||||
finally
|
||||
popup_setoptions(winid, {mapping: false})
|
||||
endtry
|
||||
return look_for == '' ? true : popup_filter_menu(winid, "\<CR>")
|
||||
endif
|
||||
|
||||
return popup_filter_menu(winid, key)
|
||||
enddef
|
||||
|
||||
def FuzzySearch(winid: number) #{{{2
|
||||
var look_for: string = getcmdline()
|
||||
if look_for == ''
|
||||
DisplayNonFuzzyToc(winid)
|
||||
return
|
||||
endif
|
||||
|
||||
# We match against *all* entries; not just the currently visible ones.
|
||||
# Rationale: If we use a (fuzzy) search, we're probably lost. We don't know
|
||||
# where the info is.
|
||||
var matches: list<list<any>> = b:toc.entries
|
||||
->copy()
|
||||
->matchfuzzypos(look_for, {key: 'text'})
|
||||
|
||||
fuzzy_entries = matches->get(0, [])->copy()
|
||||
var pos: list<list<number>> = matches->get(1, [])
|
||||
|
||||
var text: list<dict<any>>
|
||||
if !has('textprop')
|
||||
text = matches->get(0, [])
|
||||
else
|
||||
var buf: number = winid->winbufnr()
|
||||
if prop_type_get('help-fuzzy-toc', {bufnr: buf}) == {}
|
||||
prop_type_add('help-fuzzy-toc', {
|
||||
bufnr: buf,
|
||||
combine: false,
|
||||
highlight: 'IncSearch',
|
||||
})
|
||||
endif
|
||||
text = matches
|
||||
->get(0, [])
|
||||
->map((i: number, match: dict<any>) => ({
|
||||
text: match.text,
|
||||
props: pos[i]->copy()->map((_, col: number) => ({
|
||||
col: col + 1,
|
||||
length: 1,
|
||||
type: 'help-fuzzy-toc',
|
||||
}))}))
|
||||
endif
|
||||
Win_execute(winid, 'normal! 1Gzt')
|
||||
Popup_settext(winid, text)
|
||||
enddef
|
||||
|
||||
def DisplayNonFuzzyToc(winid: number) #{{{2
|
||||
fuzzy_entries = null_list
|
||||
Popup_settext(winid, GetTocEntries())
|
||||
enddef
|
||||
|
||||
def PrintEntry(winid: number) #{{{2
|
||||
echo GetTocEntries()[line('.', winid) - 1]['text']
|
||||
enddef
|
||||
|
||||
def CollapseOrExpand(winid: number, key: string) #{{{2
|
||||
# Must be saved before we reset the popup contents, so we can
|
||||
# automatically select the least unexpected entry in the updated popup.
|
||||
var buf_lnum: number = GetBufLnum(winid)
|
||||
|
||||
# find the nearest lower level for which the contents of the TOC changes
|
||||
if key == 'H'
|
||||
while b:toc.curlvl > 1
|
||||
var old: list<dict<any>> = GetTocEntries()
|
||||
--b:toc.curlvl
|
||||
var new: list<dict<any>> = GetTocEntries()
|
||||
# In `:help`, there are only entries in levels 3.
|
||||
# We don't want to collapse to level 2, nor 1.
|
||||
# It would clear the TOC which is confusing.
|
||||
if new->empty()
|
||||
++b:toc.curlvl
|
||||
break
|
||||
endif
|
||||
var did_change: bool = new != old
|
||||
if did_change || b:toc.curlvl == 1
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
# find the nearest upper level for which the contents of the TOC changes
|
||||
else
|
||||
while b:toc.curlvl < b:toc.maxlvl
|
||||
var old: list<dict<any>> = GetTocEntries()
|
||||
++b:toc.curlvl
|
||||
var did_change: bool = GetTocEntries() != old
|
||||
if did_change || b:toc.curlvl == b:toc.maxlvl
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
endif
|
||||
|
||||
# update the popup contents
|
||||
var toc_entries: list<dict<any>> = GetTocEntries()
|
||||
Popup_settext(winid, toc_entries)
|
||||
|
||||
# Try to select the same entry; if it's no longer visible, select its
|
||||
# direct parent.
|
||||
var toc_lnum: number = 0
|
||||
for entry: dict<any> in toc_entries
|
||||
if entry.lnum > buf_lnum
|
||||
break
|
||||
endif
|
||||
++toc_lnum
|
||||
endfor
|
||||
Win_execute(winid, $'normal! {toc_lnum ?? 1}Gzz')
|
||||
enddef
|
||||
|
||||
def MatchDelete() #{{{2
|
||||
if selected_entry_match == 0
|
||||
return
|
||||
endif
|
||||
|
||||
selected_entry_match->matchdelete()
|
||||
selected_entry_match = 0
|
||||
enddef
|
||||
|
||||
def Callback(winid: number, choice: number) #{{{2
|
||||
MatchDelete()
|
||||
|
||||
if help_winid != 0
|
||||
help_winid->popup_close()
|
||||
help_winid = 0
|
||||
endif
|
||||
|
||||
if choice == -1
|
||||
fuzzy_entries = null_list
|
||||
return
|
||||
endif
|
||||
|
||||
var lnum: number = GetTocEntries()
|
||||
->get(choice - 1, {})
|
||||
->get('lnum')
|
||||
|
||||
fuzzy_entries = null_list
|
||||
|
||||
if lnum == 0
|
||||
return
|
||||
endif
|
||||
|
||||
cursor(lnum, 1)
|
||||
normal! zvzt
|
||||
enddef
|
||||
|
||||
def ToggleHelp(menu_winid: number) #{{{2
|
||||
if help_winid == 0
|
||||
var height: number = [HELP_TEXT->len(), winheight(0) * 2 / 3]->min()
|
||||
var longest_line: number = HELP_TEXT
|
||||
->copy()
|
||||
->map((_, line: string) => line->strcharlen())
|
||||
->max()
|
||||
var width: number = [longest_line, winwidth(0) * 2 / 3]->min()
|
||||
var pos: dict<number> = popup_getpos(menu_winid)
|
||||
var [line: number, col: number] = [pos.line, pos.col]
|
||||
--col
|
||||
var zindex: number = popup_getoptions(menu_winid).zindex
|
||||
++zindex
|
||||
help_winid = HELP_TEXT->popup_create({
|
||||
line: line,
|
||||
col: col,
|
||||
pos: 'topright',
|
||||
minheight: height,
|
||||
maxheight: height,
|
||||
minwidth: width,
|
||||
maxwidth: width,
|
||||
border: [],
|
||||
borderchars: ['─', '│', '─', '│', '┌', '┐', '┘', '└'],
|
||||
highlight: &buftype == 'terminal' ? 'Terminal' : 'Normal',
|
||||
scrollbar: false,
|
||||
zindex: zindex,
|
||||
})
|
||||
|
||||
setwinvar(help_winid, '&cursorline', true)
|
||||
setwinvar(help_winid, '&linebreak', true)
|
||||
matchadd('Special', '^<\S\+\|^\S\{,2} \@=', 0, -1, {window: help_winid})
|
||||
matchadd('Number', '\d\+', 0, -1, {window: help_winid})
|
||||
for lnum: number in HELP_TEXT->len()->range()
|
||||
if HELP_TEXT[lnum] =~ '^─\+$'
|
||||
matchaddpos('Title', [lnum], 0, -1, {window: help_winid})
|
||||
endif
|
||||
endfor
|
||||
|
||||
else
|
||||
if IsVisible(help_winid)
|
||||
popup_hide(help_winid)
|
||||
else
|
||||
popup_show(help_winid)
|
||||
endif
|
||||
endif
|
||||
enddef
|
||||
|
||||
def Win_execute(winid: number, cmd: any) #{{{2
|
||||
# wrapper around `win_execute()` to enforce a redraw, which might be necessary
|
||||
# whenever we change the cursor position
|
||||
win_execute(winid, cmd)
|
||||
redraw
|
||||
enddef
|
||||
|
||||
def TearDown() #{{{2
|
||||
autocmd_delete([{group: AUGROUP}])
|
||||
cunmap <buffer> <Down>
|
||||
cunmap <buffer> <Up>
|
||||
cunmap <buffer> <C-N>
|
||||
cunmap <buffer> <C-P>
|
||||
enddef
|
||||
#}}}1
|
||||
# Util {{{1
|
||||
def GetType(): string #{{{2
|
||||
return &buftype == 'terminal' ? 'terminal' : &filetype
|
||||
enddef
|
||||
|
||||
def GetTocEntries(): list<dict<any>> #{{{2
|
||||
return fuzzy_entries ?? b:toc.entries
|
||||
->copy()
|
||||
->filter((_, entry: dict<any>): bool => entry.lvl <= b:toc.curlvl)
|
||||
enddef
|
||||
|
||||
def GetBufLnum(winid: number): number #{{{2
|
||||
var toc_lnum: number = line('.', winid)
|
||||
return GetTocEntries()
|
||||
->get(toc_lnum - 1, {})
|
||||
->get('lnum')
|
||||
enddef
|
||||
|
||||
def IsVisible(win: number): bool #{{{2
|
||||
return win->popup_getpos()->get('visible')
|
||||
enddef
|
||||
|
||||
def IsSpecialHelpLine(line: string): bool #{{{2
|
||||
return line =~ '^[<>]\=\s*$'
|
||||
|| line =~ '^\s*\*'
|
||||
|| line =~ HELP_RULER
|
||||
|| line =~ HELP_HEADLINE
|
||||
enddef
|
||||
|
||||
def Complete(..._): string #{{{2
|
||||
return b:toc.entries
|
||||
->copy()
|
||||
->map((_, entry: dict<any>) => entry.text->trim(' ~')->substitute('*', '', 'g'))
|
||||
->filter((_, text: string): bool => text =~ '^[-a-zA-Z0-9_() ]\+$')
|
||||
->sort()
|
||||
->uniq()
|
||||
->join("\n")
|
||||
enddef
|
||||
|
||||
5
gitportable/usr/share/vim/vim91/pack/dist/opt/helptoc/plugin/helptoc.vim
vendored
Normal file
5
gitportable/usr/share/vim/vim91/pack/dist/opt/helptoc/plugin/helptoc.vim
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
vim9script noclear
|
||||
|
||||
import autoload '../autoload/helptoc.vim'
|
||||
|
||||
command -bar HelpToc helptoc.Open()
|
||||
316
gitportable/usr/share/vim/vim91/pack/dist/opt/justify/plugin/justify.vim
vendored
Normal file
316
gitportable/usr/share/vim/vim91/pack/dist/opt/justify/plugin/justify.vim
vendored
Normal 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 'cpoptions' 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
|
||||
784
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/autoload/matchit.vim
vendored
Normal file
784
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/autoload/matchit.vim
vendored
Normal file
@@ -0,0 +1,784 @@
|
||||
" matchit.vim: (global plugin) Extended "%" matching
|
||||
" autload script of matchit plugin, see ../plugin/matchit.vim
|
||||
" Last Change: May 20, 2024
|
||||
|
||||
" Neovim does not support scriptversion
|
||||
if has("vimscript-4")
|
||||
scriptversion 4
|
||||
endif
|
||||
|
||||
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
|
||||
if &smartcase
|
||||
let restore_options = " smartcase " .. restore_options
|
||||
set nosmartcase
|
||||
endif
|
||||
return restore_options
|
||||
endfunction
|
||||
|
||||
function matchit#Match_wrapper(word, forward, mode) range
|
||||
let restore_options = s:RestoreOptions()
|
||||
" In s:CleanUp(), we may need to check whether the cursor moved forward.
|
||||
let startpos = [line("."), col(".")]
|
||||
" if a count has been applied, use the default [count]% mode (see :h N%)
|
||||
if v:count
|
||||
exe "normal! " .. v:count .. "%"
|
||||
return s:CleanUp(restore_options, a:mode, startpos)
|
||||
end
|
||||
if a:mode =~# "v" && mode(1) =~# 'ni'
|
||||
exe "norm! gv"
|
||||
elseif a:mode == "o" && mode(1) !~# '[vV]'
|
||||
exe "norm! v"
|
||||
" If this function was called from Visual mode, make sure that the cursor
|
||||
" is at the correct end of the Visual range:
|
||||
elseif a:mode == "v"
|
||||
execute "normal! gv\<Esc>"
|
||||
let startpos = [line("."), col(".")]
|
||||
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
|
||||
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,
|
||||
" #elifdef, #elifndef, #endif)
|
||||
let default = escape(&mps, '[$^.*~\\/?]') .. (strlen(&mps) ? "," : "") ..
|
||||
\ '\/\*:\*\/,#\s*if\%(n\=def\)\=:#\s*else\>:#\s*elif\%(n\=def\)\=\>:#\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')
|
||||
" un-escape \, to ,
|
||||
let s:all = substitute(s:all, '\\,', ',', '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')
|
||||
" un-escape \, to ,
|
||||
let s:patBR = substitute(s:patBR, '\\,', ',', '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)
|
||||
if &selection isnot# 'inclusive' && a:mode == 'v'
|
||||
" move cursor one pos to the right, because selection is not inclusive
|
||||
" add virtualedit=onemore, to make it work even when the match ends the
|
||||
" line
|
||||
if !(col('.') < col('$')-1)
|
||||
let eolmark=1 " flag to set a mark on eol (since we cannot move there)
|
||||
endif
|
||||
norm! l
|
||||
endif
|
||||
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
|
||||
if exists('eolmark') && eolmark
|
||||
call setpos("''", [0, line('.'), col('$'), 0]) " set mark on the eol
|
||||
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
|
||||
" un-escape \, to ,
|
||||
let currpat = substitute(currpat, '\\,', ',', 'g')
|
||||
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:
|
||||
412
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/doc/matchit.txt
vendored
Normal file
412
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/doc/matchit.txt
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
*matchit.txt* Extended "%" matching
|
||||
|
||||
For instructions on installing this file, type
|
||||
`:help matchit-install`
|
||||
inside Vim.
|
||||
|
||||
For Vim version 9.1. Last change: 2024 May 20
|
||||
|
||||
|
||||
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.
|
||||
|
||||
==============================================================================
|
||||
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.
|
||||
|
||||
To use the matchit plugin after Vim has started, execute this command: >
|
||||
packadd matchit
|
||||
|
||||
(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.
|
||||
|
||||
2.1 Temporarily disable the matchit plugin *matchit-disable* *:MatchDisable*
|
||||
|
||||
To temporarily disable the matchit plugin, after it hat been loaded,
|
||||
execute this command: >
|
||||
:MatchDisable
|
||||
|
||||
This will delete all the defined key mappings to the Vim default.
|
||||
Now the "%" command will work like before loading the plugin |%|
|
||||
|
||||
2.2 Re-enable the matchit plugin *:MatchEnable*
|
||||
|
||||
To re-enable the plugin, after it was disabled, use the following command: >
|
||||
:MatchEnable
|
||||
|
||||
This will resetup the key mappings.
|
||||
|
||||
==============================================================================
|
||||
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 thoroughly 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*
|
||||
|
||||
Repository: https://github.com/chrisbra/matchit/
|
||||
Bugs can be reported at the repository and the latest development snapshot can
|
||||
also be downloaded there.
|
||||
|
||||
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:ts=8:fo=tcq2:ft=help:
|
||||
53
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/doc/tags
vendored
Normal file
53
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/doc/tags
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
:MatchDebug matchit.txt /*:MatchDebug*
|
||||
:MatchDisable matchit.txt /*:MatchDisable*
|
||||
:MatchEnable matchit.txt /*:MatchEnable*
|
||||
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-disable matchit.txt /*matchit-disable*
|
||||
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%*
|
||||
127
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/plugin/matchit.vim
vendored
Normal file
127
gitportable/usr/share/vim/vim91/pack/dist/opt/matchit/plugin/matchit.vim
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
" matchit.vim: (global plugin) Extended "%" matching
|
||||
" Maintainer: Christian Brabandt
|
||||
" Version: 1.20
|
||||
" Last Change: 2024 May 20
|
||||
" 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
|
||||
|
||||
fun MatchEnable()
|
||||
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>
|
||||
xnoremap <silent> <Plug>(MatchitVisualForward) :<C-U>call matchit#Match_wrapper('',1,'v')<CR>
|
||||
\:if col("''") != col("$") \| exe ":normal! m'" \| endif<cr>gv``
|
||||
xnoremap <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>
|
||||
|
||||
" 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>
|
||||
xnoremap <silent> <Plug>(MatchitVisualMultiBackward) :<C-U>call matchit#MultiMatch("bW", "n")<CR>m'gv``
|
||||
xnoremap <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>
|
||||
|
||||
" text object:
|
||||
xmap <silent> <Plug>(MatchitVisualTextObject) <Plug>(MatchitVisualMultiBackward)o<Plug>(MatchitVisualMultiForward)
|
||||
|
||||
if !exists("g:no_plugin_maps")
|
||||
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:
|
||||
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
|
||||
xmap a% <Plug>(MatchitVisualTextObject)
|
||||
endif
|
||||
endfun
|
||||
|
||||
fun MatchDisable()
|
||||
" remove all the setup keymappings
|
||||
nunmap %
|
||||
nunmap g%
|
||||
xunmap %
|
||||
xunmap g%
|
||||
ounmap %
|
||||
ounmap g%
|
||||
|
||||
nunmap [%
|
||||
nunmap ]%
|
||||
xunmap [%
|
||||
xunmap ]%
|
||||
ounmap [%
|
||||
ounmap ]%
|
||||
|
||||
xunmap a%
|
||||
endfun
|
||||
|
||||
" 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
|
||||
if !exists(":MatchDisable")
|
||||
command! -nargs=0 MatchDisable :call MatchDisable()
|
||||
endif
|
||||
if !exists(":MatchEnable")
|
||||
command! -nargs=0 MatchEnable :call MatchEnable()
|
||||
endif
|
||||
|
||||
call MatchEnable()
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
||||
" vim:sts=2:sw=2:et:
|
||||
20
gitportable/usr/share/vim/vim91/pack/dist/opt/nohlsearch/plugin/nohlsearch.vim
vendored
Normal file
20
gitportable/usr/share/vim/vim91/pack/dist/opt/nohlsearch/plugin/nohlsearch.vim
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
" nohlsearch.vim: Auto turn off hlsearch
|
||||
" Last Change: 2024-07-31
|
||||
" Maintainer: Maxim Kim <habamax@gmail.com>
|
||||
"
|
||||
" turn off hlsearch after:
|
||||
" - doing nothing for 'updatetime'
|
||||
" - getting into insert mode
|
||||
|
||||
if exists('g:loaded_nohlsearch')
|
||||
finish
|
||||
endif
|
||||
let g:loaded_nohlsearch = 1
|
||||
|
||||
augroup nohlsearch
|
||||
au!
|
||||
noremap <Plug>(nohlsearch) <cmd>nohlsearch<cr>
|
||||
noremap! <Plug>(nohlsearch) <cmd>nohlsearch<cr>
|
||||
au CursorHold * call feedkeys("\<Plug>(nohlsearch)", 'm')
|
||||
au InsertEnter * call feedkeys("\<Plug>(nohlsearch)", 'm')
|
||||
augroup END
|
||||
104
gitportable/usr/share/vim/vim91/pack/dist/opt/shellmenu/plugin/shellmenu.vim
vendored
Normal file
104
gitportable/usr/share/vim/vim91/pack/dist/opt/shellmenu/plugin/shellmenu.vim
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
" 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.
|
||||
"
|
||||
" Maintainer: Ada (Haowen) Yu <me@yuhaowen.com>
|
||||
" Original author: Lennart Schultz <les@dmi.min.dk> (mail unreachable)
|
||||
|
||||
" Make sure the '<' and 'C' flags are not included in 'cpoptions', otherwise
|
||||
" <CR> would not be recognized. See ":help 'cpoptions'".
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
imenu ShellMenu.Statements.for for in <CR>do<CR><CR>done<esc>ki <esc>kk0elli
|
||||
imenu ShellMenu.Statements.case case in<CR>) ;;<CR>esac<esc>bki <esc>k0elli
|
||||
imenu ShellMenu.Statements.if if <CR>then<CR><CR>fi<esc>ki <esc>kk0elli
|
||||
imenu ShellMenu.Statements.if-else if <CR>then<CR><CR>else<CR><CR>fi<esc>ki <esc>kki <esc>kk0elli
|
||||
imenu ShellMenu.Statements.elif elif <CR>then<CR><CR><esc>ki <esc>kk0elli
|
||||
imenu ShellMenu.Statements.while while do<CR><CR>done<esc>ki <esc>kk0elli
|
||||
imenu ShellMenu.Statements.break break
|
||||
imenu ShellMenu.Statements.continue continue
|
||||
imenu ShellMenu.Statements.function () {<CR><CR>}<esc>ki <esc>k0i
|
||||
imenu ShellMenu.Statements.return return
|
||||
imenu ShellMenu.Statements.return-true return 0
|
||||
imenu ShellMenu.Statements.return-false return 1
|
||||
imenu ShellMenu.Statements.exit exit
|
||||
imenu ShellMenu.Statements.shift shift
|
||||
imenu ShellMenu.Statements.trap trap
|
||||
imenu ShellMenu.Test.Existence [ -e ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ file [ -f ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ file\ (not\ empty) [ -s ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ directory [ -d ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ executable [ -x ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ readable [ -r ]<esc>hi
|
||||
imenu ShellMenu.Test.Existence\ -\ writable [ -w ]<esc>hi
|
||||
imenu ShellMenu.Test.String\ is\ empty [ x = "x$" ]<esc>hhi
|
||||
imenu ShellMenu.Test.String\ is\ not\ empty [ x != "x$" ]<esc>hhi
|
||||
imenu ShellMenu.Test.Strings\ are\ equal [ "" = "" ]<esc>hhhhhhhi
|
||||
imenu ShellMenu.Test.Strings\ are\ not\ equal [ "" != "" ]<esc>hhhhhhhhi
|
||||
imenu ShellMenu.Test.Value\ is\ greater\ than [ -gt ]<esc>hhhhhhi
|
||||
imenu ShellMenu.Test.Value\ is\ greater\ equal [ -ge ]<esc>hhhhhhi
|
||||
imenu ShellMenu.Test.Values\ are\ equal [ -eq ]<esc>hhhhhhi
|
||||
imenu ShellMenu.Test.Values\ are\ not\ equal [ -ne ]<esc>hhhhhhi
|
||||
imenu ShellMenu.Test.Value\ is\ less\ than [ -lt ]<esc>hhhhhhi
|
||||
imenu ShellMenu.Test.Value\ is\ less\ equal [ -le ]<esc>hhhhhhi
|
||||
imenu ShellMenu.ParmSub.Substitute\ word\ if\ parm\ not\ set ${:-}<esc>hhi
|
||||
imenu ShellMenu.ParmSub.Set\ parm\ to\ word\ if\ not\ set ${:=}<esc>hhi
|
||||
imenu ShellMenu.ParmSub.Substitute\ word\ if\ parm\ set\ else\ nothing ${:+}<esc>hhi
|
||||
imenu ShellMenu.ParmSub.If\ parm\ not\ set\ print\ word\ and\ exit ${:?}<esc>hhi
|
||||
imenu ShellMenu.SpShVars.Number\ of\ positional\ parameters ${#}
|
||||
imenu ShellMenu.SpShVars.All\ positional\ parameters\ (quoted\ spaces) ${*}
|
||||
imenu ShellMenu.SpShVars.All\ positional\ parameters\ (unquoted\ spaces) ${@}
|
||||
imenu ShellMenu.SpShVars.Flags\ set ${-}
|
||||
imenu ShellMenu.SpShVars.Return\ code\ of\ last\ command ${?}
|
||||
imenu ShellMenu.SpShVars.Process\ number\ of\ this\ shell ${$}
|
||||
imenu ShellMenu.SpShVars.Process\ number\ of\ last\ background\ command ${!}
|
||||
imenu ShellMenu.Environ.HOME ${HOME}
|
||||
imenu ShellMenu.Environ.PATH ${PATH}
|
||||
imenu ShellMenu.Environ.CDPATH ${CDPATH}
|
||||
imenu ShellMenu.Environ.MAIL ${MAIL}
|
||||
imenu ShellMenu.Environ.MAILCHECK ${MAILCHECK}
|
||||
imenu ShellMenu.Environ.PS1 ${PS1}
|
||||
imenu ShellMenu.Environ.PS2 ${PS2}
|
||||
imenu ShellMenu.Environ.IFS ${IFS}
|
||||
imenu ShellMenu.Environ.SHACCT ${SHACCT}
|
||||
imenu ShellMenu.Environ.SHELL ${SHELL}
|
||||
imenu ShellMenu.Environ.LC_CTYPE ${LC_CTYPE}
|
||||
imenu ShellMenu.Environ.LC_MESSAGES ${LC_MESSAGES}
|
||||
imenu ShellMenu.Builtins.cd cd
|
||||
imenu ShellMenu.Builtins.echo echo
|
||||
imenu ShellMenu.Builtins.eval eval
|
||||
imenu ShellMenu.Builtins.exec exec
|
||||
imenu ShellMenu.Builtins.export export
|
||||
imenu ShellMenu.Builtins.getopts getopts
|
||||
imenu ShellMenu.Builtins.hash hash
|
||||
imenu ShellMenu.Builtins.newgrp newgrp
|
||||
imenu ShellMenu.Builtins.pwd pwd
|
||||
imenu ShellMenu.Builtins.read read
|
||||
imenu ShellMenu.Builtins.readonly readonly
|
||||
imenu ShellMenu.Builtins.return return
|
||||
imenu ShellMenu.Builtins.times times
|
||||
imenu ShellMenu.Builtins.type type
|
||||
imenu ShellMenu.Builtins.umask umask
|
||||
imenu ShellMenu.Builtins.wait wait
|
||||
imenu ShellMenu.Set.set set
|
||||
imenu ShellMenu.Set.unset unset
|
||||
imenu ShellMenu.Set.Mark\ created\ or\ modified\ variables\ for\ export set -a
|
||||
imenu ShellMenu.Set.Exit\ when\ command\ returns\ non-zero\ status set -e
|
||||
imenu ShellMenu.Set.Disable\ file\ name\ expansion set -f
|
||||
imenu ShellMenu.Set.Locate\ and\ remember\ commands\ when\ being\ looked\ up set -h
|
||||
imenu ShellMenu.Set.All\ assignment\ statements\ are\ placed\ in\ the\ environment\ for\ a\ command set -k
|
||||
imenu ShellMenu.Set.Read\ commands\ but\ do\ not\ execute\ them set -n
|
||||
imenu ShellMenu.Set.Exit\ after\ reading\ and\ executing\ one\ command set -t
|
||||
imenu ShellMenu.Set.Treat\ unset\ variables\ as\ an\ error\ when\ substituting set -u
|
||||
imenu ShellMenu.Set.Print\ shell\ input\ lines\ as\ they\ are\ read set -v
|
||||
imenu ShellMenu.Set.Print\ commands\ and\ their\ arguments\ as\ they\ are\ executed set -x
|
||||
|
||||
" Restore the previous value of 'cpoptions'.
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
22
gitportable/usr/share/vim/vim91/pack/dist/opt/swapmouse/plugin/swapmouse.vim
vendored
Normal file
22
gitportable/usr/share/vim/vim91/pack/dist/opt/swapmouse/plugin/swapmouse.vim
vendored
Normal 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>
|
||||
2085
gitportable/usr/share/vim/vim91/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
Normal file
2085
gitportable/usr/share/vim/vim91/pack/dist/opt/termdebug/plugin/termdebug.vim
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user