edward.ed.cmd

Library for defining custom ed editor commands through provided macros. For each command, a parser and an executor needs to be defined. The parser is defined using edward parser combinators. The executor receives an editor object as well as the return value of the parser combinator as procedure arguments and modifies the editor state accordingly. Additionally, this library defines several utility procedures that are useful for defining executor procedures and ed parser combinators.

Index

Table of contents

Defining Commands

Conceptually, edward distinguishes the following four command types:

  1. Print commands, e.g. the p command. These can be used as suffixes to edit commands.
  2. Edit commands, i.e. commands which modify the text editor buffer in some way (e.g. d).
  3. Input-mode commands. Like the edit commands, but read additional data from input mode.
  4. File commands, which perform I/O operations and cannot be suffixed with a print command.

Commands of the different types are defined using the abstractions described in this section. Every command definition requires at least a unique command name (a symbol) and an executor procedure which is passed the editor object and values returned by the command parser.

syntax define-file-cmd

Define a new file command. Apart from the unique name and executor procedure proc, commands of this type require a default edward address addr. If no default address is provided, it is assumed that this command doesn't expect an address. Furthermore, a a parser combinator definition needs to be provided in the body. The combinators defined in the body are expanded to a parse-blanks-seq. The first combinator of the body must be a parse-cmd-char. All non-ignored parser combinator return values are passed to proc as procedure arguments.

(define-file-cmd (name proc addr) body ...)

syntax define-edit-cmd

Define a new edit command. These commands are conceptually similar to file commands. Therefore, please refer to the documentation of define-file-cmd for more information on the parameters.

Contrary to file commands, edit commands can additionally be suffixed with a print command. If a print command suffix is present, this print command will be executed after the editor changes have been performed by the edit command.

(define-edit-cmd (name proc addr) body ...)

syntax define-input-cmd

Define a new input command. These commands are conceptually similar to edit commands. Similar to edit commands, input commands can also be suffixed with a print command. Therefore, please refer to the documentation of define-edit-cmd for more information on the parameters.

Contrary to other command types, input commands additionally read data using ed input mode. The received data is passed as a list of lines as the last parameter to proc.

(define-input-cmd (name proc addr) body ...)

procedure define-print-cmd

Define a new print command. Print commands are automatically parsed using parse-cmd-char based on the provided cmd-char character. No custom parser combinator can be supplied for these commands. Furthermore, print commands always use the current line as the default address. Similar to other command types, a unique command name (a symbol) must be defined. The executor procedure proc is always passed an editor object and the address range which was passed to the command.

(define-print-cmd name proc char)

Command Parsing

Procedures to invoke parsers for defined editor commands.

procedure parse-cmd

Parse a single, arbitrary command that was previously defined using one of the abstractions described above. If no command parser matches the input, then parsing fails with the error message "unknown command".

(parse-cmd)

Parser Utilities

Utility parser combinators that are useful for defining editor command parsers and, contrary to the combinators defined in edward parse, are somewhat specific to ed(1).

procedure parse-cmd-char

Parse a command character within a parse-seq / parse-blanks-seq. This character is ignored in the sequence and as such not returned.

(parse-cmd-char ch)

procedure parse-re-pair

Parse RE pair for the substitute command (e.g. /RE/replacement/). The given procedure is responsible for parsing the replacement, it is passed the utilized delimiter as a single character function argument.

Returns triplet (RE, replacement, print?) where print? indicates if the closing delimiter was emitted, i.e. if the resulting string should be printed after the replacement was performed.

(parse-re-pair delim-proc)

constant parse-re

Parses a regular expression enclosed by two matching delimiter characters.

parse-re

constant unwrap-command-list

Parse a command list, as passed to the g and v command.

unwrap-command-list

constant parse-filename

Parses a filename, which is then read/written by ed. A file name is either a path to a file or a shell command as passed to the ed shell escape command. The latter is recognized by a ! character prefix.

parse-filename

procedure parse-file-cmd

Parses a command character followed by an optional file parameter. The parameters must be separated by one or more characters.

(parse-file-cmd ch)

Executor Utilities

Utility procedures for common command executor operations.

procedure call-when-confirmed

If changes have been made to the current buffer since the last write of the buffer to a file, then ed should warn the user before the buffer is destroyed. Warnings must be confirmed by repeating the command, which closes the buffer.

This procedure expects an editor record, the symbol of the command to be repeated and a thunk executed if the command was confirmed or no confirmation is necessary (i.e. buffer was not modified).

(call-when-confirmed editor cmd-sym thunk)

constant subst-nomatch-handler

Parameterizable executor for substitution cases where no addressed line matched the desired substitution. Can be overwritten using parameterize. By default, an error is raised if no substitution was performed.

subst-nomatch-handler

procedure exec-command-list

Execute a command list, parsed using unwrap-command-list, for the g and v command.

(exec-command-list editor match-proc lines regex cmdstr)

procedure exec-command-list-interactive

Like exec-command-list but intended to be used for interactive commands, i.e. G and V.

(exec-command-list-interactive editor match-proc lines regex)

procedure filename-cmd?

Predicate which returns true if the given string fn is a file name and not a shell command.

(filename-cmd? fn)

procedure write-lines

Write a list of lines (represented as a string without a terminating newline) to a given filename. If filename starts with ! (i.e. is a command according to filename-cmd?), write data to standard input of given command string.

Returns amount of bytes written to the filename on success and false if an error occurred.

(write-lines filename lines)

procedure read-from

Read data from given filename as a list of lines. If filename start with ! (i.e. is a command), read data from the standard output of the given command.

If an error occurs, returns false and prints an error message to the current-error-port. Otherwise, returns a pair of retrieved lines and amount of total bytes received.

(read-from filename)