refactor: add cache logic

This commit is contained in:
JuanZoran 2023-03-12 21:33:00 +08:00
parent bc8c673ee0
commit f86ff7b615
9 changed files with 153 additions and 182 deletions

View File

@ -1,6 +1,7 @@
local M = {
uri = 'https://fanyi-api.baidu.com/api/trans/vip/translate',
salt = tostring(math.random(bit.lshift(1, 15))),
name = 'baidu',
}
local Trans = require('Trans')

View File

@ -1,4 +1,7 @@
local M = { no_wait = true, }
local M = {
no_wait = true,
name = 'offline',
}
local db = require 'sqlite.db'
vim.api.nvim_create_autocmd('VimLeavePre', {

View File

@ -1,26 +1,28 @@
local Trans = require('Trans')
local M = Trans.metatable('backend')
local conf = Trans.conf
--- INFO :Parse online engine keys config file
local path = conf.dir .. '/Trans.json'
local file = io.open(path, "r")
local result = {}
if file then
local content = file:read("*a")
local status, result = pcall(vim.json.decode, content)
result = vim.json.decode(content) or result
file:close()
if not status then
error('Unable to parse json file: ' .. path .. '\n' .. result)
end
return setmetatable({}, {
__index = function(self, name)
local opts = vim.tbl_extend('keep', conf.backend[name] or {}, conf.backend.default, result[name] or {})
local backend = require('Trans.backend.' .. name)
for name, private_opts in pairs(result or {}) do
local opts = vim.tbl_extend('keep', conf.backend[name] or {}, conf.backend.default, private_opts)
for k, v in pairs(opts) do
M[name][k] = v
end
end
backend[k] = v
end
return M
self[name] = backend
return backend
end
})

View File

@ -1,17 +1,40 @@
local Trans = require('Trans')
local M = Trans.metatable('frontend')
local conf = Trans.conf
local frontend_opts = conf.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 function set_frontend_keymap(frontend)
local set = vim.keymap.set
local keymap_opts = { silent = true, expr = true }
for action, key in pairs(frontend.opts.keymap) do
set('n', key, function()
local instance = frontend.get_active_instance()
if instance then
instance:execute(action)
else
return key
end
end, keymap_opts)
end
end
local M = setmetatable({}, {
__index = function(self, name)
local opts = vim.tbl_extend('keep', frontend_opts[name] or {}, frontend_opts.default)
local frontend = require('Trans.frontend.' .. name)
frontend.opts = opts
self[name] = frontend
set_frontend_keymap(frontend)
return frontend
end
})
-- local backend = M[name]
-- for k, v in pairs(opts) do
-- if not backend[k] then
-- backend[k] = v
-- end
-- end
-- end
return M

View File

@ -18,7 +18,6 @@ local function set_strategy_opts(conf)
local meta = {
__index = function(tbl, key)
tbl[key] = default_strategy[key]
@ -59,26 +58,6 @@ 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
@ -88,6 +67,8 @@ local function define_highlights(conf)
end
end
return function(opts)
if opts then
Trans.conf = vim.tbl_deep_extend('force', Trans.conf, opts)
@ -97,76 +78,5 @@ return function(opts)
set_strategy_opts(conf)
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 = "<leader>]",
-- pagedown = "]]",
-- pageup = "[[",
-- pin = "<leader>[",
-- play = "_",
-- toggle_entry = "<leader>;"
-- },
-- order = { "title", "tag", "pos", "exchange", "translation", "definition" },
-- spinner = "dots",
-- width = 37,
-- <metatable> = {
-- __index = <function 1>
-- }
-- }
-- },
-- strategy = {
-- default = {
-- backend = <1>{ "offline", "baidu" },
-- frontend = "hover"
-- },
-- input = {
-- backend = <table 1>,
-- <metatable> = <2>{
-- __index = <function 2>
-- }
-- },
-- normal = {
-- backend = <table 1>,
-- <metatable> = <table 2>
-- },
-- visual = {
-- backend = <table 1>,
-- <metatable> = <table 2>
-- }
-- },
-- style = {
-- icon = {
-- cell = "■",
-- no = "",
-- notfound = " ",
-- star = "",
-- yes = "✔"
-- },
-- theme = "default"
-- }
-- }

View File

@ -1,25 +1,39 @@
local Trans = require('Trans')
local util = Trans.util
local function new_data(opts)
local function init_opts(opts)
opts = opts or {}
local mode = opts.method or ({
opts.mode = opts.mode or ({
n = 'normal',
v = 'visual',
})[vim.api.nvim_get_mode().mode]
local str = util.get_str(mode)
if str == '' then return end
opts.str = util.get_str(opts.mode)
return opts
end
local function new_data(opts)
local mode = opts.mode
local str = opts.str
local strategy = Trans.conf.strategy[mode]
local data = {
str = str,
mode = mode,
frontend = strategy.frontend,
backend = strategy.backend,
result = {},
}
data.frontend = Trans.frontend[strategy.frontend].new()
data.backend = {}
for i, name in ipairs(strategy.backend) do
data.backend[i] = Trans.backend[name]
end
if util.is_English(str) then
data.from = 'en'
data.to = 'zh'
@ -28,52 +42,54 @@ local function new_data(opts)
data.to = 'en'
end
-- TODO : Check if the str is a word
-- FIXME : Check if the str is a word
data.is_word = true
return data
end
local function set_result(data)
local backend_list = data.backend
local backends = Trans.backend
local frontend = Trans.frontend[data.frontend]
-- HACK :Rewrite this function to support multi request
local function do_query(name)
local backend = backends[name]
-- HACK :Rewrite this function to support multi requests
local frontend = data.frontend
for _, backend in ipairs(data.backend) do
local name = backend.name
if backend.no_wait then
backend.query(data)
else
backend.query(data)
frontend.wait(data.result, name, backend.timeout)
frontend:wait(data.result, name, backend.timeout)
end
return type(data.result[name]) == "table"
if type(data.result[name]) == 'table' then break end
end
end
for _, name in ipairs(backend_list) do
if do_query(name) then
-- TODO : process data
break
end
end
end
local function render_window(data)
-- TODO
-- TODO :
vim.pretty_print(data)
print('begin to render window')
end
-- HACK : Core process logic
local function process(opts)
Trans.translate = coroutine.wrap(process)
opts = init_opts(opts)
local str = opts.str
if not str or str == '' then return end
-- Find in cache
if Trans.cache[str] then
local data = Trans.cache[opts.str]
render_window(data)
return
end
local data = new_data(opts)
if not data then return end
set_result(data)
local success = false
for _, v in pairs(data.result) do
@ -82,9 +98,9 @@ local function process(opts)
break
end
end
vim.pretty_print(data)
if success == false then return end
Trans.cache[data.str] = data
render_window(data)
end

View File

@ -1,15 +1,24 @@
local M = {}
local Trans = require('Trans')
local api = vim.api
local conf = Trans.conf
M.__index = M
function M.init()
print('TODO: init hover window')
function M.new(data)
return setmetatable({
buffer = Trans.wrapper.buffer.new(),
}, M)
end
function M.wait(tbl, name, timeout)
function M.get_active_instance()
-- TODO :
end
function M.clear_dead_instance()
-- TODO :
end
function M:wait(tbl, name, timeout)
local error_message = 'Faild'
local interval = math.floor(timeout / #error_message)
for i = 1, #error_message do
@ -21,34 +30,38 @@ function M.wait(tbl, name, timeout)
-- TODO : End waitting animation
end
function M.process(data)
function M:process(data)
print('TODO: process data')
end
function M.is_available()
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,
}
function M:execute(action)
-- 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,
-- }
end
return M
-- local hover = conf.hover

View File

@ -142,10 +142,8 @@ buffer.__index = function(self, key)
local res = buffer[key]
if res then
return res
elseif type(key) == 'number' then
return fn.getbufoneline(self.bufnr, key)
else
error('invalid key' .. key)
end
@ -159,9 +157,11 @@ end
---buffer constructor
---@return buf
return function()
function buffer.new()
return setmetatable({
bufnr = -1,
size = 0,
}, buffer)
end
return buffer

View File

@ -151,6 +151,7 @@ window.__index = window
local default_opts = {
ns = api.nvim_create_namespace('TransHoverWin'),
enter = false,
winid = -1,
win_opts = {
style = 'minimal',
border = 'rounded',
@ -159,7 +160,7 @@ local default_opts = {
},
}
return function(opts)
function window.new(opts)
opts = vim.tbl_deep_extend('keep', opts, default_opts)
local win = setmetatable(opts, window)
@ -167,6 +168,8 @@ return function(opts)
return win
end
return window
--@class win_opts
--@field buf buf buffer for attached
--@field height integer