diff options
| author | Adam Stankiewicz <sheerun@sher.pl> | 2017-12-06 13:05:56 +0100 | 
|---|---|---|
| committer | Adam Stankiewicz <sheerun@sher.pl> | 2017-12-06 13:05:56 +0100 | 
| commit | 9fe009095afdb86f6f771109ac454ccfc5340f31 (patch) | |
| tree | 1bb6b2fd7e2ff2b94bd3dd8ce6fdb735e873237b /autoload/LaTeXtoUnicode.vim | |
| parent | dce9e8dec5ef51730291c7bbff3e3997433eabbd (diff) | |
| download | vim-polyglot-9fe009095afdb86f6f771109ac454ccfc5340f31.tar.gz vim-polyglot-9fe009095afdb86f6f771109ac454ccfc5340f31.zip | |
Change julia provider to JuliaEditorSupport/julia-vim, closes #253
Diffstat (limited to '')
| -rw-r--r-- | autoload/LaTeXtoUnicode.vim | 625 | 
1 files changed, 625 insertions, 0 deletions
| diff --git a/autoload/LaTeXtoUnicode.vim b/autoload/LaTeXtoUnicode.vim new file mode 100644 index 00000000..581dec1e --- /dev/null +++ b/autoload/LaTeXtoUnicode.vim @@ -0,0 +1,625 @@ +if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'julia') == -1 +   +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Support for LaTex-to-Unicode conversion as in the Julia REPL " +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +function! s:L2U_Setup() + +  call s:L2U_SetupGlobal() + +  " 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 + +  " 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 + +  " Did we activate the L2U as-you-type substitutions? +  if !has_key(b:, "l2u_autosub_set") +    let b:l2u_autosub_set = 0 +  endif + +  " Following are some flags used to pass information between the function which +  " attempts the LaTeX-to-Unicode completion and the fallback function + +  " Was a (possibly partial) completion found? +  let b:l2u_found_completion = 0 +  " Is the cursor just after a single backslash +  let b:l2u_singlebslash = 0 +  " Backup value of the completeopt settings +  " (since we temporarily add the 'longest' setting while +  "  attempting LaTeX-to-Unicode) +  let b:l2u_backup_commpleteopt = &completeopt +  " Are we in the middle of a L2U tab completion? +  let b:l2u_tab_completing = 0 +  " Are we calling the tab fallback? +  let b:l2u_in_fallback = 0 + +endfunction + +function! s:L2U_SetupGlobal() + +  " Initialization of global and script-local variables +  " is only performed once +  if get(g:, "l2u_did_global_setup", 0) +    return +  endif + +  let g:l2u_did_global_setup = 1 + +  let g:l2u_symbols_dict = julia_latex_symbols#get_dict() + +  call s:L2U_deprecated_options() + +  if v:version < 704 +      let g:latex_to_unicode_tab = 0 +      let g:latex_to_unicode_auto = 0 +  endif + +  " YouCompleteMe and neocomplcache/neocomplete/deoplete plug-ins do not work well +  " with LaTeX symbols suggestions +  if exists("g:loaded_youcompleteme") || +        \ exists("g:loaded_neocomplcache") || +        \ exists("g:loaded_neocomplete") || +        \ exists("g:loaded_deoplete") +    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") +    if has("gui_running") +      let s:l2u_esc_sequence = "\u0006" +    else +      let s:l2u_esc_sequence = "\u0006\b" +    endif +  else +    let s:l2u_esc_sequence = "\u0091\b" +  end + +  " Trigger for the previous mapping of <Tab> +  let s:l2u_fallback_trigger = "\u0091L2UFallbackTab" + +endfunction + +" Each time the filetype changes, we may need to enable or +" disable the LaTeX-to-Unicode functionality +function! LaTeXtoUnicode#Refresh() + +  call s:L2U_Setup() + +  " by default, LaTeX-to-Unicode is only active on julia files +  let file_types = s:L2U_file_type_regex(get(g:, "latex_to_unicode_file_types", "julia")) +  let file_types_blacklist = s:L2U_file_type_regex(get(g:, "latex_to_unicode_file_types_blacklist", "$^")) + +  if match(&filetype, file_types) < 0 || match(&filetype, file_types_blacklist) >= 0 +    if b:l2u_enabled +      call LaTeXtoUnicode#Disable() +    else +      return +    endif +  elseif !b:l2u_enabled +    call LaTeXtoUnicode#Enable() +  endif + +endfunction + +function! LaTeXtoUnicode#Enable() + +  if b:l2u_enabled +    return +  end + +  call s:L2U_ResetLastCompletionInfo() + +  let b:l2u_enabled = 1 + +  " If we're editing the first file upon opening vim, this will only init the +  " command line mode mapping, and the full initialization will be performed by +  " the autocmd triggered by InsertEnter, defined in /ftdetect.vim. +  " Otherwise, if we're opening a file from within a running vim session, this +  " will actually initialize all the LaTeX-to-Unicode substitutions. +  call LaTeXtoUnicode#Init() + +  return + +endfunction + +function! LaTeXtoUnicode#Disable() +  if !b:l2u_enabled +    return +  endif +  let b:l2u_enabled = 0 +  call LaTeXtoUnicode#Init() +  return +endfunction + +" Translate old options to their new equivalents +function! s:L2U_deprecated_options() +  for [new, old] in [["latex_to_unicode_tab",         "julia_latex_to_unicode"], +                 \   ["latex_to_unicode_auto",        "julia_auto_latex_to_unicode"], +                 \   ["latex_to_unicode_suggestions", "julia_latex_suggestions_enabled"], +                 \   ["latex_to_unicode_eager",       "julia_latex_to_unicode_eager"]] +    if !has_key(g:, new) && has_key(g:, old) +      exec "let g:" . new . " = g:" . old +    endif +  endfor +endfunction + +function! s:L2U_file_type_regex(ft) +  if type(a:ft) == 3 +    let file_types = "\\%(" . join(a:ft, "\\|") . "\\)" +  elseif type(a:ft) == 1 +    let file_types = a:ft +  else +    echoerr "invalid file_type specification" +  endif +  return "^" . file_types . "$" +endfunction + +" Some data used to keep track of the previous completion attempt. +" Used to detect +" 1) if we just attempted the same completion, or +" 2) if backspace was just pressed while completing +" This function initializes and resets the required info + +function! s:L2U_ResetLastCompletionInfo() +  let b:l2u_completed_once = 0 +  let b:l2u_bs_while_completing = 0 +  let b:l2u_last_compl = { +        \ 'line': '', +        \ 'col0': -1, +        \ 'col1': -1, +        \ } +endfunction + +" This function only detects whether an exact match is found for a LaTeX +" symbol in front of the cursor +function! s:L2U_ismatch() +  let col1 = col('.') +  let l = getline('.') +  let col0 = match(l[0:col1-2], '\\[^[:space:]\\]\+$') +  if col0 == -1 +    return 0 +  endif +  let base = l[col0 : col1-1] +  return has_key(g:l2u_symbols_dict, base) +endfunction + +" Helper function to sort suggestion entries +function! s:L2U_partmatches_sort(p1, p2) +  return a:p1.word > a:p2.word ? 1 : a:p1.word < a:p2.word ? -1 : 0 +endfunction + +" Helper function to fix display of Unicode compose characters +" in the suggestions menu (they are displayed on top of '◌') +function! s:L2U_fix_compose_chars(uni) +  let u = matchstr(a:uni, '^.') +  let isc = ("\u0300" <= u && u <= "\u036F") || +          \ ("\u1DC0" <= u && u <= "\u1DFF") || +          \ ("\u20D0" <= u && u <= "\u20FF") || +          \ ("\uFE20" <= u && u <= "\uFE2F") +  return isc ? "\u25CC" . a:uni : a:uni +endfunction + +" Helper function to find the longest common prefix among +" partial completion matches (used when suggestions are disabled +" and in command line mode) +function! s:L2U_longest_common_prefix(partmatches) +  let common = a:partmatches[0] +  for i in range(1, len(a:partmatches)-1) +    let p = a:partmatches[i] +    if len(p) < len(common) +      let common = common[0 : len(p)-1] +    endif +    for j in range(1, len(common)-1) +      if p[j] != common[j] +        let common = common[0 : j-1] +        break +      endif +    endfor +  endfor +  return common +endfunction + +" Omnicompletion function. Besides the usual two-stage omnifunc behaviour, +" it has the following peculiar features: +"  *) keeps track of the previous completion attempt +"  *) sets some info to be used by the fallback function +"  *) either returns a list of completions if a partial match is found, or a +"     Unicode char if an exact match is found +"  *) forces its way out of completion mode through a hack in some cases +function! LaTeXtoUnicode#omnifunc(findstart, base) +  if a:findstart +    " first stage +    " avoid infinite loop if the fallback happens to call omnicompletion +    if b:l2u_in_fallback +      let b:l2u_in_fallback = 0 +      return -3 +    endif +    let b:l2u_in_fallback = 0 +    " set info for the callback +    let b:l2u_tab_completing = 1 +    let b:l2u_found_completion = 1 +    " analyse current line +    let col1 = col('.') +    let l = getline('.') +    let col0 = match(l[0:col1-2], '\\[^[:space:]\\]\+$') +    " compare with previous completion attempt +    let b:l2u_bs_while_completing = 0 +    let b:l2u_completed_once = 0 +    if col0 == b:l2u_last_compl['col0'] +      let prevl = b:l2u_last_compl['line'] +      if col1 == b:l2u_last_compl['col1'] && l ==# prevl +        let b:l2u_completed_once = 1 +      elseif col1 == b:l2u_last_compl['col1'] - 1 && l ==# prevl[0 : col1-2] . prevl[col1 : -1] +        let b:l2u_bs_while_completing = 1 +      endif +    endif +    " store completion info for next attempt +    let b:l2u_last_compl['col0'] = col0 +    let b:l2u_last_compl['col1'] = col1 +    let b:l2u_last_compl['line'] = l +    " is the cursor right after a backslash? +    let b:l2u_singlebslash = (match(l[0:col1-2], '\\$') >= 0) +    " completion not found +    if col0 == -1 +      let b:l2u_found_completion = 0 +      call feedkeys(s:l2u_esc_sequence, 'n') +      let col0 = -2 +    endif +    return col0 +  else +    " read settings (eager mode is implicit when suggestions are disabled) +    let suggestions = get(g:, "latex_to_unicode_suggestions", 1) +    let eager = get(g:, "latex_to_unicode_eager", 1) || !suggestions +    " search for matches +    let partmatches = [] +    let exact_match = 0 +    for k in keys(g:l2u_symbols_dict) +      if k ==# a:base +        let exact_match = 1 +      endif +      if len(k) >= len(a:base) && k[0 : len(a:base)-1] ==# a:base +        let menu = s:L2U_fix_compose_chars(g:l2u_symbols_dict[k]) +        if suggestions +          call add(partmatches, {'word': k, 'menu': menu}) +        else +          call add(partmatches, k) +        endif +      endif +    endfor +    " exact matches are replaced with Unicode +    " exceptions: +    "  *) we reached an exact match by pressing backspace while completing +    "  *) the exact match is one among many, and the eager setting is +    "     disabled, and it's the first time this completion is attempted +    if exact_match && !b:l2u_bs_while_completing && (len(partmatches) == 1 || eager || b:l2u_completed_once) +      " the completion is successful: reset the last completion info... +      call s:L2U_ResetLastCompletionInfo() +      " ...force our way out of completion mode... +      call feedkeys(s:l2u_esc_sequence, 'n') +      " ...return the Unicode symbol +      return [g:l2u_symbols_dict[a:base]] +    endif +    if !empty(partmatches) +      " here, only partial matches were found; either keep just the longest +      " common prefix, or pass them on +      if !suggestions +        let partmatches = [s:L2U_longest_common_prefix(partmatches)] +      else +        call sort(partmatches, "s:L2U_partmatches_sort") +      endif +    endif +    if empty(partmatches) +      call feedkeys(s:l2u_esc_sequence, 'n') +      let b:l2u_found_completion = 0 +    endif +    return partmatches +  endif +endfunction + +function! LaTeXtoUnicode#PutLiteral(k) +  call feedkeys(a:k, '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) +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 +  endif +  let rhs = mmdict["rhs"] +  if rhs =~# '^<Plug>L2U' +    return +  endif +  let pre = '<buffer>' +  if mmdict["silent"] +    let pre = pre . '<silent>' +  endif +  if mmdict["expr"] +    let pre = pre . '<expr>' +  endif +  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. +    if mmdict["expr"] +      let rhs = substitute(rhs, '\c' . a:s, "\<C-R>=LaTeXtoUnicode#PutLiteral('" . a:s . "')\<CR>", 'g') +    endif +  endif +  exe cmd . pre . ' ' . a:k . ' ' . 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()) +    call feedkeys(s:l2u_fallback_trigger) +    return '' +  endif +  " reset the in_fallback info +  let b:l2u_in_fallback = 0 +  " temporary change to completeopt to use the `longest` setting, which is +  " probably the only one which makes sense given that the goal of the +  " completion is to substitute the final string +  let b:l2u_backup_commpleteopt = &completeopt +  set completeopt+=longest +  set completeopt-=noinsert +  " invoke omnicompletion; failure to perform LaTeX-to-Unicode completion is +  " handled by the CompleteDone autocommand. +  return "\<C-X>\<C-O>" +endfunction + +" This function is called at every CompleteDone event, and is meant to handle +" the failures of LaTeX-to-Unicode completion by calling a fallback +function! LaTeXtoUnicode#FallbackCallback() +  if !b:l2u_tab_completing +    " completion was not initiated by L2U, nothing to do +    return +  else +    " completion was initiated by L2U, restore completeopt +    let &completeopt = b:l2u_backup_commpleteopt +  endif +  " at this point L2U tab completion is over +  let b:l2u_tab_completing = 0 +  " if the completion was successful do nothing +  if b:l2u_found_completion == 1 || b:l2u_singlebslash == 1 +    return +  endif +  " fallback +  let b:l2u_in_fallback = 1 +  call feedkeys(s:l2u_fallback_trigger) +  return +endfunction + +" This is the function which is mapped to <S-Tab> in command-line mode +function! LaTeXtoUnicode#CmdTab() +  " first stage +  " analyse command line +  let col1 = getcmdpos() - 1 +  let l = getcmdline() +  let col0 = match(l[0:col1-1], '\\[^[:space:]\\]\+$') +  let b:l2u_singlebslash = (match(l[0:col1-1], '\\$') >= 0) +  " completion not found +  if col0 == -1 +    return l +  endif +  let base = l[col0 : col1-1] +  " search for matches +  let partmatches = [] +  let exact_match = 0 +  for k in keys(g:l2u_symbols_dict) +    if k ==# base +      let exact_match = 1 +    endif +    if len(k) >= len(base) && k[0 : len(base)-1] ==# base +      call add(partmatches, k) +    endif +  endfor +  if len(partmatches) == 0 +    return l +  endif +  " exact matches are replaced with Unicode +  if exact_match +    let unicode = g:l2u_symbols_dict[base] +    if col0 > 0 +      let pre = l[0 : col0 - 1] +    else +      let pre = '' +    endif +    let posdiff = col1-col0 - len(unicode) +    call setcmdpos(col1 - posdiff + 1) +    return pre . unicode . l[col1 : -1] +  endif +  " no exact match: complete with the longest common prefix +  let common = s:L2U_longest_common_prefix(partmatches) +  if col0 > 0 +    let pre = l[0 : col0 - 1] +  else +    let pre = '' +  endif +  let posdiff = col1-col0 - len(common) +  call setcmdpos(col1 - posdiff + 1) +  return pre . common . l[col1 : -1] +endfunction + +" Setup the L2U tab mapping +function! s:L2U_SetTab(wait_insert_enter) +  if !b:l2u_cmdtab_set && get(g:, "latex_to_unicode_tab", 1) && b:l2u_enabled +    cmap <buffer> <S-Tab> <Plug>L2UCmdTab +    cnoremap <buffer> <Plug>L2UCmdTab <C-\>eLaTeXtoUnicode#CmdTab()<CR> +    let b:l2u_cmdtab_set = 1 +  endif +  if b:l2u_tab_set +    return +  endif +  " g:did_insert_enter is set from an autocommand in ftdetect +  if a:wait_insert_enter && !get(g:, "did_insert_enter", 0) +    return +  endif +  if !get(g:, "latex_to_unicode_tab", 1) || !b:l2u_enabled +    return +  endif + +  " Backup the previous omnifunc (the check is probably not really needed) +  if get(b:, "prev_omnifunc", "") != "LaTeXtoUnicode#omnifunc" +    let b:prev_omnifunc = &omnifunc +  endif +  setlocal omnifunc=LaTeXtoUnicode#omnifunc + +  call s:L2U_SetFallbackMapping('<Tab>', s:l2u_fallback_trigger) +  imap <buffer> <Tab> <Plug>L2UTab +  inoremap <buffer><expr> <Plug>L2UTab LaTeXtoUnicode#Tab() + +  augroup L2UTab +    autocmd! * <buffer> +    " Every time a completion finishes, the fallback may be invoked +    autocmd CompleteDone <buffer> call LaTeXtoUnicode#FallbackCallback() +  augroup END + +  let b:l2u_tab_set = 1 +endfunction + +" Revert the LaTeX-to-Unicode tab mapping settings +function! s:L2U_UnsetTab() +  if b:l2u_cmdtab_set +    cunmap <buffer> <S-Tab> +    let b:l2u_cmdtab_set = 0 +  endif +  if !b:l2u_tab_set +    return +  endif +  exec "setlocal omnifunc=" . get(b:, "prev_omnifunc", "") +  iunmap <buffer> <Tab> +  if empty(maparg("<Tab>", "i")) +    call s:L2U_SetFallbackMapping(s:l2u_fallback_trigger, '<Tab>') +  endif +  iunmap <buffer> <Plug>L2UTab +  exe 'iunmap <buffer> ' . s:l2u_fallback_trigger +  augroup L2UTab +    autocmd! * <buffer> +  augroup END +  let b:l2u_tab_set = 0 +endfunction + +" Function which looks for viable LaTeX-to-Unicode supstitutions as you type +function! LaTeXtoUnicode#AutoSub(...) +  let vc = a:0 == 0 ? v:char : a:1 +  let col1 = col('.') +  let lnum = line('.') +  if col1 == 1 +    if a:0 > 1 +      call feedkeys(a:2, 'n') +    endif +    return '' +  endif +  let bs = (vc != "\n") +  let l = getline(lnum)[0 : col1-1-bs] . v:char +  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') +    endif +    return '' +  endif +  let base = l[col0 : -1-bs] +  let unicode = get(g:l2u_symbols_dict, base, '') +  if empty(unicode) +    if a:0 > 1 +      call feedkeys(a:2, 'n') +    endif +    return '' +  endif +  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') +  return '' +endfunction + +" Setup the auto as-you-type LaTeX-to-Unicode substitution +function! s:L2U_SetAutoSub(wait_insert_enter) +  if b:l2u_autosub_set +    return +  endif +  " g:did_insert_enter is set from an autocommand in ftdetect +  if a:wait_insert_enter && !get(g:, "did_insert_enter", 0) +    return +  endif +  if !get(g:, "latex_to_unicode_auto", 0) || !b:l2u_enabled +    return +  endif +  " 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. +  imap <buffer> <CR> <Plug>L2UAutoSub +  inoremap <buffer><expr> <Plug>L2UAutoSub LaTeXtoUnicode#AutoSub("\n", "\<CR>") + +  augroup L2UAutoSub +    autocmd! * <buffer> +    autocmd InsertCharPre <buffer> call LaTeXtoUnicode#AutoSub() +  augroup END + +  let b:l2u_autosub_set = 1 +endfunction + +" Revert the auto LaTeX-to-Unicode settings +function! s:L2U_UnsetAutoSub() +  if !b:l2u_autosub_set +    return +  endif + +  iunmap <buffer> <CR> +  iunmap <buffer> <Plug>L2UAutoSub +  augroup L2UAutoSub +    autocmd! * <buffer> +  augroup END +  let b:l2u_autosub_set = 0 +endfunction + +" Initialization. Can be used to re-init when global settings have changed. +function! LaTeXtoUnicode#Init(...) +  let wait_insert_enter = a:0 > 0 ? a:1 : 1 + +  if !wait_insert_enter +    augroup L2UInit +      autocmd! +    augroup END +  endif + +  call s:L2U_UnsetTab() +  call s:L2U_UnsetAutoSub() + +  call s:L2U_SetTab(wait_insert_enter) +  call s:L2U_SetAutoSub(wait_insert_enter) +endfunction + +function! LaTeXtoUnicode#Toggle() +  call s:L2U_Setup() +  if b:l2u_enabled +    call LaTeXtoUnicode#Disable() +    echo "LaTeX-to-Unicode disabled" +  else +    call LaTeXtoUnicode#Enable() +    echo "LaTeX-to-Unicode enabled" +  endif +  return +endfunction + +endif | 
