diff options
author | Gabriel Holodak <gthepiper@gmail.com> | 2017-11-20 00:19:08 -0500 |
---|---|---|
committer | Gabriel Holodak <gthepiper@gmail.com> | 2017-12-27 23:27:14 -0500 |
commit | c28ce5f6191d233228d1688de300727e1ae42831 (patch) | |
tree | 409b1488d3f50369a0dd861ec97a20459d2ba604 | |
parent | 0446d4d6916d27041de5ac24ba0c741ae4ad5a39 (diff) | |
download | rneovim-c28ce5f6191d233228d1688de300727e1ae42831.tar.gz rneovim-c28ce5f6191d233228d1688de300727e1ae42831.tar.bz2 rneovim-c28ce5f6191d233228d1688de300727e1ae42831.zip |
Switch to processing in Lua
-rw-r--r-- | runtime/autoload/man.vim | 42 | ||||
-rw-r--r-- | runtime/lua/man.lua | 75 |
2 files changed, 77 insertions, 40 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim index 3ea0b734c0..12c1bf3c86 100644 --- a/runtime/autoload/man.vim +++ b/runtime/autoload/man.vim @@ -391,48 +391,10 @@ 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) + lua man = require("man") + luado return man.highlight_backspaced(line, linenr) 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() diff --git a/runtime/lua/man.lua b/runtime/lua/man.lua new file mode 100644 index 0000000000..63c2c14480 --- /dev/null +++ b/runtime/lua/man.lua @@ -0,0 +1,75 @@ +local function highlight_backspaced(line, linenr) + local chars = {} + local prev_char = '' + local overstrike = false + local hls = {} -- Store highlight groups as { attr, start, end } + local NONE, BOLD, UNDERLINE = 0, 1, 2 + local attr = NONE + local byte = 0 -- byte offset + + -- Break input into UTF8 characters + for char in line:gmatch("[^\128-\191][\128-\191]*") do + if overstrike then + local last_hl = hls[#hls] + if char == prev_char then + if char == '_' and attr == UNDERLINE and last_hl and last_hl[3] == byte then + -- This underscore is in the middle of an underlined word + attr = UNDERLINE + else + attr = BOLD + end + elseif prev_char == '_' then + -- char is underlined + attr = UNDERLINE + elseif prev_char == '+' and char == 'o' then + -- bullet (overstrike text '+^Ho') + attr = BOLD + char = [[·]] + elseif prev_char == [[·]] and char == 'o' then + -- bullet (additional handling for '+^H+^Ho^Ho') + attr = BOLD + char = [[·]] + else + -- use plain char + attr = NONE + end + + -- Grow the previous highlight group if possible + if last_hl and last_hl[1] == attr and last_hl[3] == byte then + last_hl[3] = byte + #char + else + hls[#hls + 1] = {attr, byte, byte + #char} + end + + overstrike = false + prev_char = '' + byte = byte + #char + chars[#chars + 1] = char + elseif char == "\b" then + overstrike = true + prev_char = chars[#chars] + byte = byte - #prev_char + chars[#chars] = nil + else + byte = byte + #char + chars[#chars + 1] = char + end + end + + for i, hl in ipairs(hls) do + if hl[1] ~= NONE then + vim.api.nvim_buf_add_highlight( + 0, + -1, + hl[1] == BOLD and "manBold" or "manUnderline", + linenr - 1, + hl[2], + hl[3] + ) + end + end + + return table.concat(chars, '') +end + +return { highlight_backspaced = highlight_backspaced } |