The REPL (read-eval-print-loop) console

The read-eval-print-loop (REPL) console is a convenient way to do simple programming, test out things, and experiment. As the name implies, the REPL repeatedly (in a loop) prints out a prompt, reads an input command, evaluates it, then prints the result.

The REPL is started when you invoke the kawa command with no arguments. For example:

$ kawa
#|kawa:1|# (define pi (* 2 (asin 1)))
#|kawa:2|# (list pi (sqrt pi))
(3.141592653589793 1.7724538509055159)
#|kawa:3|# 

The colors and styles used for the prompt and the user input depend on user preference and the capabilities of the console device. (If you read this on a color screen you should see pale green for the prompt and pale yellow for the user input; this matches the defaults for the DomTerm console.)

You can change the prompt string if you want. The default format depends on the (programming) language used; the one shown above is used for Scheme. It has the form of a comment, which can be convenient for copying and pasting lines.

You can change the output formatting with the --output-format command-line option.

The basic console has few frills, but should work in any enviroment where you have a console or terminal. It has no dependencies, except the kawa .jar file (and Java):

$ java kawa-2.93.jar
#|kawa:2|# 

On rare occason you may need to specify the --console flag.

Input line editing and history

When typing a command in a console it is helpful to go back and correct mistakes, repeat and edit previous commands, and so on. How well you can do this varies a lot depending on which tools you use. Kawa delegates input editing to an external tool. The recommended and default input-editing tool is the JLine3 library, which is bundled with the Kawa binary distribution.

JLine3 handles the normal editing comands, including arrow keys for moving around in the input, and deleting with backspace or delete. In general, JLine3 uses the same keybindings as GNU readline, which are based on Emacs key-bindings.

You can use the up-arrow to move to previous commands in the input history and down-arrow to go forwards. Control-R (“reverse search” searches backwards in the history for a previous command that contains the search string.

Multi-line commands are treated as a unit by JLine3: If Kawa determines that input is “incomplete” it will ask for continuation lines - and you can go back and edit previous lines in the same command. You can explicitly create a multi-line command with Escape-Space. An entry in the command history may be multiple lines.

Tab-completion works for Kawa-Scheme identifiers: If you type TAB after an identifier, Kawa will present a list of possible completions.

There are multiple alternatives to using JLine3. You can use GNU readline (if you configured with --enable-kawa-frontend). You can use a front-end program like rlfe or fep. You can use Emacs shell or scheme mode. You can also use DomTerm in line-edit mode, where the browser handles the editing.

console:use-jline=[yes|no]

Disable (with no) or enable (with yes, which is the default) input line editing with JLine.

console:console:jline-mouse=[yes|no]

Enable (with yes) mouse click reporting from most xterm-like terminals to JLine, which means you can move the input cursor with the mouse. This is disabled by default because it conflicts with other useful mouse actions (text selection using drag; middle-button paste; right-button context menu; and wheel mouse scrolling). If you enable mouse-reporting, on most terminals you can get the standard behavior when pressing the shift key. E.g. to enable selection, drag with the shift key pressed. (However, mouse-wheel scrolling may not work even with shift pressed.)

Running a Command Interpreter in a new Window

Instead of using an existing terminal window for Kawa’s REPL console, you can request a new window. The command-line options -w creates a new window. Kawa also creates a new window when it needs to create a REPL (for example if invoked with no options) and it is not running in a console.

You have a number of options for how the window appears and what it supports, controlled by text following -w. All except -wswing (and -wconsole) use DomTerm, so they depend on some kind of web browser technology. All except -wswing by default use JLine3 input editing, if available.

-w

Pick the default/preferred console implementation. You can specify your preference with the console:type= option, which is followed by one of the options below (without the "-w" prefix), It can also be list of options separated by semi-colons, in which case they are tried in order.

The current default (it may change) is as if you specified:

console:type="google-chrome;browser;javafx;swing;console"
-wbrowser

Creates a Kawa window or tab in your preferred desktop browser. Kawa starts a builtin HTTP and WebSocket server to communicate with the browser.

-wbrowser=command

Uses command to display the Kawa REPL. The command should include the pattern %U, which Kawa replaces with a URL that it listens to. (Alternatively, it can use the pattern %W, which Kawa replaces with the port number of its WebSocket server. However, this feature may be removed.) If the is no % in the command, Kawa add " %U". Thus -wbrowser=firefox is the same as -wbrowser="firefox %U".

-wgoogle-chrome

Creates a new Google Chrome window in “app mode” - i.e. with no location or menu bar. This is the same as -wbrowser="google-chrome --app=%U".

-wqtdomterm

Uses the QtDomTerm application. Same as -wbrowser="qtdomterm --connect localhost:%W", where %W is the port of the WebSocke server that Kawa starts.

-wjavafx

Creates a new window using JavaFX WebView, which runs in the same JVM as Kawa. While this doesn’t currently have much in the way of Kawa-specific menus or other features, it has the most potential for adding them in the future. However, it does require JavaFX, which is not always available, and which does not see a lot of love from Oracle. (It uses an old version of WebKit.)

-wswing

Create a console using the Swing toolkit. This is the old implementation of -w. It is deprecated because it only supports the builtin Swing line editing. (I.e. neither DomTerm or JLine3 features are available, though “printing” pictures does work.)

-wserve
-wserve=port

Starts up an HTTP server (along with a WebSocket server), but does not automatically create any browser windows. Instead you can use any modern browser to load http://localhost:port/. If port is not specified, the systems selects it (and prints it out).

-wconsole

Same as "--" - i.e. it uses the existing console.

console:type=preference-list

Specify the behavior of plain -w.

Using DomTerm

DomTerm is a family of terminal emulators that use the DomTerm JavaScript library.

You can either have Kawa start DomTerm:

$ kawa options -w

or start a DomTerm terminal emulator and have it start Kawa:

$ domterm kawa options --

(You can also start a shell in a domterm window, and then start kawa.)

Either approach works and both give you the benefits of DomTerm:

  • A xterm/ansi-compatible terminal emulator, which means you can use (for example) JLine3 for input editing.

  • You can “print” images, pictures, or HTML elements.

  • Pretty-printing is handled by the terminal, which means line-breaking is re-computed when window width changes.

  • Hide/show buttons allow you to temporarily hide/unhide the output from a specific command.

  • You can save a session as an HTML file, which can be viewed later. (Still with dynamic line-breaking and pretty-printing, as well as working hide/show buttons.) The file is actually XHTML, so it can be processed with XML-reading tools.

  • Distinct styles for prompts, input, error output and regular output, which can be customized with CSS.

For now it is recommended to use both DomTerm and JLine3.

Procedure: domterm-load-stylesheet stylesheet [name]

The string stylesheet should be a literal CSS stylesheet which is downloaded into the current DomTerm console. The new stylesheet is given the attribute name=name, where name defaults to "Kawa". If there is an existing stylesheey whose name attribute is name, it is replaced. In this example we change the background color to light gray:

(domterm-load-stylesheet "div.domterm { background-color: lightgray}")