Add support for escape sequences

This commit is contained in:
Gabriel Holodak 2017-11-30 22:15:39 -05:00
parent c28ce5f619
commit 6740c94562
3 changed files with 76 additions and 9 deletions

View File

@ -161,7 +161,7 @@ function! s:put_page(page) abort
while getline(1) =~# '^\s*$'
silent keepjumps 1delete _
endwhile
call man#highlight_backspaced_text()
call man#highlight_formatted_text()
setlocal filetype=man
endfunction
@ -375,7 +375,7 @@ function! man#init_pager() abort
else
keepjumps 1
endif
call man#highlight_backspaced_text()
call man#highlight_formatted_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')
@ -387,12 +387,12 @@ function! man#init_pager() abort
execute 'silent file man://'.fnameescape(ref)
endfunction
function! man#highlight_backspaced_text() abort
function! man#highlight_formatted_text() abort
let l:modifiable = &modifiable
set modifiable
lua man = require("man")
luado return man.highlight_backspaced(line, linenr)
luado return man.highlight_formatted(line, linenr)
let &modifiable = l:modifiable
endfunction

View File

@ -1,12 +1,60 @@
local function highlight_backspaced(line, linenr)
local function highlight_formatted(line, linenr)
local chars = {}
local prev_char = ''
local overstrike = false
local overstrike, escape = false, false
local hls = {} -- Store highlight groups as { attr, start, end }
local NONE, BOLD, UNDERLINE = 0, 1, 2
local NONE, BOLD, UNDERLINE, ITALIC = 0, 1, 2, 3
local hl_groups = {[BOLD]="manBold", [UNDERLINE]="manUnderline", [ITALIC]="manItalic"}
local attr = NONE
local byte = 0 -- byte offset
local function end_attr_hl(attr)
for i, hl in ipairs(hls) do
if hl[1] == attr and hl[3] == -1 then
hl[3] = byte
hls[i] = hl
end
end
end
local function add_attr_hl(code)
local on = true
if code == 0 then
attr = NONE
on = false
elseif code == 1 then
attr = BOLD
elseif code == 21 or code == 22 then
attr = BOLD
on = false
elseif code == 3 then
attr = ITALIC
elseif code == 23 then
attr = ITALIC
on = false
elseif code == 4 then
attr = UNDERLINE
elseif code == 24 then
attr = UNDERLINE
on = false
else
attr = NONE
return
end
if on then
hls[#hls + 1] = {attr, byte, -1}
else
if attr == NONE then
for a, _ in pairs(hl_groups) do
end_attr_hl(a)
end
else
end_attr_hl(attr)
end
end
end
-- Break input into UTF8 characters
for char in line:gmatch("[^\128-\191][\128-\191]*") do
if overstrike then
@ -45,6 +93,24 @@ local function highlight_backspaced(line, linenr)
prev_char = ''
byte = byte + #char
chars[#chars + 1] = char
elseif escape then
-- Use prev_char to store the escape sequence
prev_char = prev_char .. char
local sgr = prev_char:match("^%[([\020-\063]*)m$")
if sgr then
local match = ''
while sgr and #sgr > 0 do
match, sgr = sgr:match("^(%d*);?(.*)")
add_attr_hl(match + 0) -- coerce to number
end
escape = false
elseif not prev_char:match("^%[[\020-\063]*$") then
-- Stop looking if this isn't a partial CSI sequence
escape = false
end
elseif char == "\027" then
escape = true
prev_char = ''
elseif char == "\b" then
overstrike = true
prev_char = chars[#chars]
@ -61,7 +127,7 @@ local function highlight_backspaced(line, linenr)
vim.api.nvim_buf_add_highlight(
0,
-1,
hl[1] == BOLD and "manBold" or "manUnderline",
hl_groups[hl[1]],
linenr - 1,
hl[2],
hl[3]
@ -72,4 +138,4 @@ local function highlight_backspaced(line, linenr)
return table.concat(chars, '')
end
return { highlight_backspaced = highlight_backspaced }
return { highlight_formatted = highlight_formatted }

View File

@ -21,6 +21,7 @@ highlight default link manSubHeading Function
function! s:init_highlight_groups()
highlight default manUnderline cterm=underline gui=underline
highlight default manBold cterm=bold gui=bold
highlight default manItalic cterm=italic gui=italic
endfunction
augroup man_init_highlight_groups