summaryrefslogtreecommitdiff
path: root/lua/lvim/utils
diff options
context:
space:
mode:
authorkylo252 <[email protected]>2021-10-10 21:07:41 +0200
committerGitHub <[email protected]>2021-10-10 21:07:41 +0200
commit52b74557415eb757ad4b7481b0aec8a3f98dd58d (patch)
tree9a05ec71a46c99fbdf8df0043be652b528c7c04e /lua/lvim/utils
parente2c85df440564a62fd804555747b1652a6844a5e (diff)
feat: add an independent lvim namespace (#1699)
Diffstat (limited to 'lua/lvim/utils')
-rw-r--r--lua/lvim/utils/ft.lua47
-rw-r--r--lua/lvim/utils/hooks.lua35
-rw-r--r--lua/lvim/utils/init.lua205
-rw-r--r--lua/lvim/utils/table.lua24
4 files changed, 311 insertions, 0 deletions
diff --git a/lua/lvim/utils/ft.lua b/lua/lvim/utils/ft.lua
new file mode 100644
index 00000000..e9852e6f
--- /dev/null
+++ b/lua/lvim/utils/ft.lua
@@ -0,0 +1,47 @@
+-- Here be dragons
+-- Opening files with telescope will not start LSP without this
+local ft = {}
+
+ft.find_lua_ftplugins = function(filetype)
+ local patterns = {
+ string.format("ftplugin/%s.lua", filetype),
+
+ -- Looks like we don't need this, because the first one works
+ -- string.format("after/ftplugin/%s.lua", filetype),
+ }
+
+ local result = {}
+ for _, pat in ipairs(patterns) do
+ vim.list_extend(result, vim.api.nvim_get_runtime_file(pat, true))
+ end
+
+ return result
+end
+
+ft.do_filetype = function(filetype)
+ local ftplugins = ft.find_lua_ftplugins(filetype)
+
+ local f_env = setmetatable({
+ -- Override print, so the prints still go through, otherwise it's confusing for people
+ print = vim.schedule_wrap(print),
+ }, {
+ -- Buf default back read/write to whatever is going on in the global landscape
+ __index = _G,
+ __newindex = _G,
+ })
+
+ for _, file in ipairs(ftplugins) do
+ local f = loadfile(file)
+ if not f then
+ vim.api.nvim_err_writeln("Unable to load file: " .. file)
+ else
+ local ok, msg = pcall(setfenv(f, f_env))
+
+ if not ok then
+ vim.api.nvim_err_writeln("Error while processing file: " .. file .. "\n" .. msg)
+ end
+ end
+ end
+end
+
+return ft
diff --git a/lua/lvim/utils/hooks.lua b/lua/lvim/utils/hooks.lua
new file mode 100644
index 00000000..d536bc76
--- /dev/null
+++ b/lua/lvim/utils/hooks.lua
@@ -0,0 +1,35 @@
+local M = {}
+
+local Log = require "lvim.core.log"
+local in_headless = #vim.api.nvim_list_uis() == 0
+
+function M.run_pre_update()
+ Log:debug "Starting pre-update hook"
+ _G.__luacache.clear_cache()
+end
+
+---Reset any startup cache files used by Packer and Impatient
+---It also forces regenerating any template ftplugin files
+---Tip: Useful for clearing any outdated settings
+function M.reset_cache()
+ _G.__luacache.clear_cache()
+ require("lvim.plugin-loader"):cache_reset()
+ package.loaded["lvim.lsp.templates"] = nil
+ require("lvim.lsp.templates").generate_templates()
+end
+
+function M.run_post_update()
+ Log:debug "Starting post-update hook"
+ M.reset_cache()
+
+ if not in_headless then
+ vim.schedule(function()
+ require("packer").install()
+ -- TODO: add a changelog
+ vim.notify("Update complete", vim.log.levels.INFO)
+ vim.cmd "LspStart"
+ end)
+ end
+end
+
+return M
diff --git a/lua/lvim/utils/init.lua b/lua/lvim/utils/init.lua
new file mode 100644
index 00000000..cebbe75c
--- /dev/null
+++ b/lua/lvim/utils/init.lua
@@ -0,0 +1,205 @@
+local utils = {}
+local Log = require "lvim.core.log"
+local uv = vim.loop
+
+-- recursive Print (structure, limit, separator)
+local function r_inspect_settings(structure, limit, separator)
+ limit = limit or 100 -- default item limit
+ separator = separator or "." -- indent string
+ if limit < 1 then
+ print "ERROR: Item limit reached."
+ return limit - 1
+ end
+ if structure == nil then
+ io.write("-- O", separator:sub(2), " = nil\n")
+ return limit - 1
+ end
+ local ts = type(structure)
+
+ if ts == "table" then
+ for k, v in pairs(structure) do
+ -- replace non alpha keys with ["key"]
+ if tostring(k):match "[^%a_]" then
+ k = '["' .. tostring(k) .. '"]'
+ end
+ limit = r_inspect_settings(v, limit, separator .. "." .. tostring(k))
+ if limit < 0 then
+ break
+ end
+ end
+ return limit
+ end
+
+ if ts == "string" then
+ -- escape sequences
+ structure = string.format("%q", structure)
+ end
+ separator = separator:gsub("%.%[", "%[")
+ if type(structure) == "function" then
+ -- don't print functions
+ io.write("-- lvim", separator:sub(2), " = function ()\n")
+ else
+ io.write("lvim", separator:sub(2), " = ", tostring(structure), "\n")
+ end
+ return limit - 1
+end
+
+function utils.generate_settings()
+ -- Opens a file in append mode
+ local file = io.open("lv-settings.lua", "w")
+
+ -- sets the default output file as test.lua
+ io.output(file)
+
+ -- write all `lvim` related settings to `lv-settings.lua` file
+ r_inspect_settings(lvim, 10000, ".")
+
+ -- closes the open file
+ io.close(file)
+end
+
+-- autoformat
+function utils.toggle_autoformat()
+ if lvim.format_on_save then
+ require("lvim.core.autocmds").define_augroups {
+ autoformat = {
+ {
+ "BufWritePre",
+ "*",
+ ":silent lua vim.lsp.buf.formatting_sync()",
+ },
+ },
+ }
+ Log:debug "Format on save active"
+ end
+
+ if not lvim.format_on_save then
+ vim.cmd [[
+ if exists('#autoformat#BufWritePre')
+ :autocmd! autoformat
+ endif
+ ]]
+ Log:debug "Format on save off"
+ end
+end
+
+function utils.unrequire(m)
+ package.loaded[m] = nil
+ _G[m] = nil
+end
+
+function utils.gsub_args(args)
+ if args == nil or type(args) ~= "table" then
+ return args
+ end
+ local buffer_filepath = vim.fn.fnameescape(vim.api.nvim_buf_get_name(0))
+ for i = 1, #args do
+ args[i] = string.gsub(args[i], "${FILEPATH}", buffer_filepath)
+ end
+ return args
+end
+
+--- Returns a table with the default values that are missing.
+--- either paramter can be empty.
+--@param config (table) table containing entries that take priority over defaults
+--@param default_config (table) table contatining default values if found
+function utils.apply_defaults(config, default_config)
+ config = config or {}
+ default_config = default_config or {}
+ local new_config = vim.tbl_deep_extend("keep", vim.empty_dict(), config)
+ new_config = vim.tbl_deep_extend("keep", new_config, default_config)
+ return new_config
+end
+
+--- Checks whether a given path exists and is a file.
+--@param path (string) path to check
+--@returns (bool)
+function utils.is_file(path)
+ local stat = uv.fs_stat(path)
+ return stat and stat.type == "file" or false
+end
+
+--- Checks whether a given path exists and is a directory
+--@param path (string) path to check
+--@returns (bool)
+function utils.is_directory(path)
+ local stat = uv.fs_stat(path)
+ return stat and stat.type == "directory" or false
+end
+
+utils.join_paths = _G.join_paths
+
+function utils.write_file(path, txt, flag)
+ uv.fs_open(path, flag, 438, function(open_err, fd)
+ assert(not open_err, open_err)
+ uv.fs_write(fd, txt, -1, function(write_err)
+ assert(not write_err, write_err)
+ uv.fs_close(fd, function(close_err)
+ assert(not close_err, close_err)
+ end)
+ end)
+ end)
+end
+
+function utils.debounce(ms, fn)
+ local timer = vim.loop.new_timer()
+ return function(...)
+ local argv = { ... }
+ timer:start(ms, 0, function()
+ timer:stop()
+ vim.schedule_wrap(fn)(unpack(argv))
+ end)
+ end
+end
+
+function utils.search_file(file, args)
+ local Job = require "plenary.job"
+ local stderr = {}
+ local stdout, ret = Job
+ :new({
+ command = "grep",
+ args = { args, file },
+ cwd = get_cache_dir(),
+ on_stderr = function(_, data)
+ table.insert(stderr, data)
+ end,
+ })
+ :sync()
+ return stdout, ret, stderr
+end
+
+function utils.file_contains(file, query)
+ local stdout, ret, stderr = utils.search_file(file, query)
+ if ret == 0 then
+ return true
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ if not vim.tbl_isempty(stdout) then
+ error(vim.inspect(stdout))
+ end
+ return false
+end
+
+function utils.log_contains(query)
+ local logfile = require("lvim.core.log"):get_path()
+ local stdout, ret, stderr = utils.search_file(logfile, query)
+ if ret == 0 then
+ return true
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ if not vim.tbl_isempty(stdout) then
+ error(vim.inspect(stdout))
+ end
+ if not vim.tbl_isempty(stderr) then
+ error(vim.inspect(stderr))
+ end
+ return false
+end
+
+return utils
+
+-- TODO: find a new home for these autocommands
diff --git a/lua/lvim/utils/table.lua b/lua/lvim/utils/table.lua
new file mode 100644
index 00000000..1ac5949e
--- /dev/null
+++ b/lua/lvim/utils/table.lua
@@ -0,0 +1,24 @@
+local Table = {}
+
+--- Find the first entry for which the predicate returns true.
+-- @param t The table
+-- @param predicate The function called for each entry of t
+-- @return The entry for which the predicate returned True or nil
+function Table.find_first(t, predicate)
+ for _, entry in pairs(t) do
+ if predicate(entry) then
+ return entry
+ end
+ end
+ return nil
+end
+
+--- Check if the predicate returns True for at least one entry of the table.
+-- @param t The table
+-- @param predicate The function called for each entry of t
+-- @return True if predicate returned True at least once, false otherwise
+function Table.contains(t, predicate)
+ return Table.find_first(t, predicate) ~= nil
+end
+
+return Table