From e5f0f2bf34b6a14305f6d289e431cddc62d26997 Mon Sep 17 00:00:00 2001 From: JuanZoran <1430359574@qq.com> Date: Wed, 15 Mar 2023 11:34:50 +0800 Subject: [PATCH] feat: add auto resize animation --- lua/Trans/core/backend.lua | 2 +- lua/Trans/core/buffer.lua | 14 ------- lua/Trans/core/translate.lua | 8 +++- lua/Trans/core/util.lua | 38 +++++++++++++++++++ lua/Trans/core/window.lua | 40 +++++++++++--------- lua/Trans/frontend/hover/init.lua | 62 +++++++++++++++++++------------ 6 files changed, 106 insertions(+), 58 deletions(-) diff --git a/lua/Trans/core/backend.lua b/lua/Trans/core/backend.lua index 1ffdb5b..50a9801 100644 --- a/lua/Trans/core/backend.lua +++ b/lua/Trans/core/backend.lua @@ -2,7 +2,7 @@ local Trans = require('Trans') ---@class TransBackend ----@field query fun(TransData): TransResult +---@field query fun(data: TransData)---@async ---@field opts TransBackendOpts ---@field no_wait? boolean whether need to wait for the result ---@field name string @backend name diff --git a/lua/Trans/core/buffer.lua b/lua/Trans/core/buffer.lua index cbb9938..b9e85f2 100644 --- a/lua/Trans/core/buffer.lua +++ b/lua/Trans/core/buffer.lua @@ -14,8 +14,6 @@ end ---@param _start? integer start line index ---@param _end? integer end line index function buffer:del(_start, _end) - -- FIXME : - ---@diagnostic disable-next-line: cast-local-type _start = _start or '$' fn.deletebufline(self.bufnr, _start, _end) @@ -102,18 +100,6 @@ function buffer:add_highlight(linenr, hl_group, col_start, col_end, ns) api.nvim_buf_add_highlight(self.bufnr, ns or -1, hl_group, linenr, col_start, col_end or -1) end ----Calculate buffer content display height ----@param width integer ----@return integer height -function buffer:height(width) - local lines = self:lines() - local height = 0 - for _, line in ipairs(lines) do - height = height + math.max(1, (math.ceil(line:width() / width))) - end - return height -end - ---Get buffer line count ---@return integer function buffer:line_count() diff --git a/lua/Trans/core/translate.lua b/lua/Trans/core/translate.lua index 1328d47..b9f9936 100644 --- a/lua/Trans/core/translate.lua +++ b/lua/Trans/core/translate.lua @@ -3,7 +3,6 @@ local util = Trans.util local function init_opts(opts) opts = opts or {} - ---@type TransMode opts.mode = opts.mode or ({ n = 'normal', v = 'visual', @@ -19,9 +18,12 @@ end ---@return TransResult? @return nil if no result local function do_query(data) -- HACK :Rewrite this function to support multi requests + + ---@type TransFrontend local frontend = data.frontend local result = data.result for _, backend in ipairs(data.backends) do + ---@cast backend TransBackend local name = backend.name if backend.no_wait then backend.query(data) @@ -32,11 +34,13 @@ local function do_query(data) if type(result[name]) == 'table' then + ---@diagnostic disable-next-line: return-type-mismatch return result[name] else result[name] = nil end end + end @@ -68,7 +72,7 @@ end ---@class Trans ----@field translate fun(opts: { word: string, mode: string?}) Translate string core function +---@field translate fun(opts: { frontend: string?, mode: string?}?) Translate string core function return function(opts) coroutine.wrap(process)(opts) end diff --git a/lua/Trans/core/util.lua b/lua/Trans/core/util.lua index b2656fa..bbc5663 100644 --- a/lua/Trans/core/util.lua +++ b/lua/Trans/core/util.lua @@ -77,6 +77,44 @@ function M.is_English(str) return true end +---Calculates the height of the text to be displayed +---@param lines string[] text to be displayed +---@param width integer width of the window +---@return integer height display height +function M.display_height(lines, width) + local height = 0 + for _, line in ipairs(lines) do + height = height + math.max(1, (math.ceil(line:width() / width))) + end + return height +end + +---Calculates the width of the text to be displayed +---@param lines string[] text to be displayed +---@return integer width display width +function M.display_width(lines) + local width = 0 + for _, line in ipairs(lines) do + width = math.max(line:width(), width) + end + return width +end + +---Calculates the height and width of the text to be displayed +---@param lines string[] text to be displayed +---@param width integer width of the window +---@return { height: integer, width: integer } _ display height and width +function M.display_size(lines, width) + local ds_height, ds_width = 0, 0 + for _, line in ipairs(lines) do + local wid = line:width() + ds_height = ds_height + math.max(1, (math.ceil(wid / width))) + ds_width = math.max(wid, ds_width) + end + + return { height = ds_height, width = ds_width } +end + ---@class Trans ---@field util TransUtil return M diff --git a/lua/Trans/core/window.lua b/lua/Trans/core/window.lua index 52a9777..f5da06f 100644 --- a/lua/Trans/core/window.lua +++ b/lua/Trans/core/window.lua @@ -5,10 +5,10 @@ local Trans = require("Trans") local window = {} ---Change window attached buffer ----@param buf TransBuffer -function window:set_buf(buf) - api.nvim_win_set_buf(self.winid, buf.bufnr) - self.buf = buf +---@param buffer TransBuffer +function window:set_buf(buffer) + api.nvim_win_set_buf(self.winid, buffer.bufnr) + self.buffer = buffer end ---Check window valid @@ -54,10 +54,17 @@ function window:height() return api.nvim_win_get_height(self.winid) end --- TODO : --- function window:adjust() +---Auto adjust window size +---@param height? integer max height +function window:adjust_height(height) + local display_height = Trans.util.display_height(self.buffer:lines(), self:width()) + height = height and math.min(display_height, height) or display_height --- end + self:smooth_expand({ + field = 'height', + to = height + }) +end ---Expand window [width | height] value ---@param opts @@ -88,16 +95,8 @@ end ---@param opts ---|{ width: integer, height: integer } function window:resize(opts) - local width = opts[1] - local height = opts[2] - - - if self:width() ~= width then - self:smooth_expand { - field = 'width', - to = width - } - end + local width = opts.width + local height = opts.height if self:height() ~= height then @@ -106,6 +105,13 @@ function window:resize(opts) to = height } end + + if self:width() ~= width then + self:smooth_expand { + field = 'width', + to = width + } + end end ---Try to close window with animation? diff --git a/lua/Trans/frontend/hover/init.lua b/lua/Trans/frontend/hover/init.lua index 7457615..40bb47b 100644 --- a/lua/Trans/frontend/hover/init.lua +++ b/lua/Trans/frontend/hover/init.lua @@ -58,30 +58,32 @@ end ---Init hover window ---@param opts? ----|{win_opts: WindowOpts,} +---|{width?: integer, height?: integer} ---@return unknown function M:init_window(opts) opts = opts or {} - local win_opts = opts.win_opts or {} - opts.win_opts = win_opts local m_opts = self.opts + local option = { + ns = self.ns, + buffer = self.buffer, + animation = m_opts.animation, + } + local win_opts = { + col = 1, + row = 1, + relative = 'cursor', + title = m_opts.title, + width = opts.width or m_opts.width, + height = opts.height or m_opts.height, + } - opts.ns = self.ns - opts.buffer = self.buffer - win_opts.col = 1 - win_opts.row = 1 - win_opts.relative = 'cursor' - win_opts.title = m_opts.title if win_opts.title then win_opts.title_pos = 'center' end - win_opts.width = win_opts.width or m_opts.width - win_opts.height = win_opts.height or m_opts.height - opts.animation = m_opts.animation - - self.window = Trans.window.new(opts) + option.win_opts = win_opts + self.window = Trans.window.new(option) return self.window end @@ -102,12 +104,11 @@ function M:wait(tbl, name, timeout) self:init_window({ - win_opts = { - height = 1, - width = width, - } + height = 1, + width = width, }) + local interval = math.floor(timeout / width) local pause = Trans.util.pause local buffer = self.buffer @@ -118,11 +119,18 @@ function M:wait(tbl, name, timeout) pause(interval) end + + -- FIXME : + -- vim.api.nvim_buf_set_lines(buffer.bufnr, 1, -1, true, { '' }) + -- print('jklajsdk') + -- print(vim.fn.deletebufline(buffer.bufnr, 1)) + -- buffer:del() buffer[1] = '' end + ---Display Result in hover window ----@param _ any +---@param _ TransData ---@param result TransResult ---@overload fun(result:TransResult) function M:process(_, result) @@ -137,14 +145,20 @@ function M:process(_, result) end end - local win = self.window - if win and win:is_valid() then - win:resize { self.opts.width, self.opts.height } + local window = self.window + local display_size = Trans.util.display_size(self.buffer:lines(), opts.width) + if window and window:is_valid() then + -- win:adjust_height(opts.height) + display_size.width = math.min(opts.width, display_size.width + 6) + window:resize(display_size) else - win = self:init_window() + window = self:init_window { + height = math.min(opts.height, display_size.height), + width = math.min(opts.width, display_size.width), + } end - win:set('wrap', true) + window:set('wrap', true) end ---Check if hover window and buffer are valid