wip almost done on a first version that does nothing
This commit is contained in:
parent
35e7f18b89
commit
6f5268bec3
|
@ -12,6 +12,7 @@
|
|||
"/usr/share/nvim/runtime/",
|
||||
"/usr/share/nvim/runtime/lua",
|
||||
"/usr/share/nvim/runtime/lua/vim",
|
||||
"/usr/share/nvim/runtime/lua/vim/lsp"
|
||||
"/usr/share/nvim/runtime/lua/vim/lsp",
|
||||
"~/.local/share/nvim/site/pack/packer/start/packer.nvim/lua"
|
||||
]
|
||||
}
|
||||
|
|
48
install.lua
48
install.lua
|
@ -2,35 +2,43 @@
|
|||
-- hsv2
|
||||
---@param branch string
|
||||
local function clone(branch)
|
||||
local path = vim.fn.stdpath("data") .. "/site/pack/hsv2/opt/hsv2.nvim"
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
vim.fn.system {
|
||||
"git",
|
||||
"clone",
|
||||
local path = vim.fn.stdpath("data") .. "/site/pack/hsv2/opt/hsv2.nvim"
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
local output = vim.fn.system {
|
||||
"git",
|
||||
"clone",
|
||||
"--branch",
|
||||
branch,
|
||||
"--depth=1",
|
||||
"https://git.disroot.org/soratobuneko/hsv2-neovim",
|
||||
path
|
||||
}
|
||||
return vim.v.shell_error == 0
|
||||
end
|
||||
return true
|
||||
"--depth=1",
|
||||
"https://git.disroot.org/soratobuneko/hsv2-neovim",
|
||||
path
|
||||
}
|
||||
return vim.v.shell_error == 0, output
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---@param branch string
|
||||
---|> "master"
|
||||
---| "dev"
|
||||
function INSTALL_HSV2(branch)
|
||||
if not clone(branch) then
|
||||
vim.api.nvim_echo({{"Failed to clone repository", "Error"}}, true, {})
|
||||
return
|
||||
local valid = { master = true, dev = true }
|
||||
branch = valid[branch] and branch or "master"
|
||||
local status, output = clone(branch)
|
||||
if not status then
|
||||
vim.api.nvim_echo({
|
||||
{ "Failed to clone repository", "Error" },
|
||||
{ output, "Error" },
|
||||
}, true, {})
|
||||
return
|
||||
end
|
||||
vim.api.nvim_echo({{"Loading hsv2.nvim…"}}, true, {})
|
||||
vim.api.nvim_echo({ { "Loading hsv2.nvim…" } }, true, {})
|
||||
vim.api.nvim_exec("packadd hsv2.nvim", false)
|
||||
local status, hsv2, L = pcall(require, "hsv2")
|
||||
local status, hsv2 = pcall(require, "hsv2")
|
||||
if status then
|
||||
vim.api.nvim_echo({{"Loaded!"}}, true, {})
|
||||
return vim.pretty_print(require("hsv2"))
|
||||
vim.api.nvim_echo({ { "Loaded!" } }, true, {})
|
||||
return vim.pretty_print(require("hsv2"))
|
||||
else
|
||||
vim.api.nvim_echo({{"Failed!\n", "Error"}, {hsv2, "Error"}}, true, {})
|
||||
vim.api.nvim_echo({ { "Failed!\n", "Error" }, { hsv2, "Error" } }, true, {})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
-- vim: et sw=4 ts=4:
|
||||
local function clone_packer()
|
||||
local path = vim.fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim'
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
vim.fn.system {
|
||||
'git',
|
||||
'clone',
|
||||
'--depth=1',
|
||||
'https://github.com/wbthomason/packer.nvim',
|
||||
path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function bootstrap_packer(pkgs)
|
||||
clone_packer()
|
||||
-- Load Packer
|
||||
vim.cmd('packadd packer.nvim')
|
||||
PLUGINS.packer = require('packer')
|
||||
PLUGINS.packer.startup(pkgs)
|
||||
vim.api.nvim_create_autocmd('User', {
|
||||
pattern = 'PackerComplete',
|
||||
command = 'quitall',
|
||||
})
|
||||
PLUGINS.packer.sync()
|
||||
end
|
||||
|
||||
return { bootstrap_packer = bootstrap_packer }
|
23
lua/hsv2.lua
23
lua/hsv2.lua
|
@ -4,22 +4,33 @@
|
|||
local M = {}
|
||||
local L = {}
|
||||
|
||||
---Init HSV2
|
||||
---@param config? hsv2_config
|
||||
function M.init(config)
|
||||
M.config = require("hsv2.config")
|
||||
M.enums = require("hsv2.enums")
|
||||
M.utils = require("hsv2.utils")
|
||||
|
||||
M.config.register_listener("log", M.utils.log.config_listener,
|
||||
"default .log listener", M.enums.log_lstnr_prio.core)
|
||||
config = type(config) == "table" and config or {}
|
||||
L.init_log(config)
|
||||
L.init_pkgmanager(config)
|
||||
M.core = { pkgmanager = require("hsv2.core.pkgmanager") }
|
||||
|
||||
M.config.set(nil, config)
|
||||
|
||||
L.init_pkgmanager({})
|
||||
M.config.set(nil, M.config.from_env())
|
||||
end
|
||||
|
||||
function L.init_log(config)
|
||||
M.utils.log.init(config)
|
||||
M.config.register_listener("log", M.utils.log.config_listener,
|
||||
"default .log listener", M.enums.log_lstnr_prio.core)
|
||||
end
|
||||
|
||||
---Init plugin manager
|
||||
---@param config? hsv2_config
|
||||
function L.init_pkgmanager(config)
|
||||
local _, pkgmngr_priv = require("hsv2.utils.pkgmanager")
|
||||
pkgmngr_priv.install()
|
||||
local pkgmngr = require("hsv2.core.pkgmanager")
|
||||
pkgmngr.init(config)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -38,14 +38,15 @@ function M.set(path, value)
|
|||
end
|
||||
|
||||
---@alias config_listener_fn fun(c: table<string, any>, p: path, v: any)
|
||||
---Config listener table path -> priority group -> listeners
|
||||
---@type table<string, table<integer, config_listener[]>>
|
||||
L.listeners = {}
|
||||
|
||||
|
||||
---@class config_listener
|
||||
---@field fn config_listener_fn
|
||||
---@field name? string descriptive name
|
||||
---@field priority number [1-100]
|
||||
---@field name? string descriptive name
|
||||
---@field priority integer [1-100]
|
||||
---@param path path
|
||||
---@param listener config_listener_fn
|
||||
---@return config_listener[]
|
||||
|
@ -68,11 +69,11 @@ function L.get_listeners(path)
|
|||
if utils.paths.compare(path, p) then
|
||||
for i = 1, 100 do
|
||||
if prio_group[i] then
|
||||
local group = utils.tables.copy(prio_group[i])
|
||||
local group = vim.tbl_extend("force", {}, prio_group[i])
|
||||
for _, listener in ipairs(group) do
|
||||
listener.priority = i
|
||||
end
|
||||
path_listeners = utils.tables.join_list(path_listeners, group)
|
||||
vim.list_extend(path_listeners, group)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -81,6 +82,13 @@ function L.get_listeners(path)
|
|||
return path_listeners
|
||||
end
|
||||
|
||||
---Register a config listener
|
||||
---@param path path|path_raw
|
||||
---@param listener config_listener
|
||||
---@param name? string
|
||||
---@param priority integer [1-100]
|
||||
---@return boolean true listener registered.
|
||||
---@return boolean false same listener with same priority already registered.
|
||||
function M.register_listener(path, listener, name, priority)
|
||||
utils.asserts.type(path, { "string", "number", "table" }, "path")
|
||||
utils.asserts.type(listener, "function", "listener")
|
||||
|
@ -108,6 +116,11 @@ function M.register_listener(path, listener, name, priority)
|
|||
return true
|
||||
end
|
||||
|
||||
---Unregister a config listener.
|
||||
---@param path path|path_raw
|
||||
---@param listener config_listener
|
||||
---@param priority integer [1-100]
|
||||
---@return config_listener? removed removed listener
|
||||
function M.unregister_listener(path, listener, priority)
|
||||
utils.asserts.type(listener, "function", "listener")
|
||||
utils.asserts.type(priority, "number", "priority")
|
||||
|
@ -128,15 +141,15 @@ L.config = (function()
|
|||
local config = {}
|
||||
|
||||
return function()
|
||||
utils.tables.fill_defaults(config, nil, defaults)
|
||||
config = vim.tbl_deep_extend("keep", config, defaults())
|
||||
return config
|
||||
end
|
||||
end)()
|
||||
|
||||
---
|
||||
---Called on each new config table leaf nodes.
|
||||
---@param path path|path_raw
|
||||
---@param value any
|
||||
---@return boolean Status.
|
||||
---@return boolean, table [1] if a config_listener gaves an error returns false, true otherwise and a list of status of each config_listener call
|
||||
function L.on_config_update(path, value)
|
||||
local error = false
|
||||
local listeners = L.get_listeners(path)
|
||||
|
@ -150,21 +163,23 @@ function L.on_config_update(path, value)
|
|||
end
|
||||
|
||||
local function noop(...)
|
||||
return unpack(...)
|
||||
return ...
|
||||
end
|
||||
---@type table<string, table<string, function>> map env variable name to config table path and a preprocessing function
|
||||
---@alias env_preproc_fn fun(env_value: string):any function used to preprocess env values
|
||||
---@type table<string, table<path_raw, env_preproc_fn>> map env variable name to config table path and a preprocessing function
|
||||
L.map_env_conf = {
|
||||
HSV2_LOG_LEVEL = { "log.level", noop},
|
||||
}
|
||||
|
||||
---Load configuration from environment
|
||||
---@return hsv2_config
|
||||
function L.from_env()
|
||||
---@return hsv2_config conf
|
||||
function M.from_env()
|
||||
local conf = {}
|
||||
for env, conf_path in pairs(L.map_env_conf) do
|
||||
utils.tables.set(conf, conf_path, vim.env[env])
|
||||
for env, pair in pairs(L.map_env_conf) do
|
||||
utils.tables.set(conf, pair[1], pair[2](vim.env[env]))
|
||||
end
|
||||
|
||||
vim.pretty_print({env=conf})
|
||||
return conf
|
||||
end
|
||||
--[[
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
local L = {}
|
||||
---@type hsv2_config
|
||||
L = {}
|
||||
|
||||
---@module "hsv2.config.defaults"
|
||||
local M = function()
|
||||
return require("hsv2.utils.tables").copy(L)
|
||||
end
|
||||
|
||||
return M, L
|
||||
return M
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
---@module "hsv2.core.packer"
|
||||
local M = {}
|
||||
local L = {}
|
||||
|
||||
---Init packer and install it if missing
|
||||
---@param config table
|
||||
---@return boolean status
|
||||
function M.init(config)
|
||||
local log = require("hsv2.utils.log").log
|
||||
if not packer_plugins then
|
||||
local install_path = vim.fn.stdpath('data')
|
||||
.. '/site/pack/hsv2/opt/packer.nvim'
|
||||
local status, output = L.install(install_path)
|
||||
if not status then
|
||||
log({
|
||||
{ "Error: failed to install packer\n", "Error" },
|
||||
{ output, "Error" },
|
||||
}, "err")
|
||||
|
||||
return false
|
||||
end
|
||||
log("packer installed in " .. install_path, "info")
|
||||
vim.cmd("packadd packer.nvim")
|
||||
end
|
||||
|
||||
local status, packer = pcall(require, "packer")
|
||||
if status then
|
||||
config = vim.tbl_extend("force", {}, config, { plugin_package = "hsv2" })
|
||||
packer.init(config)
|
||||
---@module "packer"
|
||||
M.packer = packer
|
||||
log("packer loaded", "info")
|
||||
|
||||
return M.packer
|
||||
end
|
||||
|
||||
log({
|
||||
{ "failed to load packer\n", "Error" },
|
||||
{ packer, "Error" },
|
||||
}, "err")
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
---Download packer to the given path
|
||||
---@param path string
|
||||
---@return boolean, table? status status and command output on error.
|
||||
function L.install(path)
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
local log = require("hsv2.utils.log").log
|
||||
log("downloading packer…", "info")
|
||||
local output = vim.fn.system {
|
||||
'git',
|
||||
'clone',
|
||||
'--depth=1',
|
||||
'https://github.com/wbthomason/packer.nvim',
|
||||
path
|
||||
}
|
||||
|
||||
return vim.v.shell_error == 0, output
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,12 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
---@module "hsv2.core.pkgmanager"
|
||||
local M = {}
|
||||
|
||||
---Init plugin manager.
|
||||
---@param config hsv2_config
|
||||
function M.init(config)
|
||||
M.packer = require("hsv2.core.packer").init(config)
|
||||
end
|
||||
|
||||
return M
|
|
@ -20,6 +20,7 @@ M.log_lstnr_prio = {
|
|||
}
|
||||
|
||||
---@alias log_level
|
||||
---| "all" alias for the highest log level
|
||||
---| "debug" Debug-level messages
|
||||
---| "info" Informational
|
||||
---|> "notice" Normal but significant condition
|
||||
|
|
|
@ -1,258 +0,0 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
local M = {}
|
||||
local L = {}
|
||||
local cmd = require('hsv2.utils.cmd')
|
||||
local packer = require("hsv2.utils.packer")
|
||||
|
||||
function M.bootstrap_packer()
|
||||
local status, _ = pcall(require, 'packer')
|
||||
if not status then
|
||||
cmd.echo_info({ 'Install ', { "packer.nvim", "Keyword" }, "..." })
|
||||
if not L.clone_packer() then
|
||||
cmd.echo_error({ "Failed to download ", { "packer.nvim", "Keyword" }, "!" })
|
||||
return false
|
||||
end
|
||||
end
|
||||
if not package.loaded.packer then
|
||||
vim.api.nvim_exec('packadd packer.nvim', false)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function M.check_missing_requirement(reqs, disable_plugin_on_req_fail)
|
||||
local u = require("hsv2.utils")
|
||||
local not_found = {}
|
||||
for k, req in pairs(reqs) do
|
||||
local desc = (req.desc ~= nil and (string.len(req.desc) > 0 and (": " .. req.desc) or "") or "") .. "..."
|
||||
cmd.echo_info({ 'Check requirement ', { k, "Keyword" }, " for ",
|
||||
{ req.by, "Keyword" }, desc })
|
||||
if req.cmd and vim.fn.executable(req.cmd) == 0 then
|
||||
cmd.echo_error(
|
||||
{ "Requirement ", { k, "Keyword" }, " not met:\n",
|
||||
"Missing ", { req.cmd, "Keyword" }, "." },
|
||||
not req.opt)
|
||||
not_found[req.by] = not_found[req.by] or {}
|
||||
u.table_append(not_found[req.by], {
|
||||
failing = req.cmd,
|
||||
opt = req.opt,
|
||||
})
|
||||
else
|
||||
cmd.echo_info({ 'Using ', { req.cmd, "Keyword" }, "." })
|
||||
end
|
||||
end
|
||||
if next(not_found) then
|
||||
u.for_one_or_more(not_found, function(by, plugin_failed_reqs, _)
|
||||
local to_disable = {}
|
||||
u.for_one_or_more(plugin_failed_reqs, function(_, req, _)
|
||||
if req.opt then
|
||||
cmd.echo_info({
|
||||
"Failing optional requirement for ",
|
||||
{ by, "Keyword" },
|
||||
": ",
|
||||
{ req.failing, "Error" },
|
||||
})
|
||||
else
|
||||
to_disable[by] = true
|
||||
end
|
||||
end)
|
||||
if disable_plugin_on_req_fail then
|
||||
u.for_one_or_more(to_disable, function(plugin, _, _)
|
||||
cmd.echo_warning({
|
||||
"Disable plugin ", { plugin, "Keyword" },
|
||||
" because of unmet requirements.",
|
||||
})
|
||||
M.disable_plugin(plugin)
|
||||
not_found[plugin] = nil
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
return next(not_found) ~= nil and not_found or nil
|
||||
end
|
||||
|
||||
function M.disable_plugin(plugin)
|
||||
local u = require("hsv2.utils")
|
||||
local c = require("hsv2.config")
|
||||
local plugins = c.plugins()
|
||||
assert(u.is_one_of_keys(plugin, plugins))
|
||||
c.config({
|
||||
"plugins",
|
||||
plugin,
|
||||
"enabled",
|
||||
}, false)
|
||||
end
|
||||
|
||||
function M.init(config_override)
|
||||
local c = require('hsv2.config')
|
||||
c.config(nil, c.config_from_env())
|
||||
c.config(nil, config_override)
|
||||
|
||||
if M.check_missing_requirement(c.requirements_hsv2()) then
|
||||
cmd.echo_error('Some requirements aren\'t met. Errors are coming!')
|
||||
end
|
||||
|
||||
if M.check_missing_requirement(c.requirements_plugins(), true) then
|
||||
cmd.echo_warning("Some plugins had been disabled because of failing requirement.")
|
||||
end
|
||||
|
||||
for plugin, conf in pairs(c.plugins()) do
|
||||
if conf.enabled and not packer.has_plugin_loaded(plugin) then
|
||||
M.setup_packer()
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- @param params string|table a plugin name or list of plugin names
|
||||
function M.load_plugin(plugins)
|
||||
require("hsv2.utils").for_one_or_more(plugins, function(plugin)
|
||||
vim.api.nvim_exec("packadd " .. plugin)
|
||||
end)
|
||||
end
|
||||
|
||||
-- keymap = {
|
||||
-- ["<Leader>"] = {
|
||||
-- a = {
|
||||
-- name = "desc key a",
|
||||
-- rhs = "<CMD>echo 'hello'",
|
||||
-- mode = "n",
|
||||
-- opts = {
|
||||
-- buffer = true,
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
-- TODO inherit opts from upper level
|
||||
function M.map_keys(keymap, prefix)
|
||||
local wk_register = require("hsv2.plugins.which-key").register_keymap
|
||||
local function node_action(previous_keys, key, node, inherited)
|
||||
local u = require("hsv2.utils")
|
||||
local opts = {
|
||||
silent = true,
|
||||
noremap = true,
|
||||
}
|
||||
u.table_append(opts, inherited.opts)
|
||||
u.table_append(opts, node.opts)
|
||||
local mode = node.mode or inherited.mode or "n"
|
||||
vim.pretty_print({
|
||||
map_keys = {
|
||||
mode = mode,
|
||||
opts = opts,
|
||||
}
|
||||
})
|
||||
if node.rhs ~= nil then
|
||||
opts.desc = node.name
|
||||
cmd.echo_info({
|
||||
"Map keys '",
|
||||
{ previous_keys .. key, "Keyword" },
|
||||
"' to ",
|
||||
{ node.rhs, "Keyword" },
|
||||
" for modes ",
|
||||
{ require("hsv2.utils").list_values_str(mode), "Keyword" },
|
||||
"."
|
||||
})
|
||||
-- vim.keymap.set(mode, previous_keys .. key, node.rhs, opts)
|
||||
elseif node.name ~= nil then
|
||||
opts.mode = mode
|
||||
opts.prefix = previous_keys
|
||||
local map = {
|
||||
[key] = {
|
||||
name = node.name,
|
||||
},
|
||||
}
|
||||
-- wk_register(map, opts)
|
||||
end
|
||||
end
|
||||
|
||||
local u = require("hsv2.utils")
|
||||
local function recurse(mapping, previous_keys, upper_inherited)
|
||||
local inherited = u.table_deep_copy(upper_inherited)
|
||||
u.table_append({
|
||||
mode = mapping.mode,
|
||||
opts = mapping.opts,
|
||||
})
|
||||
for k, v in pairs(mapping) do
|
||||
if not u.is_one_of_values(k, {
|
||||
"name",
|
||||
"rhs",
|
||||
"mode",
|
||||
"opts",
|
||||
}) then
|
||||
node_action(previous_keys, k, v, inherited)
|
||||
recurse(v, previous_keys .. k, inherited)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
recurse(keymap, prefix)
|
||||
end
|
||||
|
||||
function M.setup_packer()
|
||||
local c = require("hsv2.config")
|
||||
if not packer.has_plugin_loaded("packer.nvim") then
|
||||
cmd.echo_info({ "Loading ", { "packer.nvim", "Keyword" }, "." })
|
||||
if not M.bootstrap_packer() then
|
||||
cmd.echo_error({
|
||||
"Failed to bootstrap packer. Aborting ",
|
||||
{ "HSV2", "Keyword" },
|
||||
" initialization.",
|
||||
})
|
||||
return false
|
||||
end
|
||||
end
|
||||
packer.init_default()
|
||||
|
||||
cmd.echo_info('Loading plugins...')
|
||||
for plugin, conf in pairs(c.plugins()) do
|
||||
if conf.enabled == true then
|
||||
M.use_plugin(plugin)
|
||||
else
|
||||
cmd.echo_info({ "Skip disabled plugin ", { plugin, "Keyword" }, "." })
|
||||
end
|
||||
end
|
||||
|
||||
cmd.echo_info("Install missing plugins...")
|
||||
packer.install()
|
||||
|
||||
vim.api.nvim_create_autocmd({ "User" }, {
|
||||
pattern = "PackerComplete",
|
||||
callback = function()
|
||||
cmd.echo_info({ "Run ", { "packer.compile()", "Keyword" }, "..." })
|
||||
packer.compile()
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
function M.use_plugin(plugins)
|
||||
require("hsv2.utils").for_one_or_more(plugins, function(_, plugin, _)
|
||||
local status, module = pcall(require, "hsv2.plugins." .. plugin)
|
||||
if status then
|
||||
cmd.echo_info({ "Add plugin ", { plugin, "Keyword" }, "." })
|
||||
packer.use(module.packer_spec())
|
||||
else
|
||||
cmd.echo_error({
|
||||
"Plugin skiped: failed to load module ",
|
||||
{ plugin, "Keyword" }, "\n", module })
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function L.clone_packer()
|
||||
local path = vim.fn.stdpath('data') .. '/site/pack/packer/opt/packer.nvim'
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
local cmd_output = vim.fn.system({
|
||||
require('hsv2.config').requirements_hsv2().git.cmd,
|
||||
'clone',
|
||||
'--depth=1',
|
||||
'https://github.com/wbthomason/packer.nvim',
|
||||
path
|
||||
})
|
||||
return vim.v.shell_error == 0
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return M
|
|
@ -8,7 +8,7 @@ local M = {}
|
|||
---@param value any The value to check.
|
||||
---@param expected types|type Type name or list of type names.
|
||||
---@param name string Value name for error message.
|
||||
---@param opt boolean? Set the value as optional (allow nil).
|
||||
---@param opt? boolean Set the value as optional (allow nil).
|
||||
---@return type value_type Value type.
|
||||
function M.type(value, expected, name, opt)
|
||||
local tables = require("hsv2.utils.tables")
|
||||
|
@ -18,7 +18,7 @@ function M.type(value, expected, name, opt)
|
|||
local value_type = type(value)
|
||||
local caller = debug.getinfo(2, "n").name or ""
|
||||
assert(opt and value == nil or tables.one_of_values(value_type, expected),
|
||||
caller .. " parameter '" .. name .. "' cannot be a " .. value_type)
|
||||
caller .. ": parameter '" .. name .. "' cannot be a " .. value_type)
|
||||
return value_type
|
||||
end
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
local M = {}
|
||||
local L = {}
|
||||
local u = require("hsv2.utils")
|
||||
local c = require("hsv2.config")
|
||||
|
||||
function M.echo(strs, cond, level)
|
||||
assert(type(strs) == "string" or type(strs) == "table",
|
||||
"strs must be a string or a list of pairs of output string and optional highlight.")
|
||||
strs = type(strs) == "string" and { { strs } } or strs
|
||||
local output = {
|
||||
{ "HSV2", "Title" },
|
||||
{ ":" },
|
||||
{ c.log_level_name(level) },
|
||||
{ "\t" },
|
||||
}
|
||||
local hl_group = "Normal"
|
||||
for k, hl in pairs({
|
||||
error = "Error",
|
||||
fatal = "Error",
|
||||
trace = "MoreMsg",
|
||||
warning = "WarningMsg",
|
||||
}) do
|
||||
if k == c.log_level_name(level) then
|
||||
hl_group = hl
|
||||
break
|
||||
end
|
||||
end
|
||||
L.add_highlight(strs, hl_group)
|
||||
strs = L.indent(strs, 2)
|
||||
for _, str in ipairs(strs) do
|
||||
if type(str) == "string" then
|
||||
str = { str }
|
||||
end
|
||||
output[#output + 1] = str
|
||||
end
|
||||
if (cond == nil or cond) and c.log_level(level or c.config("enum.log_levels.info")) then
|
||||
if level == c.config("enum.log_levels.trace") then
|
||||
u.table_append(output, { debug.traceback() })
|
||||
end
|
||||
vim.api.nvim_echo(output, true, {})
|
||||
end
|
||||
end
|
||||
|
||||
function M.pprint(obj, cond, level)
|
||||
M.echo(vim.inspect(obj), cond, level)
|
||||
end
|
||||
|
||||
u.table_map(c.config("enum.log_levels"), function(name, level)
|
||||
M["pprint_" .. name] = function(obj, cond)
|
||||
M.pprint(obj, cond, level)
|
||||
end
|
||||
M["echo_" .. name] = function(str, cond)
|
||||
M.echo(str, cond, level)
|
||||
end
|
||||
end)
|
||||
|
||||
function M.set_vim_global(prefix, value)
|
||||
if not type(prefix) == 'string' then
|
||||
prefix = ''
|
||||
end
|
||||
for k, v in pairs(value) do
|
||||
vim.g[prefix .. k] = v
|
||||
end
|
||||
end
|
||||
|
||||
function L.add_highlight(str_list, hl_group)
|
||||
hl_group = type(hl_group) == "string" and hl_group or "Normal"
|
||||
for i, str in ipairs(str_list) do
|
||||
str = type(str) == "string" and { str } or str
|
||||
str_list[i] = type(str[2]) == "string" and str or { str[1], hl_group }
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO use map or something
|
||||
function L.indent(strs, level)
|
||||
strs = type(strs) == "table" and strs or { strs }
|
||||
local tabs = ""
|
||||
for _ = 1, level do
|
||||
tabs = tabs .. "\t"
|
||||
end
|
||||
local result = {}
|
||||
for j, v in ipairs(strs) do
|
||||
if j > 1 and result[#result][1]:match("\n") then
|
||||
table.insert(result, { tabs, "Normal" })
|
||||
end
|
||||
local str = type(v) == "string" and v or v[1]
|
||||
local hlgroup = type(v) == "table" and v[2] or nil
|
||||
local lines = require("hsv2.utils").str_split(str, "\n", true)
|
||||
for i, line in ipairs(lines) do
|
||||
table.insert(result, { line, hlgroup })
|
||||
if line:match("\n") == "\n" and next(lines, i) then
|
||||
table.insert(result, { tabs, "Normal" })
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return M
|
|
@ -4,6 +4,7 @@
|
|||
---@module "hsv2.utils.generics"
|
||||
local M = {}
|
||||
|
||||
--TODO: copy functions?
|
||||
---Ensure we get copies of reference types.
|
||||
---@param x any
|
||||
---@return any x `x` or deep copy of `x` if it's a table.
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
|
||||
local M = {}
|
||||
|
||||
---@deprecated
|
||||
function M.for_one_or_more(values, callback)
|
||||
if type(values) ~= "table" then
|
||||
values = { values }
|
||||
end
|
||||
local res = {}
|
||||
for k, value in pairs(values) do
|
||||
res[#res + 1] = callback(k, value, values)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
---@deprecated
|
||||
function M.list_keys_str(list, prefix)
|
||||
local str = nil
|
||||
for k, _ in pairs(list) do
|
||||
-- TODO write it nicer
|
||||
str = str == nil and "" or str .. ", "
|
||||
str = prefix ~= nil and str .. tostring(prefix) or str
|
||||
str = str .. tostring(k)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
---@deprecated
|
||||
function M.list_values_str(list, prefix, delim)
|
||||
delim = delim or ", "
|
||||
local str = nil
|
||||
list = type(list) == "table" and list or { list }
|
||||
for _, v in pairs(list) do
|
||||
-- TODO write it nicer
|
||||
str = str == nil and "" or str .. delim
|
||||
str = prefix ~= nil and str .. tostring(prefix) or str
|
||||
str = str .. tostring(v)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function M.table_set_if_nil(t1, key, value)
|
||||
if t1[key] == nil then
|
||||
t1[key] = value
|
||||
end
|
||||
|
||||
return t1
|
||||
end
|
||||
|
||||
-- TODO
|
||||
function M.table_validate(table, schema)
|
||||
end
|
||||
|
||||
return M
|
|
@ -3,8 +3,8 @@
|
|||
---@module "hsv2.utils.io"
|
||||
local M = {}
|
||||
|
||||
---@alias hi_group string highlight group
|
||||
---@alias echo_str { [1]: string, [2]?: hi_group } string and highlight group pair
|
||||
---@alias hi_group string highlight group
|
||||
---@alias echo_str { [1]: string, [2]?: hi_group } string and highlight group pair
|
||||
|
||||
---nvim_echo, basically
|
||||
---@param msg echo_str[]
|
||||
|
|
|
@ -6,51 +6,104 @@ local L = {}
|
|||
|
||||
---@class LogConfig @Logging configuration
|
||||
---@field level log_level
|
||||
local local_config = {
|
||||
local log_config = {
|
||||
level = "notice",
|
||||
}
|
||||
|
||||
---@type string path of local_config in global config table
|
||||
L.conf_path = "log"
|
||||
|
||||
|
||||
---@type config_listener
|
||||
function M.config_listener(_, path, value)
|
||||
local paths = require("hsv2.utils.paths")
|
||||
if paths.compare(L.conf_path .. ".level", path) == true then
|
||||
if local_config.level ~= value then
|
||||
M.log({
|
||||
{ "log level changed: before '" },
|
||||
{ value, "Keyword" },
|
||||
{ "' - now '" },
|
||||
{ local_config.level, "Keyword" },
|
||||
{ "'" }
|
||||
}, "notice")
|
||||
local_config.level = value
|
||||
---Init log module
|
||||
---@param config hsv2_config
|
||||
function M.init(config)
|
||||
---@type config_listener
|
||||
function M.config_listener(_, path, value)
|
||||
vim.pretty_print({path=path,value=value})
|
||||
local paths = require("hsv2.utils.paths")
|
||||
if paths.compare("log.level", path) == true then
|
||||
local level = L.level_get(value)
|
||||
if log_config.level ~= level then
|
||||
M.log({
|
||||
{ "log level changed: before '" },
|
||||
{ log_config.level, "Keyword" },
|
||||
{ "' - now '" },
|
||||
{ level, "Keyword" },
|
||||
{ "'" }
|
||||
}, "notice")
|
||||
log_config.level = level
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---Log message at given log level
|
||||
---@param msg echo_str[]|string
|
||||
---@param level? log_level
|
||||
function M.log(msg, level)
|
||||
msg = type(msg) == "string" and { { msg } } or msg
|
||||
local io = require("hsv2.utils.io")
|
||||
if L.level_cmp(level, log_config.level) <= 0 then
|
||||
local msg_with_prefix = vim.list_extend(L.msg_prefix(level), msg)
|
||||
io.echo(msg_with_prefix, true)
|
||||
end
|
||||
end
|
||||
|
||||
require("hsv2.utils.tables").rmap(config, M.config_listener, { "log" })
|
||||
config.log = log_config
|
||||
|
||||
return M
|
||||
end
|
||||
|
||||
---Compare log level priorities
|
||||
---@param l1 log_level
|
||||
---@param l2 log_level
|
||||
---@param l1 log_level
|
||||
---@param l2 log_level
|
||||
---@return integer positive if l1 is greater than l2
|
||||
---@return integer zero if l1 and l2 are equals
|
||||
---@return integer negative if l1 is lesser than l2
|
||||
function L.level_cmp(l1, l2)
|
||||
local levels = require("hsv2.enums").log_level
|
||||
l1, l2 = levels[l1], levels[l2]
|
||||
l1, l2 = levels[L.level_get(l1)], levels[L.level_get(l2)]
|
||||
return l1 - l2
|
||||
end
|
||||
|
||||
---Log message at given log level
|
||||
---@param msg echo_str[]
|
||||
---@param level? log_level
|
||||
function M.log(msg, level)
|
||||
local io = require("hsv2.utils.io")
|
||||
if L.level_cmp(level, local_config.level) <= 0 then
|
||||
io.echo(msg, true)
|
||||
---Takes a log level name or priority and return the level name if it exists or
|
||||
---defaults to "notice".
|
||||
---@param level? log_level|integer
|
||||
---@return log_level
|
||||
---|> "notice" if level is not a valid log level
|
||||
---| "debug" if level is "all"
|
||||
---@return log_level level if level is a valid log level.
|
||||
function L.level_get(level)
|
||||
if not level then return "notice" end
|
||||
if level == "all" then return "debug" end
|
||||
|
||||
for name, prio in pairs(require("hsv2.enums").log_level) do
|
||||
if level == name or level == prio then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
M.log({
|
||||
"invalid log level '",
|
||||
{ tostring(level), "Keyword" },
|
||||
"' default to '",
|
||||
{ "notice", "Keyword" },
|
||||
"'"
|
||||
}, "debug")
|
||||
|
||||
return "notice"
|
||||
end
|
||||
|
||||
return M, L
|
||||
---Get log message prefix string
|
||||
---@param level? log_level
|
||||
---@return echo_str[] prefix
|
||||
function L.msg_prefix(level)
|
||||
level = L.level_get(level)
|
||||
local prefix = {
|
||||
{ "HSV2:", "Title" },
|
||||
{ level },
|
||||
{ ": " },
|
||||
}
|
||||
prefix[2][2] = level == "err" and "Error" or level == "warn" and "Warning"
|
||||
or "Normal"
|
||||
|
||||
return prefix
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
@ -57,7 +57,7 @@ end
|
|||
---Compare two path.
|
||||
---@param path1 path
|
||||
---@param path2 path
|
||||
---@return boolean true If paths are iguals.
|
||||
---@return boolean true If paths are equals.
|
||||
---@return boolean false If paths are not related.
|
||||
---@return number 1 If path2 is part of path1.
|
||||
---@return number -1 If path1 is part of path2.
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
-- vi: et sw=4 ts=4:
|
||||
-- hsv2
|
||||
---@module "hsv2.utils.pkgmanager"
|
||||
local M = {}
|
||||
local L = {}
|
||||
|
||||
function L.install()
|
||||
local path = vim.fn.stdpath('data') .. '/site/pack/hsv2/opt/packer.nvim'
|
||||
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
||||
vim.fn.system {
|
||||
'git',
|
||||
'clone',
|
||||
'--depth=1',
|
||||
'https://github.com/wbthomason/packer.nvim',
|
||||
path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
function L.init(config)
|
||||
if not packer_plugins then
|
||||
L.install()
|
||||
vim.cmd("packadd packer.nvim")
|
||||
else
|
||||
require("packer").reset()
|
||||
end
|
||||
L.packer = require("packer")
|
||||
L.packer.init(config)
|
||||
end
|
||||
|
||||
return M, L
|
|
@ -4,10 +4,11 @@
|
|||
---@module "hsv2.utils.str"
|
||||
local M = {}
|
||||
|
||||
--TODO: maybe multi chars delimiter
|
||||
---Split string into a list of string using a delimiter pattern.
|
||||
---@param str string String to split.
|
||||
---@param delimiter string Delimter pattern.
|
||||
---@param keep boolean? Keep delimiter in results.
|
||||
---@param keep? boolean Keep delimiter in results.
|
||||
---@return table str_list List of strings.
|
||||
function M.split(str, delimiter, keep)
|
||||
local asserts = require("hsv2.utils.asserts")
|
||||
|
@ -17,7 +18,7 @@ function M.split(str, delimiter, keep)
|
|||
|
||||
---@type string[]
|
||||
local str_list = {}
|
||||
local pattern = "([^(" .. delimiter .. ")]+)([(" .. delimiter .. ")]?)"
|
||||
local pattern = "([^" .. delimiter .. "]+)([" .. delimiter .. "]?)"
|
||||
for substr, delim in str:gmatch(pattern) do
|
||||
substr = keep and delim and substr .. delim or substr
|
||||
table.insert(str_list, substr)
|
||||
|
|
|
@ -6,7 +6,5 @@ function _G.test(reload)
|
|||
package.loaded[module] = nil
|
||||
end
|
||||
end
|
||||
package.loaded.test = nil
|
||||
end
|
||||
return require("test")
|
||||
end
|
||||
|
|
|
@ -28,28 +28,6 @@ M.sample.key_mapping = {
|
|||
},
|
||||
}
|
||||
|
||||
M.hsv2 = require("hsv2")
|
||||
|
||||
function M.tests.config_listener()
|
||||
local function listener(_, path, value)
|
||||
vim.pretty_print("listener", path, value)
|
||||
end
|
||||
local c = require("hsv2.config")
|
||||
c.register_listener("log.level", listener, "test listener")
|
||||
c.set("log.level", "all")
|
||||
end
|
||||
|
||||
function M.tests.config_get(path)
|
||||
vim.pretty_print(require("hsv2.config").get(path))
|
||||
end
|
||||
|
||||
function M.tests.config_set(path, value)
|
||||
local c = require("hsv2.config")
|
||||
c.set(path, value)
|
||||
vim.pretty_print(c.get(path))
|
||||
end
|
||||
|
||||
-- TODO: test with pattern that involves variable length matches
|
||||
function M.tests.str_split()
|
||||
local split = require("hsv2.utils.str").split
|
||||
for _, str in ipairs({
|
||||
|
@ -70,6 +48,21 @@ function M.tests.str_split()
|
|||
strip = split(str, "%.", false),
|
||||
})
|
||||
end
|
||||
for _, str in ipairs({
|
||||
"",
|
||||
".",
|
||||
",,;,a;.,a;.,,;",
|
||||
"fooa,;.",
|
||||
"foo.,a;bar",
|
||||
"foo.,;bar.,,,a;baz",
|
||||
".,;.,;.,;foo.,;.,,,;.,,;bar..baz.,;.,;",
|
||||
}) do
|
||||
vim.pretty_print({
|
||||
str = str,
|
||||
keep = split(str, "%.,+a?;", true),
|
||||
strip = split(str, "%.,+a;", false),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function M.tests.tables(start_i, end_i)
|
||||
|
|
|
@ -24,10 +24,12 @@ export HSV2_LOG_LEVEL=all
|
|||
export PLUG_DIR="$TEST_TMP_DIR/data/nvim/site/pack/hsv2/opt/hsv2.nvim"
|
||||
|
||||
mkdir -p "$PLUG_DIR"
|
||||
cp -r "$ROOT/lua" "$PLUG_DIR/"
|
||||
ln -vs "$ROOT/lua" "$PLUG_DIR/"
|
||||
|
||||
echo data stored in $TEST_TMP_DIR
|
||||
nvim -c "luafile $INSTALL_SCRIPT"\
|
||||
-c "lua hsv2 = INSTALL_HSV2('dev')" \
|
||||
-c "lua vim.opt.runtimepath:append('$ROOT/tests')" \
|
||||
-u "$MYVIMRC"
|
||||
$@;
|
||||
|
||||
|
|
Loading…
Reference in New Issue