diff options
| author | Gabriel Holodak <gthepiper@gmail.com> | 2017-11-10 23:27:00 -0500 | 
|---|---|---|
| committer | Gabriel Holodak <gthepiper@gmail.com> | 2017-12-27 23:27:14 -0500 | 
| commit | 0446d4d6916d27041de5ac24ba0c741ae4ad5a39 (patch) | |
| tree | db2f0d82703d4934db530b3bec710105090adf4a /runtime/autoload/man.vim | |
| parent | 061b942dc07c5e63186b02fa2c89ae22881fbbdf (diff) | |
| download | rneovim-0446d4d6916d27041de5ac24ba0c741ae4ad5a39.tar.gz rneovim-0446d4d6916d27041de5ac24ba0c741ae4ad5a39.tar.bz2 rneovim-0446d4d6916d27041de5ac24ba0c741ae4ad5a39.zip  | |
Highlight backspaced characters
Diffstat (limited to 'runtime/autoload/man.vim')
| -rw-r--r-- | runtime/autoload/man.vim | 57 | 
1 files changed, 52 insertions, 5 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index dd71ede680..3ea0b734c0 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -148,7 +148,8 @@ function! s:get_page(path) abort    let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH    " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).    " http://comments.gmane.org/gmane.editors.vim.devel/29085 -  let cmd = ['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'man'] +  " Set MAN_KEEP_FORMATTING so Debian man doesn't discard backspaces. +  let cmd = ['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'MAN_KEEP_FORMATTING=1', 'man']    return s:system(cmd + (s:localfile_arg ? ['-l', a:path] : [a:path]))  endfunction @@ -157,11 +158,10 @@ function! s:put_page(page) abort    setlocal noreadonly    silent keepjumps %delete _    silent put =a:page -  " Remove all backspaced/escape characters. -  execute 'silent keeppatterns keepjumps %substitute,.\b\|\e\[\d\+m,,e'.(&gdefault?'':'g')    while getline(1) =~# '^\s*$'      silent keepjumps 1delete _    endwhile +  call man#highlight_backspaced_text()    setlocal filetype=man  endfunction @@ -370,13 +370,12 @@ function! s:format_candidate(path, psect) abort  endfunction  function! man#init_pager() abort -  " Remove all backspaced/escape characters. -  execute 'silent keeppatterns keepjumps %substitute,.\b\|\e\[\d\+m,,e'.(&gdefault?'':'g')    if getline(1) =~# '^\s*$'      silent keepjumps 1delete _    else      keepjumps 1    endif +  call man#highlight_backspaced_text()    " This is not perfect. See `man glDrawArraysInstanced`. Since the title is    " all caps it is impossible to tell what the original capitilization was.    let ref = substitute(matchstr(getline(1), '^[^)]\+)'), ' ', '_', 'g') @@ -388,4 +387,52 @@ function! man#init_pager() abort    execute 'silent file man://'.fnameescape(ref)  endfunction +function! man#highlight_backspaced_text() abort +  let l:modifiable = &modifiable +  set modifiable + +  let l:lines = getline(1, line('$')) +  call map(l:lines, function('s:highlight_backspaced_line')) +  call setline(1, l:lines) + +  let &modifiable = l:modifiable +endfunction + +" This pattern is for "overstruck" text containing backspaces. It matches bold +" text first, so a word beginning with "_^H_" is bold and text such as +" "_^Hf_^Ho_^Ho_^H__^Hb_^Ha_^Hr" is entirely underlined. +" +" Bolded text can also be mixed with whitespace as a performance tweak, since +" it's visually identical. +let s:backspace_pattern = '\v%((.)\b\1\s*)+|%(_\b.)+' + +function! s:highlight_backspaced_line(index, val) abort +  let l:line = a:val +  let l:search_pos = 0 + +  while 1 +    " Scanning for the next backspace without matching the entire pattern is +    " slightly faster +    let l:match_start = stridx(l:line, "\b", l:search_pos) +    if l:match_start == -1 +      break +    endif + +    let l:match = matchstrpos(l:line, s:backspace_pattern, l:match_start - 1) +    if l:match[0] =~# '^_\b[^_]' +      let l:hlgroup = 'manUnderline' +    else +      let l:hlgroup = 'manBold' +    endif + +    let l:stripped = substitute(l:match[0], '.\b', '', 'g') +    let l:search_pos = l:match[1] + len(l:stripped) +    let l:line = strpart(l:line, 0, l:match[1]) . l:stripped . strpart(l:line, l:match[2]) + +    call nvim_buf_add_highlight(0, -1, l:hlgroup, a:index, l:match[1], l:search_pos) +  endwhile + +  return l:line +endfunction +  call s:init()  | 
