diff --git a/lua/Trans/.clocignore b/lua/Trans/.clocignore new file mode 100644 index 0000000..10a888a --- /dev/null +++ b/lua/Trans/.clocignore @@ -0,0 +1,5 @@ +./README.md +./util/md5.lua +./util/base64.lua +./util/bak_init.lua +./test diff --git a/lua/Trans/README.md b/lua/Trans/README.md index a43075c..24ab2b7 100644 --- a/lua/Trans/README.md +++ b/lua/Trans/README.md @@ -10,3 +10,4 @@ - [ ] Check if str is a word - [ ] init frontend window - [ ] build frontend window format logic +- [ ] waitting animation diff --git a/lua/Trans/core/backend.lua b/lua/Trans/core/backend.lua index 21247b1..cdec2eb 100644 --- a/lua/Trans/core/backend.lua +++ b/lua/Trans/core/backend.lua @@ -1,8 +1,9 @@ local Trans = require('Trans') local M = Trans.metatable('backend') +local conf = Trans.conf --- INFO :Parse online engine keys config file -local path = Trans.conf.dir .. '/Trans.json' +local path = conf.dir .. '/Trans.json' local file = io.open(path, "r") if file then @@ -14,19 +15,12 @@ if file then end - - local default_opts = vim.deepcopy(Trans.conf.backend) for name, private_opts in pairs(result or {}) do - local opts = vim.tbl_extend('keep', Trans.conf.backend[name] or {}, default_opts, private_opts) - - local backend = M[name] + local opts = vim.tbl_extend('keep', conf.backend[name] or {}, conf.backend.default, private_opts) for k, v in pairs(opts) do - if not backend[k] then - backend[k] = v - end + M[name][k] = v end end end - return M diff --git a/lua/Trans/core/conf.lua b/lua/Trans/core/conf.lua index 983fe13..018bd04 100644 --- a/lua/Trans/core/conf.lua +++ b/lua/Trans/core/conf.lua @@ -10,21 +10,27 @@ end return { dir = os.getenv('HOME') .. '/.vim/dict', strategy = { - frontend = 'hover', - backend = '*', + default = { + frontend = 'hover', + backend = '*', + }, }, backend = { - timeout = 2000, + default = { + timeout = 2000, + }, }, frontend = { - auto_play = true, - border = 'rounded', - animation = { - open = 'slid', -- 'fold', 'slid' - close = 'slid', - interval = 12, + default = { + auto_play = true, + border = 'rounded', + animation = { + open = 'slid', -- 'fold', 'slid' + close = 'slid', + interval = 12, + }, + title = title, -- need nvim-0.9 }, - title = title, -- need nvim-0.9 hover = { width = 37, height = 27, diff --git a/lua/Trans/core/frontend.lua b/lua/Trans/core/frontend.lua new file mode 100644 index 0000000..4c88885 --- /dev/null +++ b/lua/Trans/core/frontend.lua @@ -0,0 +1,17 @@ +local Trans = require('Trans') +local M = Trans.metatable('frontend') + + +-- local default_opts = vim.deepcopy(Trans.conf.frontend) +-- for name, private_opts in pairs(result or {}) do +-- local opts = vim.tbl_extend('keep', Trans.conf.backend[name] or {}, default_opts, private_opts) + +-- local backend = M[name] +-- for k, v in pairs(opts) do +-- if not backend[k] then +-- backend[k] = v +-- end +-- end +-- end + +return M diff --git a/lua/Trans/core/setup.lua b/lua/Trans/core/setup.lua index 011dafb..fdcecd2 100644 --- a/lua/Trans/core/setup.lua +++ b/lua/Trans/core/setup.lua @@ -13,27 +13,24 @@ local function set_strategy_opts(conf) return backend end - local global_strategy = conf.strategy - global_strategy.backend = parse_backend(global_strategy.backend) + local default_strategy = conf.strategy.default + default_strategy.backend = parse_backend(default_strategy.backend) + + local meta = { __index = function(tbl, key) - tbl[key] = global_strategy[key] + tbl[key] = default_strategy[key] return tbl[key] end } - + local strategy = conf.strategy for _, mode in ipairs(all_modes) do - if not global_strategy[mode] then - global_strategy[mode] = setmetatable({}, meta) - else - if mode.backend then - mode.backend = parse_backend(mode.backend) - end - - setmetatable(mode, meta) + strategy[mode] = setmetatable(strategy[mode] or {}, meta) + if type(strategy[mode].backend) == 'string' then + strategy[mode].backend = parse_backend(strategy[mode].backend) end end end @@ -102,4 +99,74 @@ return function(opts) set_frontend_opts(conf) define_keymaps(conf) define_highlights(conf) + end + +-- { +-- backend = { +-- default = { +-- timeout = 2000 +-- } +-- }, +-- dir = "/home/zoran/.vim/dict", +-- frontend = { +-- default = { +-- animation = { +-- close = "slid", +-- interval = 12, +-- open = "slid" +-- }, +-- auto_play = true, +-- border = "rounded", +-- title = { { "", "TransTitleRound" }, { " Trans", "TransTitle" }, { "", "TransTitleRound" } } +-- }, +-- hover = { +-- auto_close_events = { "InsertEnter", "CursorMoved", "BufLeave" }, +-- height = 27, +-- keymap = { +-- close = "]", +-- pagedown = "]]", +-- pageup = "[[", +-- pin = "[", +-- play = "_", +-- toggle_entry = ";" +-- }, +-- order = { "title", "tag", "pos", "exchange", "translation", "definition" }, +-- spinner = "dots", +-- width = 37, +-- = { +-- __index = +-- } +-- } +-- }, +-- strategy = { +-- default = { +-- backend = <1>{ "offline", "baidu" }, +-- frontend = "hover" +-- }, +-- input = { +-- backend = , +-- = <2>{ +-- __index = +-- } +-- }, +-- normal = { +-- backend =
, +-- =
+-- }, +-- visual = { +-- backend =
, +-- =
+-- } +-- }, +-- style = { +-- icon = { +-- cell = "■", +-- no = "", +-- notfound = " ", +-- star = "", +-- yes = "✔" +-- }, +-- theme = "default" +-- } +-- } diff --git a/lua/Trans/core/util.lua b/lua/Trans/core/util.lua index 8e87543..b82a1c7 100644 --- a/lua/Trans/core/util.lua +++ b/lua/Trans/core/util.lua @@ -48,6 +48,15 @@ function M.get_str(mode) end end + +function M.pause(ms) + local co = coroutine.running() + vim.defer_fn(function() + coroutine.resume(co) + end, ms) + coroutine.yield() +end + function M.is_English(str) local char = { str:byte(1, -1) } for i = 1, #str do diff --git a/lua/Trans/frontend/hover.lua b/lua/Trans/frontend/hover.lua index 39358c2..0c8c282 100644 --- a/lua/Trans/frontend/hover.lua +++ b/lua/Trans/frontend/hover.lua @@ -1,7 +1,8 @@ -local M = {} +local M = {} -local api = vim.api -local conf = require('Trans').conf +local Trans = require('Trans') +local api = vim.api +local conf = Trans.conf function M.init() @@ -9,20 +10,12 @@ function M.init() end function M.wait(tbl, name, timeout) - local thread = coroutine.running() - local function pause(ms) - vim.defer_fn(function() - coroutine.resume(thread) - end, ms) - coroutine.yield() - end - local error_message = 'Faild' local interval = math.floor(timeout / #error_message) for i = 1, #error_message do if tbl[name] ~= nil then break end print('waitting' .. ('.'):rep(i)) - pause(interval) + Trans.util.pause(interval) end -- TODO : End waitting animation diff --git a/lua/Trans/init.lua b/lua/Trans/init.lua index 13bb071..ce74727 100644 --- a/lua/Trans/init.lua +++ b/lua/Trans/init.lua @@ -19,8 +19,6 @@ local M = metatable('core') M.metatable = metatable M.style = metatable("style") M.wrapper = metatable("wrapper") -M.frontend = metatable("frontend") - M.cache = {} return M diff --git a/lua/Trans/wrapper/window.lua b/lua/Trans/wrapper/window.lua index 72dccf0..c68765d 100644 --- a/lua/Trans/wrapper/window.lua +++ b/lua/Trans/wrapper/window.lua @@ -1,13 +1,14 @@ local api = vim.api -local display = require('Trans.util.display') +local Trans = require("Trans") + ---@class win +---@field win_opts table window config [**when open**] ---@field winid integer window handle ----@field width integer ----@field height integer ---@field ns integer namespace for highlight ---@field animation table window animation ----@field buf buf buffer for attached +---@field enter boolean cursor should [enter] window when open +---@field buffer buffer attached buffer object local window = {} ---Change window attached buffer @@ -41,91 +42,98 @@ end ---@param height integer function window:set_height(height) api.nvim_win_set_height(self.winid, height) - self.height = height end ---@param width integer function window:set_width(width) api.nvim_win_set_width(self.winid, width) - self.width = width +end + +---Get window width +function window:width() + return api.nvim_win_get_width(self.winid) +end + +---Get window height +function window:height() + return api.nvim_win_get_height(self.winid) end ---Expand window [width | height] value ---@param opts table ---|'field'string [width | height] ---|'target'integer ----@return function -function window:expand(opts) - self:lock() - local field = opts.field - local target = opts.target - local cur = self[field] - local times = math.abs(target - cur) +function window:smooth_expand(opts) + local field = opts.field -- width | height + local from = self[field](self) + local to = opts.target - local wrap = self:option('wrap') - self:set('wrap', false) - local interval = opts.interval or self.animation.interval + if from == to then return end + + + local pause = Trans.util.pause local method = api['nvim_win_set_' .. field] - local winid = self.winid - local frame = target > cur and function(_, cur_times) - method(winid, cur + cur_times) - end or function(_, cur_times) - method(winid, cur - cur_times) + + local wrap = self:option('wrap') + + local interval = self.animation.interval + for i = from + 1, to, (from < to and 1 or -1) do + self:set('wrap', false) + method(self.winid, i) + pause(interval) end - local run = display { - times = times, - frame = frame, - interval = interval, - } - - run(function() - self:set('wrap', wrap) - self[field] = target - self:unlock() - end) - return run + self:set('wrap', wrap) end ---Close window ----@return function run run until close done function window:try_close() - local field = ({ - slid = 'width', - fold = 'height', - })[self.animation.close] + local close_animation = self.animation.close + if close_animation then + local field = ({ + slid = 'width', + fold = 'height', + })[close_animation] - --- 播放动画 - local run = self:expand { - field = field, - target = 1, - } - run(function() - api.nvim_win_close(self.winid, true) - end) - return run -end - ----lock window [open | close] operation -function window:lock() - while self.busy do - vim.wait(50) + self:smooth_expand({ + field = field, + target = 1, + }) end - self.busy = true + + api.nvim_win_close(self.winid, true) end -function window:unlock() - self.busy = false -end - ----设置窗口本地的高亮组 ----@param name string 高亮组的名称 ----@param opts table 高亮选项 +---set window local highlight group +---@param name string +---@param opts table function window:set_hl(name, opts) api.nvim_set_hl(self.ns, name, opts) end +function window:open() + assert(self.winid == nil, 'window already opened') + local win_opts = self.win_opts + local open_animation = self.animation.open + if open_animation then + local field = ({ + slid = 'width', + fold = 'height', + })[open_animation] + + local to = win_opts[field] + win_opts[field] = 1 + self.winid = api.nvim_open_win(self.buffer.bufnr, self.enter, win_opts) + self:smooth_expand({ + field = field, + target = to, + }) + else + self.winid = api.nvim_open_win(self.buffer.bufnr, self.enter, win_opts) + end +end + ---buffer:addline() helper function ---@param node table ---@return table node formatted node @@ -138,86 +146,91 @@ function window:center(node) return node end ----@private window.__index = window ----@class win_opts ----@field buf buf buffer for attached ----@field height integer ----@field width integer ----@field col integer ----@field row integer ----@field border string ----@field title string | nil | table ----@field relative string ----@field ns integer namespace for highlight ----@field zindex? integer ----@field enter? boolean cursor should [enter] window ----@field animation table window animation - ----window constructor ----@param opts win_opts ----@return table ----@return function -return function(opts) - assert(type(opts) == 'table') - local ns = opts.ns - local buf = opts.buf - local col = opts.col - local row = opts.row - local title = opts.title - local width = opts.width - local enter = opts.enter or false - local height = opts.height - local border = opts.border - local zindex = opts.zindex - local relative = opts.relative - local animation = opts.animation - - local open = animation.open - - local field = ({ - slid = 'width', - fold = 'height', - })[open] - - local win_opt = { - title_pos = nil, - focusable = false, +local default_opts = { + ns = api.nvim_create_namespace('TransHoverWin'), + enter = false, + win_opts = { style = 'minimal', - zindex = zindex, - width = width, - height = height, - col = col, - row = row, - border = border, - title = title, - relative = relative, - } + border = 'rounded', + focusable = false, + noautocmd = true, + }, +} - if field then - win_opt[field] = 1 - end +return function(opts) + opts = vim.tbl_deep_extend('keep', opts, default_opts) - if win_opt.title then - win_opt.title_pos = 'center' - end - - local win = setmetatable({ - buf = buf, - ns = ns, - height = win_opt.height, - width = win_opt.width, - animation = animation, - winid = api.nvim_open_win(buf.bufnr, enter, win_opt), - }, window) - - api.nvim_win_set_hl_ns(win.winid, win.ns) - win:set_hl('Normal', { link = 'TransWin' }) - win:set_hl('FloatBorder', { link = 'TransBorder' }) - - return win, win:expand { - field = field, - target = opts[field], - } + local win = setmetatable(opts, window) + win:open() + return win end + +--@class win_opts +--@field buf buf buffer for attached +--@field height integer +--@field width integer +--@field col integer +--@field row integer +--@field border string +--@field title string | nil | table +--@field relative string +--@field ns integer namespace for highlight +--@field zindex? integer +--@field enter? boolean cursor should [enter] window +--@field animation table window animation + +-- local ns = opts.ns +-- local buf = opts.buf +-- local col = opts.col +-- local row = opts.row +-- local title = opts.title +-- local width = opts.width +-- local height = opts.height +-- local border = opts.border +-- local zindex = opts.zindex +-- local relative = opts.relative +-- local animation = opts.animation + +-- local open = animation.open + +-- local field = ({ +-- slid = 'width', +-- fold = 'height', +-- })[open] + +-- local win_opt = { +-- focusable = false, +-- style = 'minimal', +-- zindex = zindex, +-- width = width, +-- height = height, +-- col = col, +-- row = row, +-- border = border, +-- title = title, +-- relative = relative, +-- } + +-- if field then +-- win_opt[field] = 1 +-- end + +-- if win_opt.title then +-- win_opt.title_pos = 'center' +-- end + +-- local win = setmetatable({ +-- buf = buf, +-- ns = ns, +-- height = win_opt.height, +-- width = win_opt.width, +-- animation = animation, +-- winid = api.nvim_open_win(buf.bufnr, enter, win_opt), +-- }, window) + +-- return win, win:expand { +-- field = field, +-- target = opts[field], +-- }