298 lines
7.9 KiB
Lua
298 lines
7.9 KiB
Lua
local M = {}
|
|
|
|
local api = vim.api
|
|
local display = require("Trans").conf.display
|
|
local icon = require("Trans").conf.icon
|
|
local order = require("Trans").conf.order
|
|
|
|
local hl = require("Trans.highlight").hlgroup
|
|
|
|
local buf = require("Trans.conf").buf
|
|
local win = 0
|
|
local line = 0
|
|
local pos_info = {}
|
|
|
|
api.nvim_buf_set_option(buf, 'filetype', 'Trans')
|
|
|
|
|
|
local function show_win(width, height)
|
|
win = api.nvim_open_win(buf, false, {
|
|
relative = 'cursor',
|
|
title = 'Trans',
|
|
title_pos = 'center',
|
|
style = display.style,
|
|
col = display.offset_x,
|
|
row = display.offset_y,
|
|
width = (display.max_width > 0 and width > display.max_width) and display.max_width or width,
|
|
height = (display.max_width > 0 and height > display.max_height) and display.max_height or height,
|
|
border = display.border_style,
|
|
focusable = true,
|
|
})
|
|
api.nvim_win_set_option(win, 'wrap', display.wrap)
|
|
end
|
|
|
|
-- NOTE: title
|
|
local function get_title(text, query_res)
|
|
local title = string.format('%s [%s] ', query_res.word, query_res.phonetic) ..
|
|
(display.oxford and (query_res.oxford == 1 and icon.isOxford .. ' ' or icon.notOxford .. ' ') or '') ..
|
|
((display.collins_star and query_res.collins) and string.rep(icon.star, query_res.collins) or '')
|
|
table.insert(text, title)
|
|
|
|
pos_info.title = {}
|
|
pos_info.title.word = #query_res.word
|
|
pos_info.title.phonetic = query_res.phonetic and #query_res.phonetic or 3
|
|
pos_info.title.line = line
|
|
line = line + 1
|
|
end
|
|
|
|
-- NOTE: tag
|
|
local function get_tag(text, query_res)
|
|
if query_res.tag and #query_res.tag > 0 then
|
|
local tag = query_res.tag:gsub('zk', '中考'):gsub('gk', '高考'):gsub('ky', '考研'):gsub('cet4', '四级'):
|
|
gsub('cet6', '六级'):
|
|
gsub('ielts', '雅思'):gsub('toefl', '托福'):gsub('gre', 'GRE')
|
|
table.insert(text, '标签:')
|
|
table.insert(text, ' ' .. tag)
|
|
table.insert(text, '')
|
|
|
|
pos_info.tag = line
|
|
line = line + 3
|
|
end
|
|
end
|
|
|
|
-- NOTE: pos 词性
|
|
local function get_pos(text, query_res)
|
|
if query_res.pos and #query_res.pos > 0 then
|
|
table.insert(text, '词性:')
|
|
|
|
local content = 0
|
|
for v in vim.gsplit(query_res.pos, [[/]]) do
|
|
table.insert(text, string.format(' %s', v .. '%'))
|
|
content = content + 1
|
|
end
|
|
|
|
table.insert(text, '')
|
|
|
|
pos_info.pos = {}
|
|
pos_info.pos.line = line
|
|
pos_info.pos.content = content
|
|
line = line + content + 2
|
|
end
|
|
end
|
|
|
|
-- NOTE: exchange
|
|
local function get_exchange(text, query_res)
|
|
if query_res.exchange and #query_res.exchange > 0 then
|
|
table.insert(text, '词形变化:')
|
|
|
|
local exchange_map = {
|
|
p = '过去式',
|
|
d = '过去分词',
|
|
i = '现在分词',
|
|
r = '形容词比较级',
|
|
t = '形容词最高级',
|
|
s = '名词复数形式',
|
|
O = '词干',
|
|
['3'] = '第三人称单数',
|
|
}
|
|
|
|
local content = 0
|
|
for v in vim.gsplit(query_res.exchange, [[/]]) do
|
|
table.insert(text, string.format(' %s: %s', exchange_map[v:sub(1, 1)], v:sub(3)))
|
|
content = content + 1
|
|
-- FIXME: 中文字符与字母位宽不一致, 暂时无法对齐
|
|
end
|
|
table.insert(text, '')
|
|
|
|
pos_info.exchange = {}
|
|
pos_info.exchange.line = line
|
|
pos_info.exchange.content = content
|
|
line = line + content + 2
|
|
end
|
|
end
|
|
|
|
-- NOTE: 中文翻译
|
|
local function get_zh(text, query_res)
|
|
if query_res.translation then
|
|
table.insert(text, '中文翻译:')
|
|
|
|
local content = 0
|
|
for v in vim.gsplit(query_res.translation, '\n') do
|
|
table.insert(text, ' ' .. v)
|
|
content = content + 1
|
|
end
|
|
table.insert(text, '')
|
|
|
|
pos_info.zh = {}
|
|
pos_info.zh.line = line
|
|
pos_info.zh.content = content
|
|
line = content + line + 2
|
|
end
|
|
end
|
|
|
|
-- NOTE: 英文翻译
|
|
local function get_en(text, query_res)
|
|
if query_res.definition and #query_res.definition > 0 then
|
|
table.insert(text, '英文翻译:')
|
|
|
|
local content = 0
|
|
for v in vim.gsplit(query_res.definition, '\n') do
|
|
table.insert(text, ' ' .. v)
|
|
content = content + 1
|
|
end
|
|
table.insert(text, '')
|
|
|
|
pos_info.en = {}
|
|
pos_info.en.line = line
|
|
pos_info.en.content = content
|
|
line = line + content + 2
|
|
end
|
|
end
|
|
|
|
local handler = {
|
|
title = get_title,
|
|
tag = get_tag,
|
|
pos = get_pos,
|
|
exchange = get_exchange,
|
|
zh = get_zh,
|
|
en = get_en,
|
|
}
|
|
|
|
|
|
-- @return string array
|
|
local function get_text(query_res)
|
|
local text = {}
|
|
for _, v in ipairs(order) do
|
|
handler[v](text, query_res)
|
|
end
|
|
return text
|
|
end
|
|
|
|
local function set_text(query_res)
|
|
local text = query_res and get_text(query_res) or { '没有找到相关定义' }
|
|
|
|
api.nvim_buf_set_lines(buf, 0, -1, false, text)
|
|
local width = 0
|
|
for _, v in ipairs(text) do
|
|
if #v > width then
|
|
width = v:len()
|
|
end
|
|
end
|
|
return width, #text
|
|
end
|
|
|
|
local function hl_title()
|
|
api.nvim_buf_add_highlight(buf, -1, hl.word, pos_info.title.line, 0, pos_info.title.word)
|
|
api.nvim_buf_add_highlight(buf, -1, hl.phonetic, pos_info.title.line, pos_info.title.word + 5,
|
|
pos_info.title.word + 5 + pos_info.title.phonetic)
|
|
end
|
|
|
|
local function hl_tag()
|
|
if pos_info.tag then
|
|
api.nvim_buf_add_highlight(buf, -1, hl.ref, pos_info.tag, 0, -1)
|
|
api.nvim_buf_add_highlight(buf, -1, hl.tag, pos_info.tag + 1, 0, -1)
|
|
end
|
|
end
|
|
|
|
local function hl_pos()
|
|
if pos_info.pos then
|
|
api.nvim_buf_add_highlight(buf, -1, hl.ref, pos_info.pos.line, 0, -1)
|
|
for i = 1, pos_info.pos.content, 1 do
|
|
api.nvim_buf_add_highlight(buf, -1, hl.pos, pos_info.pos.line + i, 0, -1)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function hl_exchange()
|
|
if pos_info.exchange then
|
|
api.nvim_buf_add_highlight(buf, -1, hl.ref, pos_info.exchange.line, 0, -1)
|
|
for i = 1, pos_info.exchange.content, 1 do
|
|
api.nvim_buf_add_highlight(buf, -1, hl.exchange, pos_info.exchange.line + i, 0, -1)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function hl_zh()
|
|
api.nvim_buf_add_highlight(buf, -1, hl.ref, pos_info.zh.line, 0, -1)
|
|
for i = 1, pos_info.zh.content, 1 do
|
|
api.nvim_buf_add_highlight(buf, -1, hl.zh, pos_info.zh.line + i, 0, -1)
|
|
end
|
|
end
|
|
|
|
local function hl_en()
|
|
if pos_info.en then
|
|
api.nvim_buf_add_highlight(buf, -1, hl.ref, pos_info.en.line, 0, -1)
|
|
for i = 1, pos_info.en.content, 1 do
|
|
api.nvim_buf_add_highlight(buf, -1, hl.en, pos_info.en.line + i, 0, -1)
|
|
end
|
|
end
|
|
end
|
|
|
|
local hl_handler = {
|
|
title = hl_title,
|
|
tag = hl_tag,
|
|
pos = hl_pos,
|
|
exchange = hl_exchange,
|
|
zh = hl_zh,
|
|
en = hl_en,
|
|
}
|
|
|
|
local function set_hl()
|
|
for _, v in ipairs(order) do
|
|
hl_handler[v]()
|
|
end
|
|
end
|
|
|
|
local function clear_tmp_info()
|
|
pos_info = {}
|
|
line = 0
|
|
end
|
|
|
|
local function get_visual_selection()
|
|
local s_start = vim.fn.getpos("'<")
|
|
local s_end = vim.fn.getpos("'>")
|
|
assert(s_end[2] == s_start[2])
|
|
local lin = vim.api.nvim_buf_get_lines(0, s_start[2] - 1, s_end[2], false)[1]
|
|
local word = string.sub(lin, s_start[3], s_end[3])
|
|
return word
|
|
end
|
|
|
|
|
|
function M.query(mode)
|
|
assert(buf > 0)
|
|
local word = ''
|
|
if mode == 'n' then
|
|
word = vim.fn.expand('<cword>')
|
|
elseif mode == 'v' then
|
|
word = get_visual_selection()
|
|
else
|
|
print(mode, 'is invalid')
|
|
assert(false)
|
|
end
|
|
|
|
local res = require("Trans.database").query(word)
|
|
local width, height = set_text(res)
|
|
show_win(width, height)
|
|
if res then
|
|
set_hl()
|
|
clear_tmp_info()
|
|
end
|
|
end
|
|
|
|
function M.query_cursor()
|
|
M.query('n')
|
|
end
|
|
|
|
function M.query_select()
|
|
M.query('v')
|
|
end
|
|
|
|
function M.close_win()
|
|
if win > 0 then
|
|
api.nvim_win_close(win, true)
|
|
win = 0
|
|
end
|
|
end
|
|
|
|
return M
|