fix: fix format and process function behaviours

This commit is contained in:
JuanZoran
2023-01-10 17:51:07 +08:00
parent 1b95485ae6
commit a57a6e47ab
14 changed files with 193 additions and 324 deletions

View File

@ -69,7 +69,7 @@
- `vsplit` 在左边或者右边分屏
- 高度(height):
- `value > 1` 实际高度
- `value > 1` 最大高度
- `0 <= value <= 1` 相对高度
- `0 < value` 无限制

View File

@ -2,141 +2,136 @@ local type_check = require("Trans.util.debug").type_check
-- NOTE :中文字符及占两个字节宽但是在lua里是3个字节长度
-- 为了解决中文字符在lua的长度和neovim显示不一致的问题
local function get_width(str)
if type(str) ~= 'string' then
vim.pretty_print(str)
error('str!')
end
return vim.fn.strdisplaywidth(str)
end
local get_width = vim.fn.strdisplaywidth
local function format(win_width, items)
table.sort(items, function(a, b)
local wa, wb = 0, 0
if type(a) == 'string' then
wa = get_width(a)
a = { a }
else
wa = get_width(a[1])
end
if type(b) == 'string' then
wb = get_width(b)
b = { b }
else
wb = get_width(b[1])
end
return wa > wb
end)
local size = #items
local width = win_width - get_width(items[1][1])
local cols = 0
for i = 2, size do
width = width - 4 - get_width(items[i][1])
if width < 0 then
cols = i
break
local tot_width = 0
for i = 1, size do
if type(items[i]) == 'string' then
items[i] = { items[i] }
end
tot_width = tot_width + get_width(items[i][1]) + 4
end
if cols == 0 then
return items
else
-- 判断宽度是否超过最大宽度
if tot_width > win_width + 4 then
-- 放不下则需要分成多行
local lines = {}
local rows = math.floor(size / cols)
-- 行内字符串按照宽度排序
table.sort(items, function(a, b)
return get_width(a[1]) > get_width(b[1])
end)
local cols = 1
win_width = win_width - get_width(items[1][1])
while win_width > 0 and cols < size do
cols = cols + 1
win_width = win_width - get_width(items[cols][1]) + 4
end
cols = cols - 1
local rows = math.ceil(size / cols)
local rest = size % cols
if rest == 0 then
rest = cols
end
local max_width = get_width(items[1][1])
for i = 1, rows do
local index = rows - i + 1
lines[index] = {
interval = items.interval,
local index = 1 -- 当前操作的字符串下标
for i = rows, 1, -1 do -- 当前操作的行号
lines[i] = {
highlight = items.highlight,
indent = items.indent,
}
items[i][1] = items[i][1] .. (' '):rep(max_width - get_width(items[i][1]))
lines[index][1] = items[i]
local item = items[index]
item[1] = item[1] .. (' '):rep(max_width - get_width(item[1]))
lines[i][1] = items[index]
index = index + 1
end
local index = rows + 1
for col = 2, cols do
max_width = get_width(items[index])
max_width = get_width(items[index][1])
local _end = col > rest and rows - 1 or rows
for i = 1, _end do
local idx = _end - i + 1 -- 当前操作的行数
local item_idx = index + i - 1
local item = items[item_idx]
for i = _end, 1, -1 do
local item = items[index]
item[1] = item[1] .. (' '):rep(max_width - get_width(item[1]))
lines[idx][col] = item
lines[i][col] = item
index = index + 1
end
index = index + _end
end
return lines
return lines, true
else
return items
end
end
local function process(opts)
type_check {
opts = { opts, 'table' },
['opts.field'] = { opts.field, 'table', true },
['opts.order'] = { opts.order, 'table' },
['opts.win'] = { opts.win, 'table' },
['opts.win'] = { opts.win, 'table' },
['opts.engine'] = { opts.engine, 'table' },
}
if opts.field == nil then
local lines = {'no tranlation'}
local lines = { '⚠️ 本地没有找到相关释义' }
vim.api.nvim_buf_set_lines(opts.bufnr, 0, -1, false, lines)
return
end
vim.api.nvim_win_set_height(opts.winid, 1)
vim.api.nvim_win_set_width(opts.winid, get_width(lines[1]))
else
local content = require('Trans.component.content'):new()
for _, v in ipairs(opts.order) do
local component = require("Trans.component." .. 'offline' --[[ opts.engine ]] .. '.' .. v).component(opts.field)
if component then
for _, items in ipairs(component) do
local content = require('Trans.component.content'):new()
if items.needformat then
local formatted_items, split = format(opts.win.width, items)
if split then
for _, itms in ipairs(formatted_items) do
content:insert(itms)
end
else
content:insert(formatted_items)
end
for _, v in ipairs(opts.order) do
local component = require("Trans.component." .. 'offline' --[[ opts.engine ]] .. '.' .. v).component(opts.field)
-- vim.pretty_print(component)
else
content:insert(items)
end
for _, items in ipairs(component) do
local formatted_items, split = format(opts.win.width, items)
if split then
for _, itms in ipairs(formatted_items) do
content:insert(itms)
end
else
content:insert(formatted_items)
end
end
content:attach(opts.bufnr, opts.winid)
end
local lines, __highlight = content:data()
vim.api.nvim_buf_set_lines(opts.bufnr, 0, -1, false, lines)
for line, l_hl in ipairs(__highlight) do
for _, hl in ipairs(l_hl) do
vim.api.nvim_buf_add_highlight(opts.bufnr, -1, hl.name, line, hl._start, hl._end)
end
end
vim.api.nvim_buf_set_option(opts.bufnr, 'modifiable', false)
vim.api.nvim_buf_set_option(opts.bufnr, 'filetype', 'Trans')
vim.api.nvim_win_set_option(opts.winid, 'winhl', 'Normal:TransCursorWin,FloatBorder:TransCursorBorder')
if opts.win.style == 'cursor' then
vim.api.nvim_create_autocmd(
{ 'InsertEnter', 'CursorMoved', 'BufLeave', }, {
buffer = 0,
once = true,
callback = function ()
vim.api.nvim_win_close(opts.winid, true)
callback = function()
if vim.api.nvim_win_is_valid(opts.winid) then
vim.api.nvim_win_close(opts.winid, true)
end
end,
})
end

View File

@ -2,14 +2,17 @@ local type_check = require("Trans.util.debug").type_check
local query = require("Trans.api").query
local function get_select()
local s_start = vim.fn.getpos("'<")
local s_end = vim.fn.getpos("'>")
if s_start[2] ~= s_start[2] then
error('TODO: multiline translate')
local s_start = vim.fn.getpos("v")
local s_end = vim.fn.getpos(".")
local n_lines = math.abs(s_end[2] - s_start[2]) + 1
local lines = vim.api.nvim_buf_get_lines(0, s_start[2] - 1, s_end[2], false)
lines[1] = string.sub(lines[1], s_start[3], -1)
if n_lines == 1 then
lines[n_lines] = string.sub(lines[n_lines], 1, s_end[3] - s_start[3] + 1)
else
lines[n_lines] = string.sub(lines[n_lines], 1, s_end[3])
end
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
return table.concat(lines, '\n')
end
local query_wrapper = function(opts)
@ -21,15 +24,15 @@ local query_wrapper = function(opts)
local word = ''
if opts.method == 'input' then
---@diagnostic disable-next-line: param-type-mismatch
word = vim.fn.input('请输入您要查询的单词:') -- TODO Use Telescope with fuzzy finder
elseif opts.method == 'n' then
word = vim.fn.expand('<cword>')
elseif opts.mehotd == 'v' then
elseif opts.method == 'v' then
word = get_select()
-- TODO : other method
else
error('invalid method' .. opts.method)
end

View File

@ -21,6 +21,7 @@ local function get_opts(opts)
opts.engine = { opts.engine }
end
if opts.win then
local width, height = opts.win.width, opts.win.height
if width and width > 0 and width <= 1 then
@ -35,6 +36,7 @@ local function get_opts(opts)
return vim.tbl_extend('force', default_conf, opts)
end
-- EXAMPLE :
-- require('Trans').translate({
-- method = 'input', -- 不填则自动判断mode获取查询的单词
@ -52,6 +54,7 @@ end
-- })
local function create_win(win)
local bufnr = vim.api.nvim_create_buf(false, true)
@ -81,6 +84,7 @@ local function create_win(win)
return bufnr, winid
end
local function translate(opts)
vim.validate {
opts = { opts, 'table', true }