diff --git a/lua/Trans/backend/baidu.lua b/lua/Trans/backend/baidu.lua index 509fbf2..ab8d3bc 100644 --- a/lua/Trans/backend/baidu.lua +++ b/lua/Trans/backend/baidu.lua @@ -1,25 +1,20 @@ -local M = {} +local M = { + uri = 'https://fanyi-api.baidu.com/api/trans/vip/translate', + salt = tostring(math.random(bit.lshift(1, 15))), +} local Trans = require('Trans') - -local baidu = Trans.conf.keys.baidu -local app_id = baidu.app_id -local app_passwd = baidu.app_passwd -local salt = tostring(math.random(bit.lshift(1, 15))) -local uri = 'https://fanyi-api.baidu.com/api/trans/vip/translate' - - function M.get_content(data) - local tmp = app_id .. data.str .. salt .. app_passwd + local tmp = M.app_id .. data.str .. M.salt .. M.app_passwd local sign = Trans.util.md5.sumhexa(tmp) return { q = data.str, from = data.from, to = data.to, - appid = app_id, - salt = salt, + appid = M.app_id, + salt = M.salt, sign = sign, } end @@ -33,7 +28,11 @@ end function M.query(data) - data.engine = 'baidu' + if M.disable then + data.result.baidu = false + return + end + local handle = function(res) local status, body = pcall(vim.json.decode, res.body) @@ -41,7 +40,7 @@ function M.query(data) local result = body.trans_result if result then -- TEST :whether multi result - assert(#result == 1, 'multi result :' .. vim.inspect(result)) + assert(#result == 1) result = result[1] data.result.baidu = { title = result.src, @@ -56,7 +55,7 @@ function M.query(data) end - Trans.wrapper.curl.get(uri, { + Trans.wrapper.curl.get(M.uri, { query = M.get_content(data), callback = handle, }) diff --git a/lua/Trans/backend/offline.lua b/lua/Trans/backend/offline.lua index 36d6c60..4d39d76 100644 --- a/lua/Trans/backend/offline.lua +++ b/lua/Trans/backend/offline.lua @@ -1,4 +1,4 @@ -local M = { no_wait = true } +local M = { no_wait = true, } local db = require 'sqlite.db' vim.api.nvim_create_autocmd('VimLeavePre', { @@ -13,7 +13,6 @@ vim.api.nvim_create_autocmd('VimLeavePre', { function M.query(data) if data.is_word == false or data.from == 'zh' then return end - data.path = data.path or require('Trans').conf.dir .. '/ultimate.db' data.engine = 'offline' data.formatter = data.formatter or M.formatter diff --git a/lua/Trans/core/backend.lua b/lua/Trans/core/backend.lua new file mode 100644 index 0000000..21247b1 --- /dev/null +++ b/lua/Trans/core/backend.lua @@ -0,0 +1,32 @@ +local Trans = require('Trans') +local M = Trans.metatable('backend') + +--- INFO :Parse online engine keys config file +local path = Trans.conf.dir .. '/Trans.json' +local file = io.open(path, "r") + +if file then + local content = file:read("*a") + local status, result = pcall(vim.json.decode, content) + file:close() + if not status then + error('Unable to parse json file: ' .. path .. '\n' .. result) + 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] + for k, v in pairs(opts) do + if not backend[k] then + backend[k] = v + end + end + end +end + + +return M diff --git a/lua/Trans/core/setup.lua b/lua/Trans/core/setup.lua index 5244200..011dafb 100644 --- a/lua/Trans/core/setup.lua +++ b/lua/Trans/core/setup.lua @@ -3,7 +3,7 @@ local Trans = require('Trans') local function set_strategy_opts(conf) local define = Trans.define local all_modes = define.modes - local all_backends = vim.tbl_keys(conf.keys) + local all_backends = define.backends local function parse_backend(backend) if type(backend) == 'string' then @@ -62,6 +62,26 @@ local function set_frontend_opts(conf) end +local function define_keymaps(conf) + local set = vim.keymap.set + local opts = { silent = true, expr = true } + + + for _, name in ipairs(Trans.define.frontends) do + for action, key in pairs(conf.frontend[name].keymap) do + set('n', key, function() + local frontend = Trans.frontend[name] + if frontend.is_available() then + frontend.actions[action]() + else + return key + end + end, opts) + end + end +end + + local function define_highlights(conf) local set_hl = vim.api.nvim_set_hl @@ -80,5 +100,6 @@ return function(opts) set_strategy_opts(conf) set_frontend_opts(conf) + define_keymaps(conf) define_highlights(conf) end diff --git a/lua/Trans/core/translate.lua b/lua/Trans/core/translate.lua index 14b7289..de1a09e 100644 --- a/lua/Trans/core/translate.lua +++ b/lua/Trans/core/translate.lua @@ -1,7 +1,6 @@ local Trans = require('Trans') local util = Trans.util -vim.pretty_print(Trans.conf) local function new_data(opts) opts = opts or {} local mode = opts.method or ({ @@ -28,37 +27,41 @@ local function new_data(opts) data.from = 'zh' data.to = 'en' end + + -- TODO : Check if the str is a word + data.is_word = true + return data end local function set_result(data) - -- local t_backend = require('Trans').backend - -- for _, name in rdata.backend do - -- local backend = t_backend[name] - -- backend.query(data) - -- if backend.no_wait then + local backend_list = data.backend + local backends = Trans.backend - -- end - -- end - -- Trans.backend.baidu.query(data) - -- local thread = coroutine.running() - -- local resume = function() - -- coroutine.resume(thread) - -- end + local frontend = Trans.frontend[data.frontend] - -- local time = 0 - -- while data.result == nil do - -- vim.defer_fn(resume, 400) - -- time = time + 1 - -- print('waiting' .. ('.'):rep(time)) - -- coroutine.yield() - -- end - -- vim.pretty_print(data) + local function do_query(name) + local backend = backends[name] + if backend.no_wait then + backend.query(data) + if type(data.result[name]) == 'table' then + return + end + else + backend.query(data) + frontend.wait(data.result, name, backend.timeout) + end + end + + for _, name in ipairs(backend_list) do + do_query(name) + end end -local function render_window() - +local function render_window(data) + -- TODO + print('begin to render window') end -- HACK : Core process logic @@ -71,7 +74,7 @@ local function process(opts) set_result(data) if data.result == false then return end - render_window() + render_window(data) end return coroutine.wrap(process) diff --git a/lua/Trans/core/util.lua b/lua/Trans/core/util.lua index 8397035..8e87543 100644 --- a/lua/Trans/core/util.lua +++ b/lua/Trans/core/util.lua @@ -36,18 +36,16 @@ end ---@param mode string 'n' | 'v' | 'i' ---@return string function M.get_str(mode) - return ({ - normal = function() - return fn.expand('') - end, - visual = function() - api.nvim_input('') - return M.get_select() - end, - input = function() - return fn.input('请输入需要查询的单词:') - end, - })[mode]() + if mode == 'n' or mode == 'normal' then + return fn.expand('') + elseif mode == 'v' or mode == 'visual' then + api.nvim_input('') + return M.get_select() + elseif mode == 'input' then + return fn.expand('') + else + error('Unsupported mode' .. mode) + end end function M.is_English(str) diff --git a/lua/Trans/frontend/hover.lua b/lua/Trans/frontend/hover.lua index a95a71d..f59b702 100644 --- a/lua/Trans/frontend/hover.lua +++ b/lua/Trans/frontend/hover.lua @@ -1,16 +1,67 @@ local M = {} local api = vim.api +local conf = require('Trans').conf -function M.process(data) +function M.init() + print('TODO: init hover window') end +function M.wait(tbl, key, 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 times = 0 + local interval = math.floor(timeout / #error_message) + while tbl[key] == nil do + print(('waitting' .. (' '):rep(times))) + pause(interval) + end + + if tbl[key] == false then + print('TODO: show error message: ' .. error_message) + else + vim.pretty_print(tbl[key]) + end +end + +function M.process(data) + print('TODO: process data') +end + +function M.is_available() + return true +end + +M.actions = { + play = function() + print('TODO: play') + end, + pageup = function() + print('TODO: pageup') + end, + pagedown = function() + print('TODO: pagedown') + end, + pin = function() + print('TODO: pin') + end, + close = function() + print('TODO: close') + end, + toggle_entry = function() + print('TODO: toggle_entry') + end, +} return M - --- local api = vim.api --- local conf = require('Trans').conf -- local hover = conf.hover -- local error_msg = conf.icon.notfound .. ' 没有找到相关的翻译' diff --git a/lua/Trans/init.lua b/lua/Trans/init.lua index 12b972a..13bb071 100644 --- a/lua/Trans/init.lua +++ b/lua/Trans/init.lua @@ -19,7 +19,6 @@ local M = metatable('core') M.metatable = metatable M.style = metatable("style") M.wrapper = metatable("wrapper") -M.backend = metatable("backend") M.frontend = metatable("frontend") diff --git a/lua/Trans/util/curl.lua b/lua/Trans/util/curl.lua deleted file mode 100644 index c2d2c28..0000000 --- a/lua/Trans/util/curl.lua +++ /dev/null @@ -1,109 +0,0 @@ ---- TODO :wrapper for curl -local curl = {} - ----Send a GET request ----@param opts table -curl.GET = function(opts) - local uri = opts.uri - local headers = opts.headers or {} - local callback = opts.callback - - -- INFO :Init Curl command with {s}ilent and {G}et - local cmd = { 'curl', '-Gs' } - - -- INFO :Add headers - for k, v in pairs(headers) do - cmd[#cmd + 1] = ([[-H '%s: %s']]):format(k, v) - end - - -- INFO :Add arguments - local info = {} - for k, v in pairs(opts.arguments) do - info[#info + 1] = ('%s=%s'):format(k, v) - end - cmd[#cmd + 1] = ([['%s?%s']]):format(uri, table.concat(info, '&')) - - - -- write a function to get the output - local outpus = {} - vim.fn.jobstart(table.concat(cmd, ' '), { - stdin = 'null', - on_stdout = function(_, stdout) - local str = table.concat(stdout) - if str ~= '' then - - end - end, - on_exit = function() - callback(output) - end, - }) - - -- local output = '' - -- local option = { - -- stdin = 'null', - -- on_stdout = function(_, stdout) - -- local str = table.concat(stdout) - -- if str ~= '' then - -- output = output .. str - -- end - -- end, - -- on_exit = function() - -- callback(output) - -- end, - -- } - - -- vim.fn.jobstart(table.concat(cmd, ' '), option) -end - - - -curl.POST = function(opts) - vim.validate { - uri = { uri, 's' }, - opts = { opts, 't' } - } - - local callback = opts.callback - - local cmd = { 'curl', '-s', ('"%s"'):format(uri) } - local size = 3 - - local function insert(...) - for _, v in ipairs { ... } do - size = size + 1 - cmd[size] = v - end - end - - local s = '"%s=%s"' - - if opts.headers then - for k, v in pairs(opts.headers) do - insert('-H', s:format(k, v)) - end - end - - for k, v in pairs(opts.data) do - insert('-d', s:format(k, v)) - end - - - local output = '' - local option = { - stdin = 'null', - on_stdout = function(_, stdout) - local str = table.concat(stdout) - if str ~= '' then - output = output .. str - end - end, - on_exit = function() - callback(output) - end, - } - - vim.fn.jobstart(table.concat(cmd, ' '), option) -end - -return curl diff --git a/plugin/Trans.lua b/plugin/Trans.lua index 4a57fc7..6b53b76 100644 --- a/plugin/Trans.lua +++ b/plugin/Trans.lua @@ -31,32 +31,3 @@ command('TransPlay', function() str:play() end end, { desc = ' 自动发音' }) - - - ---- INFO :Parse online engine keys config file -local function parse_engine_file() - local path = Trans.conf.dir .. '/Trans.json' - local file = io.open(path, "r") - - if file then - local content = file:read("*a") - local status, result = pcall(vim.json.decode, content) - file:close() - assert(status, 'Unable to parse json file: ' .. path) - return result - end -end - -local result = parse_engine_file() -if result then - for name, opts in pairs(result) do - if not opts.enable then - result[name] = nil - end - end - - Trans.conf.keys = result -else - Trans.conf.keys = {} -end