summary refs log tree commit diff
path: root/.config/nvim/lua/mod/jobs.lua
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2026-09-27 17:38:39 +0200
committerRobert Günzler <r@gnzler.io>2026-09-27 17:38:39 +0200
commit0860db73ae6fd9a6f6347219d820bf026a6b8b91 (patch)
tree11318c3670d1c32c5aa0bf404c22fba3bf63fc53 /.config/nvim/lua/mod/jobs.lua
parent4e34cbf9673aeaba252e01df554a0d204e83c5e2 (diff)
downloaddotfiles-master.tar.gz
Automated-commit-by: dots
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to '.config/nvim/lua/mod/jobs.lua')
-rw-r--r--.config/nvim/lua/mod/jobs.lua68
1 files changed, 68 insertions, 0 deletions
diff --git a/.config/nvim/lua/mod/jobs.lua b/.config/nvim/lua/mod/jobs.lua
new file mode 100644
index 0000000..a4dea6f
--- /dev/null
+++ b/.config/nvim/lua/mod/jobs.lua
@@ -0,0 +1,68 @@
+-- this plugin provides an API to register and recall jobs.
+
+local M = {
+  _jobs = {},
+}
+
+local function format_jobcmd(cmd)
+  if type(cmd) == 'table' then
+    return table.concat(cmd, ' ')
+  end
+  return cmd
+end
+
+local function register(id, cmd)
+  table.insert(M._jobs, id, cmd)
+  vim.notify_once(string.format('started job %d (%s)', id, format_jobcmd(M._jobs[id])))
+end
+
+local function deregister(id)
+  local cmd = M._jobs[id]
+  table.insert(M._jobs, id, nil)
+  vim.notify_once(string.format('stopped job %d (%s)', id, format_jobcmd(cmd)))
+end
+
+function M.start(opts)
+  local previous_on_exit = opts.on_exit or function() end
+  opts.on_exit = function(id, exitcode, event)
+    deregister(id)
+    return previous_on_exit(id, exitcode, event)
+  end
+
+  local id = vim.fn.jobstart(opts.cmd, opts)
+
+  register(id, opts.cmd)
+end
+
+function M.select()
+  if #M._jobs == 0 then
+    vim.notify('No running jobs', vim.log.levels.WARN)
+    return
+  end
+
+  local function provider(cb)
+    for id, cmd in pairs(M._jobs) do
+      cb(string.format('[%d] %s', id, format_jobcmd(cmd)))
+    end
+    cb(nil)
+  end
+  local function parse_jobid(entry)
+    return tonumber(string.match(entry, '%[([0-9]*)%]'))
+  end
+
+  require('fzf-lua').fzf_exec(provider, {
+    prompt = 'Jobs❯',
+    actions = {
+      ['ctrl-x'] = {
+        fn = function(selected)
+          for _, entry in pairs(selected) do
+            vim.fn.jobstop(parse_jobid(entry))
+          end
+        end,
+        reload = true,
+      },
+    },
+  })
+end
+
+return M