diff --git a/CHANGELOG.md b/CHANGELOG.md index ab8a2a4..3768eff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/docs/runner-mode.txt b/docs/runner-mode.txt index 9df1095..5765f18 100644 --- a/docs/runner-mode.txt +++ b/docs/runner-mode.txt @@ -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. diff --git a/nature/init.lua b/nature/init.lua index 7dd8953..8671087 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -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 diff --git a/nature/runner.lua b/nature/runner.lua new file mode 100644 index 0000000..ed1b7dd --- /dev/null +++ b/nature/runner.lua @@ -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)) + end + + return r +end + +--- 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' + end + + if type(runner) == 'function' then + runner = {run = runner} -- this probably looks confusing + end + + if type(runner) ~= 'table' then + error 'expected runner to be a table or function' + end + + if runners[name] then + error(string.format('runner %s already exists', name)) + end + + hilbish.runner.set(name, runner) +end + +--- 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' + end + + runners[name] = runner +end + +--- 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) +end + +--- 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.setMode(r.run) +end + +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 + end + + return hilbish.runner.sh(input) +end) + +hilbish.runner.add('hybridRev', function(input) + local _, _, err = hilbish.runner.sh(input) + if not err then + return input, 0, nil + end + + local cmdStr = hilbish.aliases.resolve(input) + return hilbish.runner.lua(cmdStr) +end) + +hilbish.runner.add('lua', function(input) + local cmdStr = hilbish.aliases.resolve(input) + return hilbish.runner.lua(cmdStr) +end) + +hilbish.runner.add('sh', function(input) + return hilbish.runner.sh(input) +end) +