Tuesday, January 14, 2014

The Marriage of Terminal and Shell

The past week has been an exciting one, bringing three key advancements to the interaction between Final Term and bash that I will describe in this post. Together with the extensive existing entanglements, these will be the foundation the initial stable release of Final Term builds on – a marriage of terminal and shell.

precmd and preexec

Final Term now makes use of Glyph Lefkowitz's ingenious script to emulate zsh's precmd and preexec functions, directly extracting the executed command from bash's history.

This fixes a number of bugs in command detection and enables things that would have been near impossible using the previous approach, such as correctly detecting multi-line commands.

Also, since zsh already supports precmd and preexec natively, this suggests a natural route towards zsh support for Final Term. Yes, you heard me right: zsh support is coming. Not very soon maybe (unless someone contributes it) but it will definitely happen, and could be as easy as a port of bash_startup.in to zsh. The obstacles are gone.

Return Codes, Visualized

A picture is worth a thousand words:

Final Term's collapse buttons now double as visual indicators of the associated command's exit status! They glow red if the return code is not zero, traditionally indicating an error. On hover, the exact return code is shown in a tooltip. Final Term hides all the complexity which makes that unique feature possible from the user and only shows the interesting information.

It's pretty cool, I think :)

A World of New Possibilities

This change is the big one.

Connoisseurs of Final Term's internals already know that most of its frontend magic (such as buttons over filenames in ls) is achieved through custom escape sequences in program output that are interpreted by Final Term. This idea has now been taken further: Escape sequences can now trigger Final Term commands (already heavily used in key bindings and text menus). One of the immediate consequences is that Final Term can now be controlled by the programs running inside it simply through escape sequences, no matter what language those programs are written in.

Let me say that again:

Final Term can now be scripted in any language!

The possibilities that this approach allows appear endless, but what is it really useful for? As both an example and a very useful addition, I have implemented another feature that completes the marriage of terminal and shell and showcases how incredibly powerful Final Term has become: Terminal commands.

Terminal commands are shell commands that are executed by Final Term. You define them simply by editing a .ftcommands file. Final Term's shell startup script then reads that file and registers the appropriate aliases (with a "," prefix to avoid name collisions with other shell commands) with the shell, tying them to the relevant Final Term commands which will be relayed to the terminal when the aliases are used.

Terminal commands remain shell commands, which means that they

  • Can be chained and piped with other terminal and shell commands
  • Show up in the shell's history
  • Are completed by the shell's tab completion
  • Accept shell command line arguments

What does this all mean for the user? Have a look:

What's going on here? We first define a bash alias cdtab that consists of a terminal command, ,tab (which, you guessed it, opens a new tab) and a shell command, cd. Running that command has an effect similar to the "open in new tab" middle click that browsers provide. Afterwards, we showcase the ability of terminal commands to accept command line arguments by opening four tabs at once with ,tab 4 (this suggests an obvious way to save tab and pane arrangements, of course).

I am very much looking forward to see what the community does with these new possibilities. Final Term is alive and kicking, and on the finish line towards its initial release and wide availability.

The project still needs help, though. If you have not so far, please consider contributing to the project by testing or coding. I develop and manage this very complex project in my free time exclusively, and could really use some assistance (I'd be glad to provide hints if you are unsure where to start).

And please, as always, do remember that despite all those cool features, Final Term is still unstable and NOT READY for production use.