bblgum
bblgum copied to clipboard
An extremely tiny and simple wrapper around charmbracelet/gum
bblgum
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.
Requirements
- Gum should be installed
- Babashka or the Clojure JVM runtime, latest recommended
Usage
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:\")"
Interaction
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
.
Standard Usage
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)
Usage Examples
input
(b/gum :choose ["foo" "bar" "baz"] :no-limit true)
{:status 0 :result ("foo" "baz")}
write
(b/gum :write)
filter
(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"]))
confirm
(b/gum :confirm :as :bool)
file
(b/gum :file ["src"])
pager
(b/gum :pager :as :ignored :in (clojure.java.io/input-stream "README.md"))
spin
(b/gum :spin ["sleep" "5"] :spinner "line" :title "Buying Bubble Gum...")
table
(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!
Caveats
- 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:
Low-level API
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")}
License
Copyright © 2023- Rahul De.
Distributed under the MIT License. See LICENSE.