Add readline features in OCaml toplevel

Using the OCaml Toplevel with Readline Support

The default OCaml toplevel lacks basic readline features like history, line editing, and command completion. Here are the practical approaches to fix this.

utop: Full-Featured Replacement

The best option for daily interactive OCaml work is utop, a replacement toplevel that provides:

  • Syntax highlighting with color output
  • Command completion (for identifiers, keywords, library functions)
  • Parenthesis and bracket matching
  • Command history with arrow keys
  • Multi-line input handling
  • Integration with Merlin for type information

Install it via OPAM:

opam install utop

Then start it with:

utop

If you use dune projects, utop integrates seamlessly:

dune utop

utop reads your .ocamlinit file and respects your existing toplevel configuration. For most developers, this is the clear winner — the productivity gains from completion and colors alone justify the small overhead.

rlwrap: Minimal Wrapper Approach

If you want to stick with the vanilla OCaml toplevel but add basic readline support (history, line editing, basic completion), use rlwrap:

rlwrap ocaml

rlwrap intercepts stdin/stdout and provides GNU readline functionality to any command. Install it from your package manager:

# Debian/Ubuntu
sudo apt install rlwrap

# RHEL/CentOS
sudo dnf install rlwrap

# macOS
brew install rlwrap

Creating a Wrapper Script

For convenience, create a shell script wrapper:

#!/bin/sh
exec rlwrap -H ~/.ocaml_history -i /usr/bin/ocaml "$@"

Save this as ~/bin/ocaml (or wherever your local binaries are) and make it executable:

chmod +x ~/bin/ocaml

The -H flag stores history in a persistent file, and -i adds case-insensitive completion matching. Now you get history and Ctrl+R search without installing additional OCaml packages.

rlwrap Configuration

For more sophisticated completion, create ~/.rlwrap/ocaml_completions with OCaml keywords and common library functions:

let rec if then else match with fun
List.map List.fold_left List.iter Array.map
Printf.printf Printf.sprintf

Then use:

rlwrap -f ~/.rlwrap/ocaml_completions ocaml

Comparison

Feature vanilla ocaml rlwrap utop
History No Yes Yes
Line Editing No Yes Yes
Colors No No Yes
Completion No Basic Full
Type Information N/A No Yes (with Merlin)
Setup Time < 1 min < 1 min

Practical Recommendation

  • Daily development: Use utop. The syntax highlighting and intelligent completion pay for themselves immediately.
  • Quick scripts or testing: Use rlwrap ocaml for lightweight line editing without extra dependencies.
  • Vanilla toplevel: Only if you’re constrained by environment or need exact default behavior.

Most modern OCaml workflows rely on utop within editor integrations (VS Code, Vim, Emacs) rather than standalone toplevel sessions anyway, but for interactive exploration, utop remains the standard choice.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *