An extremely tiny and simple wrapper around the awesome gum.
This is intended for babashka and JVM clojure and provides an idiomatic and data driven wrapper around the CLI tool.
- Gum should be installed
- Babashka or the Clojure JVM runtime, latest recommended
Add this to your bb.edn
or deps.edn
:
{:deps {io.github.lispyclouds/bblgum {:git/sha "1d4de3d49b84f64d1b71930fa1161f8d2622a4d9"}}}
Sample babashka usage:
$ bb -Sdeps '{:deps {io.github.lispyclouds/bblgum {:git/sha "1d4de3d49b84f64d1b71930fa1161f8d2622a4d9"}}}' \
-e "(require '[bblgum.core :as b]) (b/gum :input :placeholder \"User name:\")"
This follows the same section on the gum repo and all params should work verbatim.
Run gum <cmd> --help
to discover all the params and args.
This lib only has one public fn: bblgum.core/gum
.
gum
tries to closely mimic the usage of the CLI tool, so it works like (gum :COMMAND)
,
(gum :COMMAND [ARGS])
or (gum :COMMAND [ARGS] :OPTION VALUE :OPTION2 VALUE)
(require '[bblgum.core :as b])
Examples:
;; Command only:
(b/gum :file)
;; Command with args:
(b/gum :choose ["arg1" "arg2"])
;; Command with opts:
(b/gum :file :directory true)
;; Command with opts and args:
(b/gum :choose ["arg1" "arg2"] :header "Choose an option")
There are several special opts, that are handled by the library:
:in
: An input stream than can be passed to gum:as
: Coerce the output. Currently supports :bool, :ignored or defaults to a seq of strings:gum-path
: Path to the gum binary. Defaults togum
All other opts are passed to the CLI. Consult gum CMD --help
to see available options.
To pass flags like --directory
use :directory true
. Always use full names of the options.
Note: In the event of a name collision with a special opt and a command opt, use the low level API.
Example with special options:
(gum :table :in (clojure.java.io/input-stream f) :height 10)
(b/gum :choose ["foo" "bar" "baz"] :no-limit true)
{:status 0 :result ("foo" "baz")}
(b/gum :write)
(b/gum :filter :in (clojure.java.io/input-stream "flavours.txt"))
(b/gum :filter :in (clojure.java.io/input-stream "flavours.txt") :no-limit true)
;; Since bblgum uses babashka/process, the following are possible as well
(b/gum :filter :in "a string that will be streamed into the stdin char by char")
(b/gum :filter :in (clojure.string/join "\n" ["can" "be" "used" "as" "a" "filtering" "choose" "alternative"]))
(b/gum :confirm :as :bool)
(b/gum :file ["src"])
(b/gum :pager :as :ignored :in (clojure.java.io/input-stream "README.md"))
(b/gum :spin ["sleep" "5"] :spinner "line" :title "Buying Bubble Gum...")
(b/gum :table :in (clojure.java.io/input-stream "flavours.csv"))
All of the rest of the options and usecases should work ™. Please raise issues/PRs for any improvements. Much appreciated!
- Since this uses gum which expects an interactive TTY like terminal, this is not possible to be used from editor REPLs like Conjure, CIDER, Calva etc when jacked-in.
To use this from an editor REPL:
- First start the REPL in a terminal, for example in bb for nREPL on port 1667:
bb nrepl-server 1667
. - Connect to the port from the editor of your choice, for example with neovim and conjure:
:ConjureConnect 1667
. - Perform the usual REPL interactions and all the gum output would appear on the terminal and not your editor but the result should be on the editor as expected.
- First start the REPL in a terminal, for example in bb for nREPL on port 1667:
This was standard in previous versions of gum, we kept it for full backward compatibility.
Convention:
- The main command should be passed as a keyword or string to
:cmd
. Required - Passing opts:
- The --opts are to be passed as
:opts
- Use the full forms of the opts:
--spinner
not-s
- Seqs can be passed to opts taking multiple params as well
- Pass boolean flags like
--password
as{:password true}
- The --opts are to be passed as
- All positional args to be passed as
:args
. - An input stream can be passed to
:in
. Useful for commands like filter - Corece the output:
- Override the default gum path of
gum
by passing it via:gum-path
The gum
fn returns a map of exit status of calling gum and the result either as a seq of lines or coerced via :as
.
Exceptions are not thrown unless calling gum itself does, the status code is intended for programming for failures.
(b/gum {:cmd :choose
:opts {:no-limit true}
:args ["foo" "bar" "baz"]})
{:status 0 :result ("foo" "baz")}
Copyright © 2023- Rahul De.
Distributed under the MIT License. See LICENSE.