- Setup options
- Commands
- Highlight groups
- Lua API
- setup(opts)
- new_task(opts)
- toggle(opts)
- open(opts)
- close()
- list_tasks(opts)
- run_task(opts, callback)
- preload_task_cache(opts, cb)
- clear_task_cache(opts)
- run_action(task, name)
- add_template_hook(opts, hook)
- remove_template_hook(opts, hook)
- register_template(defn)
- register_alias(name, components, override)
- create_task_output_view(winid, opts)
- overseer.Task
- Task:serialize()
- Task:clone()
- Task:add_component(comp)
- Task:add_components(components)
- Task:set_component(comp)
- Task:set_components(components)
- Task:get_component(name)
- Task:remove_component(name)
- Task:remove_components(names)
- Task:has_component(name)
- Task:subscribe(event, callback)
- Task:unsubscribe(event, callback)
- Task:is_pending()
- Task:is_running()
- Task:is_complete()
- Task:is_disposed()
- Task:get_bufnr()
- Task:open_output(direction)
- Task:broadcast(name)
- Task:dispatch(name)
- Task:inc_reference()
- Task:dec_reference()
- Task:dispose(force)
- Task:restart(force_stop)
- Task:start()
- Task:stop()
- Components
- dependencies
- on_complete_dispose
- on_complete_notify
- on_complete_restart
- on_exit_set_status
- on_output_notify
- on_output_parse
- on_output_quickfix
- on_output_write_file
- on_result_diagnostics
- on_result_diagnostics_quickfix
- on_result_diagnostics_trouble
- on_result_notify
- open_output
- restart_on_save
- run_after
- timeout
- unique
- Strategies
- Parameters
For speed tweakers: don't worry about lazy loading; overseer lazy-loads itself!
require("overseer").setup({
-- Patch nvim-dap to support preLaunchTask and postDebugTask
dap = true,
-- Configure the task output buffer and window
output = {
-- Use a terminal buffer to display output. If false, a normal buffer is used
use_terminal = true,
-- If true, don't clear the buffer when a task restarts
preserve_output = false,
},
-- Configure the task list
task_list = {
-- Default direction. Can be "left", "right", or "bottom"
direction = "bottom",
-- Width dimensions can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
-- min_width and max_width can be a single value or a list of mixed integer/float types.
-- max_width = {100, 0.2} means "the lesser of 100 columns or 20% of total"
max_width = { 100, 0.2 },
-- min_width = {40, 0.1} means "the greater of 40 columns or 10% of total"
min_width = { 40, 0.1 },
max_height = { 20, 0.2 },
min_height = 8,
-- String that separates tasks
separator = "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",
-- Indentation for child tasks
child_indent = { "┃ ", "┣━", "┗━" },
-- Function that renders tasks. See lua/overseer/render.lua for built-in options
-- and for useful functions if you want to build your own.
render = function(task)
return require("overseer.render").format_standard(task)
end,
-- The sort function for tasks
sort = function(a, b)
return require("overseer.task_list").default_sort(a, b)
end,
-- Set keymap to false to remove default behavior
-- You can add custom keymaps here as well (anything vim.keymap.set accepts)
keymaps = {
["?"] = "keymap.show_help",
["g?"] = "keymap.show_help",
["<CR>"] = "keymap.run_action",
["dd"] = { "keymap.run_action", opts = { action = "dispose" }, desc = "Dispose task" },
["<C-e>"] = { "keymap.run_action", opts = { action = "edit" }, desc = "Edit task" },
["o"] = "keymap.open",
["<C-v>"] = { "keymap.open", opts = { dir = "vsplit" }, desc = "Open task output in vsplit" },
["<C-s>"] = { "keymap.open", opts = { dir = "split" }, desc = "Open task output in split" },
["<C-t>"] = { "keymap.open", opts = { dir = "tab" }, desc = "Open task output in tab" },
["<C-f>"] = { "keymap.open", opts = { dir = "float" }, desc = "Open task output in float" },
["<C-q>"] = {
"keymap.run_action",
opts = { action = "open output in quickfix" },
desc = "Open task output in the quickfix",
},
["p"] = "keymap.toggle_preview",
["{"] = "keymap.prev_task",
["}"] = "keymap.next_task",
["<C-k>"] = "keymap.scroll_output_up",
["<C-j>"] = "keymap.scroll_output_down",
["g."] = "keymap.toggle_show_wrapped",
["q"] = { "<CMD>close<CR>", desc = "Close task list" },
},
},
-- Custom actions for tasks. See :help overseer-actions
actions = {},
-- Configure the floating window used for task templates that require input
-- and the floating window used for editing tasks
form = {
zindex = 40,
-- Dimensions can be integers or a float between 0 and 1 (e.g. 0.4 for 40%)
-- min_X and max_X can be a single value or a list of mixed integer/float types.
min_width = 80,
max_width = 0.9,
min_height = 10,
max_height = 0.9,
border = nil,
-- Set any window options here (e.g. winhighlight)
win_opts = {},
},
-- Configuration for task floating output windows
task_win = {
-- How much space to leave around the floating window
padding = 2,
border = nil,
-- Set any window options here (e.g. winhighlight)
win_opts = {},
},
-- Aliases for bundles of components. Redefine the builtins, or create your own.
component_aliases = {
-- Most tasks are initialized with the default components
default = {
"on_exit_set_status",
"on_complete_notify",
{ "on_complete_dispose", require_view = { "SUCCESS", "FAILURE" } },
},
-- Tasks from tasks.json use these components
default_vscode = {
"default",
"on_result_diagnostics",
},
-- Tasks created from experimental_wrap_builtins
default_builtin = {
"on_exit_set_status",
"on_complete_dispose",
{ "unique", soft = true },
},
},
-- List of other directories to search for task templates.
-- This will search under the runtimepath, so for example
-- "foo/bar" will search "<runtimepath>/lua/foo/bar/*"
template_dirs = {},
-- List of module names or lua patterns that match modules (must start with '^')
-- to disable. This can be used to disable built in task providers.
disable_template_modules = {
-- "overseer.template.make",
-- "^.*cargo",
},
-- For template providers, how long to wait before timing out.
-- Set to 0 to wait forever.
template_timeout_ms = 3000,
-- Cache template provider results if the provider takes longer than this to run.
-- Set to 0 to disable caching.
template_cache_threshold_ms = 200,
log_level = vim.log.levels.WARN,
-- Overseer can wrap any call to vim.system and vim.fn.jobstart as a task.
experimental_wrap_builtins = {
enabled = false,
condition = function(cmd, caller, opts)
return true
end,
},
})| Command | Args | Description |
|---|---|---|
OverseerOpen[!] |
left/right/bottom |
Open the overseer window. With ! cursor stays in current window |
OverseerClose |
Close the overseer window | |
OverseerToggle[!] |
left/right/bottom |
Toggle the overseer window. With ! cursor stays in current window |
OverseerRun |
[name/tags] |
Run a task from a template |
OverseerShell[!] |
[command] |
Run a shell command as an overseer task. With ! the task is created but not started |
OverseerTaskAction |
Select a task to run an action on |
Overseer defines the following highlights. Override them to customize the colors.
| Group | Description |
|---|---|
OverseerPENDING |
Pending tasks |
OverseerRUNNING |
Running tasks |
OverseerSUCCESS |
Succeeded tasks |
OverseerCANCELED |
Canceled tasks |
OverseerFAILURE |
Failed tasks |
OverseerTask |
Used to render the name of a task or template |
OverseerTaskBorder |
The separator in the task list |
OverseerOutput |
The output summary in the task list |
OverseerComponent |
The name of a component in the task list or task editor |
OverseerField |
The name of a field in the task or template editor |
As overseer is in beta status, the API is not completely solidified. Breaking change may be made if necessary to improve the plugin, but they will not be made unless absolutely necessary. Wherever possible, functions will be gracefully deprecated with clear migration messages.
The official API surface includes:
- All functions exposed in overseer/init.lua
- Config options passed to
setup() - Components, including names and parameters
- Commands
setup(opts)
Initialize overseer
| Param | Type | Desc |
|---|---|---|
| opts | overseer.SetupOpts|nil |
Configuration options |
new_task(opts): overseer.Task
Create a new Task
| Param | Type | Desc |
|---|---|---|
| opts | overseer.TaskDefinition |
|
| >cmd | string|string[] |
Command to run. If it's a string it is run in the shell; a table is run directly |
| >args | nil|string[] |
Arguments to pass to the command |
| >name | nil|string |
Name of the task. Defaults to the cmd |
| >cwd | nil|string |
Working directory to run in |
| >env | nil|table<string, string> |
Additional environment variables |
| >strategy | nil|overseer.Serialized |
Definition for a run Strategy |
| >metadata | nil|table |
Arbitrary metadata for your own use |
| >default_component_params | nil|table<string, any> |
Default values for component params |
| >components | nil|overseer.Serialized[] |
List of components to attach. Defaults to {"default"} |
| >ephemeral | nil|boolean |
Indicates that this task was generated by another task (e.g. with run_after) |
Examples:
local task = overseer.new_task({
cmd = { "./build.sh", "all" },
components = { { "on_output_quickfix", open = true }, "default" }
})
task:start()toggle(opts)
Open or close the task list
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.WindowOpts |
|
| >enter | nil|boolean |
Focus the task list window after opening (default true) |
| >direction | nil|"left"|"right"|"bottom" |
|
| >winid | nil|integer |
Use this existing window instead of opening a new window |
| >focus_task_id | nil|integer |
After opening, focus this task |
open(opts)
Open the task list
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.WindowOpts |
|
| >enter | nil|boolean |
Focus the task list window after opening (default true) |
| >direction | nil|"left"|"right"|"bottom" |
|
| >winid | nil|integer |
Use this existing window instead of opening a new window |
| >focus_task_id | nil|integer |
After opening, focus this task |
close()
Close the task list
list_tasks(opts): overseer.Task[]
List all tasks
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.ListTaskOpts |
|
| >unique | nil|boolean |
Deduplicates non-running tasks by name |
| >status | nil|overseer.Status|overseer.Status[] |
Only list tasks with this status or statuses |
| >include_ephemeral | nil|boolean |
Include ephemeral tasks |
| >wrapped | nil|boolean |
Include tasks that were created by the jobstart/vim.system wrappers |
| >filter | nil|fun(task: overseer.Task): boolean |
Only include tasks where this function returns true |
| >sort | nil|fun(a: overseer.Task, b: overseer.Task): boolean |
Function that sorts tasks |
run_task(opts, callback)
Run a task from a template
| Param | Type | Desc |
|---|---|---|
| opts | overseer.TemplateRunOpts |
|
| >name | nil|string |
The name of the template to run |
| >tags | nil|string[] |
List of tags used to filter when searching for template |
| >autostart | nil|boolean |
When true, start the task after creating it (default true) |
| >first | nil|boolean |
When true, take first result and never show the task picker. Default behavior will auto-set this based on presence of name and tags |
| >params | nil|table |
Parameters to pass to template |
| >cwd | nil|string |
Working directory for the task |
| >env | nil|table<string, string> |
Additional environment variables for the task |
| >disallow_prompt | nil|boolean |
When true, if any required parameters are missing return an error instead of prompting the user for them |
| >search_params | nil|overseer.SearchParams |
Search parameters to use when looking for the template |
| >>filetype | nil|string |
|
| >>tags | nil|string[] |
|
| >>dir | string |
|
| >on_build | nil|fun(task_defn: overseer.TaskDefinition, util: overseer.TaskUtil) |
callback that is called after the task definition is built but before the task is created. |
| callback | nil|fun(task: overseer.Task|nil, err: string|nil) |
Examples:
-- Run the task named "make all"
-- equivalent to :OverseerRun make\ all
overseer.run_task({name = "make all"})
-- Run the default "build" task
-- equivalent to :OverseerRun BUILD
overseer.run_task({tags = {overseer.TAG.BUILD}})
-- Run the task named "serve" with some default parameters
overseer.run_task({name = "serve", params = {port = 8080}})
-- Create a task but do not start it
overseer.run_task({name = "make", autostart = false}, function(task)
-- do something with the task
end)
-- Run a task and immediately open the floating window
overseer.run_task({name = "make"}, function(task)
if task then
overseer.run_action(task, 'open float')
end
end)preload_task_cache(opts, cb)
Preload templates for run_task
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.SearchParams |
|
| >filetype | nil|string |
|
| >tags | nil|string[] |
|
| >dir | string |
|
| cb | nil|fun() |
Called when preloading is complete |
Note:
Typically this would be done to prevent a long wait time for :OverseerRun when using a slow template provider.
Examples:
-- Automatically preload templates for the current directory
vim.api.nvim_create_autocmd({"VimEnter", "DirChanged"}, {
local cwd = vim.v.cwd or vim.fn.getcwd()
require("overseer").preload_task_cache({ dir = cwd })
})clear_task_cache(opts)
Clear cached templates for run_task
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.SearchParams |
|
| >filetype | nil|string |
|
| >tags | nil|string[] |
|
| >dir | string |
run_action(task, name)
Run an action on a task
| Param | Type | Desc |
|---|---|---|
| task | overseer.Task |
|
| name | nil|string |
Name of action. When omitted, prompt user to pick. |
add_template_hook(opts, hook)
Add a hook that runs on a TaskDefinition before the task is created
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.HookOptions |
When nil, run the hook on all templates |
| >module | nil|string |
Only run if the template module matches this pattern (using string.match) |
| >name | nil|string |
Only run if the template name matches this pattern (using string.match) |
| hook | fun(task_defn: overseer.TaskDefinition, util: overseer.TaskUtil) |
Examples:
-- Add on_output_quickfix component to all "cargo" templates
overseer.add_template_hook({ module = "^cargo$" }, function(task_defn, util)
util.add_component(task_defn, { "on_output_quickfix", open = true })
end)
-- Remove the on_complete_notify component from "cargo clean" task
overseer.add_template_hook({ name = "cargo clean" }, function(task_defn, util)
util.remove_component(task_defn, "on_complete_notify")
end)
-- Add an environment variable for all go tasks in a specific dir
overseer.add_template_hook({ name = "^go .*", dir = "/path/to/project" }, function(task_defn, util)
task_defn.env = vim.tbl_extend('force', task_defn.env or {}, {
GO111MODULE = "on"
})
end)remove_template_hook(opts, hook)
Remove a hook that was added with add_template_hook
| Param | Type | Desc |
|---|---|---|
| opts | nil|overseer.HookOptions |
Same as for add_template_hook |
| >module | nil|string |
Only run if the template module matches this pattern (using string.match) |
| >name | nil|string |
Only run if the template name matches this pattern (using string.match) |
| hook | fun(task_defn: overseer.TaskDefinition, util: overseer.TaskUtil) |
Examples:
local opts = {module = "cargo"}
local hook = function(task_defn, util)
util.add_component(task_defn, { "on_output_quickfix", open = true })
end
overseer.add_template_hook(opts, hook)
-- Remove should pass in the same opts as add
overseer.remove_template_hook(opts, hook)register_template(defn)
Directly register an overseer template
| Param | Type | Desc |
|---|---|---|
| defn | overseer.TemplateDefinition|overseer.TemplateProvider |
Examples:
overseer.register_template({
name = "My Task",
builder = function(params)
return {
cmd = { "echo", "Hello", "world" },
}
end,
})register_alias(name, components, override)
Register a new component alias.
| Param | Type | Desc |
|---|---|---|
| name | string |
|
| components | overseer.Serialized[] |
|
| override | nil|boolean |
When true, override any existing alias with the same name |
Note:
This is intended to be used by plugin authors that wish to build on top of overseer. They do not have control over the call to overseer.setup(), so this provides an alternative method of setting a component alias that they can then use when creating tasks.
Examples:
require("overseer").register_alias("my_plugin", { "default", "on_output_quickfix" })create_task_output_view(winid, opts)
Set a window to display the output of a dynamically-chosen task
| Param | Type | Desc |
|---|---|---|
| winid | nil|integer |
The window to use for displaying the task output |
| opts | nil|overseer.TaskViewOpts |
|
| >select | nil|fun(self: overseer.TaskView, tasks: overseer.Task[], task_under_cursor?: overseer.Task): nil|overseer.Task |
Select which task in the task list to display the output of |
| >close_on_list_close | nil|boolean |
Close the window when the task list is closed |
| >list_task_opts | nil|overseer.ListTaskOpts |
Passed to list_tasks() to get the list of tasks to pass to the select() function |
| >>unique | nil|boolean |
Deduplicates non-running tasks by name |
| >>status | nil|overseer.Status|overseer.Status[] |
Only list tasks with this status or statuses |
| >>include_ephemeral | nil|boolean |
Include ephemeral tasks |
| >>wrapped | nil|boolean |
Include tasks that were created by the jobstart/vim.system wrappers |
| >>filter | nil|fun(task: overseer.Task): boolean |
Only include tasks where this function returns true |
| >>sort | nil|fun(a: overseer.Task, b: overseer.Task): boolean |
Function that sorts tasks |
Examples:
-- Always show the output from the most recent Neotest task in this window.
-- Close it automatically when all test tasks are disposed.
overseer.create_task_output_view(0, {
select = function(self, tasks, task_under_cursor)
for _, task in ipairs(tasks) do
if task.metadata.neotest_group_id then
return task
end
end
self:dispose()
end,
})| Field | Type | Desc |
|---|---|---|
| id | integer |
Unique ID for this task |
| result | nil|table<string, any> |
For successful tasks, arbitrary key-value mapping of data produced by components |
| metadata | table<string, any> |
Arbitrary key-value mapping passed by the user during construction |
| status | overseer.Status |
Current task status |
| cmd | string|string[] |
Command to run. If it's a string it is run in the shell |
| cwd | string |
Working directory the task is run in |
| env | nil|table<string, string> |
Additional environment variables for the task |
| name | string |
Name of the task |
| ephemeral | boolean |
Indicates that this task was generated indirectly (e.g. with run_after) |
| source | nil|overseer.Caller |
If this task was created by wrapping jobstart/vim.system, this contains information about the callsite |
| exit_code | nil|integer |
Exit code of the task process |
| parent_id | nil|integer |
ID of parent task. Used only to visually group tasks in the task list |
| time_start | nil|integer |
Timestamp when the task was started (os.time()) |
| time_end | nil|integer |
Timestamp when the task ended (os.time()) |
Task:serialize(): overseer.TaskDefinition
Returns the arguments require to create a clone of this task when passed to overseer.new_task
Task:clone(): overseer.Task
Create a deep copy of this task
Task:add_component(comp)
Add a component, no-op if it already exists
| Param | Type | Desc |
|---|---|---|
| comp | overseer.Serialized |
Task:add_components(components)
Add components, skipping any that already exist
| Param | Type | Desc |
|---|---|---|
| components | overseer.Serialized[] |
Task:set_component(comp)
Add component, overwriting any existing
| Param | Type | Desc |
|---|---|---|
| comp | overseer.Serialized |
Task:set_components(components)
Add components, overwriting any existing
| Param | Type | Desc |
|---|---|---|
| components | overseer.Serialized[] |
Task:get_component(name): nil|overseer.Component
| Param | Type | Desc |
|---|---|---|
| name | string |
Task:remove_component(name): nil|overseer.Component
| Param | Type | Desc |
|---|---|---|
| name | string |
Task:remove_components(names): overseer.Component[]
| Param | Type | Desc |
|---|---|---|
| names | string[] |
Task:has_component(name): boolean
| Param | Type | Desc |
|---|---|---|
| name | string |
Task:subscribe(event, callback)
Subscribe to events on this task
| Param | Type | Desc |
|---|---|---|
| event | string |
|
| callback | fun(task: overseer.Task, ...: any): nil|boolean |
Callback can return a truthy value to unsubscribe itself |
Note:
Listeners cannot be serialized, so will not be saved when saving task to disk and will not be copied when cloning the task.
Task:unsubscribe(event, callback)
Unsubscribe from an event that was previously subscribed to
| Param | Type | Desc |
|---|---|---|
| event | string |
|
| callback | fun(task: overseer.Task, ...: any) |
Task:is_pending(): boolean
Returns true if the task is PENDING
Task:is_running(): boolean
Returns true if the task is RUNNING
Task:is_complete(): boolean
Returns true if the task is complete (not PENDING or RUNNING)
Task:is_disposed(): boolean
Returns true if the task is DISPOSED
Task:get_bufnr(): integer|nil
Get the buffer containing the task output. Will be nil if task is PENDING.
Task:open_output(direction)
Open the task output in a window
| Param | Type | Desc |
|---|---|---|
| direction | nil|"float"|"tab"|"vertical"|"horizontal" |
Note:
You can also use get_bufnr() to get the buffer and open it however you like.
Task:broadcast(name)
Dispatch an event to all other tasks
| Param | Type | Desc |
|---|---|---|
| name | string |
Task:dispatch(name): any[]
Dispatch an event to all components
| Param | Type | Desc |
|---|---|---|
| name | string |
Task:inc_reference()
Increment the refcount for this Task, preventing it from being disposed (unless force=true)
Task:dec_reference()
Decrement the refcount for this Task
Task:dispose(force): boolean
Cleans up resources, removes from task list, and deletes buffer.
| Param | Type | Desc |
|---|---|---|
| force | nil|boolean |
When true, will dispose even with a nonzero refcount or when buffer is visible |
Returns:
| Type | Desc |
|---|---|
| boolean | disposed True if task was disposed |
Task:restart(force_stop): boolean
Reset and re-run the task
| Param | Type | Desc |
|---|---|---|
| force_stop | nil|boolean |
If true, restart the Task even if it is currently running |
Task:start()
Start a pending task
Task:stop(): boolean
Stop a running task
Returns:
| Type | Desc |
|---|---|
| boolean | stopped True if the task was stopped |
- dependencies
- on_complete_dispose
- on_complete_notify
- on_complete_restart
- on_exit_set_status
- on_output_notify
- on_output_parse
- on_output_quickfix
- on_output_write_file
- on_result_diagnostics
- on_result_diagnostics_quickfix
- on_result_diagnostics_trouble
- on_result_notify
- open_output
- restart_on_save
- run_after
- timeout
- unique
Parameters are a schema-defined set of options. They are used by both components and templates to expose customization options.
local params = {
my_var = {
type = "string",
-- Optional fields that are available on any type
name = "More readable name",
desc = "A detailed description",
order = 1, -- determines order of parameters in the UI
validate = function(value)
return true
end,
optional = true,
default = "foobar",
-- For component params only.
-- When true, will default to the value in the task's default_component_params
default_from_task = true,
}
}The following types are available:
{
type = "string"
}
{
type = "boolean"
}
{
type = "number"
}
{
type = "integer"
}
{
type = "list",
subtype = {
type = "string"
},
delimiter = ",",
}
{
type = "enum",
choices = {"ONE", "TWO", "THREE"},
}
{
-- This is used when the value is too complex to be represented or edited by the user in the task editor.
-- It should generally only be used by components (which are usually configured programmatically)
-- and not templates (which usually prompt the user for their parameters)
type = "opaque"
}Templates can define params to be a function, to dynamically generate the params.
require("overseer").register_template({
name = "Git checkout",
params = function()
local stdout = vim.system({ "git", "branch", "--format=%(refname:short)" }):wait().stdout
local branches = vim.split(stdout, "\n", { trimempty = true })
return {
branch = {
desc = "Branch to checkout",
type = "enum",
choices = branches,
},
}
end,
builder = function(params)
return {
cmd = { "git", "checkout", params.branch },
}
end,
})