From: martin f. krafft Date: Sun, 24 Feb 2019 21:33:08 +0000 (+0100) Subject: Add '.vim/bundle/explainpat/' from commit '8b7939ff867684ca9e31f1f0022fb91bbbdf152d' X-Git-Url: https://git.madduck.net/etc/vim.git/commitdiff_plain/34997613f623002a61f0d058789dfeabbbc0174b?ds=sidebyside;hp=-c;pf=etc Add '.vim/bundle/explainpat/' from commit '8b7939ff867684ca9e31f1f0022fb91bbbdf152d' git-subtree-dir: .vim/bundle/explainpat git-subtree-mainline: 8a97a4231254ab25e017fecd10ba2068bd588e52 git-subtree-split: 8b7939ff867684ca9e31f1f0022fb91bbbdf152d --- 34997613f623002a61f0d058789dfeabbbc0174b diff --combined .vim/bundle/explainpat/.gitignore index 0000000,926ccaa..926ccaa mode 000000,100644..100644 --- a/.vim/bundle/explainpat/.gitignore +++ b/.vim/bundle/explainpat/.gitignore @@@ -1,0 -1,1 +1,1 @@@ + doc/tags diff --combined .vim/bundle/explainpat/README index 0000000,65cba88..65cba88 mode 000000,100644..100644 --- a/.vim/bundle/explainpat/README +++ b/.vim/bundle/explainpat/README @@@ -1,0 -1,48 +1,48 @@@ + This is a mirror of http://www.vim.org/scripts/script.php?script_id=4364 + + :ExplainPattern {pattern} or + :ExplainPattern {register} + + parse the given Vim {pattern} and print a line of help + (with color) for each found pattern item. Nested + items get extra indent. + + A single-char argument is used as {register} argument: + / explain the last search pattern + * explain pattern from the clipboard + a explain pattern from register a + + + Example: :ExplainPattern * + + Register: * + Pattern: \C^\%(\\\%(@<.\|%[dxouU[(^$V#<>]\=\|z[1-9se(]\|@[>=!]\|_[[^$.]\=\|.\)\|.\) + \C match case while matching the pattern + ^ match at start of line (or string) + \%( start of non-capturing group + | \\ literal string (1 atom(s)) + | \%( start of non-capturing group + | | @< literal string (2 atom(s)) + | | . match any character + | | \| OR branch + | | % literal string (1 atom(s)) + | | [dxouU[(^$V#<>] collection + | | \= (multi) zero or one of the preceding atom + | | \| OR branch + | | z literal string (1 atom(s)) + | | [1-9se(] collection + | | \| OR branch + | | @ literal string (1 atom(s)) + | | [>=!] collection + | | \| OR branch + | | _ literal string (1 atom(s)) + | | [[^$.] collection + | | \= (multi) zero or one of the preceding atom + | | \| OR branch + | | . match any character + | \) end of group + | \| OR branch + | . match any character + \) end of group + + 2013 Jan 17 diff --combined .vim/bundle/explainpat/autoload/explainpat.vim index 0000000,0fded10..0fded10 mode 000000,100644..100644 --- a/.vim/bundle/explainpat/autoload/explainpat.vim +++ b/.vim/bundle/explainpat/autoload/explainpat.vim @@@ -1,0 -1,609 +1,609 @@@ + " File: explainpat.vim + " Created: 2011 Nov 02 + " Last Change: 2017 Dec 15 + " Version: 0.9 + " Author: Andy Wokula + " License: Vim License, see :h license + + " Implements :ExplainPattern [pattern] + + " History: "{{{ + " 2013 Jun 21 AND/OR text is confusing, removed + " 2013 Apr 20 ... + "}}} + + " TODO {{{ + " - add something like "(empty) ... match everywhere" ... example: '\v(&&|str)' + " Pattern: \v(&&|str) + " Magic Pattern: \(\&\&\|str\) + " \( start of first capturing group + " | (empty) match everywhere + " | \& AND + " | (empty) match everywhere + " | \& AND + " | (empty) match everywhere + " | \| OR + " | str literal string (3 atom(s)) + " \) end of group + " - more testing, completeness check + " ? detailed collections + " ? literal string: also print the unescaped magic items + " ? literal string: show leading/trailing spaces + " + "}}} + + " Init Folklore {{{ + let s:cpo_save = &cpo + set cpo&vim + let g:explainpat#loaded = 1 + "}}} + + func! explainpat#ExplainPattern(cmd_arg, ...) "{{{ + " {a:1} alternative help printer object (caution, no sanity check) + " (for test running) + if a:cmd_arg == "" + " let pattern_str = nwo#vis#Get() + echo "(usage) :ExplainPattern [{register} | {pattern}]" + return + elseif strlen(a:cmd_arg) == 1 && a:cmd_arg =~ '["@0-9a-z\-:.*+/]' + echo 'Register:' a:cmd_arg + let pattern_str = getreg(a:cmd_arg) + else + let pattern_str = a:cmd_arg + endif + + echo printf('Pattern: %s', pattern_str) + let magicpat = nwo#magic#MakeMagic(pattern_str) + if magicpat !=# pattern_str + echo printf('Magic Pattern: %s', magicpat) + endif + + " we need state: + " set flag when in `\%[ ... ]' (optionally matched atoms): + let s:in_opt_atoms = 0 + " counter for `\(': + let s:capture_group_nr = 0 + " >=1 at pos 0 or after '\|', '\&', '\(', '\%(' or '\n'; else 0 or less: + let s:at_begin_of_pat = 1 + + let hulit = a:0>=1 && type(a:1)==s:DICT ? a:1 : explainpat#NewHelpPrinter() + call hulit.AddIndent(' ') + let bull = s:NewTokenBiter(magicpat) + while !bull.AtEnd() + let item = bull.Bite(s:magic_item_pattern) + if item != '' + let Doc = get(s:doc, item, '') + if empty(Doc) + call hulit.AddLiteral(item) + elseif type(Doc) == s:STRING + call hulit.Print(item, Doc) + elseif type(Doc) == s:FUNCREF + call call(Doc, [bull, hulit, item]) + elseif type(Doc) == s:LIST + call call(Doc[0], [bull, hulit, item, Doc[1]]) + endif + let s:at_begin_of_pat -= 1 + else + echoerr printf('ExplainPattern: cannot parse "%s"', bull.Rest()) + break + endif + unlet Doc + endwhile + call hulit.FlushLiterals() + endfunc "}}} + + " s: types {{{ + let s:STRING = type("") + let s:DICT = type({}) + let s:FUNCREF = type(function("tr")) + let s:LIST = type([]) + " }}} + + let s:magic_item_pattern = '\C^\%(\\\%(%#=\|%[dxouU[(^$V#<>]\=\|z[1-9se(]\|@[>=!]\=\|_[[^$.]\=\|.\)\|.\)' + + let s:doc = {} " {{{ + " this is all the help data ... + " strings, funcrefs and intermixed s:DocFoo() functions + " strongly depends on s:magic_item_pattern + + func! s:DocOrBranch(bull, hulit, item) "{{{ + call a:hulit.RemIndent() + call a:hulit.Print(a:item, "OR") + call a:hulit.AddIndent(' ') + let s:at_begin_of_pat = 2 + endfunc "}}} + + let s:doc['\|'] = function("s:DocOrBranch") + + func! s:DocBeginOfPat(bull, hulit, item, msg) "{{{ + call a:hulit.Print(a:item, a:msg) + let s:at_begin_of_pat = 2 + endfunc "}}} + + let s:doc['\&'] = [function("s:DocBeginOfPat"), "AND"] + + let s:ord = split('n first second third fourth fifth sixth seventh eighth ninth') + + func! s:DocGroupStart(bull, hulit, item) "{{{ + if a:item == '\%(' + call a:hulit.Print(a:item, "start of non-capturing group") + elseif a:item == '\(' + let s:capture_group_nr += 1 + call a:hulit.Print(a:item, printf("start of %s capturing group", get(s:ord, s:capture_group_nr, '(invalid)'))) + else " a:item == '\z(' + call a:hulit.Print(a:item, 'start of "external" group (only usable in :syn-region)') + endif + call a:hulit.AddIndent('| ', ' ') + let s:at_begin_of_pat = 2 + endfunc "}}} + func! s:DocGroupEnd(bull, hulit, item) "{{{ + call a:hulit.RemIndent(2) + call a:hulit.Print(a:item, "end of group") + endfunc "}}} + + let s:doc['\('] = function("s:DocGroupStart") + let s:doc['\%('] = function("s:DocGroupStart") + let s:doc['\)'] = function("s:DocGroupEnd") + " let s:doc['\z('] = "only in syntax scripts" + let s:doc['\z('] = function("s:DocGroupStart") + + func! s:DocStar(bull, hulit, item) "{{{ + if s:at_begin_of_pat >= 1 + " call a:hulit.Print(a:item, "(at begin of pattern) literal `*'") + call a:hulit.AddLiteral(a:item) + else + call a:hulit.Print(a:item, "(multi) zero or more of the preceding atom") + endif + endfunc "}}} + + " let s:doc['*'] = "(multi) zero or more of the preceding atom" + let s:doc['*'] = function("s:DocStar") + + let s:doc['\+'] = "(multi) one or more of the preceding atom" + let s:doc['\='] = "(multi) zero or one of the preceding atom" + let s:doc['\?'] = "(multi) zero or one of the preceding atom" + " let s:doc['\{'] = "(multi) N to M, greedy" + " let s:doc['\{-'] = "(multi) N to M, non-greedy" + + func! s:DocBraceMulti(bull, hulit, item) "{{{ + let rest = a:bull.Bite('^-\=\d*\%(,\d*\)\=\\\=}') + if rest != "" + if rest == '-}' + call a:hulit.Print(a:item. rest, "non-greedy version of `*'") + elseif rest =~ '^-' + call a:hulit.Print(a:item. rest, "(multi) N to M, non-greedy") + else + call a:hulit.Print(a:item. rest, "(multi) N to M, greedy") + endif + else + call a:hulit.Print(a:item, "(invalid) incomplete `\\{...}' item") + endif + endfunc "}}} + + let s:doc['\{'] = function("s:DocBraceMulti") + + let s:doc['\@>'] = "(multi) match preceding atom like a full pattern" + let s:doc['\@='] = "(assertion) require match for preceding atom" + let s:doc['\@!'] = "(assertion) forbid match for preceding atom" + + func! s:DocBefore(bull, hulit, item) "{{{ + let rest = a:bull.Bite('^\d*\%[<[=!]]') + if rest == "<=" + call a:hulit.Print(a:item.rest, "(assertion) require match for preceding atom to the left") + elseif rest == "= 1 + call a:hulit.Print(a:item, "(assertion) require match at start of line") + " after `^' is not at begin of pattern ... handle special case `^*' here: + if a:bull.Bite('^\*') == "*" + call a:hulit.AddLiteral("*") + endif + else + " call a:hulit.Print(a:item, "(not at begin of pattern) literal `^'") + call a:hulit.AddLiteral(a:item) + endif + endfunc "}}} + + " let s:doc['^'] = "(assertion) require match at start of line" + let s:doc['^'] = function("s:DocCircumFlex") + + let s:doc['\_^'] = "(assertion) like `^', allowed anywhere in the pattern" + + func! s:DocDollar(bull, hulit, item) "{{{ + if a:bull.Rest() =~ '^$\|^\\[&|)n]' + call a:hulit.Print(a:item, "(assertion) require match at end of line") + else + call a:hulit.AddLiteral(a:item) + endif + endfunc "}}} + + " let s:doc['$'] = "(assertion) require match at end of line" + let s:doc['$'] = function("s:DocDollar") + + let s:doc['\_$'] = "(assertion) like `$', allowed anywhere in the pattern" + let s:doc['.'] = "match any character" + let s:doc['\_.'] = "match any character or newline" + + func! s:DocUnderscore(bull, hulit, item) "{{{ + let cclass = a:bull.Bite('^\a') + if cclass != '' + let cclass_doc = get(s:doc, '\'. cclass, '(invalid character class)') + call a:hulit.Print(a:item. cclass, printf('%s or end-of-line', cclass_doc)) + else + call a:hulit.Print(a:item, "(invalid) `\\_' should be followed by a letter or `[...]'") + " echoerr printf('ExplainPattern: cannot parse %s', a:item. matchstr(a:bull.Rest(), '.')) + endif + endfunc "}}} + + let s:doc['\_'] = function("s:DocUnderscore") + let s:doc['\<'] = "(assertion) require match at begin of word, :h word" + let s:doc['\>'] = "(assertion) require match at end of word, :h word" + let s:doc['\zs'] = "set begin of match here" + let s:doc['\ze'] = "set end of match here" + let s:doc['\%^'] = "(assertion) match at begin of buffer" + let s:doc['\%$'] = "(assertion) match at end of buffer" + let s:doc['\%V'] = "(assertion) match within the Visual area" + let s:doc['\%#'] = "(assertion) match with cursor position" + + func! s:DocRegexEngine(bull, hulit, item) "{{{ + let engine = a:bull.Bite('^[012]') + if engine == "0" + call a:hulit.Print(a:item.engine, 'Force automatic selection of the regexp engine (since v7.3.970).') + elseif engine == "1" + call a:hulit.Print(a:item.engine, 'Force using the old engine (since v7.3.970).') + elseif engine == "2" + call a:hulit.Print(a:item.engine, 'Force using the NFA engine (since v7.3.970).') + else + call a:hulit.Print(a:item, '(invalid) \%#= can only be followed by 0, 1, or 2') + endif + endfunc "}}} + + let s:doc['\%#='] = function("s:DocRegexEngine") + + " \%'m \%<'m \%>'m + " \%23l \%<23l \%>23l + " \%23c \%<23c \%>23c + " \%23v \%<23v \%>23v + " backslash percent at/before/after + func! s:DocBspercAt(bull, hulit, item) "{{{ + let rest = a:bull.Bite('^\%(''.\|\d\+[lvc]\)\C') + if rest[0] == "'" + call a:hulit.Print(a:item.rest, "(assertion) match with position of mark ". rest[1]) + else + let number = rest[:-2] + let type = rest[-1:] + if type ==# "l" + call a:hulit.Print(a:item.rest, "match in line ". number) + elseif type ==# "c" + call a:hulit.Print(a:item.rest, "match in column ". number) + elseif type ==# "v" + call a:hulit.Print(a:item.rest, "match in virtual column ". number) + else + call a:hulit.Print(a:item.rest, "(invalid) incomplete `\\%' item") + " echoerr printf('ExplainPattern: incomplete item %s', a:item. rest) + endif + endif + endfunc "}}} + func! s:DocBspercBefore(bull, hulit, item) "{{{ + let rest = a:bull.Bite('^\%(''.\|\d\+[lvc]\)\C') + if rest[0] == "'" + call a:hulit.Print(a:item.rest, "(assertion) match before position of mark ". rest[1]) + else + let number = rest[:-2] + let type = rest[-1:] + if type ==# "l" + call a:hulit.Print(a:item.rest, printf("match above line %d (towards start of buffer)", number)) + elseif type ==# "c" + call a:hulit.Print(a:item.rest, "match before column ". number) + elseif type ==# "v" + call a:hulit.Print(a:item.rest, "match before virtual column ". number) + else + call a:hulit.Print(a:item.rest, "(invalid) incomplete `\\%<' item") + " echoerr printf('ExplainPattern: incomplete item %s', a:item. rest) + endif + endif + endfunc "}}} + func! s:DocBspercAfter(bull, hulit, item) "{{{ + let rest = a:bull.Bite('^\%(''.\|\d\+[lvc]\)\C') + if rest[0] == "'" + call a:hulit.Print(a:item.rest, "(assertion) match after position of mark ". rest[1]) + else + let number = rest[:-2] + let type = rest[-1:] + if type ==# "l" + call a:hulit.Print(a:item.rest, printf("match below line %d (towards end of buffer)", number)) + elseif type ==# "c" + call a:hulit.Print(a:item.rest, "match after column ". number) + elseif type ==# "v" + call a:hulit.Print(a:item.rest, "match after virtual column ". number) + else + call a:hulit.Print(a:item.rest, "(invalid) incomplete `\\%>' item") + " echoerr printf('ExplainPattern: incomplete item %s', a:item. rest) + endif + endif + endfunc "}}} + + let s:doc['\%'] = function("s:DocBspercAt") + let s:doc['\%<'] = function("s:DocBspercBefore") + let s:doc['\%>'] = function("s:DocBspercAfter") + + let s:doc['\i'] = "identifier character (see 'isident' option)" + let s:doc['\I'] = "like \"\\i\", but excluding digits" + let s:doc['\k'] = "keyword character (see 'iskeyword' option)" + let s:doc['\K'] = "like \"\\k\", but excluding digits" + let s:doc['\f'] = "file name character (see 'isfname' option)" + let s:doc['\F'] = "like \"\\f\", but excluding digits" + let s:doc['\p'] = "printable character (see 'isprint' option)" + let s:doc['\P'] = "like \"\\p\", but excluding digits" + let s:doc['\s'] = "whitespace character: and " + let s:doc['\S'] = "non-whitespace character; opposite of \\s" + let s:doc['\d'] = "digit: [0-9]" + let s:doc['\D'] = "non-digit: [^0-9]" + let s:doc['\x'] = "hex digit: [0-9A-Fa-f]" + let s:doc['\X'] = "non-hex digit: [^0-9A-Fa-f]" + let s:doc['\o'] = "octal digit: [0-7]" + let s:doc['\O'] = "non-octal digit: [^0-7]" + let s:doc['\w'] = "word character: [0-9A-Za-z_]" + let s:doc['\W'] = "non-word character: [^0-9A-Za-z_]" + let s:doc['\h'] = "head of word character: [A-Za-z_]" + let s:doc['\H'] = "non-head of word character: [^A-Za-z_]" + let s:doc['\a'] = "alphabetic character: [A-Za-z]" + let s:doc['\A'] = "non-alphabetic character: [^A-Za-z]" + let s:doc['\l'] = "lowercase character: [a-z]" + let s:doc['\L'] = "non-lowercase character: [^a-z]" + let s:doc['\u'] = "uppercase character: [A-Z]" + let s:doc['\U'] = "non-uppercase character: [^A-Z]" + + let s:doc['\e'] = "match " + let s:doc['\t'] = "match " + let s:doc['\r'] = "match " + let s:doc['\b'] = "match CTRL-H" + let s:doc['\n'] = [function("s:DocBeginOfPat"), "match a newline"] + let s:doc['~'] = "match the last given substitute string" + let s:doc['\1'] = "match first captured string" + let s:doc['\2'] = "match second captured string" + let s:doc['\3'] = "match third captured string" + let s:doc['\4'] = "match fourth captured string " + let s:doc['\5'] = "match fifth captured string" + let s:doc['\6'] = "match sixth captured string" + let s:doc['\7'] = "match seventh captured string" + let s:doc['\8'] = "match eighth captured string" + let s:doc['\9'] = "match ninth captured string" + + let s:doc['\z1'] = 'match same string matched by first "external" group' + let s:doc['\z2'] = 'match same string matched by second "external" group' + let s:doc['\z3'] = 'match same string matched by third "external" group' + let s:doc['\z4'] = 'match same string matched by fourth "external" group ' + let s:doc['\z5'] = 'match same string matched by fifth "external" group' + let s:doc['\z6'] = 'match same string matched by sixth "external" group' + let s:doc['\z7'] = 'match same string matched by seventh "external" group' + let s:doc['\z8'] = 'match same string matched by eighth "external" group' + let s:doc['\z9'] = 'match same string matched by ninth "external" group' + + " from MakeMagic() + " skip the rest of a collection + let s:coll_skip_pat = '^\^\=]\=\%(\%(\\[\^\]\-\\bertn]\|\[:\w\+:]\|\[=.=]\|\[\..\.]\|[^\]]\)\@>\)*]' + + func! s:DocCollection(bull, hulit, item) "{{{ + let collstr = a:bull.Bite(s:coll_skip_pat) + if collstr == "" || collstr == "]" + call a:hulit.AddLiteral('['. collstr) + else + let inverse = collstr =~ '^\^' + let with_nl = a:item == '\_[' + let descr = inverse ? printf('collection not matching [%s', collstr[1:]) : 'collection' + let descr_nl = printf("%s%s", (inverse && with_nl ? ', but' : ''), (with_nl ? ' with end-of-line added' : '')) + call a:hulit.Print(a:item. collstr, descr. descr_nl) + endif + endfunc "}}} + + let s:doc['['] = function("s:DocCollection") + let s:doc['\_['] = function("s:DocCollection") + + func! s:DocOptAtoms(bull, hulit, item) "{{{ + if a:item == '\%[' + call a:hulit.Print(a:item, "start a sequence of optionally matched atoms") + let s:in_opt_atoms = 1 + call a:hulit.AddIndent('. ') + else " a:item == ']' + if s:in_opt_atoms + call a:hulit.RemIndent() + call a:hulit.Print(a:item, "end of optionally matched atoms") + let s:in_opt_atoms = 0 + else + call a:hulit.AddLiteral(a:item) + endif + endif + endfunc "}}} + + " let s:doc['\%['] = "start a sequence of optionally matched atoms" + let s:doc['\%['] = function("s:DocOptAtoms") + let s:doc[']'] = function("s:DocOptAtoms") + + func! s:DocAnywhere(bull, hulit, item, msg) "{{{ + call a:hulit.Print(a:item, a:msg) + " keep state: + let s:at_begin_of_pat += 1 + endfunc "}}} + + let s:doc['\c'] = [function("s:DocAnywhere"), "ignore case while matching the pattern"] + let s:doc['\C'] = [function("s:DocAnywhere"), "match case while matching the pattern"] + let s:doc['\Z'] = [function("s:DocAnywhere"), "ignore composing characters in the pattern"] + + " \%d 123 + " \%x 2a + " \%o 0377 + " \%u 20AC + " \%U 1234abcd + + func! s:DocBspercDecimal(bull, hulit, item) "{{{ + let number = a:bull.Bite('^\d\{,3}') + let char = strtrans(nr2char(str2nr(number))) + call a:hulit.Print(a:item. number, printf("match character specified by decimal number %s (%s)", number, char)) + endfunc "}}} + func! s:DocBspercHexTwo(bull, hulit, item) "{{{ + let number = a:bull.Bite('^\x\{,2}') + let char = strtrans(nr2char(str2nr(number,16))) + call a:hulit.Print(a:item. number, printf("match character specified with hex number 0x%s (%s)", number, char)) + endfunc "}}} + func! s:DocBspercOctal(bull, hulit, item) "{{{ + let number = a:bull.Bite('^\o\{,4}') + let char = strtrans(nr2char(str2nr(number,8))) + call a:hulit.Print(a:item. number, printf("match character specified with octal number 0%s (%s)", substitute(number, '^0*', '', ''), char)) + endfunc "}}} + func! s:DocBspercHexFour(bull, hulit, item) "{{{ + let number = a:bull.Bite('^\x\{,4}') + let char = has("multi_byte_encoding") ? ' ('. strtrans(nr2char(str2nr(number,16))).')' : '' + call a:hulit.Print(a:item. number, printf("match character specified with hex number 0x%s%s", number, char)) + endfunc "}}} + func! s:DocBspercHexEight(bull, hulit, item) "{{{ + let number = a:bull.Bite('^\x\{,8}') + let char = has("multi_byte_encoding") ? ' ('. strtrans(nr2char(str2nr(number,16))).')' : '' + call a:hulit.Print(a:item. number, printf("match character specified with hex number 0x%s%s", number, char)) + endfunc "}}} + + let s:doc['\%d'] = function("s:DocBspercDecimal") " 123 + let s:doc['\%x'] = function("s:DocBspercHexTwo") " 2a + let s:doc['\%o'] = function("s:DocBspercOctal") " 0377 + let s:doc['\%u'] = function("s:DocBspercHexFour") " 20AC + let s:doc['\%U'] = function("s:DocBspercHexEight") " 1234abcd + + " \m + " \M + " \v + " \V + "}}} + + " {{{ + func! s:SillyCheck(digits) "{{{ + return strlen(a:digits) < 10 ? a:digits : '{silly large number}' + endfunc "}}} + " }}} + + func! explainpat#NewHelpPrinter() "{{{ + let obj = {} + let obj.literals = '' + let obj.indents = [] + let obj.len = 0 " can be negative (!) + + func! obj.Print(str, ...) "{{{ + call self.FlushLiterals() + let indstr = join(self.indents, '') + echohl Comment + echo indstr + echohl None + if a:0 == 0 + echon a:str + else + " echo indstr. printf("`%s' %s", a:str, a:1) + echohl PreProc + echon printf("%-10s", a:str) + echohl None + echohl Comment + echon printf(" %s", a:1) + echohl None + endif + endfunc "}}} + + func! obj.AddLiteral(item) "{{{ + let self.literals .= a:item + endfunc "}}} + + func! obj.FlushLiterals() "{{{ + if self.literals == '' + return + endif + let indstr = join(self.indents, '') + echohl Comment + echo indstr + echohl None + if self.literals =~ '^\s\|\s$' + echon printf("%-10s", '"'. self.literals. '"') + else + echon printf("%-10s", self.literals) + endif + echohl Comment + echon " literal string" + if exists("*strchars") + if self.literals =~ '\\' + let self.literals = substitute(self.literals, '\\\(.\)', '\1', 'g') + endif + let spconly = self.literals =~ '[^ ]' ? '' : ', spaces only' + let nlit = strchars(self.literals) + echon " (". nlit. (nlit==1 ? " atom" : " atoms"). spconly.")" + endif + echohl None + let self.literals = '' + endfunc "}}} + + func! obj.AddIndent(...) "{{{ + call self.FlushLiterals() + if self.len >= 0 + call extend(self.indents, copy(a:000)) + elseif self.len + a:0 >= 1 + call extend(self.indents, a:000[-(self.len+a:0):]) + endif + let self.len += a:0 + endfunc "}}} + + func! obj.RemIndent(...) "{{{ + call self.FlushLiterals() + if a:0 == 0 + if self.len >= 1 + call remove(self.indents, -1) + endif + let self.len -= 1 + else + if self.len > a:1 + call remove(self.indents, -a:1, -1) + elseif self.len >= 1 + call remove(self.indents, 0, -1) + endif + let self.len -= a:1 + endif + endfunc "}}} + + return obj + endfunc "}}} + + func! s:NewTokenBiter(str) "{{{ + " {str} string to eat pieces from + let obj = {'str': a:str} + + " consume piece from start of input matching {pat} + func! obj.Bite(pat) "{{{ + " {pat} should start with '^' + let bite = matchstr(self.str, a:pat) + let self.str = strpart(self.str, strlen(bite)) + return bite + endfunc "}}} + + " get the unparsed rest of input (not consuming) + func! obj.Rest() "{{{ + return self.str + endfunc "}}} + + " check if end of input reached + func! obj.AtEnd() "{{{ + return self.str == "" + endfunc "}}} + + return obj + endfunc "}}} + + " Modeline: {{{1 + let &cpo = s:cpo_save + unlet s:cpo_save + " vim:ts=8:fdm=marker: diff --combined .vim/bundle/explainpat/autoload/nwo/magic.vim index 0000000,557af82..557af82 mode 000000,100644..100644 --- a/.vim/bundle/explainpat/autoload/nwo/magic.vim +++ b/.vim/bundle/explainpat/autoload/nwo/magic.vim @@@ -1,0 -1,169 +1,169 @@@ + " File: makemagic.vim + " Created: 2011 Apr 18 + " Last Change: 2013 Mar 06 + " Rev Days: 6 + " Author: Andy Wokula + " License: Vim License, see :h license + " Version: 0.3 + + "" Comments {{{ + + " nwo#magic#MakeMagic({pat}) + " + " remove embedded switches (\v, \m, \M and \V) from pattern {pat} by + " converting {pat} into a purely magic pattern. Return the converted + " pattern. + " + + " TODO + " - recognize [#-\\]], with spaces: [ #-\ \] ] + " (collection ends at second ']') + " + \v\z( => \z( + + " 2011 Nov 01 copied from asneeded\makemagic.vim + " now asneeded\nwo\makemagic.vim (comments there!) + "}}} + + " Init Folklore {{{ + let s:cpo_save = &cpo + set cpo&vim + let g:nwo#magic#loaded = 1 + "}}} + + func! nwo#magic#MakeMagic(pat, ...) "{{{ + " {pat} (string) + " {a:1} (boolean) initial magic mode (default follows the 'magic' option) + + if a:0>=1 ? a:1 : &magic + let magic_mode = 'm' + let bracket_is_magic = 1 + else + let magic_mode = 'M' + let bracket_is_magic = 0 + endif + let result_pat = '' + let endpos = strlen(a:pat) + + let spos = 0 + while spos >= 0 && spos < endpos + let mc1 = a:pat[spos] + let mc2 = a:pat[spos+1] + + let collection = 0 + if mc1 == '\' + if mc2 == '[' && !bracket_is_magic + let collection = 1 + let spos += 1 + elseif mc2 =~ '[vmMV]' + let magic_mode = mc2 + let bracket_is_magic = mc2 =~# '[vm]' + let spos += 2 + elseif mc2 == '_' + let mc3 = a:pat[spos+2] + if mc3 == '[' + let collection = 1 + endif + endif + elseif mc1 == '[' && bracket_is_magic + let collection = 1 + endif + + if collection + let nextpos = matchend(a:pat, s:collection_skip_pat, spos) + if nextpos >= 0 + let magpart = strpart(a:pat, spos, nextpos-spos) + else + let magpart = strpart(a:pat, spos) + endif + else + let nextpos = match(a:pat, s:switchpat[magic_mode], spos) + if nextpos >= 0 + if nextpos == spos + continue " optional + endif + let part = strpart(a:pat, spos, nextpos-spos) + else + let part = strpart(a:pat, spos) + endif + if magic_mode ==# 'v' + let magpart = substitute(part, s:vmagic_items_pat, '\=s:ToggleVmagicBslash(submatch(0))', 'g') + elseif magic_mode ==# 'm' + let magpart = part + elseif magic_mode ==# 'M' + let s:rem_bslash_before = '.*[~' + " the first two branches are only to eat the matches: + let magpart = substitute(part, '\\%\[\|\\_\\\=.\|\\.\|[.*[~]', '\=s:ToggleBslash(submatch(0))', 'g') + elseif magic_mode ==# 'V' + let s:rem_bslash_before = '^$.*[~' + let magpart = substitute(part, '\\%\[\|\\_\\\=.\|\\.\|[\^$.*[~]', '\=s:ToggleBslash(submatch(0))', 'g') + endif + endif + + let result_pat .= magpart + let spos = nextpos + endwhile + + return result_pat + endfunc "}}} + + " s:variables {{{ + + " pattern to match very magic items: + let s:vmagic_items_pat = '\C\\\%(z(\|.\)\|%\%([#$(UV[\^cdlouvx]\|[<>]\=\%(''.\|\d\+[clv]\)\)\|[&()+<=>?|]\|@\%([!=>]\|<[!=]\)\|{' + + " not escaped - require an even number of '\' (zero or more) to the left: + let s:not_escaped = '\%(\%(^\|[^\\]\)\%(\\\\\)*\)\@<=' + + " prohibit an unescaped match for '%' before what follows (used when trying + " to find '[', but not '%[', :h /\%[ ) + let s:not_vmagic_opt_atoms = '\%(\%(^\|[^\\]\)\%(\\\\\)*%\)\@\)*]' + + " }}} + + " for magic modes 'V' and 'M' + func! s:ToggleBslash(patitem) "{{{ + " {patitem} magic char or '\'.char + if a:patitem =~ '^.$' + return '\'.a:patitem + else + let mchar = matchstr(a:patitem, '^\\\zs.') + if stridx(s:rem_bslash_before, mchar) >= 0 + return mchar + else + return a:patitem + endif + endif + endfunc "}}} + + func! s:ToggleVmagicBslash(patitem) "{{{ + " {patitem} magic char or '\'.char + if a:patitem =~ '^\\' + let mchar = a:patitem[1] + if mchar =~ '[\^$.*[\]~\\[:alnum:]_]' + return a:patitem + else + return mchar + endif + else + return '\'.a:patitem + endif + endfunc "}}} + + " Modeline: {{{1 + let &cpo = s:cpo_save + unlet s:cpo_save + " vim:ts=8:fdm=marker: diff --combined .vim/bundle/explainpat/doc/explainpat.txt index 0000000,0268c69..0268c69 mode 000000,100644..100644 --- a/.vim/bundle/explainpat/doc/explainpat.txt +++ b/.vim/bundle/explainpat/doc/explainpat.txt @@@ -1,0 -1,103 +1,103 @@@ + *explainpat.txt* Give detailed help on a regexp pattern. + + For Vim version 7.0. Last change: 2017 Dec 15 + By Andy Wokula + + *explainpat* *explainpat.vim* + ExplainPat is a plugin to inspect a Vim regexp pattern and show a line of help + for each found regexp item. Purpose is to get a better view on somebody + else's complex regexp string. It may also help with spotting mistakes. + + If you find that it explains something wrong, please drop me an email. + + URL http://vim.sourceforge.net/scripts/script.php?script_id=4364 + ============================================================================== + *:ExplainPattern* + :ExplainPattern {pattern} + :ExplainPattern {register} + inspect the given Vim {pattern} and print a line of + help (with color) for each found pattern item. Nested + items get extra indent. + + A single-char argument is used as {register} argument: + / explain the last search pattern + * explain pattern from the clipboard + a explain pattern from register a + etc. + + > + :ExplainPattern \C^\%(\\\%(@<\|%#=\|%[dxouU[(^$V#<>]\=\|z[1-9se(]\|@[>=!]\|_[[^$.]\=\|.\)\|.\) + + Notes: + The pattern is first converted into a purely |magic| pattern using + |nwo#magic#MakeMagic()|. This means that embedded |/\V| |/\M| |/\m| |/\v| + specifiers are effectively removed from the explanation. + + :ExplainPattern also accepts some invalid patterns: > + :ExplainPattern \) + Pattern: \) + \) end of group + + ============================================================================== + TODO: + ? `\%[...]` can be nested? But documentation |/\%[]| says no. + + Ideas: + - If the user already knows regular expressions but of a different kind, + explain items in that different language. + Other regexp idioms: + Perl, Python, Emacs, Java, C#, Sed, Grep; + Vim ... very magic, nomagic, very nomagic + Possible config var name: + g:explainpat_user_knows = "Perl" + g:explainpat_background = "Perl" + g:explainpat_in_terms_of = "Perl" + g:explainpat_language = "Perl" + + ============================================================================== + History: + + v0.9 + + BF accept `\@123<=` and `\@123 explainpat#NewHelpPrinter() + + v0.7 + + BF `\{3,4\}` not accepted, only `\{3,4}` + + v0.6 + + BF `[]` is a literal string (not a collection) + + v0.5 + + BF `$\n^` + + wording: `\|` is not an "OR branch" (it separates or branches) + + NF added tests (not part of release) + + NF accept custom help printer (for testing purpose, could also be used to + export HTML etc.) + + v0.4 + + BF `[foo` is a literal string + + BF for |/star|, |/^| and |/$|, distinguish position in the pattern + (sometimes these become literal); special cases: `^**`, `^^`, `\c^^`, `$$`, + `a\|^b`, `a\&*b`, `[ab`, `\_[ab`, ... + + v0.3 + + BF accept `\z(...\)` and `\z[N]` + + BF accept `[=a=]` and `[.a.]` in collections + + v0.2 + + include vim_use suggestions [2012 Dec 19] + * for collections [^...], add "not matching [...]" + * fix `\%>'a1` + * more detailed `\%x31` + + v0.1 (initial version) + + start of "first" capturing group, start of 2nd ... + + `\|` should get less indent than the branches, do we need to create an + AST? ! no, keep it straight forward + + `\%[...]` + + `\{`, `\{-` + + ============================================================================== + vim:tw=78:fo=tcq2:sts=0:ts=8:sw=8:fdm=marker:fmr=^_\^,^\^:ft=help: diff --combined .vim/bundle/explainpat/plugin/explainpat.vim index 0000000,731f9a4..731f9a4 mode 000000,100644..100644 --- a/.vim/bundle/explainpat/plugin/explainpat.vim +++ b/.vim/bundle/explainpat/plugin/explainpat.vim @@@ -1,0 -1,34 +1,34 @@@ + " File: explainpat.vim + " Created: 2011 Nov 02 + " Last Change: 2013 Mar 08 + " Rev Days: 7 + " Author: Andy Wokula + " License: Vim License, see :h license + " Version: 0.5 + + " :ExplainPattern [pattern] + " + " parse the given Vim [pattern] (default: text in the Visual area) and + " print a line of help (with color!) for each found pattern item. Nested + " items get extra indent. + " + " A single-char [pattern] argument is used as register argument: + " / explain the last search pattern + " * explain pattern from the clipboard + " a explain pattern from register a + " + + if exists("loaded_explainpat") + finish + endif + let loaded_explainpat = 1 + + if v:version < 700 + echomsg "explainpat: you need at least Vim 7.0" + finish + endif + + com! -nargs=? ExplainPattern call explainpat#ExplainPattern() + + " Modeline: {{{1 + " vim:ts=8:fdm=marker: