Tab is a little program that turns Clojure data structures into tables.
Tab's primary aim is to help Clojure programmers make sense of data.
Most interesting Clojure values are maps or seqs of maps. When small, pretty-printing is an adequate tool for inspecting such values. When they get to medium size (like, say, your typical Ring request map), you're better off reaching for something else.
Tab aims to be that something else.
- Tab only shows you one value at a time.
- Tab datafies (via
clojure.datafy/datafy
) values you give it. - Tab aims to be useful without forcing you to choose between different viewers (table, tree, etc).
- Tab has no dependencies.
Given that you have the Clojure CLI installed, on the command line, run:
clj -Sdeps '{:deps {io.github.eerohele/tab {:git/tag "2024-09-27.371", :git/sha "c5d51f4"}}}'
Then, in the REPL:
user=> (require 'tab.auto)
Tab is listening on http://localhost:57426
nil
user=> (tap> BigInteger)
true
Then, bask in the glory of the table that appears in your browser. If a tabulated BigInteger
doesn't do it for you, there are more examples available.
Note In general, you'll probably want to use
tab.api
instead oftab.auto
. The only purpose of thetab.auto
namespace is to make it as easy as possible to run a Tab.
See the user manual for instructions of use.
To stop Tab:
user=> (tab.auto/halt)
The tab.auto
namespace is the easiest way to run Tab. The tab.api
namespace exposes the API proper.
Most importantly, there's tab.api/run
and tab.api/halt
:
user=> (require '[tab.api :as tab])
nil
;; - Run a Tab in port 1234
;; - Don't open a browser by default.
;; - Set print length to 8
;; - Set print level to 2
user=> (def tab (tab/run :port 1234 :browse? false :print-length 8 :print-level 2))
#'user/tab
user=> (tab/halt tab)
nil
See also:
user=> (require '[tab.api :as tab])
nil
user=> (doc tab/run)
...
user=> (doc tab/tab>)
...
user=> (doc tab/address)
...
user=> (doc tab/halt)
...
Only tab.api
and tab.auto
are part of Tab's public API. All other namespaces are internal and subject to change.
- Click
-
to collapse a node. - Click
+
to expand a node. - Press Alt and click
-
or+
to expand or collapse all nodes underneath a node. - Click a table header (e.g.
ARRAY MAP
) to zoom in on that table. - Press Alt and click a table header (e.g.
ARRAY MAP
) to copy the value backing that table to your clipboard. - Click opaque objects (
#object[...]
) to view datafied versions of them (provided that they implementclojure.core.protocols/Datafiable
). - Click the text that says
$N vals
in the footer to empty Tab's in-memory database (and release values for garbage collection). - Use the buttons in the footer to go to the next/previous value.
- Click the lightning icon in the footer to pause or resume page updates.
For more examples on what Tab can do, see repl/demo/intro.repl
.
- Can make tables.
- Zero dependencies, apart from Clojure itself.
- Prefers operating system theme (light or dark mode).
- Can only make tables.
- Will blow up if you expand an infinite seq of scalars in a table cell with an ellipsis.
- You might be able to have Tab do a denial-of-service attack on itself if you Alt-click a node with many children.
- Requires a modern browser to look good. If your browser supports
backdrop-filter
, you should be good. - Might not work with Clojure versions older than 1.10.2.
- Untested on Windows.
:browse? true
reportedly has no effect on Windows Subsystem for Linux 2, at least.
- Gregoire, Daniel. (2018, November 30). Tables Considered Helpful (Clojure/conj 2018).
- My previous employer, for graciously sponsoring the development of this tool.
- Nikita Prokopov, for the Alabaster Color Scheme.
- Pedro Girardi, for alpha testing and improvement ideas.