LXF SHELL
Add some history to the LXF Shell
Refusing to ever learn from anything, Ferenc Deák realises that adding history to the LXF Shell will help him repeat his mistakes.
Part Six!
Don’t miss next issue, subscribe on page 16!
OUR EXPERT
Ferenc Deák feels this project is his Sistine Chapel, only with less of the Pope shouting at him and more Mancunian editors.
The code for the shell still can be found at https://github. com/fritzone/lxf-shell.
In the world of the Linux shell, the command line history stands as a silent but powerful ally I to users navigating the intricate pathways of their systems. It serves as a virtual breadcrumb trail, providing users with a means to recall, analyse and replicate their past interactions with the system.
In this episode of our shell saga, we will delve into the mechanisms, practical applications and, last but not least, the implementation details of how to make the command line history work as expected by a grown-up shell. Not that ours is one, but it will be.
The mechanisms
Modern shells, such as Bash and Zsh, offer similar command history navigation using the up and down arrow keys, Ctrl+R for reverse search, and more advanced commands such as !n , !! and !string to execute specific or recent commands. For the implementation of this feature in our tiny shell, we plan to provide support for the previous and next elements. However, as it is not that difficult, we will also add some extra features: if the user presses Ctrl+Up/Down, we will search for the history in the current folder.
For the moment, we present the following structure for these hotkeys, without too much explanation – but no worries, that will come at a later stage: static const std::map> reservedKeys { {“Up”, {27, 91, 65}}, {“Down”, {27, 91, 66}}, {“CtrlUp”, {27, 91, 49, 59, 53, 65}}, {“CtrlDown”, {27, 91, 49, 59, 53, 66}},
};
Current shells usually keep the history in a file called .xxx_history, where xxx is based on the name of the shell, for example .bash_history. These are simple text files that contain all the commands executed since the shall was taken into first use. As our solution will be a bit more complex, we need a quick and dirty database set up for this, so a short intro to SQLite is to be found in the boxout (opposite). We will create the following database layout to store the commands. The following SQL script is used to create the database:
The structure of the database that’s running behind the scenes.
CREATE TABLE command ( id INTEGER PRIMARY KEY, command VARCHAR(255) );
CREATE TABLE location ( id INTEGER PRIMARY KEY, location VARCHAR(255) );
CREATE TABLE command_location ( created_at DATETIME, command_id INTEGER, location_id INTEGER, PRIMARY KEY (created_at), FOREIGN KEY (command_id) REFERENCES command (id), FOREIGN KEY (location_id) REFERENCES location (id) );
It might feel overcomplicated to have three tables, but we have to keep in mind, that:
A command can appear more than once;