diff --git a/.stylua.toml b/.stylua.toml
index f6b869b..7662e6a 100644
--- a/.stylua.toml
+++ b/.stylua.toml
@@ -5,4 +5,3 @@ indent_type = "Spaces"
 indent_width = 2
 line_endings = "Unix"
 quote_style = "AutoPreferDouble"
-remove_trailing_separators = false
diff --git a/lua/markmap/config.lua b/lua/markmap/config.lua
index 05d403a..c14b78d 100644
--- a/lua/markmap/config.lua
+++ b/lua/markmap/config.lua
@@ -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.
diff --git a/lua/markmap/init.lua b/lua/markmap/init.lua
index 3a09ce2..eced275 100644
--- a/lua/markmap/init.lua
+++ b/lua/markmap/init.lua
@@ -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
@@ -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()
@@ -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
diff --git a/lua/markmap/utils.lua b/lua/markmap/utils.lua
index a720bbe..07bf64b 100644
--- a/lua/markmap/utils.lua
+++ b/lua/markmap/utils.lua
@@ -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
 
@@ -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