1

I am relatively new to vim, but I'm trying to get acquainted. I use vim mainly for .tex files and on two different machines (office and home). In both cases, I use Vim-Latex. No problem on the machine in the office (at the moment, I don't remember the version of vim used there.) At home (vim 8.2), instead, when jumping between parentheses, I get the following error message:

Error detected while processing function matchit#Match_wrapper[161]..<SNR>71_ParseSkip:                                                                                                 
line   10:
E488: Trailing characters: . strpart(skip,2). "'"
Error detected while processing function matchit#Match_wrapper:
line  174:
E121: Undefined variable: r
line  176:
E121: Undefined variable: r
Press ENTER or type command to continue

Also, I have tried jumping between parentheses in a blank file (no .tex), and I don't have any problem there. Looking around, I found a solution for a similar problem, but involving a later version of vim.

I hope that someone can direct me towards a working solution.

Edit:

Here is a sample tex

\documentclass{article}
\usepackage{amsmath}

\begin{document}
This is a sample text with a formula
\begin{equation}
  i \hbar \frac{d}{d t} \Psi(x,t) = \hat{H} \Psi(x,t)
\end{equation}
\end{document}

To reproduce the problem, I just go on any of the brackets on any of the lines and press "%" (on my keyboard, Shift+5.)

4
  • Welcome to Vi and Vim! Can you show some sample (La)TeX and exact key-presses?
    – D. Ben Knoble
    Jun 5, 2022 at 16:08
  • @D.BenKnoble Thanks for the comment. I just included a sample code and the key strokes.
    – Aschkal
    Jun 5, 2022 at 17:25
  • Seems like something to post on github issues pages of the plugin.
    – eyal karni
    Jun 6, 2022 at 8:54
  • 1
    The error message quotes matchit#Match_wrapper[161]..<SNR>71_ParseSkip. This tells me the error is from the matchit plugin, which can be found in "{vim-installation-directory}/pack/dist/opt/matchit/autoload/matchit.vim", and in particular, s:ParseSkip at the end of that file. This matchit plugin is maintained (upstream) in github.com/chrisbra/matchit. Perhaps you could file an issue there :)
    – husB
    Jun 14, 2022 at 14:56

1 Answer 1

1

Taking inspiration from @husB's comment, I copied the matchit.vim file from another computer I have access to with vim 81 installed and copied on this present computer with vim 82. Now, everything seems to work.

In case anyone is interested or hoping it can be useful to someone, I post here the differences between the matchit.vim files in the two versions (notice the date of last change)

"  Last Change: Jun 10, 2021                                                        |   "  Last Change: 2019 Oct 24
" Neovim does not support scriptversion                                             |   le s:last_mps = ""
if has("vimscript-4")                                                               <
  scriptversion 4                                                                   <
endif                                                                               <
                                                                                    <
let s:last_mps = ""                                                                 <
    let restore_options ..= (&ic ? " " : " no") .. "ignorecase"                     |       let restore_options .= (&ic ? " " : " no") . "ignorecase"
    let restore_options = " ve=" .. &ve .. restore_options                          |       let restore_options = " ve=" . &ve . restore_options
                                                                                    >     " If this function was called from Visual mode, make sure that the cursor
                                                                                    >     " is at the correct end of the Visual range:
                                                                                    >     if a:mode == "v"
                                                                                    >       execute "normal! gv\<Esc>"
                                                                                    >     elseif a:mode == "o" && mode(1) !~# '[vV]'
                                                                                    >       exe "norm! v"
                                                                                    >     endif
  " if a count has been applied, use the default [count]% mode (see :h N%)          |     " Use default behavior if called with a count.
    exe "normal! " .. v:count .. "%"                                                |       exe "normal! " . v:count . "%"
  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                                                                             <
    let default = escape(&mps, '[$^.*~\\/?]') .. (strlen(&mps) ? "," : "") ..       |       let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
    let match_words = match_words .. (strlen(match_words) ? "," : "") .. default    |       let match_words = match_words . (strlen(match_words) ? "," : "") . default
    if match_words !~ s:notslash .. '\\\d'                                          |       if match_words !~ s:notslash . '\\\d'
    let s:all = substitute(s:pat, s:notslash .. '\zs[,:]\+', '\\|', 'g')            |       let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
    let s:all = '\%(' .. s:all .. '\)'                                              |       let s:all = '\%(' . s:all . '\)'
    let s:patBR = substitute(match_words .. ',',                                    |       let s:patBR = substitute(match_words.',',
      \ s:notslash .. '\zs[,:]*,[,:]*', ',', 'g')                                   |         \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
    let s:patBR = substitute(s:patBR, s:notslash .. '\zs:\{2,}', ':', 'g')          |       let s:patBR = substitute(s:patBR, s:notslash.'\zs:\{2,}', ':', 'g')
      " Make sure macros abort properly                                             <
      "exe "norm! \<esc>"                                                           <
      call feedkeys("\e", 'tni')                                                    <
    let prefix = (curcol ? '^.*\%' .. (curcol + 1) .. 'c\%(' : '^\%(')              |       let prefix = (curcol ? '^.*\%'  . (curcol + 1) . 'c\%(' : '^\%(')
    let suffix = (suf ? '\)\%' .. (endcol + 1) .. 'c.*$'  : '\)$')                  |       let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$'  : '\)$')
  let i = matchend(group, s:notslash .. ",")                                        |     let i = matchend(group, s:notslash . ",")
    let i = matchend(groupBR, s:notslash .. ":")                                    |       let i = matchend(groupBR, s:notslash . ":")
  let i = matchend(group, s:notslash .. ":")                                        |     let i = matchend(group, s:notslash . ":")
  let j = matchend(group, '.*' .. s:notslash .. ":")                                |     let j = matchend(group, '.*' . s:notslash . ":")
  let mid = substitute(strpart(group, i,j-i-1), s:notslash .. '\zs:', '\\|', 'g')   |     let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
  let ini = substitute(ini, s:notslash .. '\zs\\\(:\|,\)', '\1', 'g')               |     let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
  let mid = substitute(mid, s:notslash .. '\zs\\\(:\|,\)', '\1', 'g')               |     let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
  let fin = substitute(fin, s:notslash .. '\zs\\\(:\|,\)', '\1', 'g')               |     let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
  let ini = substitute(ini, s:notslash .. '\zs\\(', '\\%(', 'g')                    |     let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
  let mid = substitute(mid, s:notslash .. '\zs\\(', '\\%(', 'g')                    |     let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
  let fin = substitute(fin, s:notslash .. '\zs\\(', '\\%(', 'g')                    |     let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
  if a:forward && matchline =~ prefix .. fin .. suffix                              |     if a:forward && matchline =~ prefix . fin . suffix
    \ || !a:forward && matchline =~ prefix .. ini .. suffix                         |       \ || !a:forward && matchline =~ prefix . ini . suffix
  if a:forward && matchline =~ prefix .. fin .. suffix                              |     if a:forward && matchline =~ prefix . fin . suffix
    \ || !a:forward && matchline !~ prefix .. ini .. suffix                         |       \ || !a:forward && matchline !~ prefix . ini . suffix
    let skip = "r:" .. b:match_comment                                              |       let skip = "r:" . b:match_comment
    let b:match_tail = (strlen(mid) ? mid .. '\|' : '') .. fin                      |       let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
    execute "if " .. skip .. "| let skip = '0' | endif"                             |       execute "if " . skip . "| let skip = '0' | endif"
    " add virtualedit=onemore, to make it work even when the match ends the         |       " add virtualedit=onemore, to make it work even when the match ends the " line
    " line                                                                          <
      let eolmark=1 " flag to set a mark on eol (since we cannot move there)        |         set ve=onemore
  let final_position = "call cursor(" .. line(".") .. "," .. col(".") .. ")"        |     let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
  if exists('eolmark') && eolmark                                                   |     return s:CleanUp(restore_options, a:mode, startpos, mid.'\|'.fin)
    call setpos("''", [0, line('.'), col('$'), 0]) " set mark on the eol            <
  endif                                                                             <
  return s:CleanUp(restore_options, a:mode, startpos, mid .. '\|' .. fin)           <
  if a:matchline !~ a:prefix ..                                                     |     if a:matchline !~ a:prefix .
    \ substitute(a:group, s:notslash .. '\zs:', '\\|', 'g') .. a:suffix             |       \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
  let i = matchend(a:groupBR, s:notslash .. ':')                                    |     let i = matchend(a:groupBR, s:notslash . ':')
  let i = matchend(word, s:notslash .. ":")                                         |     let i = matchend(word, s:notslash . ":")
      if tailBR =~ s:notslash .. '\\' .. d                                          |         if tailBR =~ s:notslash . '\\' . d
        let table = table .. d                                                      |           let table = table . d
        let table = table .. "-"                                                    |           let table = table . "-"
      let backref = substitute(a:matchline, a:prefix .. word .. a:suffix,           |         let backref = substitute(a:matchline, a:prefix.word.a:suffix,
        \ '\' .. table[d], "")                                                      |           \ '\'.table[d], "")
      let ini = strpart(ini, 0, start) .. backref .. strpart(ini, start+len)        |         let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
      let tailBR = substitute(tailBR, s:notslash .. '\zs\\' .. d,                   |         let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
  return ini .. ":" .. tailBR                                                       |     return ini . ":" . tailBR
  let groups = substitute(a:groups .. ",", s:notslash .. '\zs[,:]*,[,:]*', ',', 'g  |     let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
  let groups = substitute(groups, s:notslash .. '\zs:\{2,}', ':', 'g')              |     let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
    let i = matchend(groups, s:notslash .. ':')                                     |       let i = matchend(groups, s:notslash . ':')
    let j = matchend(groups, s:notslash .. ',')                                     |       let j = matchend(groups, s:notslash . ',')
    let tail = strpart(groups, i, j-i-1) .. ":"                                     |       let tail = strpart(groups, i, j-i-1) . ":"
    let parsed = parsed .. ini                                                      |       let parsed = parsed . ini
    let i = matchend(tail, s:notslash .. ':')                                       |       let i = matchend(tail, s:notslash . ':')
      let i = matchend(tail, s:notslash .. ':')                                     |         let i = matchend(tail, s:notslash . ':')
      let parsed = parsed .. ":" .. s:Resolve(ini, word, "word")                    |         let parsed = parsed . ":" . s:Resolve(ini, word, "word")
    let parsed = parsed .. ","                                                      |       let parsed = parsed . ","
  let group = '\%(' .. a:pat .. '\)'                                                |     let group = '\%(' . a:pat . '\)'
  let prefix = (a:start ? '\(^.*\%<' .. (a:start + 2) .. 'c\)\zs' : '^')            |     let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
  let suffix = (a:start+1 < len ? '\(\%>' .. (a:start+1) .. 'c.*$\)\@=' : '$')      |     let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
  if a:string !~ prefix .. group .. suffix                                          |     if a:string !~ prefix . group . suffix
  return prefix .. group .. suffix                                                  |     return prefix . group . suffix
      let index = matchend(match, s:notslash .. '\\(')                              |         let index = matchend(match, s:notslash . '\\(')
      let index = matchend(match, s:notslash .. '\\(\|\\)') - 1                     |         let index = matchend(match, s:notslash . '\\(\|\\)') - 1
    return "let " .. a:1 .. "=" .. start .. "| let " .. a:2 .. "=" .. len           |       return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
    let foo = substitute(a:string, '[^' .. a:pattern .. ']', "a:1", "g")            |       let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
    let foo = substitute(foo, '[^' .. a:2 .. ']', "", "g")                          |       let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
  let i = matchend(word, s:notslash .. '\\\d') - 1                                  |     let i = matchend(word, s:notslash . '\\\d') - 1
          let table = strpart(table, 0, s) .. (w+b) .. strpart(table, s+1)          |             let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
        let backref = strpart(backref, 0, start) .. ":" .. table[s]                 |           let backref = strpart(backref, 0, start) . ":". table[s]
        \ .. strpart(backref, start+len)                                            |           \ . strpart(backref, start+len)
    let word = strpart(word, 0, i-1) .. backref .. strpart(word, i+1)               |       let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
    let i = matchend(word, s:notslash .. '\\\d') - 1                                |       let i = matchend(word, s:notslash . '\\\d') - 1
  let word = substitute(word, s:notslash .. '\zs:', '\\', 'g')                      |     let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
    return table .. word                                                            |       return table . word
  let tail = (a:patterns =~ a:comma .. "$" ? a:patterns : a:patterns .. a:comma)    |     let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
  let i = matchend(tail, s:notslash .. a:comma)                                     |     let i = matchend(tail, s:notslash . a:comma)
    let alttail = (a:1 =~ a:comma .. "$" ? a:1 : a:1 .. a:comma)                    |       let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
    let j = matchend(alttail, s:notslash .. a:comma)                                |       let j = matchend(alttail, s:notslash . a:comma)
    let currpat = substitute(current, s:notslash .. a:branch, '\\|', 'g')           |       let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
  while a:string !~ a:prefix .. currpat .. a:suffix                                 |     while a:string !~ a:prefix . currpat . a:suffix
    let i = matchend(tail, s:notslash .. a:comma)                                   |       let i = matchend(tail, s:notslash . a:comma)
      let currpat = substitute(current, s:notslash .. a:branch, '\\|', 'g')         |         let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
      let j = matchend(alttail, s:notslash .. a:comma)                              |         let j = matchend(alttail, s:notslash . a:comma)
    let current = current .. a:comma .. strpart(alttail, 0, j-1)                    |       let current = current . a:comma . strpart(alttail, 0, j-1)
  amenu &Matchit.t&able :echo '0:' .. b:match_table .. ':9'<CR>                     |     amenu &Matchit.t&able :echo '0:' . b:match_table . ':9'<CR>
    let default = escape(&mps, '[$^.*~\\/?]') .. (strlen(&mps) ? "," : "") ..       |       let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
    let match_words = match_words .. (strlen(match_words) ? "," : "") .. default    |       let match_words = match_words . (strlen(match_words) ? "," : "") . default
    if match_words !~ s:notslash .. '\\\d'                                          |       if match_words !~ s:notslash . '\\\d'
    let s:all = '\%(' .. substitute(s:pat, '[,:]\+', '\\|', 'g') .. '\)'            |       let s:all = '\%(' . substitute(s:pat, '[,:]\+', '\\|', 'g') . '\)'
    let s:patBR = substitute(match_words .. ',',                                    |       let s:patBR = substitute(match_words.',',
      \ s:notslash .. '\zs[,:]*,[,:]*', ',', 'g')                                   |         \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
    let s:patBR = substitute(s:patBR, s:notslash .. '\zs:\{2,}', ':', 'g')          |       let s:patBR = substitute(s:patBR, s:notslash.'\zs:\{2,}', ':', 'g')
  let openlist = split(s:pat .. ',', s:notslash .. '\zs:.\{-}' .. s:notslash .. ',  |     let openlist = split(s:pat . ',', s:notslash . '\zs:.\{-}' . s:notslash . ',')
  let midclolist = 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 .. ':')})                        |     call map(midclolist, {-> split(v:val, s:notslash . ':')})
  call map(openlist,   {i,v -> v =~# s:notslash .. '\\|' ? '\%(' .. v .. '\)' : v}  |     call map(openlist,   {i,v -> v =~# s:notslash . '\\|' ? '\%(' . v . '\)' : v})
  call map(middlelist, {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}  |     call map(closelist,  {i,v -> v =~# s:notslash . '\\|' ? '\%(' . v . '\)' : v})
    let skip = "r:" .. b:match_comment                                              |       let skip = "r:" . b:match_comment
  let openpat = substitute(open, '\%(' .. s:notslash .. '\)\@<=\\(', '\\%(', 'g')   |     let openpat = substitute(open, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g')
  let closepat = substitute(close, '\%(' .. s:notslash .. '\)\@<=\\(', '\\%(', 'g'  |     let closepat = substitute(close, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g')
  let middlepat = substitute(middle, '\%(' .. s:notslash .. '\)\@<=\\(', '\\%(', '  |     let middlepat = substitute(middle, '\%(' . s:notslash . '\)\@<=\\(', '\\%(', 'g'
      execute "if " .. skip .. "| let skip = '0' | endif"                           |         execute "if " . skip . "| let skip = '0' | endif"
      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" ..           |         let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
        \ strpart(skip,2) .. "'"                                                    |           \ strpart(skip,2) . "'"
      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" ..           |         let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
        \ strpart(skip,2) .. "'"                                                    |           \ strpart(skip,2) . "'"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.