initial commit
This commit is contained in:
parent
57f0da4eca
commit
819a4620de
582
lua/nvim-haven/init.lua
Normal file
582
lua/nvim-haven/init.lua
Normal file
@ -0,0 +1,582 @@
|
|||||||
|
local action_state = require("telescope.actions.state")
|
||||||
|
local actions = require("telescope.actions")
|
||||||
|
local conf = require("telescope.config").values
|
||||||
|
local finders = require("telescope.finders")
|
||||||
|
local global_state = require("telescope.state")
|
||||||
|
local pfiletype = require("plenary.filetype")
|
||||||
|
local pickers = require("telescope.pickers")
|
||||||
|
local previewers = require("telescope.previewers")
|
||||||
|
local putils = require("telescope.previewers.utils")
|
||||||
|
local utils = require("nvim-haven.utils")
|
||||||
|
|
||||||
|
local ns_previewer = vim.api.nvim_create_namespace("telescope.previewers")
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local active_saves = {}
|
||||||
|
local changed_lookup = {}
|
||||||
|
local directory_sep = utils.iff(utils.is_windows, "\\", "/")
|
||||||
|
local haven_config = {
|
||||||
|
enabled = true,
|
||||||
|
exclusions = {
|
||||||
|
function(path, _)
|
||||||
|
if utils.is_windows then
|
||||||
|
return path:lower():starts_with((vim.fn.eval("$VIMRUNTIME") .. directory_sep):lower())
|
||||||
|
end
|
||||||
|
return path:starts_with(vim.fn.eval("$VIMRUNTIME") .. directory_sep)
|
||||||
|
end,
|
||||||
|
function(path, _)
|
||||||
|
if utils.is_windows then
|
||||||
|
return path:lower():starts_with((vim.fn.stdpath("data") .. directory_sep):lower())
|
||||||
|
end
|
||||||
|
return path:starts_with(vim.fn.stdpath("data") .. directory_sep)
|
||||||
|
end,
|
||||||
|
function(path, _)
|
||||||
|
if utils.is_windows then
|
||||||
|
return path:lower():starts_with(
|
||||||
|
(utils.create_path(vim.fn.eval("$XDG_CONFIG_HOME"), "coc") .. directory_sep):lower()
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return path:starts_with(
|
||||||
|
utils.create_path(vim.fn.eval("$XDG_CONFIG_HOME"), "coc") .. directory_sep
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
function(path, _)
|
||||||
|
if utils.is_windows then
|
||||||
|
return path:lower():ends_with(
|
||||||
|
(directory_sep .. ".git" .. directory_sep .. "COMMIT_EDITMSG"):lower()
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return path:ends_with(directory_sep .. ".git" .. directory_sep .. "COMMIT_EDITMSG")
|
||||||
|
end,
|
||||||
|
function(path, config)
|
||||||
|
if utils.is_windows then
|
||||||
|
return path:lower():starts_with((config.haven_path .. directory_sep):lower())
|
||||||
|
end
|
||||||
|
return path:starts_with(config.haven_path .. directory_sep)
|
||||||
|
end
|
||||||
|
},
|
||||||
|
haven_path = utils.create_path(vim.fn.stdpath("data"), "nvim-haven"),
|
||||||
|
inclusions = {},
|
||||||
|
max_history_count = 200,
|
||||||
|
save_timeout = 10000
|
||||||
|
}
|
||||||
|
local line_ending = utils.iff(utils.is_windows, "\r\n", "\n")
|
||||||
|
|
||||||
|
local print_message = function(...)
|
||||||
|
print("nvim-haven", ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local diff_strings = function(a, b)
|
||||||
|
return vim.diff(a, b, {algorithm = "minimal"})
|
||||||
|
end
|
||||||
|
|
||||||
|
local encode = function(str)
|
||||||
|
return str:gsub("\r?\n", "\r\n"):gsub(
|
||||||
|
"([^%w%-%.%_%~ ])",
|
||||||
|
function(c)
|
||||||
|
return string.format("%%%02X", string.byte(c))
|
||||||
|
end
|
||||||
|
):gsub(" ", "+")
|
||||||
|
end
|
||||||
|
|
||||||
|
local create_save_file = function(buf_info)
|
||||||
|
return utils.create_path(haven_config.haven_path, encode(buf_info.name) .. ".save")
|
||||||
|
end
|
||||||
|
|
||||||
|
local save_change_file = function(buf_info, lines, save_file)
|
||||||
|
print_message("save_changed_file", buf_info.name)
|
||||||
|
active_saves[save_file] = nil
|
||||||
|
|
||||||
|
local file, err = io.open(save_file, "a")
|
||||||
|
if file == nil then
|
||||||
|
print_message(err)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local file_entry =
|
||||||
|
vim.json.encode(
|
||||||
|
{
|
||||||
|
date = os.time(),
|
||||||
|
ft = pfiletype.detect(buf_info.name, {}),
|
||||||
|
lines = lines
|
||||||
|
}
|
||||||
|
)
|
||||||
|
_, err = file:write(file_entry .. line_ending)
|
||||||
|
if err ~= nil then
|
||||||
|
print_message(err)
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local save_change_file_entries = function(buf_info, entries, save_file)
|
||||||
|
print_message("save_changed_file", buf_info.name)
|
||||||
|
active_saves[save_file] = nil
|
||||||
|
|
||||||
|
local file, err = io.open(save_file, "w+")
|
||||||
|
if file == nil then
|
||||||
|
print_message(err)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, entry in pairs(entries) do
|
||||||
|
_, err = file:write(vim.json.encode(entry) .. line_ending)
|
||||||
|
if err ~= nil then
|
||||||
|
print_message(err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local read_change_file = function(buf_info, save_file)
|
||||||
|
local file, err = io.open(save_file, "r")
|
||||||
|
if file == nil then
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
|
||||||
|
local save_data
|
||||||
|
save_data, err = file:read("a")
|
||||||
|
if err ~= nil then
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
local entries = vim.json.decode("[" .. table.concat(save_data:split(line_ending), ",") .. "]")
|
||||||
|
if #entries > haven_config.max_history_count then
|
||||||
|
while #entries > haven_config.max_history_count do
|
||||||
|
table.remove(entries, 1)
|
||||||
|
end
|
||||||
|
save_change_file_entries(buf_info, entries, save_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
return entries
|
||||||
|
end
|
||||||
|
|
||||||
|
local process_file_changed = function(buf_info)
|
||||||
|
local save_file = create_save_file(buf_info)
|
||||||
|
local changed_data = changed_lookup[save_file]
|
||||||
|
local immediate = vim.fn.filereadable(save_file) == 0
|
||||||
|
if
|
||||||
|
not immediate and
|
||||||
|
(changed_data == nil or (buf_info.changed == 0 and changed_data.changed == 0) or
|
||||||
|
buf_info.changedtick == changed_data.changedtick)
|
||||||
|
then
|
||||||
|
changed_lookup[save_file] = {changed = buf_info.changed, changedtick = buf_info.changedtick}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if active_saves[save_file] ~= nil then
|
||||||
|
active_saves[save_file].timer:stop()
|
||||||
|
active_saves[save_file] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
changed_lookup[save_file] = {changed = buf_info.changed, changedtick = buf_info.changedtick}
|
||||||
|
|
||||||
|
local lines = vim.api.nvim_buf_get_lines(buf_info.bufnr, 0, -1, true)
|
||||||
|
|
||||||
|
local entries, _ = read_change_file(buf_info, save_file)
|
||||||
|
if entries ~= nil then
|
||||||
|
if
|
||||||
|
diff_strings(
|
||||||
|
table.concat(entries[#entries].lines, line_ending),
|
||||||
|
table.concat(lines, line_ending)
|
||||||
|
):len() == 0
|
||||||
|
then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
entries = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local saved = false
|
||||||
|
local do_save = function()
|
||||||
|
if not saved then
|
||||||
|
saved = true
|
||||||
|
save_change_file(buf_info, lines, save_file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if immediate then
|
||||||
|
do_save()
|
||||||
|
else
|
||||||
|
active_saves[save_file] = {
|
||||||
|
timer = vim.defer_fn(do_save, haven_config.save_timeout),
|
||||||
|
do_save = do_save
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local check_requirements = function()
|
||||||
|
if vim.o.modifiable ~= 0 and vim.o.buftype ~= "nofile" then
|
||||||
|
local buf_info = vim.fn.getbufinfo(vim.fn.bufname())
|
||||||
|
if buf_info ~= nil and #buf_info > 0 then
|
||||||
|
buf_info = buf_info[1]
|
||||||
|
if buf_info.name:len() ~= 0 and vim.fn.filereadable(buf_info.name) ~= 0 then
|
||||||
|
if changed_lookup[create_save_file(buf_info)] == nil then
|
||||||
|
for _, is_included in pairs(haven_config.inclusions) do
|
||||||
|
if is_included(buf_info.name, haven_config) then
|
||||||
|
return true, buf_info
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, is_excluded in pairs(haven_config.exclusions) do
|
||||||
|
if is_excluded(buf_info.name, haven_config) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true, buf_info
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local handle_buffer_changed = function()
|
||||||
|
local ok, buf_info = check_requirements()
|
||||||
|
if ok and buf_info ~= nil then
|
||||||
|
process_file_changed(buf_info)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local handle_vim_leave = function()
|
||||||
|
for _, active in pairs(active_saves) do
|
||||||
|
active.timer:stop()
|
||||||
|
active.do_save()
|
||||||
|
end
|
||||||
|
active_saves = {}
|
||||||
|
changed_lookup = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local setup_autocmds = function()
|
||||||
|
local group_id = vim.api.nvim_create_augroup("nvim-haven-internal", {clear = true})
|
||||||
|
if haven_config.enabled then
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"BufEnter",
|
||||||
|
{
|
||||||
|
group = group_id,
|
||||||
|
pattern = "*",
|
||||||
|
callback = handle_buffer_changed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"InsertLeave",
|
||||||
|
{
|
||||||
|
group = group_id,
|
||||||
|
pattern = "*",
|
||||||
|
callback = handle_buffer_changed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"TextChanged",
|
||||||
|
{
|
||||||
|
group = group_id,
|
||||||
|
pattern = "*",
|
||||||
|
callback = handle_buffer_changed
|
||||||
|
}
|
||||||
|
)
|
||||||
|
vim.api.nvim_create_autocmd(
|
||||||
|
"VimLeave",
|
||||||
|
{
|
||||||
|
group = group_id,
|
||||||
|
pattern = "*",
|
||||||
|
callback = handle_vim_leave
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else
|
||||||
|
vim.api.nvim_del_augroup_by_id(group_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local apply_diff_to_lines = function(diff, source_lines)
|
||||||
|
local diff_lines = diff:split(line_ending)
|
||||||
|
local changes = {}
|
||||||
|
local current_diff
|
||||||
|
|
||||||
|
for _, line in pairs(diff_lines) do
|
||||||
|
if line:len() > 0 then
|
||||||
|
if line:starts_with("@@") and line:ends_with("@@") then
|
||||||
|
local diff_range = line:sub(3, -1):sub(1, -3):split(" ")[1]:split(",")
|
||||||
|
if #diff_range == 1 then
|
||||||
|
table.insert(diff_range, "1")
|
||||||
|
end
|
||||||
|
|
||||||
|
local diff_start = math.abs(tonumber(diff_range[1], 10))
|
||||||
|
local diff_count = tonumber(diff_range[2], 10)
|
||||||
|
if diff_count == 0 then
|
||||||
|
diff_start = diff_start + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
current_diff = {
|
||||||
|
diff = {line},
|
||||||
|
next = diff_start + diff_count,
|
||||||
|
start = diff_start
|
||||||
|
}
|
||||||
|
table.insert(changes, current_diff)
|
||||||
|
elseif current_diff ~= nil then
|
||||||
|
table.insert(current_diff.diff, line)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
current_diff = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local actual_line = 1
|
||||||
|
local buffer_lines = {}
|
||||||
|
local diff_rows = {}
|
||||||
|
local source_line = 1
|
||||||
|
for _, change in pairs(changes) do
|
||||||
|
while source_line < change.start do
|
||||||
|
table.insert(buffer_lines, source_lines[source_line])
|
||||||
|
actual_line = actual_line + 1
|
||||||
|
source_line = source_line + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(diff_rows, actual_line)
|
||||||
|
for _, change_diff_lines in pairs(change.diff) do
|
||||||
|
table.insert(buffer_lines, change_diff_lines)
|
||||||
|
actual_line = actual_line + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
source_line = change.next
|
||||||
|
end
|
||||||
|
|
||||||
|
while source_line <= #source_lines do
|
||||||
|
table.insert(buffer_lines, source_lines[source_line])
|
||||||
|
actual_line = actual_line + 1
|
||||||
|
source_line = source_line + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return buffer_lines, diff_rows
|
||||||
|
end
|
||||||
|
|
||||||
|
local show_picker = function(entries)
|
||||||
|
global_state.set_global_key("selected_entry", nil)
|
||||||
|
|
||||||
|
local jump_state
|
||||||
|
|
||||||
|
local jump_to_line = function(self, bufnr, lnum)
|
||||||
|
pcall(vim.api.nvim_buf_clear_namespace, bufnr, ns_previewer, 0, -1)
|
||||||
|
if lnum and lnum > 0 then
|
||||||
|
pcall(
|
||||||
|
vim.api.nvim_buf_add_highlight,
|
||||||
|
bufnr,
|
||||||
|
ns_previewer,
|
||||||
|
"TelescopePreviewLine",
|
||||||
|
lnum - 1,
|
||||||
|
0,
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
pcall(vim.api.nvim_win_set_cursor, self.state.winid, {lnum, 0})
|
||||||
|
vim.api.nvim_buf_call(
|
||||||
|
bufnr,
|
||||||
|
function()
|
||||||
|
vim.cmd "norm! zz"
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local do_forward_jump = function()
|
||||||
|
if jump_state ~= nil and #jump_state.diff_rows > 0 then
|
||||||
|
jump_state.cur =
|
||||||
|
utils.iff(
|
||||||
|
(jump_state.cur + 1) <= #jump_state.diff_rows,
|
||||||
|
jump_state.cur + 1,
|
||||||
|
#jump_state.diff_rows
|
||||||
|
)
|
||||||
|
jump_to_line(
|
||||||
|
jump_state.self,
|
||||||
|
jump_state.self.state.bufnr,
|
||||||
|
jump_state.diff_rows[jump_state.cur]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local do_reverse_jump = function()
|
||||||
|
if jump_state ~= nil and #jump_state.diff_rows > 0 then
|
||||||
|
jump_state.cur = utils.iff((jump_state.cur - 1) > 0, jump_state.cur - 1, 1)
|
||||||
|
jump_to_line(
|
||||||
|
jump_state.self,
|
||||||
|
jump_state.self.state.bufnr,
|
||||||
|
jump_state.diff_rows[jump_state.cur]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pickers.new(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
prompt_title = "File History",
|
||||||
|
previewer = previewers.new_buffer_previewer(
|
||||||
|
{
|
||||||
|
define_preview = function(self, entry)
|
||||||
|
jump_state = nil
|
||||||
|
if entry.index < #entries then
|
||||||
|
local previous_lines = entries[entry.index + 1].lines
|
||||||
|
local buffer_lines, diff_rows =
|
||||||
|
apply_diff_to_lines(
|
||||||
|
diff_strings(
|
||||||
|
table.concat(previous_lines, line_ending),
|
||||||
|
table.concat(entry.value.lines, line_ending)
|
||||||
|
),
|
||||||
|
previous_lines
|
||||||
|
)
|
||||||
|
previous_lines = nil
|
||||||
|
|
||||||
|
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, buffer_lines)
|
||||||
|
putils.regex_highlighter(self.state.bufnr, "diff")
|
||||||
|
|
||||||
|
jump_state = {self = self, cur = 0, diff_rows = diff_rows}
|
||||||
|
vim.schedule(
|
||||||
|
function()
|
||||||
|
do_forward_jump()
|
||||||
|
end
|
||||||
|
)
|
||||||
|
else
|
||||||
|
vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, entry.value.lines)
|
||||||
|
putils.highlighter(self.state.bufnr, entry.value.ft, {})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
),
|
||||||
|
sorter = conf.generic_sorter({}),
|
||||||
|
finder = finders.new_table(
|
||||||
|
{
|
||||||
|
results = entries,
|
||||||
|
entry_maker = function(item)
|
||||||
|
return {
|
||||||
|
value = item,
|
||||||
|
ordinal = tostring(item.date),
|
||||||
|
display = os.date("%m-%d-%Y %H:%M:%S", item.date)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
),
|
||||||
|
attach_mappings = function(prompt_bufnr, map)
|
||||||
|
actions.select_default:replace(
|
||||||
|
function()
|
||||||
|
actions.close(prompt_bufnr)
|
||||||
|
local selection = action_state.get_selected_entry()
|
||||||
|
if selection ~= nil then
|
||||||
|
vim.api.nvim_buf_set_lines(0, 0, -1, false, selection.value.lines)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
map("i", "<c-l>", do_forward_jump)
|
||||||
|
map("n", "<c-l>", do_forward_jump)
|
||||||
|
map("i", "<c-h>", do_reverse_jump)
|
||||||
|
map("n", "<c-h>", do_reverse_jump)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
}
|
||||||
|
):find()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.setup = function(config)
|
||||||
|
if config == nil then
|
||||||
|
config = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.exclusions ~= nil then
|
||||||
|
for _, e in pairs(config.exclusions) do
|
||||||
|
if type(e) ~= "function" then
|
||||||
|
print_message(
|
||||||
|
"'exlcusions' contains an entry that is not a function. Skipping all exclusions until this is corrected:"
|
||||||
|
)
|
||||||
|
utils.dump_table(e)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
table.insert(haven_config.exclusions, e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
haven_config.enabled = vim.F.if_nil(config.enabled, haven_config.enabled)
|
||||||
|
haven_config.haven_path = vim.F.if_nil(config.haven_path, haven_config.haven_path)
|
||||||
|
|
||||||
|
if config.inclusions ~= nil then
|
||||||
|
for _, e in pairs(config.inclusions) do
|
||||||
|
if type(e) ~= "function" then
|
||||||
|
print_message(
|
||||||
|
"'inclusions' contains an entry that is not a function. Skipping this inclusion until it is corrected:"
|
||||||
|
)
|
||||||
|
utils.dump_table(e)
|
||||||
|
end
|
||||||
|
table.insert(haven_config.inclusions, e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
haven_config.max_history_count =
|
||||||
|
vim.F.if_nil(config.max_history_count, haven_config.max_history_count)
|
||||||
|
if haven_config.max_history_count < 10 then
|
||||||
|
print_message("'max_history_count' too low: " .. haven_config.max_history_count)
|
||||||
|
haven_config.max_history_count = 100
|
||||||
|
print_message("reset 'max_history_count': " .. haven_config.max_history_count)
|
||||||
|
elseif haven_config.max_history_count > 500 then
|
||||||
|
print_message("'max_history_count' too high: " .. haven_config.max_history_count)
|
||||||
|
haven_config.max_history_count = 500
|
||||||
|
print_message("reset 'max_history_count': " .. haven_config.max_history_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
haven_config.save_timeout = vim.F.if_nil(config.save_timeout, haven_config.save_timeout)
|
||||||
|
if haven_config.save_timeout < 135 then
|
||||||
|
print_message("'save_timeout' too low: " .. haven_config.save_timeout)
|
||||||
|
haven_config.save_timeout = 135
|
||||||
|
print_message("reset 'save_timeout': " .. haven_config.save_timeout)
|
||||||
|
elseif haven_config.save_timeout > 10000 then
|
||||||
|
print_message("'save_timeout' too high: " .. haven_config.save_timeout)
|
||||||
|
haven_config.save_timeout = 10000
|
||||||
|
print_message("reset 'save_timeout': " .. haven_config.save_timeout)
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim.fn.mkdir(haven_config.haven_path, "p") == 0 then
|
||||||
|
print_message("directory create failed: " .. haven_config.haven_path)
|
||||||
|
haven_config.enabled = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if vim.fn.isdirectory(haven_config.haven_path) == 0 then
|
||||||
|
print_message("directory not found: " .. haven_config.haven_path)
|
||||||
|
haven_config.enabled = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
setup_autocmds()
|
||||||
|
end
|
||||||
|
|
||||||
|
M.disable = function()
|
||||||
|
if haven_config.enabled then
|
||||||
|
haven_config.enabled = false
|
||||||
|
setup_autocmds()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.enable = function()
|
||||||
|
if not haven_config.enabled then
|
||||||
|
haven_config.enabled = true
|
||||||
|
handle_buffer_changed()
|
||||||
|
setup_autocmds()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.history = function(bufname)
|
||||||
|
bufname = vim.F.if_nil(bufname, vim.fn.bufname())
|
||||||
|
local buf_info = vim.fn.getbufinfo(bufname)
|
||||||
|
if buf_info ~= nil and #buf_info > 0 then
|
||||||
|
buf_info = buf_info[1]
|
||||||
|
local save_file = create_save_file(buf_info)
|
||||||
|
if vim.fn.filereadable(save_file) ~= 0 then
|
||||||
|
local entries, err = read_change_file(buf_info, save_file)
|
||||||
|
if entries == nil then
|
||||||
|
print_message(err)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
show_picker(table.reverse(entries))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
_G.Nvim_Haven_Disable = M.disable
|
||||||
|
_G.Nvim_Haven_Enable = M.enable
|
||||||
|
_G.Nvim_Haven_History = M.history
|
||||||
|
|
||||||
|
return M
|
58
lua/nvim-haven/utils/init.lua
Normal file
58
lua/nvim-haven/utils/init.lua
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
function string:ends_with(suffix)
|
||||||
|
return suffix == "" or self:sub(-(#suffix)) == suffix
|
||||||
|
end
|
||||||
|
|
||||||
|
function string:split(sep)
|
||||||
|
sep = sep or ":"
|
||||||
|
local fields = {}
|
||||||
|
local pattern = string.format("([^%s]+)", sep)
|
||||||
|
_ =
|
||||||
|
self:gsub(
|
||||||
|
pattern,
|
||||||
|
function(c)
|
||||||
|
fields[#fields + 1] = c
|
||||||
|
end
|
||||||
|
)
|
||||||
|
return fields
|
||||||
|
end
|
||||||
|
|
||||||
|
function string:starts_with(prefix)
|
||||||
|
return self:sub(1, #prefix) == prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.reverse(self)
|
||||||
|
local n = #self
|
||||||
|
local i = 1
|
||||||
|
while i < n do
|
||||||
|
self[i], self[n] = self[n], self[i]
|
||||||
|
i = i + 1
|
||||||
|
n = n - 1
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.iff(b, l, r)
|
||||||
|
if b then
|
||||||
|
return l
|
||||||
|
end
|
||||||
|
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
|
M.is_windows = vim.fn.has("win32") == 1 or vim.fn.has("win64") == 1
|
||||||
|
M.directory_sep = M.iff(M.is_windows, "\\\\", "/")
|
||||||
|
M.not_directory_sep = M.iff(M.is_windows, "/", "\\\\")
|
||||||
|
|
||||||
|
function M.create_path(...)
|
||||||
|
local Path = require "plenary.path"
|
||||||
|
local ret =
|
||||||
|
Path:new({...}):absolute():gsub(M.not_directory_sep, M.directory_sep):gsub(
|
||||||
|
M.directory_sep .. M.directory_sep,
|
||||||
|
M.directory_sep
|
||||||
|
)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
4
plugin/nvim-haven.lua
Normal file
4
plugin/nvim-haven.lua
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
if vim.g.loaded_nvim_haven == 1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
vim.g.loaded_nvim_haven = 1
|
Loading…
x
Reference in New Issue
Block a user