-- @module hilbish local bait = require 'bait' local fs = require 'fs' local readline = require 'readline' local snail = require 'snail' hilbish.snail = snail.new() hilbish.snail:run 'true' -- to "initialize" snail bait.catch('hilbish.cd', function(path) hilbish.snail:dir(path) end) local function abbrevHome(path) if path:sub(1, hilbish.home:len()) == hilbish.home then return fs.join('~', path:sub(hilbish.home:len() + 1)) end end local function fmtPrompt(p) return p:gsub('%%(%w)', function(c) if c == 'd' then return abbrevHome(hilbish.cwd()) elseif c == 'u' then return hilbish.user elseif c == 'h' then return hilbish.host end end) end --- prompt(str, typ) --- Changes the shell prompt to the provided string. --- There are a few verbs that can be used in the prompt text. --- These will be formatted and replaced with the appropriate values. --- `%d` - Current working directory --- `%u` - Name of current user --- `%h` - Hostname of device --- #param str string --- #param typ? string Type of prompt, being left or right. Left by default. --- #example --- -- the default hilbish prompt without color --- hilbish.prompt '%u %d ∆' --- -- or something of old: --- hilbish.prompt '%u@%h :%d $' --- -- prompt: user@hostname: ~/directory $ --- #example -- @param p string -- @param typ string Type of prompt, either left or right function hilbish.prompt(p, typ) if type(p) ~= 'string' then error('expected #1 to be string, got ' .. type(p)) end if not typ or typ == 'left' then hilbish.editor:prompt(fmtPrompt(p)) if not hilbish.running then hilbish.editor:refreshPrompt() end elseif typ == 'right' then hilbish.editor:rightPrompt(fmtPrompt(p)) if not hilbish.running then hilbish.editor:refreshPrompt() end else error('expected prompt type to be right or left, got ' .. tostring(typ)) end end --- read(prompt) -> input (string) --- Read input from the user, using Hilbish's line editor/input reader. --- This is a separate instance from the one Hilbish actually uses. --- Returns `input`, will be nil if Ctrl-D is pressed, or an error occurs. -- @param prompt? string Text to print before input, can be empty. -- @returns string|nil function hilbish.read(prompt) prompt = prompt or '' if type(prompt) ~= 'string' then error 'expected #1 to be a string' end local rl = readline.new() rl:prompt(prompt) return rl:read() end --- Runs `cmd` in Hilbish's shell script interpreter. --- The `streams` parameter specifies the output and input streams the command should use. --- For example, to write command output to a sink. --- As a table, the caller can directly specify the standard output, error, and input --- streams of the command with the table keys `out`, `err`, and `input` respectively. --- As a boolean, it specifies whether the command should use standard output or return its output streams. --- #example --- -- This code is the same as `ls -l | wc -l` --- local fs = require 'fs' --- local pr, pw = fs.pipe() --- hilbish.run('ls -l', { --- stdout = pw, --- stderr = pw, --- }) --- pw:close() --- hilbish.run('wc -l', { --- stdin = pr --- }) --- #example -- @param cmd string -- @param streams table|boolean -- @returns number, string, string function hilbish.run(cmd, streams) local sinks = {} if type(streams) == 'boolean' then if not streams then sinks = { out = hilbish.sink.new(), err = hilbish.sink.new(), input = io.stdin } end elseif type(streams) == 'table' then sinks = streams end local out = hilbish.snail:run(cmd, {sinks = sinks}) local returns = {out.exitCode} if type(streams) == 'boolean' and not streams then table.insert(returns, sinks.out:readAll()) table.insert(returns, sinks.err:readAll()) end return table.unpack(returns) end --- Sets the execution/runner mode for interactive Hilbish. --- **NOTE: This function is deprecated and will be removed in 3.0** --- Use `hilbish.runner.setCurrent` instead. --- This determines whether Hilbish wll try to run input as Lua --- and/or sh or only do one of either. --- Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua), --- sh, and lua. It also accepts a function, to which if it is passed one --- will call it to execute user input instead. --- Read [about runner mode](../features/runner-mode) for more information. -- @param mode string|function function hilbish.runnerMode(mode) if type(mode) == 'string' then hilbish.runner.setCurrent(mode) elseif type(mode) == 'function' then hilbish.runner.set('_', { run = mode }) hilbish.runner.setCurrent '_' else error('expected runner mode type to be either string or function, got', type(mode)) end end