feat: extend hilbish.runner interface to allow multiple runners (#159)

sammyette 2022-05-28 19:06:18 -04:00 committed by GitHub
parent b28a2c24c1
commit 3990d370fa
No known key found for this signature in database
4 changed files with 123 additions and 1 deletions

View File

@ -46,6 +46,8 @@ includes git commit, branch, and (new!!) release name.
- Added `fg` and `bg` builtins
- `job.foreground()` and `job.background()`, when `job` is a job object,
foreground and backgrounds a job respectively.
- Friendlier functions to the `hilbish.runner` interface, which also allow
having and using multiple runners.
### Changed
- **Breaking Change:** Upgraded to Lua 5.4.

View File

@ -35,8 +35,21 @@ The exit code has to be a number, it will be 0 otherwise and the error can be
`nil` to indicate no error.
## Functions
These are the functions for the `hilbish.runner` interface
These are the "low level" functions for the `hilbish.runner` interface.
+ setMode(mode) > The same as `hilbish.runnerMode`
+ sh(input) -> input, code, err > Runs `input` in Hilbish's sh interpreter
+ lua(input) -> input, code, err > Evals `input` as Lua code
The others here are defined in Lua and have EmmyLua documentation.
These functions should be preferred over the previous ones.
+ setCurrent(mode) > The same as `setMode`, but works with runners managed
via the functions below.
+ add(name, runner) > Adds a runner to a table of available runners. The `runner`
argument is either a function or a table with a run callback.
+ set(name, runner) > The same as `add` but requires passing a table and
overwrites if the `name`d runner already exists.
+ get(name) > runner > Gets a runner by name. It is a table with at least a
run function, to run input.
+ exec(cmd, runnerName) > Runs `cmd` with a runner. If `runnerName` isn't passed,
the current runner mode is used.

View File

@ -8,6 +8,7 @@ require 'nature.commands'
require 'nature.completions'
require 'nature.opts'
require 'nature.vim'
require 'nature.runner'
local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then

nature/runner.lua 100644
View File

@ -0,0 +1,106 @@
local currentRunner = 'hybrid'
local runners = {}
-- lsp shut up
hilbish = hilbish
--- Get a runner by name.
--- @param name string
--- @return table
function hilbish.runner.get(name)
local r = runners[name]
if not r then
error(string.format('runner %s does not exist', name))
return r
--- Adds a runner to the table of available runners. If runner is a table,
--- it must have the run function in it.
--- @param name string
--- @param runner function | table
function hilbish.runner.add(name, runner)
if type(name) ~= 'string' then
error 'expected runner name to be a table'
if type(runner) == 'function' then
runner = {run = runner} -- this probably looks confusing
if type(runner) ~= 'table' then
error 'expected runner to be a table or function'
if runners[name] then
error(string.format('runner %s already exists', name))
hilbish.runner.set(name, runner)
--- Sets a runner by name. The runner table must have the run function in it.
--- @param name string
--- @param runner table
function hilbish.runner.set(name, runner)
if not runner.run or type(runner.run) ~= 'function' then
error 'run function in runner missing'
runners[name] = runner
--- Executes cmd with a runner. If runnerName isn't passed, it uses
--- the user's current runner.
--- @param cmd string
--- @param runnerName string?
--- @return string, number, string
function hilbish.runner.exec(cmd, runnerName)
if not runnerName then runnerName = currentRunner end
local r = hilbish.runner.get(runnerName)
return r.run(cmd)
--- Sets the current interactive/command line runner mode.
--- @param name string
function hilbish.runner.setCurrent(name)
local r = hilbish.runner.get(name)
currentRunner = name
hilbish.runner.add('hybrid', function(input)
local cmdStr = hilbish.aliases.resolve(input)
local _, _, err = hilbish.runner.lua(cmdStr)
if not err then
return input, 0, nil
return hilbish.runner.sh(input)
hilbish.runner.add('hybridRev', function(input)
local _, _, err = hilbish.runner.sh(input)
if not err then
return input, 0, nil
local cmdStr = hilbish.aliases.resolve(input)
return hilbish.runner.lua(cmdStr)
hilbish.runner.add('lua', function(input)
local cmdStr = hilbish.aliases.resolve(input)
return hilbish.runner.lua(cmdStr)
hilbish.runner.add('sh', function(input)
return hilbish.runner.sh(input)