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.