1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-01-24 06:30:03 +08:00
SpaceVim/lua/spacevim/plugin/a.lua

219 lines
6.2 KiB
Lua
Raw Normal View History

2021-11-04 18:44:50 +08:00
--=============================================================================
-- a.lua --- alternate plugin for SpaceVim
2023-03-26 13:50:22 +08:00
-- Copyright (c) 2016-2023 Wang Shidong & Contributors
2021-11-04 18:44:50 +08:00
-- Author: Wang Shidong < wsdjeg@outlook.com >
-- URL: https://spacevim.org
-- License: GPLv3
--=============================================================================
2021-08-15 19:06:48 +08:00
local M = {}
local sp = require('spacevim')
local cmp = require('spacevim.api').import('vim.compatible')
local cmd = require('spacevim').cmd
local sp_file = require('spacevim.api').import('file')
2021-08-18 20:54:54 +08:00
local sp_opt = require('spacevim.opt')
2021-08-15 19:06:48 +08:00
local sp_json = require('spacevim.api').import('data.json')
local toml = require('spacevim.api.data.toml')
2022-11-05 22:35:13 +08:00
local logger = require('spacevim.logger').derive('a.lua')
2022-07-03 15:29:16 +08:00
local fn = vim.fn or require('spacevim').fn
2023-06-24 21:55:10 +08:00
local nt = require('spacevim.api').import('notify')
2021-08-15 19:06:48 +08:00
local alternate_conf = {}
alternate_conf['_'] = '.project_alt.json'
2021-08-18 20:54:54 +08:00
local cache_path = sp_file.unify_path(sp_opt.data_dir, ':p') .. 'SpaceVim/a.json'
2021-08-15 19:06:48 +08:00
local project_config = {}
local function cache()
2022-11-05 22:35:13 +08:00
logger.debug('write cache into file:' .. cache_path)
local ok, errors = pcall(fn.writefile, { sp_json.json_encode(project_config) }, cache_path)
if not ok then
logger.debug('cache failed!')
else
logger.debug('cache succeeded!')
end
2021-08-15 19:06:48 +08:00
end
local function get_type_path(a, f, b)
2022-11-05 22:35:13 +08:00
local begin_len = fn.strlen(a[1])
local end_len = fn.strlen(a[2])
local r = fn.substitute(b, '{}', string.sub(f, begin_len + 1, (end_len + 1) * -1), 'g')
return r
2021-08-15 19:06:48 +08:00
end
local function load_cache()
2022-11-05 22:35:13 +08:00
logger.info('load project alternate conf cache from:' .. cache_path)
local cache_context = fn.join(fn.readfile(cache_path, ''), '')
if cache_context ~= '' then
project_config = sp_json.json_decode(cache_context)
end
2021-08-15 19:06:48 +08:00
end
function M.set_config_name(path, name)
2022-11-05 22:35:13 +08:00
alternate_conf[path] = name
2021-08-15 19:06:48 +08:00
end
function M.alt(request_parse, ...)
2022-11-05 22:38:21 +08:00
local argvs = ...
local alt_type = 'alternate'
if argvs ~= nil then
alt_type = argvs[1] or alt_type
end
2022-11-05 22:35:13 +08:00
local alt = nil
if fn.exists('b:alternate_file_config') ~= 1 then
local conf_file_path = M.getConfigPath()
2023-06-22 22:34:18 +08:00
if vim.fn.filereadable(conf_file_path) ~= 1 then
2023-06-24 21:55:10 +08:00
nt.notify('no alternate config file!', 'WarningMsg')
2023-06-22 22:34:18 +08:00
return
end
2022-11-05 22:35:13 +08:00
local file = sp_file.unify_path(fn.bufname('%'), ':.')
alt = M.get_alt(file, conf_file_path, request_parse, alt_type)
end
if alt ~= nil and alt ~= '' then
2023-07-16 13:10:27 +08:00
logger.info(' > found alternate file: ' .. alt)
2022-11-05 22:35:13 +08:00
cmd('e ' .. alt)
else
2023-07-16 13:10:27 +08:00
logger.info(' > failed to find alternate file')
2023-06-24 21:55:10 +08:00
nt.notify('failed to find alternate file!', 'WarningMsg')
2022-11-05 22:35:13 +08:00
end
2021-08-15 19:06:48 +08:00
end
local function get_project_config(conf_file)
local conf
if conf_file:sub(-4) == 'toml' then
conf = toml.parse_file(conf_file)
else
conf = sp_json.json_decode(fn.join(fn.readfile(conf_file), '\n'))
end
-- logger.debug(vim.inspect(conf))
2022-11-05 23:17:54 +08:00
if type(conf) ~= 'table' then
2022-11-05 22:35:13 +08:00
conf = {}
end
local root = sp_file.unify_path(conf_file, ':p:h')
return {
['root'] = root,
['config'] = conf,
}
2021-08-15 19:06:48 +08:00
end
-- we need to sort the keys in config
--
local function _keys(val)
2022-11-05 22:35:13 +08:00
local new_keys = {}
for k, v in pairs(val) do
table.insert(new_keys, k)
end
return new_keys
2021-08-15 19:06:48 +08:00
end
local function _comp(a, b)
2022-11-05 22:35:13 +08:00
if string.match(a, '*') == '*' and string.match(b, '*') == '*' then
return #a < #b
elseif string.match(a, '*') == '*' then
return true
elseif string.match(b, '*') == '*' then
return false
else
local _, al = string.gsub(a, '/', '')
local _, bl = string.gsub(b, '/', '')
return al < bl
end
2021-08-15 19:06:48 +08:00
end
local function parse(alt_config_json)
2022-11-05 23:17:54 +08:00
logger.info('parse alternate file for:' .. alt_config_json.root)
2022-11-05 22:35:13 +08:00
project_config[alt_config_json.root] = {}
local keys = _keys(alt_config_json.config)
table.sort(keys, _comp)
for _, key in pairs(keys) do
local searchpath = key
if string.match(searchpath, '*') == '*' then
searchpath = string.gsub(searchpath, '*', '**/*')
end
for _, file in pairs(cmp.globpath('.', searchpath)) do
file = sp_file.unify_path(file, ':.')
project_config[alt_config_json.root][file] = {}
if alt_config_json.config[file] ~= nil then
for alt_type, type_v in pairs(alt_config_json.config[file]) do
project_config[alt_config_json.root][file][alt_type] = type_v
2021-08-15 19:06:48 +08:00
end
2022-11-05 22:35:13 +08:00
else
for a_type, _ in pairs(alt_config_json.config[key]) do
local begin_end = fn.split(key, '*')
if #begin_end == 2 then
project_config[alt_config_json.root][file][a_type] =
get_type_path(begin_end, file, alt_config_json.config[key][a_type])
end
2021-08-15 19:06:48 +08:00
end
2022-11-05 22:35:13 +08:00
end
2021-08-15 19:06:48 +08:00
end
2022-11-05 22:35:13 +08:00
end
cache()
2021-08-15 19:06:48 +08:00
end
local function is_config_changed(conf_path)
2022-11-05 22:35:13 +08:00
if fn.getftime(conf_path) > fn.getftime(cache_path) then
2022-11-05 23:17:54 +08:00
return true
else
return false
2022-11-05 22:35:13 +08:00
end
2021-08-15 19:06:48 +08:00
end
function M.get_alt(file, conf_path, request_parse, a_type)
2022-11-05 22:35:13 +08:00
logger.info('getting alt file for:' .. file)
logger.info(' > type: ' .. a_type)
logger.info(' > parse: ' .. request_parse)
logger.info(' > config: ' .. conf_path)
alt_config_json = get_project_config(conf_path)
if
project_config[alt_config_json.root] == nil
2022-11-05 23:17:54 +08:00
and not is_config_changed(conf_path)
2022-11-05 22:35:13 +08:00
and request_parse == 0
then
load_cache()
if
project_config[alt_config_json.root] == nil
or project_config[alt_config_json.root][file] == nil
then
parse(alt_config_json)
2021-08-15 19:06:48 +08:00
end
2022-11-05 22:35:13 +08:00
else
parse(alt_config_json)
end
if
project_config[alt_config_json.root] ~= nil
and project_config[alt_config_json.root][file] ~= nil
and project_config[alt_config_json.root][file][a_type] ~= nil
then
return project_config[alt_config_json.root][file][a_type]
else
return ''
end
2021-08-15 19:06:48 +08:00
end
function M.getConfigPath()
2022-11-05 22:35:13 +08:00
local pwd = fn.getcwd()
local p = alternate_conf['_']
if alternate_conf[pwd] ~= nil then
p = alternate_conf[pwd]
end
return sp_file.unify_path(p, ':p')
2021-08-15 19:06:48 +08:00
end
function M.complete(arglead, cmdline, cursorpos)
2022-11-05 22:35:13 +08:00
local file = sp_file.unify_path(fn.bufname('%'), ':.')
local conf_file_path = M.getConfigPath()
local alt_config_json = get_project_config(conf_file_path)
M.get_alt(file, conf_file_path, 0, '')
local a = project_config[alt_config_json.root][file]
if a ~= nil then
return fn.join(fn.keys(a), '\n')
else
return ''
end
2021-08-15 19:06:48 +08:00
end
return M