vimwiki

Personal wiki for vim
git clone https://github.com/vimwiki/vimwiki.git
Log | Files | Refs | README | LICENSE

commit 72d02207b021b968a185ed68b949c7a15f82c3d4
parent f4bd841a4c72c1cbd6373395c968e463dcf5798f
Author: Tinmarino <tinmarino@gmail.com>
Date:   Sat, 18 Mar 2023 01:45:02 -0300

Syntax: Fasten highlighting, from 200ms to 20ms for first screen update

Problem:

The loading of a .md file was slow due to multiple nested lookback.
It is advised in vim help to prefer \zs, see :h /\@<
Anyway, it is useless to nest them.

089.080  000.085  000.085: sourcing /home/mtourneb/.vim/after/syntax/vimwiki.vim
089.264  005.184: opening buffers
089.322  000.058: BufEnter autocommands
089.323  000.001: editing files in windows
089.414  000.091: VimEnter autocommands
089.415  000.001: before starting main loop
303.698  214.283: first screen update
303.700  000.002: --- VIM STARTED ---

Solution:

Remove the function s:expand_delimiter in vars.vim.
It was doing a duplicate job with vimwiki#u#hi_expand_regex
And ... well avoid lookback as much as possible

091.784  000.087  000.087: sourcing /home/mtourneb/.vim/after/syntax/vimwiki.vim
091.991  006.034: opening buffers
092.050  000.059: BufEnter autocommands
092.052  000.002: editing files in windows
092.172  000.120: VimEnter autocommands
092.173  000.001: before starting main loop
112.574  020.401: first screen update
112.578  000.004: --- VIM STARTED ---

Diffstat:
Mautoload/vimwiki/u.vim | 44+++++++++++++++++++++++++++-----------------
Mautoload/vimwiki/vars.vim | 43++++++++-----------------------------------
Mtest/search.vader | 7++++++-
Mtest/syntax.vader | 4+++-
Mtest/syntax_markdown_gfm_typeface.vader | 4++--
5 files changed, 46 insertions(+), 56 deletions(-)

diff --git a/autoload/vimwiki/u.vim b/autoload/vimwiki/u.vim @@ -295,13 +295,19 @@ endfunction function! vimwiki#u#get_punctuation_string() abort " Faster " See: https://github.github.com/gfm/#ascii-punctuation-character - return '!"#$%&''()*+,-./:;<=>?@\[\\\]^`{}|~' + " res = '!"#$%&''()*+,-./:;<=>?@\[\\\]^`{}|~' + " But I removed the * as it is treated as a special case + return '!"#$%&''()+,-./:;<=>?@\[\\\]^`{}|~' endfunction function! vimwiki#u#hi_expand_regex(lst) abort " Helper: Expand regex from reduced typeface delimiters " :param: list<list,delimiters>> with reduced regex + " 1: Left delimiter + " 2: right delimiter + " 3: possible characters to ignore (default '$^' => never match) + " 4: can multiply delimiter (boolean) (default 0 => do not repeat) " Return: list with extended regex delimiters (not inside a word) " -- [['\*_', '_\*']] -> [['\*_\S\@=', '\S\@<=_\*\%(\s\|$\)\@=']] " Note: For purposes of this definition, the beginning and the end of the line count as Unicode whitespace. @@ -313,42 +319,46 @@ function! vimwiki#u#hi_expand_regex(lst) abort for a_delimiter in a:lst let r_left_del = a_delimiter[0] let r_right_del = a_delimiter[1] + let r_repeat_del = len(a_delimiter) >= 3 ? a_delimiter[2] : '$^' + let b_can_mult = len(a_delimiter) >= 4 ? a_delimiter[3] : 0 + + " Craft the repeatable middle + let r_mult = b_can_mult ? '\+' : '' + let r_left_repeat = '\%(\%(' . r_left_del . '\)' . r_mult . '\)' + let r_right_repeat = '\%(\%(' . r_right_del . '\)' . r_mult . '\)' + let r_unescaped_repeat = '\%(\\\|\\\@<!' . r_repeat_del . '\)' " Regex Start: " Left-Flanking is not followed by space (or need of line) - let r_left_prefix = '\%(^\|[[:space:]]\@<=\)' - let r_left_prefix = '\\\@<!' - " -- not followed by Unicode whitespace, - let r_left_suffix = '\%([[:space:]\n]\@!\)' - " Left Case1: not followed by punctuation - let r_left_suffix1 = '\%(\%([[:space:]\n' . punctuation . ']\)\@!\)' + " Left Case1: not followed by punctuation, start with blacklist " -- Can escape the leftflank - let r_left_prefix1 = '\%(^\|\\\@<!\)' + let r_left_prefix1 = '\%(^\|' . r_unescaped_repeat . '\@<!\)' + let r_left_suffix1 = '\%(\%([[:space:]\n' . punctuation . ']\|' . r_unescaped_repeat . '\)\@!\)' - " Left Case2: followed by punctuation so must be preceded by Unicode whitespace or start of line or a punctuation character. - let r_left_suffix2 = '\%([' . punctuation . ']\@=\)' + " Left Case2: followed by punctuation so must be preceded by whitelisted Unicode whitespace or start of line or a punctuation character. let r_left_prefix2 = '\%(\%(^\|[[:space:]\n' . punctuation . ']\)\@<=\)' + let r_left_suffix2 = '\%([' . punctuation . ']\@=\)' " Left Concatenate - let r_start = '\%(' . r_left_prefix1 . r_left_del . r_left_suffix1 - let r_start .= '\|' . r_left_prefix2 . r_left_del . r_left_suffix2 . '\)' + let r_start = '\%(' . r_left_prefix1 . '\zs' . r_left_repeat . '\ze' . r_left_suffix1 + let r_start .= '\|' . r_left_prefix2 . '\zs' . r_left_repeat . '\ze' . r_left_suffix2 . '\)' " Regex End: " not preceded by Unicode whitespace let r_right_prefix = '\(^\|[^[:space:]]\@<=\)' " Right Case1: not preceded by a punctuation character (or start of line) - let r_right_prefix1 = '\%(\%(^\|[^[:space:]' . punctuation . ']\)\@<=\)' - let r_right_suffix1 = '' + let r_right_prefix1 = '\%(^\|\%([[:space:]\n' . punctuation . ']\|' . r_unescaped_repeat . '\)\@<!\)' + let r_right_suffix1 = '\%($\|' . r_unescaped_repeat . '\@!\)' - " Right Case2: preceded by a punctuation character and followed by Unicode whitespace or end of line or a punctuation character + " Right Case2: preceded by a punctuation character and followed by Unicode whitespace or end of line or a punctuation character let r_right_prefix2 = '\%([' . punctuation . ']\@<=\)' let r_right_suffix2 = '\%(\%($\|[[:space:]' . punctuation . ']\)\@<=\)' " Right Concatenate - let r_end = '\%(' . r_right_prefix1 . r_right_del . r_right_suffix1 - let r_end .= '\|' . r_right_prefix2 . r_right_del . r_right_suffix2 . '\)' + let r_end = '\%(' . r_right_prefix1 . r_right_repeat . r_right_suffix1 + let r_end .= '\|' . r_right_prefix2 . r_right_repeat . r_right_suffix2 . '\)' call add(res, [r_start, r_end]) endfor diff --git a/autoload/vimwiki/vars.vim b/autoload/vimwiki/vars.vim @@ -753,19 +753,19 @@ function! s:get_markdown_syntaxlocal() abort \ 'symH': {'type': type(0), 'default': 0}, \ 'typeface': {'type': type({}), 'default': { \ 'bold': vimwiki#u#hi_expand_regex([ - \ [s:expand_delimiter('__', 1), s:expand_delimiter('__', 1)], - \ [s:expand_delimiter('\*\*', 1), s:expand_delimiter('\*\*', 1)], + \ ['__', '__', '[_*]', 1], + \ ['\*\*', '\*\*', '[_*]', 1], \ ]), \ 'italic': vimwiki#u#hi_expand_regex([ - \ [s:expand_delimiter('_', 0), s:expand_delimiter('_', 0)], - \ [s:expand_delimiter('\*', 0), s:expand_delimiter('\*', 0)], - \ [s:expand_delimiter('\*_', 1), s:expand_delimiter('_\*', 1)], - \ [s:expand_delimiter('_\*', 1), s:expand_delimiter('\*_', 1)], + \ ['_', '_', '[_*]', 0], + \ ['\*', '\*', '[_*]', 0], + \ ['\*_', '_\*', '[_*]', 1], + \ ['_\*', '\*_', '[_*]', 1], \ ]), \ 'underline': vimwiki#u#hi_expand_regex([]), \ 'bold_italic': vimwiki#u#hi_expand_regex([ - \ [s:expand_delimiter('\*\*\*', 1), s:expand_delimiter('\*\*\*', 1)], - \ [s:expand_delimiter('___', 1), s:expand_delimiter('___', 1)], + \ ['___', '___', '[_*]', 1], + \ ['\*\*\*', '\*\*\*', '[_*]', 1], \ ]), \ 'code': [ \ ['\%(^\|[^`\\]\)\@<=`\%($\|[^`]\)\@=', @@ -1344,33 +1344,6 @@ function! s:normalize_syntax_settings(syntax) abort endfunction -function! s:expand_delimiter(delim, b_can_mult) abort - " Helper: From a delimiter to the lookhead defensive version - " See: also vimwiki#u#hi_expand_regex - " TODO: get some cache to avoid recrafting the same prefix always - - " Clause: if nothing, return nothing - if len(a:delim) == 0 - return '\%(\)' - endif - - " let c_start = a:delim[0] ==# '\' ? a:delim[0:1] : a:delim[0] - " let c_end = (len(a:delim) > 1 && a:delim[-2:-2] ==# '\') ? a:delim[-2:-1] : a:delim[-1:] - " Hardcode for markdown - let c_start = '[_*]' - let c_end = '[_*]' - - let rx_mult = a:b_can_mult ? '\+' : '' - - let rx_start = '\%(^\|\%(\\\@<!' . c_start . '\)\@<!\)' - let rx_middle = '\%(\%(' . a:delim . '\)' . rx_mult . '\)' - let rx_end = '\%($\|\%(\\\@<!' . c_end . '\)\@!\)' - - let res = '\%(' . rx_start . rx_middle . rx_end . '\)' - return res -endfunction - - " ---------------------------------------------------------- " 4. Command (exported) {{{1 " ---------------------------------------------------------- diff --git a/test/search.vader b/test/search.vader @@ -7,10 +7,16 @@ Execute (Setup search testing wrapper): Log 'Cheating for old vim version, do not want to reverse bug' return endif + + " Execute command and grab output redir => output silent execute a:search_command redir END + + " The location list should not be empty Assert !empty(getloclist(0)), a:test_name.": no location list result" + + " The location list should contains entries Assert match(output, '\d of \d') > -1, a:test_name.": no result message" " Tests that VimwikiSearch is quoting the pattern correctly. @@ -30,7 +36,6 @@ Execute (Search test wiki): AssertEqual "= Test Wiki =", getline(1) AssertEqual "vimwiki", &filetype - call TestSearch('VimwikiSearch foo', 'pattern with no spaces') call TestSearch('VimwikiSearch foo bar', 'pattern with spaces') call TestSearch('VimwikiSearch foo\bar', 'pattern with ''\''') diff --git a/test/syntax.vader b/test/syntax.vader @@ -37,6 +37,7 @@ Given vimwiki (Markdown typeface with escape sequence #1044: _ __ * ** {{{2): a ~~staaill deleted~~ Del 9 $$Eq\$$ uation follows$ Math 10 `code \` not finished inline` Code 11 + 012345678901234567890 Execute (Set syntax markdown): call SetSyntax('markdown') @@ -48,7 +49,8 @@ Execute (Assert Syntax of escape typeface): AssertEqual 'VimwikiBold4' , SyntaxAt(4, 14) . 4 AssertEqual 'VimwikiItalic5' , SyntaxAt(5, 14) . 5 " See: #1303 where an escape start can close the region - AssertEqual '6' , SyntaxAt(6, 14) . 6 + " Fixed removing vars.vim::expand_delimiter + AssertEqual 'VimwikiItalic6' , SyntaxAt(6, 14) . 6 AssertEqual 'VimwikiSuperScript7', SyntaxAt(7, 14) . 7 AssertEqual 'VimwikiSubScript8' , SyntaxAt(8, 14) . 8 AssertEqual 'VimwikiDelText9' , SyntaxAt(9, 14) . 9 diff --git a/test/syntax_markdown_gfm_typeface.vader b/test/syntax_markdown_gfm_typeface.vader @@ -623,8 +623,8 @@ Execute (Set Markdown): Execute (Assert Syntax): CommentLine 'Empty emphasis' - AssertEqual '', SyntaxAt(1, 1) - AssertEqual '', SyntaxAt(2, 1) + AssertEqual '1', SyntaxAt(1, 1) . 1 + AssertEqual '2', SyntaxAt(2, 1) . 2 Given vimwiki (Typeface: https://github.github.com/gfm/#example-446):