diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 0000000..606edce --- /dev/null +++ b/go/go.mod @@ -0,0 +1,3 @@ +module query_online + +go 1.19 diff --git a/go/query_online.go b/go/query_online.go new file mode 100644 index 0000000..fc5345e --- /dev/null +++ b/go/query_online.go @@ -0,0 +1,50 @@ +package query_youcao + +import ( + "net/url" + "time" +) + +const ( + youdao = "https://openapi.youdao.com/api" + appKey = "1858465a8708c121" + appPasswd = "fG0sitfk16nJOlIlycnLPYZn1optxUxL" +) + +type data struct { + q string + from string + to string + // appKey string + salt string + sign string + signType string + curtime string +} + + +func input(word string) string { + var input string + len := len(word) + if len > 20 { + input = word[:10] + string(rune(len)) + word[len-10:] + } else { + input = word + } + return input +} + +func salt(_ string) string { + // TODO : hash salt + var salt string + + return salt +} + +func to_value(d data) url.Values { + // return value +} + +func Query(word string) { + +} diff --git a/lua/.luarc.json b/lua/.luarc.json index 43e8c9f..97534e4 100644 --- a/lua/.luarc.json +++ b/lua/.luarc.json @@ -1,6 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", "Lua.diagnostics.disable": [ - "unused-local" + "empty-block", + "trailing-space" ] } \ No newline at end of file diff --git a/lua/Trans/component/init.lua b/lua/Trans/component/init.lua new file mode 100644 index 0000000..10247c9 --- /dev/null +++ b/lua/Trans/component/init.lua @@ -0,0 +1,8 @@ +local M = {} +local order = require('Trans.conf.loader').loaded_conf.order + +M._ = function (query_) + +end + +return M diff --git a/lua/Trans/component/offline/Title.lua b/lua/Trans/component/offline/Title.lua index 71d3068..19861b0 100644 --- a/lua/Trans/component/offline/Title.lua +++ b/lua/Trans/component/offline/Title.lua @@ -1,6 +1,6 @@ local M = {} -local display = require("Tran.conf").ui.display +local display = require("Trans.conf.loader").loaded.conf.ui.display -- Example: -- local content = { -- width = 1, diff --git a/lua/Trans/conf/default.lua b/lua/Trans/conf/default.lua index 80d8694..c182892 100644 --- a/lua/Trans/conf/default.lua +++ b/lua/Trans/conf/default.lua @@ -7,14 +7,6 @@ M.conf = { cursor = 'cursor', select = 'cursor' }, - order = { - 'Title', - 'Tag', - 'Pos', - 'Exchange', - 'Translation', - 'Definition', - }, window = { cursor = { border = 'rounded', @@ -34,8 +26,21 @@ M.conf = { limit = nil, }, }, + order = { + offline = { + 'Title', + 'Tag', + 'Pos', + 'Exchange', + 'Translation', + 'Definition', + }, + -- online = { + -- -- TODO + -- }, + }, ui = { - highligh = { + highlight = { TransWord = { fg = '#7ee787', bold = true, @@ -79,16 +84,19 @@ M.conf = { base = { db_path = '$HOME/.vim/dict/ultimate.db', auto_close = true, - lazy_load = false, debug = { enable = true, type_check = true, unknown_conf = true, }, + engine = { + -- TODO + } }, - map = { - -- TODO - }, + -- map = { + -- -- TODO + -- }, + -- TODO add online translate engine -- online_search = { -- enable = false, @@ -100,8 +108,8 @@ M.conf = { -- INFO :加载的规则 [LuaRule] M.replace_rules = { - 'order', - 'Trans.+', + 'order.*', + 'ui.highlight.*', } return M diff --git a/lua/Trans/conf/init.lua b/lua/Trans/conf/init.lua deleted file mode 100644 index 01baf8e..0000000 --- a/lua/Trans/conf/init.lua +++ /dev/null @@ -1 +0,0 @@ -return require("Trans.conf.loader").get_conf() diff --git a/lua/Trans/conf/loader.lua b/lua/Trans/conf/loader.lua index 7ccad44..67a5e08 100644 --- a/lua/Trans/conf/loader.lua +++ b/lua/Trans/conf/loader.lua @@ -1,52 +1,56 @@ ----@diagnostic disable: unused-local, unused-function +-- -@diagnostic disable: unused-local, unused-function, lowercase-global local M = {} local replace_rules = require("Trans.conf.default").replace_rules -local conf = require("Trans.conf.default").conf -local user_conf = require("Trans").conf -local type_check = require("Trans.util.debug").type_check -local is_loaded = false -local function need_extend(name) - type_check { - name = { name, 'string' } - } - for _, rule in ipairs(replace_rules) do - if name:match(rule) then - return false - end +local star_format = [[ +local def, usr = default_conf.%s, user_conf.%s +if def and usr then + for k, v in pairs(usr) do + def[k] = v + usr[k] = nil end - return true end +]] --- 加载用户自定义的配置 ----@param t1 table ----@param t2 table -local function extend(t1, t2) - type_check { - t1 = { t1, 'table' }, - t2 = { t2, 'table' }, - } - for k, v in pairs(t2) do - if type(v) == 'table' and need_extend(k) then - extend(t1[k], v) - else - t1[k] = v +local plain_format = [[ +default_conf.%s = user_conf.%s or default_conf.%s +]] + +local function pre_process() + if replace_rules then + for _, v in ipairs(replace_rules) do + local start = v:find('.*', 1, true) + local operation + if start then + -- 替换表内所有键 + v = v:sub(1, start - 1) + -- print('v is :', v) + operation = string.format(star_format, v, v) + else + operation = plain_format:format(v, v, v) + end + -- print(operation) + pcall(loadstring(operation)) end end end -M.get_conf = function() - if not is_loaded then - M.load_conf() + + +M.load_conf = function(conf) + if #M.loaded_conf == 0 then + user_conf = conf or {} + default_conf = require("Trans.conf.default").conf + pre_process() + M.loaded_conf = vim.tbl_deep_extend('force', default_conf, user_conf) + user_conf = nil + default_conf = nil + else + vim.notify('Configuration has been loaded...') end - return conf end -M.load_conf = function() - -- loaded_conf = default_conf:extend(user_conf) - extend(conf, user_conf) - is_loaded = true -end +M.loaded_conf = {} return M diff --git a/lua/Trans/conf/window.lua b/lua/Trans/conf/window.lua index 04c6b49..1bad06c 100644 --- a/lua/Trans/conf/window.lua +++ b/lua/Trans/conf/window.lua @@ -1,5 +1,5 @@ local M = {} -local conf = require("Trans.conf").style.window +local conf = require("Trans.conf.loader").loaded_conf.style.window local type_check = require("Trans.util.debug").type_check -- FIXME diff --git a/lua/Trans/database/init.lua b/lua/Trans/database/init.lua index aeab460..02b1405 100644 --- a/lua/Trans/database/init.lua +++ b/lua/Trans/database/init.lua @@ -18,7 +18,7 @@ local query_field = { } -- INFO : init database -local path = require("Trans.conf").base.db_path +local path = require("Trans.conf.loader").loaded.conf.base.db_path local dict = db:open(path) -- INFO :Auto Close diff --git a/lua/Trans/init.lua b/lua/Trans/init.lua index e076815..5b4853a 100644 --- a/lua/Trans/init.lua +++ b/lua/Trans/init.lua @@ -2,12 +2,6 @@ local M = {} M.conf = {} -function M.setup(conf) - M.conf = conf or {} - if conf.base and not conf.base.lazy_load then - require("Trans.conf.loader").load_conf() - end - -- require("Trans.setup") -end +M.setup = require('Trans.conf.loader').load_conf return M diff --git a/lua/Trans/util/debug.lua b/lua/Trans/util/debug.lua index 874954b..58cb855 100644 --- a/lua/Trans/util/debug.lua +++ b/lua/Trans/util/debug.lua @@ -1,7 +1,7 @@ local M = {} -- INFO : get loaded debug conf -local base = require("Trans").conf.base +local base = require("Trans.conf.loader").loaded_conf.base local debug = require("Trans.conf.default").conf.base.debug if base and base.debug then debug = vim.tbl_extend('force', debug, base) diff --git a/lua/Trans/util/format.lua b/lua/Trans/util/format.lua index 7d9bf80..a143705 100644 --- a/lua/Trans/util/format.lua +++ b/lua/Trans/util/format.lua @@ -2,52 +2,138 @@ local M = {} local type_check = require("Trans.util.debug").type_check +-- NOTE :中文字符及占两个字节宽,但是在lua里是3个字节长度 +-- 为了解决中文字符在lua的长度和neovim显示不一致的问题 +function string:width() + local wid = 0 + local bytes = { self:byte(1, #self) } + local index = 1 + while true do + local char = bytes[index] + if char > 0 and char <= 127 then -- 英文[1] + wid = wid + 1 + index = index + 1 + elseif char >= 224 and char <= 239 then -- 中文[3] + index = index + 3 -- 原本的宽度 + wid = wid + 2 + -- elseif char >= 194 and char <= 223 then -- TODO :2 + -- width = width + 2 + -- index = index + 2 + -- elseif char >=240 and char <= 247 then -- TODO :4 + -- width = width + 4 + -- index = index + 4 + else + error('unknown char len:' .. tostring(char)) + end + + if index > #bytes then + return wid + end + end +end + -- 各种风格的基础宽度 local style_width = { float = require("Trans.conf.window").float.width, -- NOTE : need window parsed conf cursor = require("Trans.conf.window").cursor.width, } -local m_width = nil -- 需要被格式化窗口的高度 -local m_fields = nil -- 待格式化的字段 -local m_indent = nil -- 每行的行首缩进 -local m_length = nil -- 所有字段加起来的长度(不包括缩进和间隔) +local s_to_b = true -- 从小到大排列 -local function get_rows() - -- TODO - return rows -end +local m_win_width -- 需要被格式化窗口的高度 +local m_fields -- 待格式化的字段 +local m_indent -- 每行的行首缩进 +local m_length -- 所有字段加起来的长度(不包括缩进和间隔) +local m_item_width -- 每个字段的宽度 +local m_interval -- 每个字段的间隔 -local function do_indent(lines) - for i, v in ipairs(lines) do - lines[i] = (' '):rep(m_indent) .. v +local function caculate_format() + local width = m_win_width - m_item_width[1] + local cols = 0 + for i = 2, #m_fields do + width = width - m_item_width[i] - m_interval + if width < 0 then + cols = i - 1 + break + else + cols = i + end end + + return math.ceil(#m_fields / cols), cols end local function format_to_line() - local space = math.floor((m_width - m_length) / #m_fields) + local line = m_fields[1] + local space = math.floor((m_win_width - m_length) / #m_fields) + for i = 2, #m_fields do + line = line .. (' '):rep(space) .. m_fields[i] + end return line end -local function format_to_multilines() - -- TODO - type_check { - interval = { interval, 'number' }, - rows = { rows, 'number' }, - } +local function sort_tables() + table.sort(m_item_width, function(a, b) + return a > b + end) + + table.sort(m_fields, function(a, b) + return a:width() > b:width() -- 需要按照width排序 + end) end -local function get_formatted_lines() +local function format_to_multilines() + local lines = {} + sort_tables() + + --- NOTE : 计算应该格式化成多少行和列 + local rows, cols = caculate_format() + local rest = #m_fields % cols + if rest == 0 then + rest = cols + end + + local s_width = m_item_width[1] -- 列中最宽的字符串宽度 + -- NOTE : 第一列不需要加空格 + for i = 1, rows do + local idx = s_to_b and rows - i + 1 or i + local space = (' '):rep(s_width - m_item_width[i]) + lines[idx] = m_fields[i] .. space -- NOTE 由大到小 + end + + local index = rows + 1 -- 最宽字符的下标 + local interval = (' '):rep(m_interval) -- 每个字符串间的间隙 + + for j = 2, cols do -- 以列为单位遍历 + s_width = m_item_width[index] + local stop = (j > rest and rows - 1 or rows) + for i = 1, stop do + local idx = s_to_b and stop - i + 1 or i -- 当前操作的行数 + local item = index + i - 1 -- 当前操作的字段数 + local space = (' '):rep(s_width - m_item_width[item]) -- 对齐空格 + + lines[idx] = lines[idx] .. interval .. m_fields[item] .. space -- NOTE 从大到小 + end + index = index + stop -- 更新最宽字符的下标 + end + + return lines -- TODO : evaluate the width +end + +local function formatted_lines() local lines = {} -- NOTE : 判断能否格式化成一行 - if m_length + (#m_fields * m_indent) > m_width then + if m_length + (#m_fields * m_indent) > m_win_width then lines = format_to_multilines() else lines[1] = format_to_line() end - if m_indent then - do_indent(lines) + -- NOTE :进行缩进 + if m_indent and m_indent > 0 then + for i, v in ipairs(lines) do + lines[i] = (' '):rep(m_indent) .. v + end end return lines end @@ -58,9 +144,6 @@ end ---@param indent number 缩进的长度 ---@return string[] lines 便于vim.api.nvim_buf_set_lines M.to_lines = function(style, fields, indent) - if not fields then - return {} - end type_check { style = { style, { 'string' } }, fields = { fields, { 'table' } }, @@ -68,57 +151,22 @@ M.to_lines = function(style, fields, indent) } local length = 0 - for _, v in ipairs(fields) do - length = length + #v + local width = 0 + local item_size = {} + for i, v in ipairs(fields) do + width = v:width() + items_size[i] = width + length = length + width end - m_width = style_width[style] - indent - m_indent = indent - m_fields = fields - m_length = length - return get_formatted_lines() + m_indent = indent or 0 + m_win_width = style_width[style] - m_indent + m_fields = fields + m_length = length + m_item_width = item_size + m_interval = m_win_width > 50 and 6 or 4 + + return formatted_lines() end --- local function get_lines(win_width, components) --- local lines = {} --- local interval = win_width > 40 and 6 or 4 --- local row = 1 --- local width = win_width - #components[1] --- for i in 2, #components do --- width = width - #components[i] - interval --- if width < 0 then --- width = win_width - #components[i] --- row = row + 1 --- end --- end --- if row == 1 then --- local format = '%s' .. ((' '):rep(interval) .. '%s') --- lines[1] = string.format(format, unpack(components)) --- else --- table.sort(components, function (a, b) --- return #a > #b --- end) --- -- FIXME --- local res, rem = #components / (row + 1), #components % (row + 1) --- row = math.ceil(res) --- local rol = row - rem - 1 --- end --- --- return lines --- end --- --- M.format = function(style, components, indent) --- local lines = {} --- if #components > 1 then --- indent = indent or 0 --- type_check { --- style = { style, 'string' }, --- components = { components, 'table' }, ---@string[] --- -- max_items = { max_items, { 'nil', 'number' } }, ---@string[] --- } --- local win_width = (style == 'float' and float_win_width or cursor_win_width) - indent --- local res = get_lines(win_width, components) --- end --- return lines --- end return M diff --git a/lua/Trans/util/test/a.lua b/lua/Trans/util/test/a.lua deleted file mode 120000 index 9b39cbe..0000000 --- a/lua/Trans/util/test/a.lua +++ /dev/null @@ -1 +0,0 @@ -query_youdao.lua \ No newline at end of file diff --git a/lua/Trans/util/test/format.lua b/lua/Trans/util/test/format.lua new file mode 100644 index 0000000..fe66581 --- /dev/null +++ b/lua/Trans/util/test/format.lua @@ -0,0 +1,205 @@ +local M = {} +-- local type_check = require("Trans.util.debug").type_check + + +-- NOTE :中文字符及占两个字节宽,但是在lua里是3个字节长度 +-- 为了解决中文字符在lua的长度和neovim显示不一致的问题 +function string:width() + local width = 0 + local bytes = { self:byte(1, #self) } + local index = 1 + while true do + local char = bytes[index] + if char > 0 and char <= 127 then -- 英文[1] + width = width + 1 + index = index + 1 + elseif char >= 224 and char <= 239 then -- 中文[3] + index = index + 3 -- 原本的宽度 + width = width + 2 + -- elseif char >= 194 and char <= 223 then -- TODO :2 + -- width = width + 2 + -- index = index + 2 + -- elseif char >=240 and char <= 247 then -- TODO :4 + -- width = width + 4 + -- index = index + 4 + else + error('unknown char len:' .. tostring(char)) + end + if index > #bytes then + return width + end + end +end + +-- 各种风格的基础宽度 +local style_width = { + -- float = require("Trans.conf.window").float.width, -- NOTE : need window parsed conf + cursor = 60, +} +local s_to_b = true -- 从小到大排列 + +local m_fields -- 待格式化的字段 +local m_indent -- 每行的行首缩进 +local m_length -- 所有字段加起来的长度(不包括缩进和间隔) +local m_interval -- 每个字段的间隔 +local m_win_width -- 需要被格式化窗口的高度 +local m_item_width -- 每个字段的宽度 + +local function caculate_format() + local width = m_win_width - m_item_width[1] + local cols = 0 + for i = 2, #m_fields do + width = width - m_item_width[i] - m_interval + if width < 0 then + cols = i - 1 + break + else + cols = i + end + end + + return math.ceil(#m_fields / cols), cols +end + +local function format_to_line() + local line = m_fields[1] + local space = math.floor((m_win_width - m_length) / #m_fields) + for i = 2, #m_fields do + line = line .. (' '):rep(space) .. m_fields[i] + end + return line +end + + +local function sort_tables() + table.sort(m_item_width, function (a, b) + return a > b + end) + + table.sort(m_fields, function (a, b) + return a:width() > b:width() + end) +end + + +local function format_to_multilines() + local lines = {} + sort_tables() + + --- NOTE : 计算应该格式化成多少行和列 + local rows, cols = caculate_format() + local rest = #m_fields % cols + if rest == 0 then + rest = cols + end + + local s_width = m_item_width[1] -- 列中最宽的字符串宽度 + -- NOTE : 第一列不需要加空格 + for i = 1, rows do + local idx = s_to_b and rows - i + 1 or i + local space = (' '):rep(s_width - m_item_width[i]) + lines[idx] = m_fields[i] .. space -- NOTE 由大到小 + end + + local index = rows + 1 -- 最宽字符的下标 + local interval = (' '):rep(m_interval) -- 每个字符串间的间隙 + + for j = 2, cols do -- 以列为单位遍历 + s_width = m_item_width[index] + local stop = (j > rest and rows - 1 or rows) + for i = 1, stop do + local idx = s_to_b and stop - i + 1 or i -- 当前操作的行数 + local item = index + i - 1 -- 当前操作的字段数 + local space = (' '):rep(s_width - m_item_width[item]) -- 对齐空格 + + lines[idx] = lines[idx] .. interval .. m_fields[item] .. space -- NOTE 从大到小 + end + index = index + stop -- 更新最宽字符的下标 + end + + return lines +end + + +local function get_formatted_lines() + local lines = {} + -- NOTE : 判断能否格式化成一行 + local line_size = m_length + (#m_fields * m_interval) + if line_size > m_win_width then + lines = format_to_multilines() + else + lines[1] = format_to_line() + end + + -- NOTE :进行缩进 + if m_indent > 0 then + for i, v in ipairs(lines) do + lines[i] = (' '):rep(m_indent) .. v + end + end + return lines +end + +---将组件格式化成相应的vim支持的lines格式 +---@param style string 窗口的风格 +---@param fields string[] 需要格式化的字段 +---@param indent? number 缩进的长度 +---@return string[] lines 便于vim.api.nvim_buf_set_lines +M.to_lines = function(style, fields, indent) + + local length = 0 + local width = 0 + local item_size = {} + for i, v in ipairs(fields) do + width = v:width() + item_size[i] = width + length = length + width + end + + m_indent = indent or 0 + m_win_width = style_width[style] - m_indent + m_fields = fields + m_length = length + m_item_width = item_size + m_interval = m_win_width > 50 and 6 or 4 + + return get_formatted_lines() +end + +local test = { + 'ajlkasj', + 'jklasjldajjnn测试', + 'ljlklkjjlIi戳', + '测试将安得拉蓝色', + '戳将安塞', + 'isjlkajsldj', +} + +local lines = M.to_lines('cursor', test) + +-- print('===========================================') +-- for _, v in ipairs(test) do +-- print(v .. ' width:', v:width()) +-- end +-- print('===========================================') +-- print('===========================================') +-- print('===========================================') + +-- print('type is :' .. type(lines) .. ' size is :' .. #lines[1]) + +for _, v in ipairs(lines) do + print(v) +end + +-- lines = M.to_lines('cursor', { +-- 'ajlkasj', +-- 'jklasjldajjnn测试', +-- '测试将安得拉蓝色', +-- 'cool this', +-- }, 4) + +-- for _, v in ipairs(lines) do +-- print(v) +-- end +return M + diff --git a/lua/Trans/util/test/is_Chinese.lua b/lua/Trans/util/test/is_Chinese.lua new file mode 100644 index 0000000..cf15825 --- /dev/null +++ b/lua/Trans/util/test/is_Chinese.lua @@ -0,0 +1,15 @@ +local M = {} +-- local type_check = require("Trans.util.debug").type_check + + +---@param str string +local function is_Chinese(str) + for i = 1, #str do + if not str:byte(i) >= [[\u4e00]] then + return false + end + end + return true +end + +return M diff --git a/lua/Trans/util/test/test.lua b/lua/Trans/util/test/test.lua new file mode 100644 index 0000000..5c5d03f --- /dev/null +++ b/lua/Trans/util/test/test.lua @@ -0,0 +1,13 @@ +local M = {} + +local a = { + b = 'test', +} + +local c = a +c.b = 'notest' + + + +print(a.b) +return M