:rocket: A task launcher plugin for neovim allowing dynamic task configuration per directory, with optional support for debugging
:rocket: launch.nvim
A task launcher plugin for neovim which allows dynamically configuring tasks per project (i.e current working directory), inspired by the framework in Visual Studio Code. It also provides (optional) support for debugging via nvim-dap, a debug adapter protocol implementation for neovim.
[!IMPORTANT]
Development is actively ongoing for v1.0.0 release on the
release/v1.0.0 branch,
with a revamped user interface for configuring tasks, debuggers and user variables. The core
functionality will remain the same as main branch for the most part. Development on the
main branch will be on hold indefinitely, since it is planned to be replaced.
A discussion has been opened here
for new and existing users to provide feedback or ideas on what they would like to see in the
upcoming release. They will be added to the feature roadmap based on feasibility and popularity.
Contents
- Setup - Commands - Task Configuration - Debug Configuration - User VariablesDemo
This short 3 minute demo video covers all major features and commands offered by launch.nvim, starting from an empty project and a new configuration file. *(This demo shows the config file using the old path; the new path does not pollute the project root anymore)*
Although debugger-related configurations and commands are not covered in the above demo, they have exactly the same UI and behavior as the task-related commands.
Features
- Create custom tasks for every working directory using the file opened by
LaunchOpenConfigFile command
All configurations in this file are hot-reloaded upon saving changes
- Configured tasks can be launched in a tabpage or a floating window, managed by the plugin
- Closing the plugin-managed tabpage or floating window will not kill the current task(s);
- Already launched tasks (active tasks) can be reopened in a tabpage or a floating window,
- Create debugger configurations and launch debug sessions using nvim-dap plugin *(can be
- Create custom placeholder variables which can be used in both task and debug
NOTE : Every floating window created by the plugin can be closed by pressing the q key
Installation
Requirements
- Neovim 0.9+ (nightly recommended)
- nvim-dap for debugging support (optional)
- Decorator plugins that provide customization for
vim.notify(optional)
lazy.nvim
-- LazySpec (plugin specification)
-- return {
{
'dasupradyumna/launch.nvim',
-- add below plugins as per user requirement
dependencies = {
'mfussenegger/nvim-dap',
'rcarriga/nvim-notify',
}
}
-- }
packer.nvim
-- inside setup function
-- packer.startup(function(use)
use {
'dasupradyumna/launch.nvim',
-- add below plugins as per user requirement
requires = {
'mfussenegger/nvim-dap',
'rcarriga/nvim-notify',
}
}
-- end)
vim-plug
" add below dependencies as per user requirement
Plug 'mfussenegger/nvim-dap'
Plug 'rcarriga/nvim-notify'
Plug 'dasupradyumna/launch.nvim'
Usage
Setup
The main setup function can be called independently in your config or as a part of the plugin specification depending on the plugin manager that you are using. The plugin sets very sensible defaults so you can pass an empty configuration table to the setup to check it out. (The demo video shows the plugin being run on default setup options)
-- table of user-defined configuration options which override the plugin defaults
local cfg = {} -- uses the plugin defaults
-- independent setup (for vim-plug as well) require('launch').setup(cfg)
-- for lazy.nvim return { 'dasupradyumna/launch.nvim', opts = cfg }
-- for packer.nvim use { 'dasupradyumna/launch.nvim', config = function() require('launch').setup(cfg) end}
The plugin sets the following default options -
-- PLUGIN DEFAULTS
default_cfg = {
-- debugger settings
debug = {
-- mapping from filetypes to debug adapter names as specified in require('dap').adapters
-- nil implies that the filetypes themselves are used as the adapter names
adapters = nil, ---@type table<string, string>
-- disable all debugger related functionality disable = false, ---@type boolean
-- custom debugger launcher function which receives the selected debug configuration as an -- argument; nil implies require('dap').run is used by default -- NOTE : users should ignore this unless they know what they are doing runner = nil, ---@type function
-- table containing debug configuration template per filetype templates = nil, },
-- task runner settings task = { -- whether to render the task output in a tabpage or a floating window, by default display = 'float', ---@type 'float' | 'tab'
-- configuration options for floating window, see {config} in :h nvimopenwin() float_config = { relative = 'editor', border = 'rounded', title_pos = 'center', style = 'minimal', },
-- custom user functions which will be executed before and/or after creating a floating -- window or a tabpage for a newly launched task hooks = { -- floating window hooks float = { pre = nil, ---@type function post = nil, ---@type function }, -- tabpage hooks tab = { pre = nil, ---@type function post = nil, ---@type function }, },
-- whether to enter INSERT mode after launching task in a buffer insertonlaunch = false, ---@type boolean
-- same fields as TaskOptions in "Task Configuration" subsection options = { -- set the default current working directory for all tasks cwd = nil, ---@type string|fun():string
-- table with definitions of environment variables to be set for all tasks env = nil, ---@type table<string, string|number>
-- table containing executable and command-line arguments to launch a shell process shell = nil, ---@type { exec: string, args: string[] } },
-- custom task launcher function which receives the selected task configuration as an -- argument; nil implies require('launch.task').runner is used by default -- NOTE : users should ignore this unless they know what they are doing runner = nil, ---@type function
-- config options for opening task in a terminal instance; see {opts} in :h jobstart() term = { clear_env = false, }, }, }
For further details about the configuration table and its fields, refer to SETUP.md.
Commands
- LaunchTask
- LaunchTaskFT
- LaunchShowTaskConfigs
- LaunchShowTaskConfigsFT
- LaunchShowActiveTasks
<C-T> opens the active task under the cursor in the tabpage, <C-F> opens it in a floating
window whereas <CR> opens it based on display option in its configuration
*An active task is one which still has a running process or finished execution but its terminal
buffer is still open*
- LaunchDebugger
- LaunchDebuggerFT
- LaunchShowDebugConfigs
- LaunchShowDebugConfigsFT
- LaunchShowUserVariables
- LaunchOpenConfigFile
Schemas
The plugin configuration file should return a table with one or more of the following 3 fields: task, debug and var. task and debug should be array-like tables of task and debug configurations respectively, and var should be a dictionary-like table of user variable definitions with the key being a variable's name and the value being its config.
Every field is optional, and can be omitted if no configurations need to be specified. If the plugin configuration file returns nil or an empty table {}; all task, debug and variable configurations are cleared. (*If the user variable syntax is used in any configuration, then the corresponding variable definition should be specified under the var field*)
-- config file
return {
task = {
{ --[[ TaskConfig1 ]] },
{ --[[ TaskConfig2 ]] },
},
debug = {
{ --[[ DebugConfig1 ]] },
{ --[[ DebugConfig2 ]] },
},
var = {
InputVar1 = { --[[ InputVarConfig1 ]] },
InputVar2 = { --[[ InputVarConfig2 ]] },
},
}
*NOTE : The plugin will issue error notifications if the user makes any syntax errors while writing configurations for any field. Open an issue if you notice gaps in the syntax checker's logic.*
Task Configuration
A task configuration can have the following structure
local task_config = {
name = '<config_name>',
command = '<config_command>',
args = { '<commandarg1>', '<commandarg2>' },
display = 'float',
options = {
cwd = '<pathtocustomcwd>', -- OR function() return <pathtocustomcwd> end,
env = {
STRINGVAR = 'helloworld',
NUMERIC_VAR = 42.42,
},
shell = {
exec = '<shell_executable>',
args = { '<shellarg1>', '<shellarg2>' },
}
},
}
return { task = { task_config } }
- name (required)
string
LaunchTask(FT) command
- filetype
string
LaunchTaskFT and LaunchShowTaskConfigsFT commands to filter tasks based on current buffer
filetype
- command (required)
string
- args
string[]
- display
'float' | 'tab'
- options
TaskOptions
1. TaskOptions.cwd string | fun():string Path (absolute or relative) to the custom directory to be set as the current working directory for the task This path can be specified directly as a string or via a function which returns a string
2. TaskOptions.env table<string, string | number> Dictionary of specifications for environment variables to be defined before running the task
3. TaskOptions.shell ShellOptions Options to customize the shell used for launching the task
- ShellOptions.exec (required) string Path to the custom shell executable (must be specified if shell is not nil)
- ShellOptions.args string[] List of command-line arguments fed to the custom shell executable Each argument in the list will be concatenated with a space character
Debug Configuration
A debug configuration (compatible with nvim-dap) requires 3 compulsory fields and other additional fields that may depend on the actual debugger on a case-by-case basis. More information about valid configuration fields can be found here and here.
local debug_config = {
type = '<adapter_name>',
-- OR
-- filetype = '<target_ft>', -- filetype-adapter mapping can be specified in setup()
request = 'launch', name = '<config_name>',
-- Additional debugger-specific fields -- field1 = value1, -- field2 = value2, }
return { debug = { debug_config } }
User Variables
An example user-defined variable specification can look like this -
return {
task = {
{
name = 'Test User Variables',
command = 'echo',
args = { '{@selecttype}', '{@inputtype}' },
}
},
var = {
select_type = {
type = 'select',
desc = 'selection type variable',
items = { '<item1>', '<item2>' }
},
input_type = {
type = 'input',
desc = 'input type variable',
default = '<default_value>',
},
}
}
Defined user variables can be used in both task and debug configurations with the following syntax {@<variable_name>}, in command and args fields. When a task using this syntax is launched, it will prompt a choice from the user, substitute the syntax with the user's choice and then launches the task. (this will be supported in all string fields in the future)
- type (required)
'select' | 'input'
- desc (required)
string
- default
string | number | boolean
- items
(string | number | boolean)[]
Contributing
Any ideas for new features and quality-of-life changes that you wish to see in this plugin or its documentation are welcome. Please feel free to open an issue or even start a discussion regarding your requirement. And as always, all PRs are welcome! (preferably after the new feature has been discussed in a post)
License
launch.nvim is licensed under the GNU General Public License 3.0.
More plugins by Author
midnight.nvim :crescentmoon: A modern black neovim theme written in Lua (colorscheme used in the demo)