From 9a2d3b4e0acd9a2c209f8cc19d16746e4ce888e2 Mon Sep 17 00:00:00 2001 From: JuanZoran <1430359574@qq.com> Date: Thu, 16 Mar 2023 11:49:26 +0800 Subject: [PATCH] fix: use backend local strategy instead of global strategy --- lua/Trans/backend/baidu.lua | 4 +- lua/Trans/backend/youdao.lua | 71 +++++++++++++-- lua/Trans/core/conf.lua | 16 ++-- lua/Trans/core/data.lua | 8 +- lua/Trans/core/translate.lua | 41 +++------ lua/Trans/frontend/hover/init.lua | 47 ++++++---- lua/Trans/frontend/hover/load.lua | 147 ++++++++++++++++++------------ 7 files changed, 210 insertions(+), 124 deletions(-) diff --git a/lua/Trans/backend/baidu.lua b/lua/Trans/backend/baidu.lua index 55cc70d..b54f0e1 100644 --- a/lua/Trans/backend/baidu.lua +++ b/lua/Trans/backend/baidu.lua @@ -58,14 +58,14 @@ function M.query(data) return end - local result = body.trans_result + if result then -- TEST :whether multi result assert(#result == 1) result = result[1] data.result.baidu = { - ['title'] = result.src, + ['str'] = result.src, [data.from == 'en' and 'translation' or 'definition'] = { result.dst }, } end diff --git a/lua/Trans/backend/youdao.lua b/lua/Trans/backend/youdao.lua index 97d5160..b04acb3 100644 --- a/lua/Trans/backend/youdao.lua +++ b/lua/Trans/backend/youdao.lua @@ -46,6 +46,62 @@ function M.get_content(data) } end +-- { +-- dict = { +-- url = "yddict://m.youdao.com/dict?le=eng&q=shows+your+registers+on+%22+in+NORMAL+or+%3CC-r%3E+in+INSERT+mode" +-- }, +-- errorCode = "0", +-- isWord = false, +-- l = "en2zh-CHS", +-- mTerminalDict = { +-- url = "https://m.youdao.com/m/result?lang=en&word=shows+your+registers+on+%22+in+NORMAL+or+%3CC-r%3E+in+INSERT+mode" +-- }, +-- query = 'shows your registers on " in NORMAL or in INSERT mode', +-- requestId = "9dddf583-1233-48a5-a9ca-f1d0324a5349", +-- speakUrl = "https://openapi.youdao.com/ttsapi?q=shows+your+registers+on+%22+in+NORMAL+or+%3CC-r%3E+in+INSERT+mode&langType=en-USA&sign=8A0B3742F4E9FA92D4B65F028E1A6008&salt=1678931340864&voice=4&format=mp3&appKey=1858465a8708c121&ttsVoiceStrict=false", +-- tSpeakUrl = "https://openapi.youdao.com/ttsapi?q=%E5%9C%A8%E6%AD%A3%E5%B8%B8%E6%88%96%3CC-r%3E%E6%8F%92%E5%85%A5%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%98%BE%E7%A4%BA%E4%BD%A0%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8&langType=zh-CHS&sign=456E436DBEC35447D36157200FC5ACA7&salt=1678931340864&voice=4&format=mp3&appKey=1858465a8708c121&ttsVoiceStrict=false", +-- translation = { "在正常或插入模式下显示你的寄存器" }, +-- webdict = { +-- url = "http://mobile.youdao.com/dict?le=eng&q=shows+your+registers+on+%22+in+NORMAL+or+%3CC-r%3E+in+INSERT+mode" +-- } +-- } + +-- { +-- basic = { +-- explains = { "normal", "regular", "normality" }, +-- phonetic = "zhèng cháng" +-- }, +-- dict = { +-- url = "yddict://m.youdao.com/dict?le=eng&q=%E6%AD%A3%E5%B8%B8" +-- }, +-- errorCode = "0", +-- isWord = true, +-- l = "zh-CHS2en", +-- mTerminalDict = { +-- url = "https://m.youdao.com/m/result?lang=zh-CHS&word=%E6%AD%A3%E5%B8%B8" +-- }, +-- query = "正常", +-- requestId = "a8a40c0e-0d3b-49d5-a8fe-b1cd211ff5db", +-- returnPhrase = { "正常" }, +-- speakUrl = "https://openapi.youdao.com/ttsapi?q=%E6%AD%A3%E5%B8%B8&langType=zh-CHS&sign=164F6EFF2EFFC7626FB70DBCF796AE70&salt=1678931501049&voice=4&format=mp3&appKey=1858465a8708c121&ttsVoiceStrict=false", +-- tSpeakUrl = "https://openapi.youdao.com/ttsapi?q=normal&langType=en-USA&sign=6A0CF2EF076EA8D82453956B33F69A51&salt=1678931501049&voice=4&format=mp3&appKey=1858465a8708c121&ttsVoiceStrict=false", +-- translation = { "normal" }, +-- web = { { +-- key = "正常", +-- value = { "normal", "ordinary", "normo", "regular" } +-- }, { +-- key = "正常利润", +-- value = { "normal profits" } +-- }, { +-- key = "邦交正常化", +-- value = { "normalize relations", "normalization of diplomatic relations" } +-- } }, +-- webdict = { +-- url = "http://mobile.youdao.com/dict?le=eng&q=%E6%AD%A3%E5%B8%B8" +-- } +-- } + + ---@overload fun(TransData): TransResult ---Query Using Baidu API ---@param data TransData @@ -63,16 +119,11 @@ function M.query(data) return end - local result = body.trans_result - if result then - -- TEST :whether multi result - assert(#result == 1) - result = result[1] - data.result.youdao = { - ['title'] = result.src, - [data.from == 'en' and 'translation' or 'definition'] = { result.dst }, - } - end + -- TEST :whether multi result + data.result.youdao = { + ['title'] = body.src, + [data.from == 'en' and 'translation' or 'definition'] = body.translation, + } end require('Trans').curl.get(M.uri, { diff --git a/lua/Trans/core/conf.lua b/lua/Trans/core/conf.lua index 2b7e37a..f696f49 100644 --- a/lua/Trans/core/conf.lua +++ b/lua/Trans/core/conf.lua @@ -69,14 +69,16 @@ return { 'CursorMoved', 'BufLeave', }, - ---@type string[] order to display translate result + ---@type table order to display translate result order = { - 'title', - 'tag', - 'pos', - 'exchange', - 'translation', - 'definition', + offline = { + 'title', + 'tag', + 'pos', + 'exchange', + 'translation', + 'definition', + }, }, ---@type table icon = { diff --git a/lua/Trans/core/data.lua b/lua/Trans/core/data.lua index b79f282..4faf44c 100644 --- a/lua/Trans/core/data.lua +++ b/lua/Trans/core/data.lua @@ -52,6 +52,7 @@ function M.new(opts) end ---@class TransResult +---@field str? string? @The original string ---@field title table | string @table: {word, phonetic, oxford, collins} ---@field tag string[]? @array of tags ---@field pos table? @table: {name, value} @@ -61,14 +62,17 @@ end ---Get the first available result [return nil if no result] ----@return TransResult? +---@return TransResult | false? +---@return string? backend.name function M:get_available_result() local result = self.result + if result['offline'] then return result['offline'], 'offline' end + for _, backend in ipairs(self.backends) do if result[backend.name] then ---@diagnostic disable-next-line: return-type-mismatch - return result[backend.name] + return result[backend.name], backend.name end end end diff --git a/lua/Trans/core/translate.lua b/lua/Trans/core/translate.lua index b311120..bb95449 100644 --- a/lua/Trans/core/translate.lua +++ b/lua/Trans/core/translate.lua @@ -13,28 +13,27 @@ local function init_opts(opts) end ----@type table +---@type table local strategy = { - fallback = function(data, update) + fallback = function(data) local result = data.result + Trans.backend.offline.query(data) + if result.offline then return true end + + local update = data.frontend:wait() for _, backend in ipairs(data.backends) do ---@cast backend TransBackend - local name = backend.name backend.query(data) + local name = backend.name while result[name] == nil do - if not update() then - break - end + if not update() then return end end - if type(result[name]) == 'table' then - return result[name] - end + if result[name] then return true end end end, - --- TODO :More Strategys } @@ -48,28 +47,16 @@ local function process(opts) -- Find in cache if Trans.cache[str] then local data = Trans.cache[str] - - local result = data:get_available_result() - if result then - data.frontend:process(data, result) - return - end + data.frontend:process(data) + return end local data = Trans.data.new(opts) - Trans.backend.offline.query(data) - local result = data.result['offline'] - if not result then - result = strategy[Trans.conf.query](data, data.frontend:wait()) - if not result then - data.frontend:fallback() - return - end + if strategy[Trans.conf.query](data) then + Trans.cache[data.str] = data end - - Trans.cache[data.str] = data - data.frontend:process(data, result) + data.frontend:process(data) end diff --git a/lua/Trans/frontend/hover/init.lua b/lua/Trans/frontend/hover/init.lua index 5de6b81..d430589 100644 --- a/lua/Trans/frontend/hover/init.lua +++ b/lua/Trans/frontend/hover/init.lua @@ -116,12 +116,20 @@ function M:wait() buffer[1] = spinner[cur % size + 1] .. (cell):rep(cur) buffer:add_highlight(1, 'TransWaitting') pause(interval) - return cur == times + return cur < times end end ---FallBack window for no result function M:fallback() + if not self.window then + self:init_window { + height = 1, + width = self.opts.width, + } + end + + local buffer = self.buffer local opts = self.opts buffer:wipe() @@ -153,34 +161,35 @@ end ---Display Result in hover window ---@param data TransData ----@param result TransResult ---@overload fun(result:TransResult) -function M:process(data, result) +function M:process(data) + if self.pin then return end + + local result, name = data:get_available_result() + if not result then + self:fallback() + return + end + local opts = self.opts + if opts.auto_play then + (data.from == 'en' and data.str or result.definition[1]):play() + end -- local node = Trans.util.node -- local it, t, f = node.item, node.text, node.format -- self.buffer:setline(it('hello', 'MoreMsg')) - local opts = self.opts - if self.pin then return end - local buffer = self.buffer - if not buffer:is_valid() then buffer:init() end - buffer:deleteline(1) - - - if opts.auto_play then - (data.from == 'en' and data.str or result.definition[1]):play() + if not buffer:is_valid() then + buffer:init() + else + buffer:wipe() end - for _, field in ipairs(opts.order) do - if result[field] then - self:load(result, field) - end - end + ---@cast name string + self:load(result, name, opts.order[name]) - local window = self.window local display_size = Trans.util.display_size(buffer:lines(), opts.width) - + local window = self.window if window and window:is_valid() then if opts.auto_resize then display_size.width = math.min(opts.width, display_size.width + opts.padding) diff --git a/lua/Trans/frontend/hover/load.lua b/lua/Trans/frontend/hover/load.lua index 242a089..5285164 100644 --- a/lua/Trans/frontend/hover/load.lua +++ b/lua/Trans/frontend/hover/load.lua @@ -1,5 +1,6 @@ local node = require('Trans').util.node local it, t, f = node.item, node.text, node.format +local interval = (' '):rep(4) local function conjunction(text) return { @@ -9,44 +10,89 @@ local function conjunction(text) } end -local interval = (' '):rep(4) +---@type table +local default = { + str = function(hover, result) + -- TODO : + hover.buffer:setline(it(result.str, 'TransWord')) + end, + translation = function(hover, result) + local translation = result.translation + if not translation then return end -local strategy = { - title = function(hover, title) - if type(title) == 'string' then - hover.buffer:setline(it(title, 'TransWord')) - return + local buffer = hover.buffer + buffer:setline(conjunction('中文翻译')) + + for _, value in ipairs(translation) do + buffer:setline( + it(interval .. value, 'TransTranslation') + ) end - local icon = hover.opts.icon + buffer:setline('') + end, + definition = function(hover, result) + local definition = result.definition + if not definition then return end + local buffer = hover.buffer + buffer:setline(conjunction('英文注释')) + + for _, value in ipairs(definition) do + buffer:setline( + it(interval .. value, 'TransDefinition') + ) + end + + buffer:setline('') + end, +} + +---@diagnostic disable-next-line: assign-type-mismatch +default.__index = default + +local strategy = setmetatable({}, { + __index = function(tbl, key) + tbl[key] = default + return tbl[key] + end, + __newindex = function(tbl, key, value) + rawset(tbl, key, setmetatable(value, default)) + end +}) + + +strategy.offline = { + title = function(hover, result) + local title = result.title + if not title then return end + + local icon = hover.opts.icon local word = title.word local oxford = title.oxford local collins = title.collins local phonetic = title.phonetic - - if not phonetic and not collins and not oxford then - hover.buffer:setline(it(word, 'TransWord')) - else - hover.buffer:setline(f { - width = hover.opts.width, - text = t { - it(word, 'TransWord'), - t { - it('['), - it((phonetic and phonetic ~= '') and phonetic or icon.notfound, 'TransPhonetic'), - it(']') - }, - - it(collins and icon.star:rep(collins) or icon.notfound, 'TransCollins'), - it(oxford == 1 and icon.yes or icon.no) + hover.buffer:setline(f { + width = hover.opts.width, + text = t { + it(word, 'TransWord'), + t { + it('['), + it((phonetic and phonetic ~= '') and phonetic or icon.notfound, 'TransPhonetic'), + it(']') }, - }) - end + + it(collins and icon.star:rep(collins) or icon.notfound, 'TransCollins'), + it(oxford == 1 and icon.yes or icon.no) + }, + }) end, - tag = function(hover, tag) + tag = function(hover, result) + local tag = result.tag + if not tag then return end + local buffer = hover.buffer buffer:setline(conjunction('标签')) @@ -65,7 +111,10 @@ local strategy = { buffer:setline('') end, - exchange = function(hover, exchange) + exchange = function(hover, result) + local exchange = result.exchange + if not exchange then return end + local buffer = hover.buffer buffer:setline(conjunction('词形变化')) @@ -77,7 +126,10 @@ local strategy = { buffer:setline('') end, - pos = function(hover, pos) + pos = function(hover, result) + local pos = result.pos + if not pos then return end + local buffer = hover.buffer buffer:setline(conjunction('词性')) @@ -87,39 +139,20 @@ local strategy = { ) end - buffer:setline('') - end, - translation = function(hover, translation) - local buffer = hover.buffer - buffer:setline(conjunction('中文翻译')) - - for _, value in ipairs(translation) do - buffer:setline( - it(interval .. value, 'TransTranslation') - ) - end - - buffer:setline('') - end, - definition = function(hover, definition) - local buffer = hover.buffer - buffer:setline(conjunction('英文注释')) - - for _, value in ipairs(definition) do - buffer:setline( - it(interval .. value, 'TransDefinition') - ) - end - buffer:setline('') end, } - - +-- FIXME : ---@class TransHover ----@field load fun(hover: TransHover, result: TransResult, field: string) -return function(hover, result, field) - strategy[field](hover, result[field]) +---@field load fun(hover: TransHover, result: TransResult, name: string, order: string[]) +return function(hover, result, name, order) + order = order or { 'str', 'translation', 'definition' } + + local method = strategy[name] + + for _, field in ipairs(order) do + method[field](hover, result) + end end