arsd.shell

Support functions to build a custom unix-style shell.

More...

Members

Aliases

Globber
alias Globber = string[] delegate(ShellLexeme[] str, ShellContext context)

Classes

Shell
class Shell
Undocumented in source.
ShellCommand
class ShellCommand
Undocumented in source.

Functions

constructLineGetter
auto constructLineGetter()

Constructs an instance of arsd.terminal.LineGetter appropriate for use in a repl for this shell.

enableInteractiveShell
void enableInteractiveShell()

Sets up signal handling and progress groups to become an interactive shell.

lexShellCommandLine
ShellLexeme[] lexShellCommandLine(string commandLine)

This function in pure in all but formal annotation; it does not interact with the outside world.

nextComponent
ShellLexeme[] nextComponent(ShellLexeme[] lexemes)

A shell component - which is likely an argument, but that is a semantic distinction we can't make until parsing - may be made up of several lexemes. Think foo'bar'. This will extract them from the given array up to and including the next unquoted space or newline char.

parseShellCommand
ShellCommand[] parseShellCommand(ShellLexeme[] lexemes, ShellContext context, Globber globber)

Parses a set of lexemes into set of command objects.

Structs

ShellContext
struct ShellContext

Holds some context needed for shell expansions.

ShellLexeme
struct ShellLexeme

Represents one component of a shell command line as a precursor to parsing.

Detailed Description

Do NOT use this to try to sanitize, escape, or otherwise parse what another shell would do with a string! Every shell is different and this implements my rules which may differ in subtle ways from any other common shell.

If you want to use this to understand a command, also use it to execute that command so you get what you expect.

Some notes about this shell syntax:

  • An "execution batch" is a set of command submitted to be run. This is typically a single command line or shell script.
  • ; means "execute the current command and wait for it to complete". If it returns a non-zero errorlevel, the current execution batch is aborted.
  • ;; means the same as ;, except that if it returned a non-zero errorlevel, the current batch is allowed to proceed.
  • & means "execute current command in the background"
  • ASCII space, tab, and newline outside of quotes are all collapsed to a single space, html style. If you want multiple commands in a single execution, use ;. Interactively, pressing enter usually means a new execution, but in a script, you need to use ; (or &, &&, or ||), not just newline, to separate commands.

Bugs

  • a failure in a pipeline at any point should mark that command as failing, not just the first command.
  • sleep 1 && sleep 1 & only puts the second sleep in the background.
  • bash supports $'\e' which follows C escape rules inside the single quotes. want?
  • ${name:use_if_unset} not implemented. might not bother.
  • glob expansion is minimal - * works, but no ?, no stuff. The * is all i personally care about.
  • substitution and $(...) is not implemented
  • variable expansion ${IDENT} is not implemented.
  • no !history recall. or history command in general
  • job control is rudimentary - no fg, bg, jobs, ctrl+z, etc.
  • i'd like it to automatically set -o ignoreeof in some circumstances
  • prompt could be cooler PS1 = normal prompt PS2 = continuation prompt Bash shell executes the content of the PROMPT_COMMAND just before displaying the PS1 variable.

    bash does it with \u and stuff but i kinda think using $USER and such might make more sense.

  • i do alias thing args... instead of alias thing="args...". i kinda prefer it this way tho
  • the api is not very good
  • ulimit? sourcing things too. aliases.
  • deeshrc is pulled from cwd
  • tab complete of available commands not implemented - get it from path search.

Questionable ideas

  • be able to receive an external command, e.g. from vim hotkey
  • separate stdout and stderr more by default, allow stderr pipes.
  • custom completion scripts? prolly not bash compatible since the scripts would be more involved
  • some kind of scriptable cmdlet? a full on script language with shell stuff embeddable? see https://hush-shell.github.io/cmd/index.html for some ok ideas
  • do something fun with job control. idk what tho really.
  • can terminal emulators get notifications when the foreground process group changes? i don't think so but i could make a "poll again now" sequence since i control shell and possibly terminal emulator now.
  • change DISPLAY and such when attaching remote sessions

Meta

History

Added October 18, 2025