This is a simple REPL in C that reads a line of input from the user and prints it back to the user. It also saves the history of inputs entered by the user.
Well, creating a basic REPL that reads input until the user hits ENTER
is straightforward. However, allowing the user to navigate through input history with the UP and DOWN arrow keys is more challenging because:
-
Immediate Input Handling: You don't get what the user typed until they hit
ENTER
. This is problematic because users expect the previous command to be displayed immediately upon pressing the UP arrow key. -
Raw Mode and Escape Sequences: To handle user input on each key press, the terminal input must be in raw mode. And once you're in raw mode, say bye bye to the default behavior of the terminal like
CTRL+C
to exit,CTRL+D
to send EOF, or something as simple as backspace handling. You have to handle all of these manually. In fact, you have to responsible for writing back the character that the user types to the terminal.
Read more about raw mode and escape sequences in my notes
I created this REPL because I was reading Build your own Lisp, where the author used the editline
library to handle input history. I wanted to build this functionality from scratch but initially opted to use editline
. But well, I couldn't build it on my Mac, so I decided to implement a naive version that suited my needs. I was already familiar with raw mode and escape sequences from my previous project, Texterm, a simple text editor in C so I knew what I was getting into.
- You can navigate through the history of inputs using the UP and DOWN arrow keys.
- If you navigate to an old input in the history & edit it, then it will remain in the history, even after you hit
ENTER
. This is different from the behavior of most shells where the edited input is not saved in the history after you hitENTER
, but I'm too lazy to implement that behavior. - Your last input is always the latest in the history (duh!).
-
Clone the repo
-
Build the project
make
-
Run the project
./bin/repl
- MacOS 14.4.1, Apple M1 Chip
- gcc 11.4.0, Ubuntu 22.04 (Intel)