diff options
Diffstat (limited to 'autoload/LaTeXtoUnicode.vim')
| -rw-r--r-- | autoload/LaTeXtoUnicode.vim | 190 | 
1 files changed, 136 insertions, 54 deletions
| diff --git a/autoload/LaTeXtoUnicode.vim b/autoload/LaTeXtoUnicode.vim index fed23032..2be1a492 100644 --- a/autoload/LaTeXtoUnicode.vim +++ b/autoload/LaTeXtoUnicode.vim @@ -12,28 +12,14 @@ function! s:L2U_Setup()    " Keep track of whether LaTeX-to-Unicode is activated    " (used when filetype changes) -  if !has_key(b:, "l2u_enabled") -    let b:l2u_enabled = 0 -  endif -  if !has_key(b:, "l2u_autodetect_enable") -    let b:l2u_autodetect_enable = 1 -  endif +  let b:l2u_enabled = get(b:, "l2u_enabled", 0) +  let b:l2u_autodetect_enable = get(b:, "l2u_autodetect_enable", 1) -  " Did we install the L2U tab mappings? -  if !has_key(b:, "l2u_tab_set") -    let b:l2u_tab_set = 0 -  endif -  if !has_key(b:, "l2u_cmdtab_set") -    let b:l2u_cmdtab_set = 0 -  endif -  if !has_key(b:, "l2u_keymap_set") -    let b:l2u_keymap_set = 0 -  endif - -  " Did we activate the L2U as-you-type substitutions? -  if !has_key(b:, "l2u_autosub_set") -    let b:l2u_autosub_set = 0 -  endif +  " Did we install the L2U tab/as-you-type/keymap... mappings? +  let b:l2u_tab_set = get(b:, "l2u_tab_set", 0) +  let b:l2u_cmdtab_set = get(b:, "l2u_cmdtab_set", 0) +  let b:l2u_autosub_set = get(b:, "l2u_autosub_set", 0) +  let b:l2u_keymap_set = get(b:, "l2u_keymap_set", 0)    " Following are some flags used to pass information between the function which    " attempts the LaTeX-to-Unicode completion and the fallback function @@ -77,17 +63,19 @@ function! s:L2U_SetupGlobal()      let g:latex_to_unicode_suggestions = 0    endif -  " A hack to forcibly get out of completion mode: feed -  " this string with feedkeys() -  if has("win32") || has("win64") -    let s:l2u_esc_sequence = "\u0006" -  else -    let s:l2u_esc_sequence = "\u0091\b" -  end +  " Forcibly get out of completion mode: feed +  " this string with feedkeys(s:l2u_esc_sequence, 'n') +  let s:l2u_esc_sequence = " \b"    " Trigger for the previous mapping of <Tab>    let s:l2u_fallback_trigger = "\u0091L2UFallbackTab" +  " Trigger for the previous mapping of <CR> +  let s:l2u_fallback_trigger_cr = "\u0091L2UFallbackCR" + +  " Trigger for autosub completion cleanup autocommand +  let s:l2u_autosub_cleanup_trigger = "\u0091L2UAutosubCleanup" +  endfunction  " Each time the filetype changes, we may need to enable or @@ -203,7 +191,7 @@ function! s:L2U_ismatch()    if col0 == -1      return 0    endif -  let base = l[col0 : col1-1] +  let base = l[col0:col1-2]    return has_key(g:l2u_symbols_dict, base)  endfunction @@ -258,8 +246,14 @@ function! LaTeXtoUnicode#completefunc(findstart, base)        let b:l2u_in_fallback = 0        return -3      endif +    " make sure that the options are still set +    " (it may happen that <C-X><C-U> itself triggers the fallback before +    " restarting, thus reseetting them; this happens when the prompt is +    " waiting for ^U^N^P during a partial completion)      call s:L2U_SetCompleteopt() +    " setup the cleanup/fallback operations when we're done      call s:L2U_InsertCompleteDoneAutocommand() +    call s:L2U_InsertInsertLeaveAutocommand()      " set info for the callback      let b:l2u_found_completion = 1      " analyse current line @@ -345,48 +339,83 @@ function! LaTeXtoUnicode#PutLiteral(k)    return ''  endfunction +function! LaTeXtoUnicode#PutLiteralCR() +  call feedkeys('
', 'ni') +  return '' +endfunction +  " Function which saves the current insert-mode mapping of a key sequence `s`  " and associates it with another key sequence `k` (e.g. stores the current -" <Tab> mapping into the Fallback trigger) +" <Tab> mapping into the Fallback trigger). +" It returns the previous maparg dictionary, so that the previous mapping can +" be reinstated if needed.  function! s:L2U_SetFallbackMapping(s, k)    let mmdict = maparg(a:s, 'i', 0, 1)    if empty(mmdict)      exe 'inoremap <buffer> ' . a:k . ' ' . a:s -    return +    return mmdict    endif    let rhs = mmdict["rhs"]    if rhs =~# '^<Plug>L2U' -    return +    return mmdict    endif    let pre = '<buffer>' -  if mmdict["silent"] -    let pre = pre . '<silent>' -  endif -  if mmdict["expr"] -    let pre = pre . '<expr>' -  endif +  let pre = pre . (mmdict["silent"] ? '<silent>' : '') +  let pre = pre . (mmdict["expr"] ? '<expr>' : '')    if mmdict["noremap"]      let cmd = 'inoremap '    else      let cmd = 'imap '      " This is a nasty hack used to prevent infinite recursion. It's not a -    " general solution. +    " general solution. Also, it doesn't work with <CR> since that stops +    " parsing of the <C-R>=... expression, so we need to special-case it. +    " Also, if the original mapping was intended to be recursive, this +    " will break it.      if mmdict["expr"] -      let rhs = substitute(rhs, '\c' . a:s, "\<C-R>=LaTeXtoUnicode#PutLiteral('" . a:s . "')\<CR>", 'g') +      if a:s != "<CR>" +        let rhs = substitute(rhs, '\c' . a:s, "\<C-R>=LaTeXtoUnicode#PutLiteral('" . a:s . "')\<CR>", 'g') +      else +        let rhs = substitute(rhs, '\c' . a:s, "\<C-R>=LaTeXtoUnicode#PutLiteralCR()\<CR>", 'g') +      endif +      " Make the mapping silent even if it wasn't originally +      if !mmdict["silent"] +        let pre = pre . '<silent>' +      endif      endif    endif    exe cmd . pre . ' ' . a:k . ' ' . rhs +  return mmdict +endfunction + +" Reinstate a mapping from the maparg dict returned by SetFallbackMapping +" (only if buffer-local, since otherwise it should still be available) +function! s:L2U_ReinstateMapping(mmdict) +  if empty(a:mmdict) || !a:mmdict["buffer"] +    return '' +  endif +  let lhs = a:mmdict["lhs"] +  let rhs = a:mmdict["rhs"] +  if rhs =~# '^<Plug>L2U' +    return '' +  endif +  let pre = '<buffer>' +  let pre = pre . (a:mmdict["silent"] ? '<silent>' : '') +  let pre = pre . (a:mmdict["expr"] ? '<expr>' : '') +  let cmd = a:mmdict["noremap"] ? 'inoremap ' : 'imap ' +  exe cmd . pre . ' ' . lhs . ' ' . rhs  endfunction  " This is the function which is mapped to <Tab>  function! LaTeXtoUnicode#Tab()    " the <Tab> is passed through to the fallback mapping if the completion    " menu is present, and it hasn't been raised by the L2U tab, and there -  " isn't an exact match before the cursor when suggestions are disabled -  if pumvisible() && !b:l2u_tab_completing && (get(g:, "latex_to_unicode_suggestions", 1) || !s:L2U_ismatch()) +  " isn't an exact match before the cursor +  if pumvisible() && !b:l2u_tab_completing && !s:L2U_ismatch()      call feedkeys(s:l2u_fallback_trigger)      return ''    endif +  " ensure that we start completion with some reasonable options +  call s:L2U_SetCompleteopt()    " reset the in_fallback info    let b:l2u_in_fallback = 0    let b:l2u_tab_completing = 1 @@ -497,7 +526,7 @@ function! s:L2U_RestoreCompleteopt()  endfunction  function! s:L2U_InsertCompleteDoneAutocommand() -  augroup L2UTab +  augroup L2UCompleteDone      autocmd! * <buffer>      " Every time a L2U completion finishes, the fallback may be invoked      autocmd CompleteDone <buffer> call LaTeXtoUnicode#FallbackCallback() @@ -505,8 +534,22 @@ function! s:L2U_InsertCompleteDoneAutocommand()  endfunction  function! s:L2U_RemoveCompleteDoneAutocommand() -  augroup L2UTab +  augroup L2UCompleteDone +    autocmd! * <buffer> +  augroup END +endfunction + +function s:L2U_InsertLeaveClenup() +    call s:L2U_ResetLastCompletionInfo() +    augroup L2UInsertLeave +      autocmd! * <buffer> +    augroup END +endfunction + +function! s:L2U_InsertInsertLeaveAutocommand() +  augroup L2UInsertLeave      autocmd! * <buffer> +    autocmd InsertLeave <buffer> call s:L2U_InsertLeaveClenup()    augroup END  endfunction @@ -537,12 +580,12 @@ function! s:L2U_SetTab(wait_insert_enter)    endif    " Backup the previous completefunc (the check is probably not really needed) -  if get(b:, "prev_completefunc", "") != "LaTeXtoUnicode#completefunc" -    let b:prev_completefunc = &completefunc +  if get(b:, "l2u_prev_completefunc", "") != "LaTeXtoUnicode#completefunc" +    let b:l2u_prev_completefunc = &completefunc    endif    setlocal completefunc=LaTeXtoUnicode#completefunc -  call s:L2U_SetFallbackMapping('<Tab>', s:l2u_fallback_trigger) +  let b:l2u_prev_map_tab = s:L2U_SetFallbackMapping('<Tab>', s:l2u_fallback_trigger)    imap <buffer> <Tab> <Plug>L2UTab    inoremap <buffer><expr> <Plug>L2UTab LaTeXtoUnicode#Tab() @@ -560,10 +603,10 @@ function! s:L2U_UnsetTab()    if !b:l2u_tab_set      return    endif -  exec "setlocal completefunc=" . get(b:, "prev_completefunc", "") +  exec "setlocal completefunc=" . get(b:, "l2u_prev_completefunc", "")    iunmap <buffer> <Tab>    if empty(maparg("<Tab>", "i")) -    call s:L2U_SetFallbackMapping(s:l2u_fallback_trigger, '<Tab>') +    call s:L2U_ReinstateMapping(b:l2u_prev_map_tab)    endif    iunmap <buffer> <Plug>L2UTab    exe 'iunmap <buffer> ' . s:l2u_fallback_trigger @@ -572,13 +615,25 @@ endfunction  " Function which looks for viable LaTeX-to-Unicode supstitutions as you type  function! LaTeXtoUnicode#AutoSub(...) +  " avoid recursive calls +  if get(b:, "l2u_in_autosub", 0) +    return '' +  endif    let vc = a:0 == 0 ? v:char : a:1 +  " for some reason function keys seem to be passed as characters 149 (F1-F12) +  " or 186 (F13-F37, these are entered with shift/ctrl). In such cases, we +  " can't really do any better than giving up. +  if char2nr(vc) == 149 || char2nr(vc) == 186 +    return '' +  endif +  let b:l2u_in_autosub = 1    let col1 = col('.')    let lnum = line('.')    if col1 == 1      if a:0 > 1 -      call feedkeys(a:2, 'n') +      call feedkeys(a:2, 't')      endif +    let b:l2u_in_autosub = 0      return ''    endif    let bs = (vc != "\n") @@ -586,21 +641,42 @@ function! LaTeXtoUnicode#AutoSub(...)    let col0 = match(l, '\\\%([_^]\?[A-Za-z]\+\%' . col1 . 'c\%([^A-Za-z]\|$\)\|[_^]\%([0-9()=+-]\)\%' . col1 .'c\%(.\|$\)\)')    if col0 == -1      if a:0 > 1 -      call feedkeys(a:2, 'n') +      call feedkeys(a:2, 't')      endif +    let b:l2u_in_autosub = 0      return ''    endif -  let base = l[col0 : -1-bs] +  let base = l[col0 : col1-1-bs]    let unicode = get(g:l2u_symbols_dict, base, '')    if empty(unicode)      if a:0 > 1 -      call feedkeys(a:2, 'n') +      call feedkeys(a:2, 't')      endif +    let b:l2u_in_autosub = 0      return ''    endif + +  " create a temporary mapping to reset b:l2u_in_autosub when done +  " (when invoked, it removes itself) +  exec 'imap <buffer> ' . s:l2u_autosub_cleanup_trigger . ' <Plug>L2UAutosubReset' +  inoremap <buffer><expr> <Plug>L2UAutosubReset <SID>L2U_AutosubReset() + +  " perform the substitution, wrapping it in undo breakpoints so that +  " we can revert it as a whole    call feedkeys("\<C-G>u", 'n')    call feedkeys(repeat("\b", len(base) + bs) . unicode . vc . s:l2u_esc_sequence, 'nt')    call feedkeys("\<C-G>u", 'n') +  " enqueue the reset mechanism +  call feedkeys(s:l2u_autosub_cleanup_trigger) +  return '' +endfunction + +function! s:L2U_AutosubReset() +  " no longer doing substitution +  let b:l2u_in_autosub = 0 +  " remove the mapping that triggered this function +  exec 'iunmap <buffer> ' . s:l2u_autosub_cleanup_trigger +  iunmap <buffer> <Plug>L2UAutosubReset    return ''  endfunction @@ -619,8 +695,10 @@ function! s:L2U_SetAutoSub(wait_insert_enter)    " Viable substitutions are searched at every character insertion via the    " autocmd InsertCharPre. The <Enter> key does not seem to be catched in    " this way though, so we use a mapping for that case. + +  let b:l2u_prev_map_cr = s:L2U_SetFallbackMapping('<CR>', s:l2u_fallback_trigger_cr)    imap <buffer> <CR> <Plug>L2UAutoSub -  inoremap <buffer><expr> <Plug>L2UAutoSub LaTeXtoUnicode#AutoSub("\n", "\<CR>") +  exec 'inoremap <buffer><expr> <Plug>L2UAutoSub LaTeXtoUnicode#AutoSub("\n", "' . s:l2u_fallback_trigger_cr . '")'    augroup L2UAutoSub      autocmd! * <buffer> @@ -637,7 +715,11 @@ function! s:L2U_UnsetAutoSub()    endif    iunmap <buffer> <CR> +  if empty(maparg("<CR>", "i")) +    call s:L2U_ReinstateMapping(b:l2u_prev_map_cr) +  endif    iunmap <buffer> <Plug>L2UAutoSub +  exe 'iunmap <buffer> ' . s:l2u_fallback_trigger_cr    augroup L2UAutoSub      autocmd! * <buffer>    augroup END | 
