fix: fix float window style

This commit is contained in:
JuanZoran 2023-01-31 23:17:03 +08:00
parent 50ff4980ef
commit 86f8b7f6e8
10 changed files with 198 additions and 192 deletions

View File

@ -45,6 +45,11 @@
### 演示
https://user-images.githubusercontent.com/107862700/213752097-2eee026a-ddee-4531-bf80-ba2cbc8b44ef.mp4
> 视频演示的在线查询, 查询速度取决于你的网络状况
> 可以打开音量查看自动读音
https://user-images.githubusercontent.com/107862700/215941500-3293c571-20a1-44e2-b202-77079f158ce9.mp4
### 主题
> 如果你有更美观或者更适合的配色, 欢迎提PR
> 主题配色在: `lua/Trans/theme.lua`文件中,你只需要添加你主题的表就可以了

View File

@ -1,32 +1,16 @@
local api = vim.api
local format_meta = {
load_hl = function(self, content, line, col)
local space = self.space
for _, item in ipairs(self.items) do
item:load_hl(content, line, col)
col = col + #item.text + space
end
end
}
local content = {
newline = function(self, value)
if not self.modifiable then
error('content can not add newline now')
end
self.size = self.size + 1
self.lines[self.size] = value
local index = self.size + 1
self.size = index
self.lines[index] = value
end,
newhl = function(self, opt)
if not self.modifiable then
error('content can not add newline now')
end
self.hl_size = self.hl_size + 1
self.highlights[self.hl_size] = opt
local index = self.hl_size + 1
self.hl_size = index
self.highlights[index] = opt
end,
wipe = function(self)
@ -46,17 +30,19 @@ local content = {
end
offset = offset or 0
self.window:bufset('modifiable', true)
local window = self.window
local win = self.window
win:bufset('modifiable', true)
--- NOTE : 使用-1 则需要按顺序设置
api.nvim_buf_set_lines(window.bufnr, offset, -1, true, self.lines)
api.nvim_buf_set_lines(win.bufnr, offset, -1, true, self.lines)
local hl
local highlights = self.highlights
local method = api.nvim_buf_add_highlight
for i = 1, self.hl_size do
hl = self.highlights[i]
api.nvim_buf_add_highlight(window.bufnr, window.hl, hl.name, offset + hl.line, hl._start, hl._end)
hl = highlights[i]
method(win.bufnr, win.hl, hl.name, offset + hl.line, hl._start, hl._end)
end
self.window:bufset('modifiable', false)
win:bufset('modifiable', false)
end,
actual_height = function(self, wrap)
@ -80,45 +66,53 @@ local content = {
local nodes = opt.nodes
local size = #nodes
assert(size > 1, 'check items size')
local width = 0
local tot_width = 0
local strs = {}
for i, node in ipairs(nodes) do
local str = node.text
local str
for i = 1, size do
str = nodes[i].text
strs[i] = str
width = width + str:width()
tot_width = tot_width + str:width()
end
local space = math.floor(((win_width - width) / (size - 1)))
local space = math.floor(((win_width - tot_width) / (size - 1)))
if opt.strict and space < 0 then
return false
end
local interval = (' '):rep(space)
return setmetatable({
return {
text = table.concat(strs, interval),
items = nodes,
space = space,
}, { __index = format_meta })
load_hl = function(_, content, line, col)
for _, item in ipairs(nodes) do
item:load_hl(content, line, col)
col = col + #item.text + space
end
end
}
end,
center = function(self, item)
local space = bit.rshift(self.window.width - item.text:width(), 1)
item.text = (' '):rep(space) .. item.text
local text = item.text
local space = bit.rshift(self.window.width - text:width(), 1)
item.text = (' '):rep(space) .. text
local load_hl = item.load_hl
item.load_hl = function(this, content, line, col)
load_hl(this, content, line, col + space)
end
return item
end,
addline = function(self, ...)
local strs = {}
local col = 0
local str
local line = self.size -- line is zero index
for i, node in ipairs { ... } do
local str = node.text
str = node.text
strs[i] = str
node:load_hl(self, self.size, col)
node:load_hl(self, line, col)
col = col + #str
end
self:newline(table.concat(strs))
@ -135,7 +129,6 @@ return function(window)
window = { window, 't' },
}
return setmetatable({
modifiable = true,
window = window,
size = 0,
hl_size = 0,

View File

@ -61,9 +61,6 @@ M.conf = {
fail = '#e46876',
success = '#10b981',
},
engine = {
'本地',
}
},
order = { -- only work on hover mode
'title',
@ -117,17 +114,22 @@ M.setup = function(opts)
if opts then
M.conf = vim.tbl_deep_extend('force', M.conf, opts)
end
local conf = M.conf
local float = M.conf.float
local float = conf.float
if 0 < float.height and float.height <= 1 then
float.height = math.floor((vim.o.lines - vim.o.cmdheight - 1) * float.height)
end
if 0 < float.width and float.width <= 1 then
float.width = math.floor(vim.o.columns * float.width)
end
local engines = {}
for k, _ in pairs(conf.engine) do
table.insert(engines, k)
end
conf.engines = engines
times = times + 1
if times == 1 then
M.translate = require('Trans.translate')
@ -145,7 +147,7 @@ M.setup = function(opts)
end, { desc = ' 搜索翻译' })
local hls = require('Trans.ui.theme')[M.conf.theme]
local hls = require('Trans.ui.theme')[conf.theme]
for hl, opt in pairs(hls) do
vim.api.nvim_set_hl(0, hl, opt)
end

View File

@ -1,6 +1,5 @@
-- NOTE : 设置content的node
local item_meta = {
load_hl = function(self, content, line, col)
local item_load = function(self, content, line, col)
if self.hl then
content:newhl {
name = self.hl,
@ -10,41 +9,31 @@ local item_meta = {
}
end
end
}
local text_meta = {
load_hl = function(self, content, line, col)
for _, item in ipairs(self.items) do
item:load_hl(content, line, col)
col = col + #item.text
end
end,
}
item_meta.__index = item_meta
text_meta.__index = text_meta
return {
item = function(text, hl)
return setmetatable({
return {
text = text,
hl = hl,
}, item_meta)
load_hl = item_load,
}
end,
text = function(...)
local items = { ... }
local strs = {}
for i, item in ipairs(items) do
strs[i] = item.text
end
return setmetatable({
return {
text = table.concat(strs),
items = items,
}, text_meta)
load_hl = function(_, content, line, col)
for _, item in ipairs(items) do
item:load_hl(content, line, col)
col = col + #item.text
end
end
}
end,
}

View File

@ -17,33 +17,37 @@ local function get_select()
end
local function get_word(mode)
local word
if mode == 'n' then
return vim.fn.expand('<cword>')
word = vim.fn.expand('<cword>')
elseif mode == 'v' then
vim.api.nvim_input('<ESC>')
return get_select()
word = get_select()
elseif mode == 'i' then
-- TODO Use Telescope with fuzzy finder
---@diagnostic disable-next-line: param-type-mismatch
return vim.fn.input('请输入您要查询的单词: ')
vim.ui.input({ prompt = '请输入需要查询的单词: ' }, function(input)
word = input
end)
else
error('invalid mode: ' .. mode)
end
return word
end
local function translate(mode, view)
return function(mode, view)
vim.validate {
mode = { mode, 's', true },
view = { view, 's', true }
}
---@diagnostic disable-next-line: undefined-field
mode = mode or vim.api.nvim_get_mode().mode
view = view or require('Trans').conf.view[mode]
assert(mode and view)
local word = get_word(mode):gsub('^%s+', '', 1)
require('Trans.view.' .. view)(word)
local word = get_word(mode)
if word == nil or word == '' then
return
else
require('Trans.view.' .. view)(word:gsub('^%s+', '', 1))
end
end
return translate

View File

@ -1,5 +1,4 @@
local animation = {
display = function(self)
local display = function(self)
local callback = self.callback or function()
end
@ -46,12 +45,11 @@ local animation = {
end
frame()
end
end,
}
end
animation.__index = animation
return function(opts)
opts.run = true
return setmetatable(opts, animation)
opts.display = display
return opts
end

View File

@ -0,0 +1,6 @@
---判断单词是否含有中文
---@param word string 需要判断的单词
---@return boolean 判断结果
return function (word)
return false
end

View File

@ -3,17 +3,18 @@ local m_window
local m_result
local m_content
local engine_map = {
['本地'] = 'offline',
['百度'] = 'baidu',
['有道'] = 'youdao',
}
local node = require("Trans.node")
local t = node.text
local it = node.item
local engine_map = {
baidu = '百度',
youdao = '有道',
iciba = 'iciba',
offline = '本地',
}
local function set_tag_hl(name, status)
local hl = conf.float.tag[status]
m_window:set_hl(name, {
@ -27,29 +28,28 @@ local function set_tag_hl(name, status)
end
local function set_title()
local title = m_window.contents[1]
local title = m_window:new_content()
local github = ' https://github.com/JuanZoran/Trans.nvim'
title:addline(
title:center(it(github, '@text.uri'))
)
local format = '%s(%d)'
for i, engine_ch in ipairs(conf.float.engine) do
local engine_us = engine_map[engine_ch]
set_tag_hl(engine_us, 'wait')
local f = '%s(%d)'
local round = engine_us .. 'round'
title:addline(
t(
local tags = {}
local load_tag = function(engine, index)
set_tag_hl(engine, 'wait')
local round = engine .. 'round'
table.insert(tags, t(
it('', round),
it(format:format(engine_ch, i), engine_us),
it(f:format(engine_map[engine], index), engine),
it('', round)
)
)
title:newline('')
))
end
load_tag('offline', 1)
title:addline(unpack(tags))
title:newline('')
end
local action = {
@ -58,22 +58,34 @@ local action = {
end,
}
local exist = function (str)
return str and str ~= ''
end
local function process()
-- TODO :
local icon = conf.icon
m_content:addline(m_content:format {
nodes = {
it(m_result.word, 'TransWord'),
t(
it('['),
it(exist(m_result.phonetic) and m_result.phonetic or icon.notfound, 'TransPhonetic'),
it(']')
),
it(m_result.collins and icon.star:rep(m_result.collins) or icon.notfound, 'TransCollins'),
it(m_result.oxford == 1 and icon.yes or icon.no)
},
width = math.floor(m_window.width * 0.5)
})
m_content:addline(it('该窗口还属于实验性功能 .... '))
end
return function(word)
-- TODO :online query
local float = conf.float
local engine_ch = '本地'
local engine_us = engine_map[engine_ch]
vim.notify('[注意]: float窗口目前还待开发, 如果需要input查询功能, 请将窗口改成hover',
vim.log.WARN)
m_result = require('Trans.query.' .. engine_us)(word)
local opt = {
relative = 'editor',
width = float.width,
@ -83,19 +95,17 @@ return function(word)
animation = float.animation,
row = bit.rshift((vim.o.lines - float.height), 1),
col = bit.rshift((vim.o.columns - float.width), 1),
zindex = 50,
zindex = 20,
}
m_window = require('Trans.window')(true, opt)
set_title()
m_content = m_window.contents[2]
m_content = m_window:new_content()
m_result = require('Trans.query.offline')(word)
if m_result then
set_tag_hl(engine_us, 'success')
set_tag_hl('offline', 'success')
process()
else
set_tag_hl(engine_us, 'fail')
set_tag_hl('offline', 'fail')
end
m_window:open()

View File

@ -282,22 +282,23 @@ end
local function online_query(word)
-- TODO :Progress Bar
local lists = {}
local size = 0
local engines = conf.engines
local size = #engines
local icon = conf.icon
for k, _ in pairs(conf.engine) do
size = size + 1
lists[size] = require('Trans.query.' .. k)(word)
end
local error_msg = icon.notfound .. ' 没有找到相关的翻译'
m_window:set_height(1)
local width = m_window.width
m_window:set_width(error_msg:width())
if size == 0 then
m_content:addline(it(error_msg, 'TransFailed'))
m_window:open()
return
else
m_window:open()
for i = 1, size do
lists[size] = require('Trans.query.' .. engines[i])(word)
end
end
local cell = icon.cell

View File

@ -2,10 +2,7 @@ local api = vim.api
local new_content = require('Trans.content')
local new_animation = require('Trans.util.animation')
function string:width()
---@diagnostic disable-next-line: param-type-mismatch
return vim.fn.strwidth(self)
end
string.width = vim.fn.strwidth
local busy = false
local function lock()
@ -57,7 +54,7 @@ local window = {
---@nodiscard
is_open = function(self)
return self.winid > 0 and api.nvim_win_is_valid(self.winid)
return api.nvim_win_is_valid(self.winid)
end,
normal = function(self, key)
@ -96,12 +93,13 @@ local window = {
slid = 'width',
})[animation]
local method = 'nvim_win_set_' .. field
local method = api['nvim_win_set_' .. field]
local winid = self.winid
new_animation({
interval = interval,
times = self[field],
frame = function(_, times)
api[method](self.winid, times)
method(winid, times)
end,
callback = callback,
}):display()
@ -141,11 +139,12 @@ local window = {
})[animation]
local target = self[field]
local method = 'nvim_win_set_' .. field
local method = api['nvim_win_set_' .. field]
local winid = self.winid
new_animation({
times = target,
frame = function(_, times)
api[method](self.winid, target - times)
method(winid, target - times)
end,
callback = callback,
interval = interval,
@ -172,13 +171,13 @@ local window = {
self:open(opt)
end,
set_hl = function(self, name, hl)
api.nvim_set_hl(self.hl, name, hl)
set_hl = function(self, name, opts)
api.nvim_set_hl(self.hl, name, opts)
end,
new_content = function(self)
local index = self.size + 1
self.size = index + 1
self.size = index
self.contents[index] = new_content(self)
return self.contents[index]
@ -246,7 +245,6 @@ return function(entry, option)
api.nvim_win_set_hl_ns(win.winid, win.hl)
win:set_hl('Normal', { link = 'TransWin' })
win:set_hl('FloatBorder', { link = 'TransBorder' })
win:set_hl('NormalFloat', { link = 'TransBorder' })
---@diagnostic disable-next-line: return-type-mismatch
return win
end