Highlight backspaced characters

This commit is contained in:
Gabriel Holodak
2017-11-10 23:27:00 -05:00
parent 061b942dc0
commit 0446d4d691
2 changed files with 64 additions and 5 deletions

View File

@@ -148,7 +148,8 @@ function! s:get_page(path) abort
let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH let manwidth = empty($MANWIDTH) ? winwidth(0) : $MANWIDTH
" Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db). " Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).
" http://comments.gmane.org/gmane.editors.vim.devel/29085 " 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])) return s:system(cmd + (s:localfile_arg ? ['-l', a:path] : [a:path]))
endfunction endfunction
@@ -157,11 +158,10 @@ function! s:put_page(page) abort
setlocal noreadonly setlocal noreadonly
silent keepjumps %delete _ silent keepjumps %delete _
silent put =a:page 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*$' while getline(1) =~# '^\s*$'
silent keepjumps 1delete _ silent keepjumps 1delete _
endwhile endwhile
call man#highlight_backspaced_text()
setlocal filetype=man setlocal filetype=man
endfunction endfunction
@@ -370,13 +370,12 @@ function! s:format_candidate(path, psect) abort
endfunction endfunction
function! man#init_pager() abort 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*$' if getline(1) =~# '^\s*$'
silent keepjumps 1delete _ silent keepjumps 1delete _
else else
keepjumps 1 keepjumps 1
endif endif
call man#highlight_backspaced_text()
" This is not perfect. See `man glDrawArraysInstanced`. Since the title is " This is not perfect. See `man glDrawArraysInstanced`. Since the title is
" all caps it is impossible to tell what the original capitilization was. " all caps it is impossible to tell what the original capitilization was.
let ref = substitute(matchstr(getline(1), '^[^)]\+)'), ' ', '_', 'g') let ref = substitute(matchstr(getline(1), '^[^)]\+)'), ' ', '_', 'g')
@@ -388,4 +387,52 @@ function! man#init_pager() abort
execute 'silent file man://'.fnameescape(ref) execute 'silent file man://'.fnameescape(ref)
endfunction 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() call s:init()

View File

@@ -18,6 +18,18 @@ highlight default link manOptionDesc Constant
highlight default link manReference PreProc highlight default link manReference PreProc
highlight default link manSubHeading Function highlight default link manSubHeading Function
function! s:init_highlight_groups()
highlight default manUnderline cterm=underline gui=underline
highlight default manBold cterm=bold gui=bold
endfunction
augroup man_init_highlight_groups
autocmd!
autocmd ColorScheme * call s:init_highlight_groups()
augroup END
call s:init_highlight_groups()
if &filetype != 'man' if &filetype != 'man'
" May have been included by some other filetype. " May have been included by some other filetype.
finish finish