Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: close markmap when watched buffer is closed #16

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .stylua.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ indent_type = "Spaces"
indent_width = 2
line_endings = "Unix"
quote_style = "AutoPreferDouble"
remove_trailing_separators = false
5 changes: 3 additions & 2 deletions lua/markmap/config.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
-- Config options to keep init clean.
local M = {}

local is_windows = vim.uv.os_uname().sysname == "Windows_NT"
local is_android = vim.fn.isdirectory('/data') == 1
local uv = vim.uv or vim.loop
local is_windows = uv.os_uname().sysname == "Windows_NT"
local is_android = vim.fn.isdirectory("/data") == 1

---Parse user options, or set the defaults
---@param opts table A table with options to set.
Expand Down
97 changes: 63 additions & 34 deletions lua/markmap/init.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-- This plugin is a wrapper for markmap-cli
local api = vim.api
local utils = require("markmap.utils")
local jobstart = utils.jobstart
local jobstop = vim.fn.jobstop
Expand All @@ -13,6 +14,7 @@ M.setup = function(opts)
local config = vim.g.markmap_config
local job = nil
local arguments = {}
local lookup_table = {}

-- Setup commands -----------------------------------------------------------
cmd("MarkmapOpen", function()
Expand All @@ -27,48 +29,75 @@ M.setup = function(opts)
cmd("MarkmapSave", function()
config = vim.g.markmap_config
arguments = utils.reset_arguments()
local path = '"' .. vim.fn.expand("%:p") .. '"' -- current buffer path
table.insert(arguments, "--no-open") -- specific to this command
table.insert(arguments, path)
if job ~= nil then jobstop(job) end -- kill jobs
table.insert(arguments, "--no-open") -- specific to this command
table.insert(arguments, vim.fn.expand("%:p")) -- current buffer path
if job ~= nil then jobstop(job) end -- kill jobs
job = jobstart(config.markmap_cmd, arguments)
end, { desc = "Save the HTML file without opening the mindmap" })

cmd("MarkmapWatch", function()
config = vim.g.markmap_config
arguments = utils.reset_arguments()
local path = '"' .. vim.fn.expand("%:p") .. '"' -- current buffer path
table.insert(arguments, "--watch") -- spetific to this command
table.insert(arguments, path)
if job ~= nil then jobstop(job) end -- kill jobs
job = jobstart(config.markmap_cmd, arguments)
end, { desc = "Show a mental map of the current file and watch for changes" })
cmd(
"MarkmapWatch",
function()
local watch_buffer = vim.api.nvim_get_current_buf()
config = vim.g.markmap_config
arguments = utils.reset_arguments()
table.insert(arguments, "--watch") -- spetific to this command
table.insert(arguments, vim.fn.expand("%:p")) -- current buffer path

cmd("MarkmapWatchStop", function()
if job ~= nil then jobstop(job) end -- kill jobs
end, { desc = "Manually stops markmap watch" })
if lookup_table[watch_buffer] then
vim.notify("You're already watching this buffer.", vim.log.levels.WARN)
else
local kill_on_close =
augroup("markmap_kill_on_close", { clear = false })

-- Autocmds -----------------------------------------------------------------
-- Kill jobs after a grace period
local last_execution = vim.uv.now() -- timer for grace period
autocmd("CursorHold", {
desc = "Kill all markmap jobs after a grace period",
group = augroup("markmap_kill_after_grace_period", { clear = true }),
callback = function()
-- If grace_periodd is disabled, remove the autocmd and return
if config.grace_period == 0 then
vim.cmd "autocmd! markmap_kill_after_grace_period"
return
end
job = jobstart(config.markmap_cmd, arguments, {
stderr_buffered = true, -- needed so on_stderr is only called once
on_stderr = function(_, data)
local message = table.concat(data, "\n")
message = message:gsub("\r", "")
vim.notify(message, vim.log.levels.ERROR)

lookup_table[watch_buffer] = nil
api.nvim_clear_autocmds({
group = kill_on_close,
buffer = watch_buffer,
})
end,
})

lookup_table[watch_buffer] = job

-- Otherwise, use grace_period
local current_time = vim.uv.now()
if current_time - last_execution >= config.grace_period then -- if grace period exceeded
if job ~= nil then jobstop(job) end -- pkill jobs
last_execution = current_time -- update time
-- Register buffer local autocmd to kill job when buffer closes
autocmd("BufDelete", {
desc = "Kill markmap when watched buffer is closed",
buffer = watch_buffer,
group = kill_on_close,
callback = function()
jobstop(job)
lookup_table[watch_buffer] = nil
api.nvim_clear_autocmds({
group = kill_on_close,
buffer = watch_buffer,
})
end,
})
end
end,
})
{ desc = "Show a mental map of the current file and watch for changes" }
)

cmd("MarkmapWatchStop", function()
local watch_buffer = vim.api.nvim_get_current_buf()
local job = lookup_table[watch_buffer]
if job then
jobstop(job)
lookup_table[watch_buffer] = nil
api.nvim_clear_autocmds({
group = kill_on_close,
buffer = watch_buffer,
})
end
end, { desc = "Manually stops markmap watch" })
end

return M
9 changes: 5 additions & 4 deletions lua/markmap/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ local is_windows = vim.uv.os_uname().sysname == "Windows_NT"
--- the executables must be added to path in at windows level.
---@param cmd string command to run.
---@param arguments table arguments to pass to the cmd.
---@param opts table vim.fn.jobstart options
---@return number job pid of the job, so we can stop it later.
M.jobstart = function(cmd, arguments)
M.jobstart = function(cmd, arguments, opts)
if is_windows then
return vim.fn.jobstart({ cmd, unpack(arguments) })
return opts and vim.fn.jobstart({ cmd, unpack(arguments) }, opts) or vim.fn.jobstart({ cmd, unpack(arguments) })
else
return vim.fn.jobstart(cmd .. " " .. table.concat(arguments, " "))
return opts and vim.fn.jobstart(cmd .. " " .. table.concat(arguments, " "), opts) or vim.fn.jobstart(cmd .. " " .. table.concat(arguments, " "))
end
end

Expand All @@ -28,7 +29,7 @@ M.reset_arguments = function()
local config = vim.g.markmap_config

local arguments = {}
if config.html_output ~= "" then -- if html_output is "", don't pass the parameter
if config.html_output ~= "" then -- if html_output is "", don't pass the parameter
table.insert(arguments, "-o")
table.insert(arguments, '"' .. config.html_output .. '"')
end
Expand Down