• Stars
    star
    400
  • Rank 107,843 (Top 3 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created over 6 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Terminal emulator configurable in Haskell.

Termonad

CI Hackage Stackage LTS Stackage Nightly BSD3 license Join the chat at https://gitter.im/termonad/Lobby

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.

image of Termonad

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 the haskell-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 of stack. Make sure cabal's constraint solver picks the latest versions of the haskell-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:

  1. 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 like nix-env or home-manager. If you're using NixOS, you can add termonad to your environment.systemPackages list.

    Keep in mind that if you're using an old release of NixOS, you'll likely get an older version of Termonad.

  2. 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
  3. Build Termonad using stack with Nix-integration. The following commands install stack for your user, clone this repository, and install the termonad 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, and stack to build Termonad.

    If you are a nix user, but want to use stack to actually do development on Termonad, using stack may be easier than using cabal.

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

More Repositories

1

pretty-simple

pretty-printer for Haskell data types that have a Show instance
Haskell
242
star
2

servant-checked-exceptions

type-level errors for Servant APIs.
Haskell
73
star
3

nix-query-tree-viewer

GTK viewer for the output of `nix-store --query --tree`
Rust
65
star
4

password

datatypes and functions for easily working with passwords in Haskell
Haskell
49
star
5

stacklock2nix

Easily build a Haskell project from a stack.yaml.lock file with Nix
Nix
34
star
6

world-peace

open union and open product types in Haskell
Haskell
32
star
7

testing-code-that-accesses-db-in-haskell

5 ways to test code that accesses a DB in Haskell
Haskell
30
star
8

post-about-nix-and-haskell

29
star
9

cabal2nixWithoutIFD

PureScript
29
star
10

purescript2nix

Tool for easily building PureScript projects with Nix
Nix
17
star
11

purescript-email-validate

Validating an email address string against RFC 5322
PureScript
17
star
12

servant-rawm

Effectful Raw handler for Servant servers.
Haskell
16
star
13

haskell-type-families-presentation

This is a presentation about haskell's type families.
JavaScript
15
star
14

nix-reverse-deps-of-haskell-package

Find or build all reverse dependencies of a Haskell package using Nix
Nix
14
star
15

servant-static-th

Embed a directory of static files in your application and serve them from your Servant server
Haskell
14
star
16

break-time

break timer that forces you to take a break
Rust
13
star
17

nix-haskell-updates-status

Automatically-updated Hydra status of the `haskell-updates` branch in Nixpkgs
Shell
13
star
18

servant-on-heroku

Example app showing how to release a Haskell web app on Heroku
Haskell
9
star
19

print-console-colors

Print all the ANSI console colors for your terminal
Haskell
8
star
20

purescript-boxes

PureScript
7
star
21

yahoo-finance-api

Haskell wrapper for Yahoo Finance API
Haskell
7
star
22

purescript-road-to-react

PureScript translation of example JavaScript React app from https://www.roadtoreact.com/
PureScript
7
star
23

cps-vs-codensity-vs-reflection-without-remorse

Example code showing the difference between CPS, codensity, and reflection without remorse styles in Haskell
Haskell
6
star
24

nix-cabal-example-project

Nix
6
star
25

docs

My dot files.
Shell
6
star
26

xml-html-qq

QuasiQuoter for XML and HTML Documents
Haskell
5
star
27

emailaddress

Wrapper around email-validate adding new non-orphaned instances to EmailAddress
Haskell
5
star
28

highlight

command line tool for highlighting parts of files that match a regex
Haskell
5
star
29

heterocephalus-example

simple explanation on how to use -ddump-splices with stack
Haskell
5
star
30

geneticmidi

a java project to generate a chosen midi file using a genetic algorithm
Java
4
star
31

purenix-examples

Examples of common Nix things written in PureNix
Nix
4
star
32

open-blog-posts

Blog posts
4
star
33

from-sum

Canonical fromMaybeM and fromEitherM functions.
Haskell
4
star
34

envelope

Envelope type used to return responses from a JSON API for Haskell
Haskell
4
star
35

servant-example

Example servant project used to explain advanced Haskell features like type-level strings, type families, etc.
Haskell
3
star
36

advent-of-code

My solutions to various Advent of Code problems
Haskell
3
star
37

purescript-typesafe-localstorage

PureScript
3
star
38

read-env-var

Haskell library for safely reading environment variables
Haskell
3
star
39

icfp-tutorial-extensible-effects

Haskell
3
star
40

coq-playground

Coq
2
star
41

software-foundations

https://softwarefoundations.cis.upenn.edu/
HTML
2
star
42

advent-of-code2018

Advent of Code 2018 problems in Haskell. Archived and moved to https://github.com/cdepillabout/advent-of-code
Haskell
2
star
43

focuslist

A Haskell data structure for lists with a focus
Haskell
2
star
44

icfp-tutorial-generics

Haskell
2
star
45

dict-scrape

A web scraper that gets information from yahoo.co.jp's japanese dictionaries
Python
2
star
46

large-file-parser-ng

Parsing a large file with constant heap usage
Haskell
2
star
47

ssh

Ssh server/client in Haskell. Fork of http://hackage.haskell.org/package/ssh
Haskell
2
star
48

ctf

Notes about problems I could not solve from CTFs.
Haskell
1
star
49

large-file-parser

Haskell
1
star
50

singletons-doggy-test

Test code using Haskell's singletons library.
Haskell
1
star
51

haskell-meetup-2016-10-23

Haskell
1
star
52

accelerate-singleton-test

Haskell
1
star
53

purescript-community-presentation

lightning talk about the PureScript Community (in Japanese)
1
star
54

hn-markov-headlines

Create new headlines for hacker news using markov chains
Haskell
1
star
55

tempreader

Throw-away code demonstrating a little about the reader monad
Haskell
1
star
56

tohmato

online pomodoro timer in elm
JavaScript
1
star
57

oi-oi-oi

Haskell
1
star
58

coursera

solutions to coursera courses
MATLAB
1
star
59

haskell-uuid-test

Test creating uuids in Haskell.
Haskell
1
star
60

lenstestwhat

Haskell
1
star
61

udacity-scalable-microservices-with-kubernetes

Nix
1
star
62

mystreaming

Haskell
1
star
63

bash

Unofficial bash repository (since no official repository exists). This repo will not be kept up-to-date.
C
1
star
64

continuation-monad-test

This is just a test project for playing around with the continuation monad.
Haskell
1
star
65

haskell-backprop

Haskell
1
star
66

purescript-in-purescript

purescript compiler implemented in purescript
PureScript
1
star
67

free-monad-test

Some code to play around with testing free monads.
Haskell
1
star
68

coq-equivalence-not-congruence

Coq proof of an equivalence relation that is not congruent on the Imp language from Software Foundations
Coq
1
star
69

scary

Haskell
1
star
70

purescript-twitter-types

PureScript
1
star
71

hailgun-simple

Simple wrapper around the hailgun package.
Haskell
1
star
72

ddump-splices-test

Haskell
1
star
73

wwtw-haskell-solver

A solution to wibbly-wobbly-timey-wimey from the Defcon 23 (2015) prequalifiers. Not yet complete.
Haskell
1
star
74

ebstuff

Various projects using the eb library for accessing epwing dictionaries
C
1
star
75

recursion-schemes-test

This is just a small test of the haskell recursion-schemes library.
Haskell
1
star
76

ropasaurusrex

Solution for ropasaurusrex
Shell
1
star
77

twitter-app-only

Haskell
1
star
78

example-haskell-nix-flake

Nix
1
star
79

the-monad-reader-24-sample-code

Sample code from the Monad Reader Issue 24: https://themonadreader.files.wordpress.com/2015/08/issue24.pdf
Haskell
1
star
80

haskell-github-updater

This is a haskell cgi script that will automatically update a repo when hit with one of github's callbacks.
Haskell
1
star
81

anki-high-priority

Automatically mark facts as HighPriority in Anki decks
Python
1
star
82

port-purescript-package

Script to easily port a PureScript package to an alternative backend
Shell
1
star
83

frp

Haskell
1
star
84

free-monad-logger

Haskell
1
star
85

dependent-walrus

Haskell
1
star
86

reverse-engineering-lt

A lightening-talk about reverse engineering on Linux
CSS
1
star
87

purescript-words-lines

words, unwords, lines, and unlines functions for PureScript
PureScript
1
star
88

saabanto

Rust
1
star
89

haskell-git-too-many-cherry-picks

Checks which commits have been cherry-picked between branches.
Haskell
1
star
90

screenshot-to-clipboard

Utility for taking a screenshot and copying it to the clipboard
Haskell
1
star
91

codejam

Haskell
1
star
92

google-code-jam-twenty-seventeen

Haskell
1
star
93

xml-indexed-cursor

Indexed XML cursors similar to Text.XML.Cursor from xml-conduit
Haskell
1
star
94

math-stuff

Haskell
1
star
95

recursion-schemes-two

A small repository for playing around with recursion-schemes.
Haskell
1
star
96

codeiq-cyberdefence-reversing-challenge

Files for a reversing challenge from codeiq
Haskell
1
star
97

haskell-random-dice-test

Creates a test for the solution to the problem from here (Simulate a 7-sided die using only a 5-sided die): http://www.careercup.com/question?id=3043
Haskell
1
star
98

haskell-sqlitetest-error

Small repo to reproduce sqlite error
Haskell
1
star
99

brazile-web-scraper

web scraper for brazilian website
Haskell
1
star
100

example-static-haskell-nix

Example showing how to build a statically-linked Haskell executable with Nix and attach it to a GitHub Release
Nix
1
star