termonad
Terminal emulator configurable in Haskell
https://github.com/cdepillabout/termonad
Version on this page: | 4.4.0.0 |
LTS Haskell 22.39: | 4.5.0.0 |
Stackage Nightly 2024-10-31: | 4.6.0.0 |
Latest on Hackage: | 4.6.0.0 |
termonad-4.4.0.0@sha256:af2a4e377145cb26dfc021883355abe3811a0bd7ccf373023344d109368576fa,10640
Termonad
Termonad is a terminal emulator configurable in Haskell. It is extremely customizable and provides hooks to modify the default behavior. It can be thought of as the “XMonad” of terminal emulators.
Termonad was featured on an episode of DistroTube. This video gives a short overview of Termonad.
Table of Contents
Installation
Termonad can be installed on any system as long as the necessary GTK libraries are available. The following are instructions for installing Termonad on a few different distributions and systems. If the given steps don’t work for you, or you want to add instructions for an additional system, please send a pull request.
The following steps use the
stack
build tool to build
Termonad, but cabal
can be used as well. Steps for
installing stack
can be found on
this page.
Arch Linux
First, you must install the required Gnome/GTK system libraries:
$ pacman -S vte3 gobject-introspection
In order to install Termonad, clone this repository and run stack install
.
This will install the termonad
binary to ~/.local/bin/
:
$ git clone https://github.com/cdepillabout/termonad
$ cd termonad/
$ stack install
Note that Termonad depends on the haskell-gi
family of Haskell libraries. haskell-gi
contains Haskell wrappers for for Gnome/GTK system libraries. It uses the GObject Introspection functionality from the Gnome libraries.
One problem that Arch users often run into is that their system Gnome/GTK libraries are newer than what the haskell-gi
dependencies from Stackage support. If you run into this problem, there are a couple things you can try:
- Manually switch to a newer Stackage resolver (probably Stackage Nightly). Newer Stackage resolvers often have newer versions of the
haskell-gi
libraries. Newer versions of thehaskell-gi
libraries are more likely to support your newer system Gnome/GTK libraries. If you get something working like this, please open a PR. - Use
cabal
for building Termonad instead ofstack
. Make surecabal
’s constraint solver picks the latest versions of thehaskell-gi
libraries on Hackage. - Use Nix for installing Termonad.
My suggestion is to use Nix, since it is highly likely to “just work” (because with Nix, all libraries are pinned to known working versions, even system libraries).
Ubuntu / Debian
Termonad can be installed through apt
on Debian and Ubuntu:
$ sudo apt install termonad libghc-termonad-dev
Note that the libghc-termonad-dev
package is necessary if you want to be able
to compile the Haskell-based settings file, termonad.hs
.
Compiling from source on Ubuntu / Debian
First, you must install the required Gnome/GTK system libraries:
$ apt-get install gobject-introspection libgirepository1.0-dev libgtk-3-dev libvte-2.91-dev libpcre2-dev
In order to install Termonad, clone this repository and run stack install
.
This will install the termonad
binary to ~/.local/bin/
:
$ git clone https://github.com/cdepillabout/termonad
$ cd termonad/
$ stack install
Nix
If you have nix
installed, you should be able to use it to obtain Termonad.
This means that it will work on NixOS, or with nix
on another distro. There
are three different ways to use nix
to get Termonad:
-
Get Termonad from Nixpkgs. Termonad is provided as a top-level
termonad
attribute in Nixpkgs.For instance, run a
nix-shell
with Termonad:$ nix-shell -p termonad $ termonad # run termonad within the nix-shell
You can also install
termonad
with tools likenix-env
or home-manager. If you’re using NixOS, you can addtermonad
to yourenvironment.systemPackages
list.Keep in mind that if you’re using an old release of NixOS, you’ll likely get an older version of Termonad.
-
Build Termonad using the code in this repository. The following commands clone this repo and build the
termonad
binary at./result/bin/
:$ git clone https://github.com/cdepillabout/termonad $ cd termonad/ $ nix-build
-
Build Termonad using
stack
with Nix-integration. The following commands installstack
for your user, clone this repository, and install thetermonad
binary to~/.local/bin/
:$ nix-env -i stack $ git clone https://github.com/cdepillabout/termonad $ cd termonad/ $ stack --nix install
(edit: Building with
stack
using Nix-integration does not currently work. See #99.)
Mac OS X
Building and installing Termonad on Mac OS X should be possible with any of the following three methods:
-
Install the required system libraries (like GTK and VTE) by hand, then use
stack
to build Termonad.This is probably the easiest method. You don’t have to understand anything about
nix
. However, it is slightly annoying to have to install GTK and VTE by hand. -
Use
nix
to install both the required system libraries and Termonad itself.If you are a nix user and want an easy way to install Termonad, this is the recommended method.
-
Use
nix
to install install the required system libraries, andstack
to build Termonad.If you are a nix user, but want to use
stack
to actually do development on Termonad, usingstack
may be easier than usingcabal
.
The following sections describe each method.
Installing with just stack
(currently no instructions available. please send a PR adding instructions if you get termonad to build using this method.)
Installing with just nix
nix
can be used to install Termonad with the following steps, assuming you
have nix
installed. These commands
clone this repository and build the termonad
binary at ./result/bin/
:
$ git clone https://github.com/cdepillabout/termonad
$ cd termonad/
$ nix-build
Installing with stack
using nix
stack
can be used in conjunction with nix
to install Termonad. nix
will
handle installing system dependencies (like GTK and VTE), while stack
will
handle compiling and installing Haskell packages.
You must have nix
installed.
You will also need stack
installed. You can do that with the following command:
$ nix-env -i stack
After stack
is installed, you will need to clone Termonad and build it:
$ git clone https://github.com/cdepillabout/termonad
$ cd termonad/
$ stack --nix install
This will install the termonad
binary to ~/.local/bin/
.
Windows
To run Termonad on Windows, you’ll need:
- any X server app, for example Vcxsrv
- any WSL, for example Ubuntu
I’m using both Vcxsrv and Ubuntu WSL.
Configure both Vcxsrv and WSL. For Vcxsrv go with default settings everywhere, it will be fine. Configure your WSL as you want (choose your name etc.). After you set up the user, you’ll have to update your OS, run:
$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo apt-get dist-upgrade -y
$ sudo apt-get autoremove -y
Configure the DISPLAY
environment variable for the X server, and load the changes in bash:
For WSL1:
$ echo "export DISPLAY=localhost:0.0" >> ~/.bashrc
$ source ~/.bashrc
For WSL2:
$ echo export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0 >> ~/.bashrc
$ echo export LIBGL_ALWAYS_INDIRECT=1 >> ~/.bashrc
$ source ~/.bashrc
If you’re using WSL2, you have to create a separate inbound rule for TCP port 6000, to allow WSL access to the X server.
If you’re using mentioned earlier Vcxsrv you can enable public access for your X server by disabling Access Control on the Extra Settings.
You can also use -ac
flag in the Additional parameters for VcXsrv section.
Your X server should now be configured.
Execute following command to install the necessary GTK system libraries:
$ apt-get install gobject-introspection libgirepository1.0-dev libgtk-3-dev libvte-2.91-dev libpcre2-dev
The required GTK system libraries should now be installed.
Clone the Termonad repo:
$ git clone https://github.com/cdepillabout/termonad
$ cd termonad/
$ stack build
$ stack run
After stack run
, you should see a new window with your Termonad running.
How to use Termonad
Termonad is similar to XMonad. The above steps will install a termonad
binary
somewhere on your system. If you have installed Termonad using stack
, the
termonad
binary will be in ~/.local/bin/
. This binary is a version of
Termonad configured with default settings. You can try running it to get an idea
of what Termonad is like:
$ ~/.local/bin/termonad
The following section describes the default key bindings.
If you would like to configure Termonad with your own settings, first you will
need to create a Haskell file called ~/.config/termonad/termonad.hs
. A following
section gives an example configuration file.
If this configuration file exists, when the ~/.local/bin/termonad
binary
launches, it will try to use GHC to compile the configuration file. If GHC
is able to successfully compile the configuration file, a separate binary will
be created called something like ~/.cache/termonad/termonad-linux-x86_64
.
This binary file can be thought of as your own personal Termonad, configured
with all your own settings.
When you run ~/.local/bin/termonad
, it will re-exec
~/.cache/termonad/termonad-linux-x86_64
if it exists.
However, there is one difficulty with this setup. In order for the
~/.local/bin/termonad
binary to be able to compile your
~/.config/termonad/termonad.hs
configuration file, Termonad needs to know
where GHC is, as well as where all your Haskell packages live. This presents
some difficulties that will be discussed in a following section.
Default Key Bindings
Termonad provides the following default key bindings.
Key binding | Action |
---|---|
Ctrl Shift t | Open new tab. |
Ctrl Shift w | Close tab. |
Ctrl Shift f | Open Find dialog for searching for a regex. |
Ctrl Shift p | Find the regex above the current position. |
Ctrl Shift i | Find the regex below the current position. |
Ctrl + | Increase font size. |
Ctrl - | Decrease font size. |
Ctrl PgUp | Switch to previous tab. |
Ctrl PgDown | Switch to next tab. |
Alt (number key) | Switch to tab number . For example, Alt 2 switches to tab 2. |
Configuring Termonad
Termonad has two different ways to be configured.
The first way is to use the built-in Preferences editor. You can find this in
the Preferences
menu under Edit
in the menubar.
When opening Termonad for the first time, it will create a preferences file at
~/.config/termonad/termonad.yaml
. When you change a setting in the
Preferences editor, Termonad will update the setting in the preferences file.
When running Termonad, it will load settings from the preferences file. Do not edit the preferences file by hand, because it will be overwritten when updating settings in the Preferences editor.
This method is perfect for users who only want to make small changes to the Termonad settings, like the default font size.
The second way to configure Termonad is to use a Haskell-based settings file,
called ~/.config/termonad/termonad.hs
by default. This method allows you to
make large, sweeping changes to Termonad. This method is recommended for power
users.
WARNING: If you have a ~/.config/termonad/termonad.hs
file, then all
settings from ~/.config/termonad/termonad.yaml
will be ignored. If you want
to set ANY settings in ~/.config/termonad/termonad.hs
, then you must
set ALL settings in ~/.config/termonad/termonad.hs
.
The following is an example Termonad configuration file. You should save this to
~/.config/termonad/termonad.hs
. You can find more information on the available
configuration options within the
Termonad.Config
module.
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Termonad.App (defaultMain)
import Termonad.Config
( FontConfig, FontSize(FontSizePoints), Option(Set)
, ShowScrollbar(ShowScrollbarAlways), defaultConfigOptions, defaultFontConfig
, defaultTMConfig, fontConfig, fontFamily, fontSize, options, showScrollbar
)
import Termonad.Config.Colour
( AlphaColour, ColourConfig, addColourExtension, createColour
, createColourExtension, cursorBgColour, defaultColourConfig
)
-- | This sets the color of the cursor in the terminal.
--
-- This uses the "Data.Colour" module to define a dark-red color.
-- There are many default colors defined in "Data.Colour.Names".
cursBgColour :: AlphaColour Double
cursBgColour = createColour 204 0 0
-- | This sets the colors used for the terminal. We only specify the background
-- color of the cursor.
colConf :: ColourConfig (AlphaColour Double)
colConf =
defaultColourConfig
{ cursorBgColour = Set cursBgColour
}
-- | This defines the font for the terminal.
fontConf :: FontConfig
fontConf =
defaultFontConfig
{ fontFamily = "DejaVu Sans Mono"
, fontSize = FontSizePoints 13
}
main :: IO ()
main = do
colExt <- createColourExtension colConf
let termonadConf =
defaultTMConfig
{ options =
defaultConfigOptions
{ fontConfig = fontConf
-- Make sure the scrollbar is always visible.
, showScrollbar = ShowScrollbarAlways
}
}
`addColourExtension` colExt
defaultMain termonadConf
There are other example configuration files in the example-config/ directory.
If you want to test what all the colors look like, you may find it convenient
to use the
print-console-colors
package, which provides an executable called print-console-colors
that prints
all of the colors for your terminal.
Compiling Local Settings
If you launch Termonad by calling ~/.local/bin/termonad
, it will try to
compile the ~/.config/termonad/termonad.hs
file if it exists. The problem is
that ~/.local/bin/termonad
needs to be able to see GHC and the required
Haskell libraries to be able to compile ~/.config/termonad/termonad.hs
.
There are a couple solutions to this problem, listed in the sections below.
(These steps are definitely confusing. I would love to figure out a better way to do this. Please submit an issue or PR if you have a good idea about how to fix this.)
Running with stack
If you originally compiled Termonad with stack
, you can use stack
to
execute Termonad. First, you must change to the directory with the Termonad
source code. From there, you can run stack exec
:
$ cd termonad/ # change to the termonad source code directory
$ stack exec -- termonad
stack
will pick up the correct GHC version and libraries from the
stack.yaml
and termonad.cabal
file. termonad
will be run in an
environment with GHC available. termonad
will use this GHC and libraries to
compile your ~/.config/termonad/termonad.hs
file. It if succeeds, it should
create a ~/.cache/termonad/termonad-linux-x86_64
binary.
If you need extra Haskell libraries available when compiling your
~/.config/termonad/termonad.hs
file, you can specify them to stack exec
:
$ stack exec --package lens --package conduit -- termonad
The problem with this is that stack exec
changes quite a few of your
environment variables. It is not recommended to actually run Termonad from
within stack exec
. After you run stack exec -- termonad
and let it
recompile your ~/.config/termonad/termonad.hs
file, exit Termonad.
Re-run Termonad by calling it directly. Termonad will notice that
~/.config/termonad/termonad.hs
hasn’t changed since
~/.cache/termonad/termonad-linux-x86_64
has been recompiled, so it will
directly execute ~/.cache/termonad/termonad-linux-x86_64
.
Running with nix
Building Termonad with nix
(by running nix-build
in the top
directory) sets it up so that Termonad can see GHC. Termonad should be able
to compile the ~/.config/termonad/termonad.hs
file by default.
If you’re interested in how this works, or want to change which Haskell
packages are available from your ~/.config/termonad/termonad.hs
file, please
see the documentation in the
.nix-helpers/termonad-with-packages.nix
file.
Additional Info
This section contains some additional info that may be helpful for using Termonad.
Opening URLs by right-clicking
It is possible to open a URL in a browser by right-clicking on it, and
selecting Open URL in browser
. In order for this you work, you may
have to setup your XDG defaults. You can set the default browser to
Firefox with a command like the following:
$ xdg-mime default firefox.desktop x-scheme-handler/http
$ xdg-mime default firefox.desktop x-scheme-handler/https
This xdg-mime
executable comes from a package called xdg-utils
in both
Nixpkgs and Ubutun/Debian.
Goals
Termonad has the following goals:
-
fully configurable in Haskell
There are already many good terminal emulators. However, there are no terminal emulators fully configurable in Haskell. Termonad fills this niche.
-
flexible
Most people only need a terminal emulator that lets you change the font-size, cursor color, etc. They don’t need tons of configuration options. Termonad should be for people that like lots of configuration options. Termonad should provide many hooks to allow the user full control over its behavior.
-
stable
Termonad should be able to be used everyday as your main terminal emulator. It should not crash for any reason. If you experience a crash, please file an issue or a pull request!
-
good documentation
The documentation for Termonad on Hackage should be good. You shouldn’t have to guess at what certain data types or functions do. If you have a hard time understanding anything in the documentation, please submit an issue or PR.
Where to get help
If you find a bug in Termonad, please either send a PR fixing it or create an issue explaining it.
If you just need help with configuring Termonad, you can either join the Gitter room or #termonad on irc.freenode.net.
Contributions
Contributions are highly appreciated. Termonad is currently missing many helpful configuration options and behavior hooks. If there is something you would like to add, please submit an issue or PR.
Maintainers
Changes
4.4.0.0
- Add support for opening URLs in a browser by right-clicking on them. URLs will also become underlined if you mouse-over them. #222
4.3.0.0
- Add SIXEL support. Note that you will need to set
enableSixel
toTrue
in yourConfigOptions
. In order forenableSixel
to have any affect, you’ll need to use version of VTE that is >= 0.63, and has been compiled with SIXEL support. There is also a report that even if you enable SIXEL and have a supported version of VTE, there may still be some problems. See the linked PR for more information, including how to compile VTE with SIXEL support. Thanks @junjihashimoto! #219
4.2.0.1
-
Added an example of how to setup a Dracula color scheme. Thanks @craigem! #195
-
Bump to allow both aeson-1 and aeson-2. Thanks @gelisam! #210
4.2.0.0
-
Add new options
highlightFgColour
andhighlightBgColour
for setting the color of highlighted text #190. Thanks @zanculmarktum! -
Termonad creates a configuration file in
~/.config/termonad/termonad.yaml
for use with the Preferences editor. This is only used if you don’t have atermonad.hs
file.The configuration file loading code has been updated to be more robust in loading configurations that are missing fields. This means that if you update Termonad from an old version, your preferences will still be able to be loaded in most cases #191. Thanks again @jecaro!
-
Added an example of how to setup a PaperColour color scheme. Thanks @craigem! #193
4.1.1.0
- Add new shortcuts to switch to the next and previous tab: CtrlPgDown and CtrlPgUp. This works similar to gnome-terminal and xfce4-terminal. #180. Thanks @juliendehos!
4.1.0.0
- Add an option for enabling “bold is bright”. This forces colors from the extended light palette to be used whenever Termonad prints bold text. #178. Thanks @M0M097!
4.0.1.2
- Disable doctest test-suite when building with GHC-8.10.3. The doctests appear to be segfaulting, but only when compiled with GHC-8.10.3. #175.
4.0.1.1
4.0.1.0
- Add Preferences link to context menu. This is a convenient way to open the Preferences if you don’t have the menu shown by default. #171 Thanks @maridonkers!
4.0.0.1
- Update Termonad to be able to be built with the latest versions of the
haskell-gi libraries. This shouldn’t affect most users building with
stack
. It is only used currently for building Termonad with packages from Nixpkgs.
4.0.0.0
-
Remove the dependently typed code for specifying terminal colors. #161. Thanks @ssbothwell!
The
Palette
data type has been updated to not used length-indexed lists, but instead just newtype wrappers around normal lists.In prevous versions, the
Palette
data type looked like this:data Palette c = NoPalette | BasicPalette !(Vec N8 c) | ExtendedPalette !(Vec N8 c) !(Vec N8 c) | ColourCubePalette !(Vec N8 c) !(Vec N8 c) !(Matrix '[N6, N6, N6] c) | FullPalette !(Vec N8 c) !(Vec N8 c) !(Matrix '[N6, N6, N6] c) !(Vec N24 c)
In 4.0.0.0,
Palette
has been changed to the following:data Palette c = NoPalette | BasicPalette !(List8 c) | ExtendedPalette !(List8 c) !(List8 c) | ColourCubePalette !(List8 c) !(List8 c) !(Matrix c) | FullPalette !(List8 c) !(List8 c) !(Matrix c) !(List24 c)
Instead of using types like
Vec N8 c
, you will use types likeList8 c
.When setting the
palette
field of in aColourConfig
, you can now do it like the following. Note that there is both amkList8
function that returnsMaybe
, and anunsafeMkList8
that throws a runtime error. Most users will probably want to use theunsafeMkList8
function, since it is easy to use, and you can eyeball whether the list has the correct number of elements. If you’re doing something more complicated, you may want to use themkList8
function:myColourConfig :: ColourConfig (AlphaColour Double) myColourConfig = defaultColourConfig { palette = ExtendedPalette myStandardColours (maybe defaultLightColours id myLightColours) } where -- This is a an example of creating a linked-list of colours, -- This function uses an unsafe method for generating the list. -- An exception will be thrown if your list does not have exactly 8 elements. myStandardColours :: List8 (AlphaColour Double) myStandardColours = unsafeMkList8 [ createColour 40 30 20 -- dark brown (used as background colour) , createColour 180 30 20 -- red , createColour 40 160 20 -- green , createColour 180 160 20 -- dark yellow , createColour 40 30 120 -- dark purple , createColour 180 30 120 -- bright pink , createColour 40 160 120 -- teal , createColour 180 160 120 -- light brown ] -- This is an example of creating a linked-list of colours with a type -- safe method. mkList8 produces a Maybe value which must be handled explicitely. myLightColours :: Maybe (List8 (AlphaColour Double)) myLightColours = mkList8 [ createColour 70 60 50 -- brown , createColour 220 30 20 -- light red , createColour 40 210 20 -- light green , createColour 220 200 20 -- yellow , createColour 40 30 180 -- purple , createColour 140 30 80 -- dark pink , createColour 50 200 160 -- light teal , createColour 220 200 150 -- light brown ]
Also see the functions
setAtList8
,overAtList8
,setAtList24
,overAtList24
, etc.
3.1.0.1
-
Add an example showing Gruvbox colours #149. Thanks again @craigem!
-
Set an upperbound on
base
so we make sure that only GHC-8.8 is used. Some of the dependencies of Termonad don’t support GHC-8.10 yet.
3.1.0.0
-
Fix up deprecated functions used in Setup.hs. This should allow Termonad to be compiled with Cabal-3.0.0.0 (which is used by default in GHC-8.8). #144 Thanks mdorman!
-
Fully update to LTS-15 and GHC-8.8. Termonad now requires GHC-8.8 in order to be compiled. #145.
3.0.0.0
-
Remove the one-pixel white border around the
GtkNotebook
(the GTK widget thing that contains the tabs). #138 -
Add a right-click menu for the terminal. It currently allows copy and paste. #136 Thanks @jecaro!
-
Add a preferences file that settings will be saved to and read from at
~/.config/termonad/termonad.yaml
. You can change settings with the Preferences dialog. The settings will only be used from this file if you do not have a~/.config/termonad/termonad.hs
file. #140 Thanks again @jecaro!
2.1.0.0
- Add a menu option to set preferences for a running Termonad session. The preferences you have set are lost when you end the Termonad session. #130 Thanks @jecaro!
2.0.0.0
- Added menu option to search for a regex within the terminal output. This removes support for versions of VTE-2.91 older than 0.46. This means that compiling on older versions of Debian and Ubuntu may no longer work. #118
1.3.0.0
- Change all uses of
Colour
toAlphaColour
inTermonad.Config.Colour
. Users should now useAlphaColour
instead ofColour
. Also, all uses ofsRGB24
should be replaced withcreateColour
. This change is mechanical and should not affect how Termonad works at all. Thanks to @jecaro and @amir! #116
1.2.0.0
-
Got the code for setting the backgroud color of the terminal actually working. Thanks @dakotaclemenceplaza. #111
- This changes the type of
ColourConfig
to make the foreground and background colors of the terminal optional.
- This changes the type of
-
Various cleanup in the nix files.
1.1.0.0
-
Added an example of how to setup a solarized color scheme. Thanks @craigem. #90 and #103
-
Various fixes in the nix files. Make sure Termonad can see the GTK icons. #91 and #92
-
Add a menu option to change the font size at runtime. You should be able to do this with the
Ctrl-+
andCtrl--
keys. #95 -
Get building with GHC 8.6. Thanks @clinty. #98
1.0.1.0
-
Stop using the
widgetSetFocusOnClick
function, which is not supported on older versions of GTK. This lets Termonad be compiled with older versions of GTK. #87. -
Add CI. #87.
-
Support versions of VTE-2.91 older than 0.44. #87.
-
Add some functions for converting from a list to a
Vec
inTermonad.Config.Vec
:fromListVec
andfromListVec_
. Commit 883eb98b5f. -
Fix the paste hotkey. #86.
1.0.0.0
-
The API for configuring Termonad is now completely different. Many, many changes have gone into this version. You should approach it as a completely different application.
The CHANGELOG will be kept up-to-date for future releases.
0.2.1.0
-
Make sure the window title is set to “Termonad”.
-
Relabel tabs when termonad is started.
0.2.0.0
-
Open dialog asking if you want to quit when you try to use your WM to quit.
-
Termonad will attempt to open up a new terminal in the working directory of the current terminal.
-
Make sure termonad won’t crash if dyre can’t find GHC.
-
Add a few more ways to compile on NixOS.
-
Add an icon for termonad.
0.1.0.0
- Initial release.