diff options
-rw-r--r-- | runtime/autoload/man.vim | 8 | ||||
-rw-r--r-- | runtime/lua/man.lua | 76 | ||||
-rw-r--r-- | runtime/syntax/man.vim | 1 |
3 files changed, 76 insertions, 9 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 12c1bf3c86..0a502be4c7 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -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 diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua index 63c2c14480..c3d7df2a2a 100644 --- a/runtime/lua/man.lua +++ b/runtime/lua/man.lua @@ -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 } diff --git a/runtime/syntax/man.vim b/runtime/syntax/man.vim index 9eb613169c..0544fb29e2 100644 --- a/runtime/syntax/man.vim +++ b/runtime/syntax/man.vim @@ -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 |