phronmophobic / membrane.term

A terminal emulator in pure clojure
Eclipse Public License 1.0
53 stars 1 forks source link
clojure membrane terminal

membrane.term

cljdoc clojurians slack clojars

A simple terminal emulator in clojure. Built with membrane.

Rationale

I thought it would be fun. There's not much code. All of the ANSI parsing work is done by asciinema/vt. membrane.term is just small UI on top.

Some reasons to use membrane.term:

Status

Pre 1.0 release. APIs and behavior are subject to change.

Installation

Membrane.term works on macOS and Linux operating systems.

To invoke via clj -M:membrane.term add the following alias to your deps.edn:

{:aliases
 {:membrane.term
  {:replace-deps
   {com.phronemophobic/membrane.term {:git/url "https://github.com/phronmophobic/membrane.term.git"
                                      :git/sha "7b973adc4910729042736d8a84e5fce4f4f43722"}
    ;; the next 2 optional deps appease pty4j which does some logging
    ;; change nop to simple if you'd actually like to see the log lines
    org.slf4j/log4j-over-slf4j {:mvn/version "1.7.32"}
    org.slf4j/slf4j-nop {:mvn/version "1.7.32"}}
   :main-opts ["-m" "com.phronemophobic.membrane.term.main"]}}
 :mvn/repos
 ;; pty4j is currently only available from the jetbrains maven repo
 {"jetbrains-intellij-dependencies" {:url "https://packages.jetbrains.team/maven/p/ij/intellij-dependencies"}}}

Command Line Usage

For usage help run:

clj -M:membrane.term --help

Run an interactive GUI terminal

clj -M:membrane.term run-term

A demo of the types of things you can do:

run-term-demo

You can also optional specify:

Run a headless terminal and take a screenshot

Play a script in a headless terminal and write an image to terminal.png.

Given play script play-msgcat.sh:

# override prompt to something doc-friendly
export PS1="$ "
# print out some  colors
clear
msgcat --color=test | head -11

If we run:

clj -M:membrane.term screenshot --play play-msgcat.sh --height 14

Membrane.term passes the script to the terminal character by character, then writes a screenshot to terminal.png:

play-msgcat-example

You must specify:

You can also optionally specify:

Given play script play-deep-diff.sh:

# our setup
export PS1="$ "
cd
mkdir -p target/term-screenshot
cd target/term-screenshot
echo '{:deps {lambdaisland/deep-diff2 {:mvn/version "2.0.108"}}}' > deps.edn
# we clear to wipe setup output
clear
clojure
(require '[lambdaisland.deep-diff2 :as ddiff])
(ddiff/pretty-print (ddiff/diff {:a 1 :b 2} {:a 1 :c 3}))

Let's increase the line delay to give the Clojure REPL a chance to start up before feeding it input. We'll also reduce the final delay, we just don't need 10 seconds for this one:

clj -M:membrane.term screenshot --play play-deep-diff.sh \
  --width 80 --height 9 \
  --final-delay 1000 --line-delay 3000 \
  --out deep-diff.jpg

Produces deep-diff.jpg:

play-deep-diff-example

Color Schemes

There are boatloads of terminal color schemes available at iTerm2-Color-Schemes. Review what you might like from their screenshots, then find the corresponding .itermcolors file under their schemes directory.

Use the --color-scheme option to specify an .itermcolors file, either from a copy you have downloaded:

clj -M:membrane.term run-term --width 90 --height 30 \
  ---color-scheme "Builtin Solarized Dark.itermcolors"

...or directly from the raw GitHub URL:

clj -M:membrane.term screenshot --play play-msgcat.sh --height 14 \
  --color-scheme "https://raw.githubusercontent.com/mbadolato/iTerm2-Color-Schemes/master/schemes/Builtin%20Solarized%20Dark.itermcolors"

The screenshot command produces terminal.png:

play-msgcat-scheme-example

Fonts

You can specify a font family and size. The font must be OS installed and is assumed to be monospace.

Let's pretend that, for whatever reason, you've fallen in love with the Nova Mono font, and have installed it on your system.

To use this font in an interactive membrane.term terminal, specify its installed name. Here we've opted for a point size of 16:

clj -M:membrane.term run-term --font-family "NovaMono" --font-size 16

The same options are available for screenshots:

clj -M:membrane.term screenshot --play play-msgcat.sh --height 14 \
  --font-family "NovaMono" --font-size 16

produces terminal.png:

play-msgcat-font-example

Toolkits

You can specify a toolkit. Available options are "java2d" (the default) and "skia".

Java2d

The java2d toolkit will use swing for windowing, graphics, and events.

Skia

The skia toolkit will use skia for graphics and glfw for windowing and events. Using the skia toolkit requires the following extra dependency:

M1 mac:

com.phronemophobic.membrane/skialib-macosx-aarch64 {:mvn/version "0.9.31.0-beta"}

Non-M1 mac:

com.phronemophobic.membrane/skialib-macosx-x86-64 {:mvn/version "0.9.31.0-beta"}

Linux

com.phronemophobic.membrane/skialib-linux-x86-64 {:mvn/version "0.9.31.0-beta"}

If running from the membrane.term project, you can use the :skia alias to add the dependency:

clojure -M:membrane.term:skia run-term --toolkit skia

Discuss

Questions? Comments? Connect with us on clojurians slack in #membrane-term (join here)

License

Copyright © 2021 Adrian Smith

Distributed under the Eclipse Public License version 1.0.