Refactor: Syntax as region (code, eq, sub, sup, strike) => Fix (Issue #709)
More syntax pattern are defined as regions => Faster, enable nesting
This commit is contained in:
		@@ -40,6 +40,22 @@ let rxItalicBold = '\%(^\|\s\|[[:punct:]]\)\@<='.
 | 
			
		||||
      \'\%([[:punct:]]\|\s\|$\)\@='
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" text: $ equation_inline $
 | 
			
		||||
let s:rxEqIn = '\$[^$`]\+\$'
 | 
			
		||||
 | 
			
		||||
" text: `code`
 | 
			
		||||
let s:rxCode = '`[^`]\+`'
 | 
			
		||||
 | 
			
		||||
" text: ~~deleted text~~
 | 
			
		||||
let s:rxDelText = '\~\~[^~`]\+\~\~'
 | 
			
		||||
 | 
			
		||||
" text: ^superscript^
 | 
			
		||||
let s:rxSuperScript = '\^[^^`]\+\^'
 | 
			
		||||
 | 
			
		||||
" text: ,,subscript,,
 | 
			
		||||
let s:rxSubScript = ',,[^,`]\+,,'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function! s:root_path(subdir) abort
 | 
			
		||||
  return repeat('../', len(split(a:subdir, '[/\\]')))
 | 
			
		||||
endfunction
 | 
			
		||||
@@ -598,12 +614,12 @@ function! s:make_tag(line, regexp, func, ...) abort
 | 
			
		||||
                    \ '\(<a href.\{-}</a>\)\|'.
 | 
			
		||||
                    \ '\(<img src.\{-}/>\)\|'.
 | 
			
		||||
                    \ '\(<pre.\{-}</pre>\)\|'.
 | 
			
		||||
                    \ '\('.vimwiki#vars#get_syntaxlocal('rxEqIn').'\)'
 | 
			
		||||
                    \ '\('.s:rxEqIn.'\)'
 | 
			
		||||
 | 
			
		||||
  "FIXME FIXME !!! these can easily occur on the same line!
 | 
			
		||||
  "XXX  {{{ }}} ??? obsolete
 | 
			
		||||
  if '`[^`]\+`' ==# a:regexp || '{{{.\+}}}' ==# a:regexp ||
 | 
			
		||||
        \ vimwiki#vars#get_syntaxlocal('rxEqIn') ==# a:regexp
 | 
			
		||||
        \ s:rxEqIn ==# a:regexp
 | 
			
		||||
    let res_line = s:subst_func(a:line, a:regexp, a:func)
 | 
			
		||||
  else
 | 
			
		||||
    let pos = 0
 | 
			
		||||
@@ -643,11 +659,11 @@ function! s:process_tags_typefaces(line, header_ids) abort
 | 
			
		||||
  let line = s:make_tag(line, s:rxItalic, 's:tag_em')
 | 
			
		||||
  let line = s:make_tag(line, s:rxBold, 's:tag_strong', a:header_ids)
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_global('rxTodo'), 's:tag_todo')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxDelText'), 's:tag_strike')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxSuperScript'), 's:tag_super')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxSubScript'), 's:tag_sub')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxCode'), 's:tag_code')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxEqIn'), 's:tag_eqin')
 | 
			
		||||
  let line = s:make_tag(line, s:rxDelText, 's:tag_strike')
 | 
			
		||||
  let line = s:make_tag(line, s:rxSuperScript, 's:tag_super')
 | 
			
		||||
  let line = s:make_tag(line, s:rxSubScript, 's:tag_sub')
 | 
			
		||||
  let line = s:make_tag(line, s:rxCode, 's:tag_code')
 | 
			
		||||
  let line = s:make_tag(line, s:rxEqIn, 's:tag_eqin')
 | 
			
		||||
  let line = s:make_tag(line, vimwiki#vars#get_syntaxlocal('rxTags'), 's:tag_tags', a:header_ids)
 | 
			
		||||
  return line
 | 
			
		||||
endfunction
 | 
			
		||||
 
 | 
			
		||||
@@ -218,24 +218,44 @@ function! vimwiki#u#ft_is_vw() abort
 | 
			
		||||
  endif
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Helper: Expand regex from reduced typeface delimiters
 | 
			
		||||
" :param: list<list,delimiters>> with reduced regex
 | 
			
		||||
" Return: list with extended regex delimiters (not inside a word)
 | 
			
		||||
"   -- [['\*_', '_\*']] -> [['\S\@<=\*_\|\*_\S\@=', '\S\@<=_\*\|_\*\S\@=']]
 | 
			
		||||
function! vimwiki#u#hi_expand_regex(lst) abort
 | 
			
		||||
  let res = []
 | 
			
		||||
  function! s:expand_regex(rx) abort
 | 
			
		||||
    return '\S\@<=' .a:rx . '\|' . a:rx . '\S\@='
 | 
			
		||||
  endfunction
 | 
			
		||||
  for delimiters in a:lst
 | 
			
		||||
    call add(res, [s:expand_regex(delimiters[0]), s:expand_regex(delimiters[1])])
 | 
			
		||||
  endfor
 | 
			
		||||
  return res
 | 
			
		||||
endfunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
" Helper: Create highlight region between two tags
 | 
			
		||||
" :param: tag <string> example '<b>'
 | 
			
		||||
" :param: syntax_group <string> example: VimwikiBold
 | 
			
		||||
" :param: contains <string> coma separated and prefixed, default VimwikiHTMLTag
 | 
			
		||||
" :param: (1) <boolean> is contained
 | 
			
		||||
" :param: (2) <string> more param ex:oneline
 | 
			
		||||
function! vimwiki#u#hi_tag(tag_pre, tag_post, syntax_group, contains, ...) abort
 | 
			
		||||
  let opt_is_contained = a:0 > 0  ? 'contained ' : ''
 | 
			
		||||
  let opt_is_contained = a:0 > 0 && a:1 > 0 ? 'contained ' : ''
 | 
			
		||||
  let opt_more = a:0 > 1  ? ' ' . a:2 : ''
 | 
			
		||||
  let opt_contains = ''
 | 
			
		||||
  if a:contains !=# ''
 | 
			
		||||
    let opt_contains = 'contains=' . a:contains . ' '
 | 
			
		||||
  endif
 | 
			
		||||
  let cmd = 'syn region ' . a:syntax_group . ' matchgroup=VimwikiHTMLDelimiter ' .
 | 
			
		||||
  let cmd = 'syn region ' . a:syntax_group . ' matchgroup=VimwikiDelimiter ' .
 | 
			
		||||
        \ opt_is_contained .
 | 
			
		||||
        \ 'start="' . a:tag_pre . '" ' .
 | 
			
		||||
        \ 'end="' . a:tag_post . '" ' .
 | 
			
		||||
        \ 'keepend ' .
 | 
			
		||||
        \ opt_contains .
 | 
			
		||||
        \ b:vimwiki_syntax_concealends
 | 
			
		||||
        \ b:vimwiki_syntax_concealends .
 | 
			
		||||
        \ opt_more
 | 
			
		||||
  "echom cmd
 | 
			
		||||
  exe cmd
 | 
			
		||||
endfunction
 | 
			
		||||
@@ -247,50 +267,89 @@ endfunction
 | 
			
		||||
" -- see here for underline not defined: https://stackoverflow.com/questions/3003476
 | 
			
		||||
function! vimwiki#u#hi_typeface(dic) abort
 | 
			
		||||
  " Italic must go before, otherwise single * takes precedence over ** and ** is considered as
 | 
			
		||||
  " a void italic.
 | 
			
		||||
  " Note that the last syntax defined take precedence so that user can change at runtime
 | 
			
		||||
  " (:h :syn-define)
 | 
			
		||||
  " -- a void italic.
 | 
			
		||||
  " Note:
 | 
			
		||||
  " -- The last syntax defined take precedence so that user can change at runtime (:h :syn-define)
 | 
			
		||||
  " -- Some cases are contained by default:
 | 
			
		||||
  " -- -- ex: VimwikiCodeBoldUnderline is not defined in colorschemes -> VimwikiCode
 | 
			
		||||
  " -- -- see: #709 asking for concealing quotes in bold, so it must be higlighted differently
 | 
			
		||||
  " -- -- -- for the user to understand what is concealed around
 | 
			
		||||
  " Bold > Italic > Underline
 | 
			
		||||
 | 
			
		||||
  " Declare nesting capabilities
 | 
			
		||||
  " -- to be embeded in standard: bold, italic, underline
 | 
			
		||||
  let nested = 'VimwikiCode,VimwikiEqIn,VimwikiDelText,VimwikiSuperScript,VimwikiSubScript'
 | 
			
		||||
  " -- to be embeded in exetended (the one above)
 | 
			
		||||
  let nested .= ',VimwikiBold,VimwikiItalic,VimwikiUmderline'
 | 
			
		||||
 | 
			
		||||
  for i in a:dic['italic']
 | 
			
		||||
    "  -- Italic 1
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiItalic ', 'VimwikiItalicBold,VimwikiItalicUnderline')
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiItalic ', nested .',VimwikiItalicBold,VimwikiItalicUnderline')
 | 
			
		||||
    " -- Bold 2
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiBoldItalic', 'VimwikiBoldItalicUnderline', 1)
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiBoldItalic', nested . ',VimwikiBoldItalicUnderline', 1)
 | 
			
		||||
    " -- Bold 3
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiBoldUnderlineItalic', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiBoldUnderlineItalic', nested, 2)
 | 
			
		||||
    " -- Underline 2
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiUnderlineItalic', 'VimwikiUnderlineItalicBold', 1)
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiUnderlineItalic', nested . ',VimwikiUnderlineItalicBold', 1)
 | 
			
		||||
    " -- Underline 3
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiUnderlineBoldItalic', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(i[0], i[1], 'VimwikiUnderlineBoldItalic', nested, 2)
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  for b in a:dic['bold']
 | 
			
		||||
    " -- Bold 1
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0],b[1], 'VimwikiBold', 'VimwikiBoldUnderline,VimwikiBoldItalic')
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0],b[1], 'VimwikiBold', nested . ',VimwikiBoldUnderline,VimwikiBoldItalic')
 | 
			
		||||
    " -- Italic 2
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiItalicBold', 'VimwikiItalicBoldUnderline', 1)
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiItalicBold', nested . ',VimwikiItalicBoldUnderline', 1)
 | 
			
		||||
    " -- Italic 3
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiItalicUnderlineBold', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiItalicUnderlineBold', nested, 2)
 | 
			
		||||
    " -- Underline 2
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiUnderlineBold',  'VimwikiUnderlineBoldItalic', 1)
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiUnderlineBold', nested . ',VimwikiUnderlineBoldItalic', 1)
 | 
			
		||||
    " -- Underline 3
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiUnderlineItalicBold', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(b[0], b[1], 'VimwikiUnderlineItalicBold', nested, 2)
 | 
			
		||||
  endfor
 | 
			
		||||
  " markdown
 | 
			
		||||
 | 
			
		||||
  if has_key(a:dic, 'bold_italic')
 | 
			
		||||
    for bi in a:dic['bold_italic']
 | 
			
		||||
      call vimwiki#u#hi_tag(bi[0], bi[1], 'VimwikiBoldItalic', 'VimwikiBoldItalicUnderline')
 | 
			
		||||
      call vimwiki#u#hi_tag(bi[0], bi[1], 'VimwikiBoldItalic', nested . ',VimwikiBoldItalicUnderline')
 | 
			
		||||
    endfor
 | 
			
		||||
  endif
 | 
			
		||||
 | 
			
		||||
  for u in a:dic['underline']
 | 
			
		||||
    " -- Underline 1
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiUnderline', 'VimwikiUnderlineBold,VimwikiUnderlineItalic')
 | 
			
		||||
    " -- Bold 2
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiBoldUnderline', 'VimwikiBoldUnderlineItalic', 1)
 | 
			
		||||
    " -- Bold 3
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiBoldItalicUnderline', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiUnderline', nested . ',VimwikiUnderlineBold,VimwikiUnderlineItalic')
 | 
			
		||||
    " -- Italic 2
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiItalicUnderline', 'VimwikiItalicUnderlineBold', 1)
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiItalicUnderline', nested . ',VimwikiItalicUnderlineBold', 1)
 | 
			
		||||
    " -- Italic 3
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiItalicBoldUnderline', '', 2)
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiBoldItalicUnderline', nested, 2)
 | 
			
		||||
    " -- Underline 2
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiBoldUnderline', nested . ',VimwikiBoldUnderlineItalic', 1)
 | 
			
		||||
    " -- Underline 3
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiItalicBoldUnderline', nested, 2)
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  "" Code do not contain anything but can be contained very nested
 | 
			
		||||
  for u in a:dic['code']
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiCode', '')
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  " Deleted
 | 
			
		||||
  for u in a:dic['del']
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiDelText', nested)
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  "" Equation
 | 
			
		||||
  for u in a:dic['eq']
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiEqIn', nested)
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  " Superscript
 | 
			
		||||
  for u in a:dic['sup']
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiSuperScript', nested, 0, 'oneline')
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  " Subscript
 | 
			
		||||
  for u in a:dic['sub']
 | 
			
		||||
    call vimwiki#u#hi_tag(u[0], u[1], 'VimwikiSubScript', nested, 0, 'oneline')
 | 
			
		||||
  endfor
 | 
			
		||||
 | 
			
		||||
  " Prevent var_with_underscore to trigger italic text
 | 
			
		||||
 
 | 
			
		||||
@@ -582,6 +582,7 @@ endfunction
 | 
			
		||||
 | 
			
		||||
" Populate syntax variable
 | 
			
		||||
" Exported: syntax/vimwiki.vim
 | 
			
		||||
" TODO refactor <= too big function
 | 
			
		||||
function! vimwiki#vars#populate_syntax_vars(syntax) abort
 | 
			
		||||
  " Create is not exists
 | 
			
		||||
  if !exists('g:vimwiki_syntax_variables')
 | 
			
		||||
@@ -600,6 +601,35 @@ function! vimwiki#vars#populate_syntax_vars(syntax) abort
 | 
			
		||||
  " Autoload default syntax file
 | 
			
		||||
  execute 'runtime! syntax/vimwiki_'.a:syntax.'.vim'
 | 
			
		||||
 | 
			
		||||
  " text: `code` or ``code`` only inline
 | 
			
		||||
  " Note: `\%(^\|[^`]\)\@<=` means after a new line or a non `
 | 
			
		||||
  let syntax_dic.dTypeface['code'] = [
 | 
			
		||||
        \ ['\%(^\|[^`]\)\@<=`\%($\|[^`]\)\@=',
 | 
			
		||||
        \  '\%(^\|[^`]\)\@<=`\%($\|[^`]\)\@='],
 | 
			
		||||
        \ ['\%(^\|[^`]\)\@<=``\%($\|[^`]\)\@=',
 | 
			
		||||
        \  '\%(^\|[^`]\)\@<=``\%($\|[^`]\)\@='],
 | 
			
		||||
        \ ]
 | 
			
		||||
 | 
			
		||||
  " text: ~~deleted text~~
 | 
			
		||||
  let syntax_dic.dTypeface['del'] = ([
 | 
			
		||||
        \ ['\~\~', '\~\~']])
 | 
			
		||||
 | 
			
		||||
  " text: $ equation_inline $
 | 
			
		||||
  " Match only one $
 | 
			
		||||
  " ( ^ or not $) before $ and after: not $
 | 
			
		||||
  let syntax_dic.dTypeface['eq'] = ([
 | 
			
		||||
        \ ['\%(^\|[^$]\)\@<=\$\%($\|[^$]\)\@=',
 | 
			
		||||
        \  '\%(^\|[^$]\)\@<=\$\%($\|[^$]\)\@=']])
 | 
			
		||||
 | 
			
		||||
  " text: ^superscript^
 | 
			
		||||
  let syntax_dic.dTypeface['sup'] = ([
 | 
			
		||||
        \ ['\^', '\^']])
 | 
			
		||||
 | 
			
		||||
  " text: ,,subscript,,
 | 
			
		||||
  let syntax_dic.dTypeface['sub'] = ([
 | 
			
		||||
        \ [',,', ',,']])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  " TODO make that clean (i.e clearify what is local to syntax ot to buffer)
 | 
			
		||||
  " Get from local vars
 | 
			
		||||
  let bullet_types = vimwiki#vars#get_wikilocal('bullet_types')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user