stevearc / overseer.nvim

A task runner and job management plugin for Neovim

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

idea: allowing harpoon-like configuration with commands referencing task id and swapping task ids

matu3ba opened this issue · comments

LMK if you have specific requests for an API or questions about how to best accomplish something.

Continuation from discussion in #203 (comment).

The following does not restart t1 and always just restarts the most upper one, which may lead to a lot accidental time being wasted:

local function get_task_callback(i, action)
  return function()
    local tasks = require("overseer").list_tasks({ recent_first = true })
    local task = tasks[i]
    if task then
      require("overseer").run_action(task, action)
    end
  end
end

for i = 1, 9 do
  vim.keymap.set("n", ";o" .. i, get_task_callback(i, 'open'), { desc = string.format("Open output here task #%d", i) })
  vim.keymap.set("n", ";t" .. i, get_task_callback(i, 'open tab'), { desc = string.format("Open output tab task #%d", i) })
  vim.keymap.set("n", ";e" .. i, get_task_callback(i, 'edit'), { desc = string.format("Edit task #%d", i) })
  vim.keymap.set("n", ";" .. i, get_task_callback(i, 'restart'), { desc = string.format("Restart task #%d", i) })
end
// taskname t1, cmd zig test --test-filter t1 src/test_simple.zig
// taskname t2, cmd zig test --test-filter t2 src/test_simple.zig
// taskname t3, cmd zig test --test-filter t3 src/test_simple.zig
test "t1" {
    return;
    // return error.t1;
}
test "t2" {
    return;
    // return error.t2;
}
test "t3" {
    return;
    // return error.t3;
}

I would prefer having a way to keep the order in the view and ideally having a way to associate t1<->1, t2<->2, .. visually and with keys for restarting things.
These other things make running things like a breeze except for the missing terminal completion (but I can copy things relative fast over from an harpoon terminal except for huge cli args, but there is no solution in [neo]vim for that anyway).

I'm pretty sure task.id would work, but I'm not sure if the plugin might break if the users changes the ids and/or what functionality for swapping task ids would be needed and/or what would be needed to customize the taskbar visualization and/or what would be needed to write my own one (if you want to keep the logic as it is).

Also, again, thanks for the plugin.

I found some minor nits while trying to figure out some solution:

  • you are using chan_id and job_id interchangeably, but it is not always clear if the chan_id represents a runnable job ie in cleanup_autocmd or all_channels[job_id] (not all channels are job channels), so it is abit hard to follow what is meant
  • It is not clear to me, why chan_id = self.term.job_id in lua/overseer/strategy/toggleterm.lua is needed
  • this one:
 ---@param filename string
+---@return boolean
 M.delete_file = function(filename)
   if M.exists(filename) then
     vim.loop.fs_unlink(filename)
     return true
   end
+  return false
 end

From what I understand, this would require 1. some sort of introspection into (id<->index_tasks) and it would 2. be needed to load the tasks with explicit ids instead of using next_id:

---@param opts overseer.TaskDefinition
---@return overseer.Task
function Task.new(opts)
  log:trace("New task: %s", opts)
  local task = Task.new_uninitialized(opts)
  task.id = next_id
  next_id = next_id + 1
  task:dispatch("on_init")
  return task
end

As of now, 3. :OverseerLoadBundle messes up the ids. So even my basic example does not work.
Not reusing ids sounds ok to me, but can be abit annoying, so having 4. a helper function to "left shift tasks to close unused ids", if and/or once no tasks are running (as to not mess up anything) would be nice.

@stevearc Would you be open for PRs to fix at least problem 3+4?

Example:

local function get_task_callback(task_id, action)
  return function()
    local tasks = require("overseer").list_tasks()
    for i = 1, #tasks do
      local task = tasks[i]
      if task and task.id == task_id then
        if action == "print_info" then
          print(task.id, task.name, task.status)
        else
          require("overseer").run_action(task, action)
        end
      end
    end
  end
end

-- ;1 does not necessarily run t1. t2 or t3 may also get loaded as id=1.
for i = 1, 9 do
  vim.keymap.set("n", ";" .. i, get_task_callback(i, 'restart'), { desc = string.format("Restart task #%d", i) })
  vim.keymap.set("n", ";p" .. i, get_task_callback(i, 'print_info'), { desc = string.format("Print id of task #%d", i) })
end

Sorry for the delay, I don't have as much free time these days and the issue reports get backed up. This is one that I'm going to need a solid, uninterrupted chunk of time to think about and I haven't had that yet. The good news is that this is now towards the top of my backlog, so it should be the next big task I get to.

FYI with harpoon2, harpoon now supports custom lists that can represent whatever you want.

I created a small overseer integration using harpoon2 and I am quite happy with the results. It's very minimal, only supporting shell tasks at the moment, but it could conceivably serialize complete task objects. It seems to me as the most promising way to deliver the ask here (as I understand it).

You can try it out here: https://github.com/itsfrank/overseer-quick-tasks

Thanks @itsfrank, I have not been following harpoon2 development much. Code looks like a good first start.

Semi-related: Does casual buffer assignment, selection and do advanced use cases for shell work again?
Last time I tried it, there was no assignment with index for buffers as API, only appending to list, which makes static key usage assignment non-satisfying and so I stopped trying version 2.

M.bashCmdLogAndExec = function(harpoon_term_nr)
  -- Escape ensures visual mode in vi mode
  harp_term.sendCommand(harpoon_term_nr, '\27')
  -- open cli args in EDITOR (other neovim instance)
  harp_term.sendCommand(harpoon_term_nr, 'v')
  -- send the log lua function exec cmd to other neovim instance
  harp_term.sendCommand(harpoon_term_nr, ":lua local ut=require('my_utils');ut.appDateLog(ut.getCurrLinePlNL())\n")
  -- quit other neovim instance
  harp_term.sendCommand(harpoon_term_nr, ':q\n')
  -- shell will execute command
end

map('n', '<leader>j', [[<cmd>lua require("harpoon.ui").nav_file(1)<CR>]], opts) -- bare means fast navigate
map('n', '<leader>mj', [[<cmd>lua require("harpoon.mark").set_current_at(1)<CR>]], opts) --m means make to 1
map('n', '<leader>cj', [[<cmd>lua require("harpoon.term").gotoTerminal(1)<CR>]], opts) -- c means goto control terminal
map('n', ';sj', [[<cmd>lua require("my_harpoon").bashCmdLogAndExec(1)<CR>]], opts)

Can you recommend any dotfiles to steal copy?

Semi-related: Does casual buffer assignment, selection and do advanced use cases for shell work again?

Full disclosure, I'm not exactly sure what you are referring to, I migrated to harpoon2 ~2 weeks ago and found no regressions from harpoon1. Though it seems like you are a more advanced user than myself, I have never used harpoon for terminal stuff (only used overseer and toggleterm before making oqt above).

Last time I tried it, there was no assignment with index for buffers as API, only appending to list

So I know if you want to replace a specific pre-existing index, you can just change it in-place, something like list("foo"):get(i).value = { ... }. Though insertion at a specific index, or non-incrementing/non-numeric indices, seems to have an open issue where the maintainer is not yet convinced of the use-case's validity: ThePrimeagen/harpoon#436

I'll be playing some more with the harpoon2 api over the coming days, if I misunderstood your question please let me know, I'll provide more info as I find it.

Can you recommend any dotfiles to steal copy?

I have not yet looked at anyone else's harpoon dotfile, mine can be found here, though as stated above, I don't do anything fancy