neovim/runtime/lua/man.lua
2017-12-27 23:27:14 -05:00

76 lines
2.0 KiB
Lua

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 }