From 1b95485ae68439e1833a30e32cecb731cfb66973 Mon Sep 17 00:00:00 2001 From: JuanZoran <1430359574@qq.com> Date: Tue, 10 Jan 2023 14:40:28 +0800 Subject: [PATCH] fix: try reducing some bugs --- lua/Trans/component/content.lua | 1 + lua/Trans/component/offline/Title.lua | 21 ++-- lua/Trans/conf/default.lua | 2 +- lua/Trans/core/process.lua | 132 +++++++++++++++++++++++--- lua/Trans/core/translate.lua | 16 ++-- lua/Trans/util/format.lua | 1 - lua/Trans/util/test/query_youdao.lua | 23 +++-- lua/Trans/util/test/test.lua | 12 ++- 8 files changed, 163 insertions(+), 45 deletions(-) diff --git a/lua/Trans/component/content.lua b/lua/Trans/component/content.lua index 86c7e3b..7adc86a 100644 --- a/lua/Trans/component/content.lua +++ b/lua/Trans/component/content.lua @@ -69,6 +69,7 @@ function M:data() -- NOTE 返回格式化的行,如果需要高亮,则第二个参数返回高亮 local lines = {} local highlights = {} + for index = 1, #self.lines do local line = '' local highlight = {} diff --git a/lua/Trans/component/offline/Title.lua b/lua/Trans/component/offline/Title.lua index d02eb69..c1203a8 100644 --- a/lua/Trans/component/offline/Title.lua +++ b/lua/Trans/component/offline/Title.lua @@ -37,15 +37,15 @@ local icon = require("Trans.conf.loader").loaded_conf.ui.icon ---@return component component 提取的组件信息[包含多个组件] M.component = function(field) local component = {} - local stuffs = {} local data = { - {field.word, 'TransWord'}, + { field.word, 'TransWord' }, } - if display.phonetic and field.phonetic then - table.insert(data, { - '[' .. field.phonetic .. ']', 'TransPhonetic' - }) + if display.phnoetic and field.phonetic ~= '' then + table.insert( + data, + { '[' .. field.phonetic .. ']', 'TransPhonetic' } + ) end if display.collins and field.collins then @@ -55,13 +55,12 @@ M.component = function(field) end if display.oxford and field.oxford then - table.insert(data, { - field.oxford - }) + table.insert(data, + { field.oxford == 1 and icon.isOxford or icon.notOxford, } + ) end - stuffs.data = data - component[1] = stuffs + component[1] = data return component end diff --git a/lua/Trans/conf/default.lua b/lua/Trans/conf/default.lua index 5e92c18..4518665 100644 --- a/lua/Trans/conf/default.lua +++ b/lua/Trans/conf/default.lua @@ -75,7 +75,7 @@ M.conf = { }, display = { phnoetic = true, - collins_star = true, + collins = true, oxford = true, -- TODO -- history = false, diff --git a/lua/Trans/core/process.lua b/lua/Trans/core/process.lua index dd2ef48..82df19b 100644 --- a/lua/Trans/core/process.lua +++ b/lua/Trans/core/process.lua @@ -1,39 +1,145 @@ 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 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 + end + end -local function format(component, interval) + if cols == 0 then + return items + else + local lines = {} + local rows = math.floor(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, + 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] + end + + local index = rows + 1 + for col = 2, cols do + max_width = get_width(items[index]) + 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] + item[1] = item[1] .. (' '):rep(max_width - get_width(item[1])) + + + lines[idx][col] = item + end + index = index + _end + end + + return lines + end end -local function process (opts) +local function process(opts) type_check { - opts = { opts, 'table' }, - ['opts.field'] = { opts.field , 'table' }, - ['opts.order'] = { opts.order , 'table' }, - ['opts.win'] = { opts.win , 'table' }, - ['opts.engine'] = { opts.engine , 'table' }, + opts = { opts, 'table' }, + ['opts.field'] = { opts.field, 'table', true }, + ['opts.order'] = { opts.order, 'table' }, + ['opts.win'] = { opts.win, 'table' }, + ['opts.engine'] = { opts.engine, 'table' }, } + if opts.field == nil then + local lines = {'no tranlation'} + vim.api.nvim_buf_set_lines(opts.bufnr, 0, -1, false, lines) + return + end + + local content = require('Trans.component.content'):new() for _, v in ipairs(opts.order) do - local component = require("Trans.component." .. opts.engine .. '.' .. v) + local component = require("Trans.component." .. 'offline' --[[ opts.engine ]] .. '.' .. v).component(opts.field) + -- vim.pretty_print(component) + for _, items in ipairs(component) do - format(items) - content:insert(items) + 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 end local lines, __highlight = content:data() - vim.api.nvim_buf_set_lines(opts.bufnr, 0, lines) + 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, line, hl.name, hl._start, hl._end) + 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') + 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) + end, + }) + end end - return process diff --git a/lua/Trans/core/translate.lua b/lua/Trans/core/translate.lua index af88e91..b66b3c2 100644 --- a/lua/Trans/core/translate.lua +++ b/lua/Trans/core/translate.lua @@ -7,7 +7,7 @@ local function get_opts(opts) local default_conf = { method = vim.api.nvim_get_mode().mode, engine = { - 'local', + 'offline', -- TODO : other engine }, win = { @@ -52,18 +52,16 @@ end -- }) -local function create_win(opts) +local function create_win(win) local bufnr = vim.api.nvim_create_buf(false, true) - vim.api.nvim_buf_set_option(bufnr, 'filetype', 'Trans') - vim.api.nvim_buf_set_option(bufnr, 'modifiable', false) - local is_float = opts.style == 'float' + local is_float = win.style == 'float' local win_opts = { relative = is_float and 'editor' or 'cursor', - width = opts.width, - height = opts.height, + width = win.width, + height = win.height, style = 'minimal', - border = conf.style.window[opts.win.style].border, + border = conf.style.window[win.style].border, title = 'Trans', title_pos = 'center', focusable = true, @@ -98,10 +96,10 @@ local function translate(opts) local proc_opts = { bufnr = bufnr, winid = winid, + win = opts.win, field = field, order = conf.order['offline'], engine = { 'offline' }, - win_opts = opts.win, } core.process(proc_opts) diff --git a/lua/Trans/util/format.lua b/lua/Trans/util/format.lua index bdc4bec..b9c62fe 100644 --- a/lua/Trans/util/format.lua +++ b/lua/Trans/util/format.lua @@ -7,7 +7,6 @@ function string:width() return vim.fn.strdisplaywidth(self) end - local s_to_b = true -- 从小到大排列 local m_win_width -- 需要被格式化窗口的高度 diff --git a/lua/Trans/util/test/query_youdao.lua b/lua/Trans/util/test/query_youdao.lua index 1d064f8..8653e25 100644 --- a/lua/Trans/util/test/query_youdao.lua +++ b/lua/Trans/util/test/query_youdao.lua @@ -43,16 +43,21 @@ end -- curl --data {{'{"name":"bob"}'}} --header {{'Content-Type: application/json'}} {{http://example.com/users/1234}} local function query_word(q) - local field = ( - [[curl -s --header 'Content-Type: application/x-www-form-urlencoded' https://openapi.youdao.com/api]]) - for k, v in pairs(q) do - field = field .. ([[ -d '%s=%s']]):format(k, v) + local ok, curl = pcall(require, 'plenary.curl') + if ok then + -- TODO + else + local field = ( + [[curl -s --header 'Content-Type: application/x-www-form-urlencoded' https://openapi.youdao.com/api]]) + + for k, v in pairs(q) do + field = field .. ([[ -d '%s=%s']]):format(k, v) + end + + local output = vim.fn.system(field) + local tb = vim.fn.json_decode(output) + return tb end - -- vim.pretty_print(field) - local output = vim.fn.system(field) - local tb = vim.fn.json_decode(output) - -- print(type(output)) - -- vim.pretty_print(tb.basic) end M.test = function(query) diff --git a/lua/Trans/util/test/test.lua b/lua/Trans/util/test/test.lua index a5bd3c3..72af591 100644 --- a/lua/Trans/util/test/test.lua +++ b/lua/Trans/util/test/test.lua @@ -5,4 +5,14 @@ local a = { } -print(a, b) +local function test(tmp) + tmp = { + 'bbbbbb' + } +end + + +test(a) +for i, v in ipairs(a) do + print(v) +end