View Source Owl.IO (Owl v0.12.0)
A set of functions for handling IO with support of Owl.Data.t/0
.
Summary
Functions
Returns a width of a terminal.
Asks user to type a confirmation.
Reads a line from the stdio
and casts a value to the given type.
Wrapper around IO.inspect/3
with changed defaults.
Select multiple values from the given nonempty list.
Opens data
in editor for editing.
Wrapper around IO.puts/2
that accepts Owl.Data.t/0
.
Returns a height of a terminal.
Selects one item from the given nonempty list.
Types
@type cast_input() :: (String.t() | nil -> {:ok, value :: any()} | {:error, reason :: String.Chars.t()})
@type input_option() :: {:label, Owl.Data.t()} | {:cast, atom() | {atom(), Keyword.t()} | cast_input()} | {:optional, boolean()}
@type multiselect_option() :: {:label, Owl.Data.t() | nil} | {:render_as, (any() -> Owl.Data.t())} | {:min, non_neg_integer() | nil} | {:max, non_neg_integer() | nil}
@type select_option() :: {:label, Owl.Data.t() | nil} | {:render_as, (any() -> Owl.Data.t())}
Functions
@spec columns(IO.device()) :: pos_integer() | nil
Returns a width of a terminal.
A wrapper around :io.columns/1
, but returns nil
if terminal is not found.
This is useful for convenient falling back to other value using ||/2
operator.
Example
Owl.IO.columns() || 80
@spec confirm([confirm_option()]) :: boolean()
Asks user to type a confirmation.
Valid inputs are a blank string and values specified in :answers
option.
User will be asked to type a confirmation again on invalid input.
Options
:message
- typically a question about performing operation. Defaults to"Are you sure?"
.:default
- a value that is used when user responds with a blank string. Defaults tofalse
.:answers
- allows to specify alternative answers. Defaults to[true: {"y", ["yes"]}, false: {"n", ["no"]}]
.
Examples
Owl.IO.confirm()
#=> Are you sure? [yN] n
false
Owl.IO.confirm(message: Owl.Data.tag("Really?", :red), default: true)
#=> Really? [Yn]
true
Owl.IO.confirm(
message: Owl.Data.tag("Справді?", :red),
answers: [true: {"т", ["так", "y", "yes"]}, false: {"н", ["ні", "n", "no"]}]
)
#=> Справді? [тН] НІ
false
@spec input([input_option()]) :: any()
Reads a line from the stdio
and casts a value to the given type.
After reading a line from stdio
it will be automatically trimmed with String.trim/2
.
The end value will be returned when user types a valid value.
Options
:secret
- set totrue
if you want to make input invisible. Defaults tofalse
.:label
- a text label. Defaults tonil
(no label).:optional
- a boolean that sets whether value is optional. Defaults tofalse
.:cast
- casts a value after reading it fromstdio
. Defaults to:string
. Possible values:- an anonymous function with arity 1 that is described by
cast_input/0
- a pair with built-in type represented as atom and a keyword-list with options. Built-in types:
:integer
, options::min
- a minimum allowed value. Defaults tonil
(no lower bound).:max
- a maximum allowed value. Defaults tonil
(no upper bound).
:string
, options:- no options
- an atom which is simply an alias to
{atom(), []}
- an anonymous function with arity 1 that is described by
Examples
Owl.IO.input()
#=> > hello world
"hello world"
Owl.IO.input(secret: true)
#=> >
"password"
Owl.IO.input(optional: true)
#=> >
nil
Owl.IO.input(label: "Your age", cast: {:integer, min: 18, max: 100})
#=> Your age
#=> > 12
#=> must be greater than or equal to 18
#=> Your age
#=> > 102
#=> must be less than or equal to 100
#=> Your age
#=> > 18
18
Owl.IO.input(label: "Birth date in ISO 8601 format:", cast: &Date.from_iso8601/1)
#=> Birth date in ISO 8601 format:
#=> > 1 January
#=> invalid_format
#=> Birth date in ISO 8601 format:
#=> > 2021-01-01
~D[2021-01-01]
Wrapper around IO.inspect/3
with changed defaults.
As in puts/2
, device
argument is moved to the end.
Options are the same as for IO.inspect/3
with small changes:
:pretty
istrue
by default.:syntax_colors
uses color schema fromIEx
by default.:label
is extended and acceptsOwl.Data.t/0
.
Examples
"Hello"
|> Owl.IO.inspect(label: "Greeting")
|> String.upcase()
|> Owl.IO.inspect(label: Owl.Data.tag("GREETING", :cyan))
#=> Greeting: "Hello"
#=> GREETING: "HELLO"
# inspect data above rendered live blocks
Owl.IO.inspect("Hello", [], Owl.LiveScreen)
#=> "Hello"
@spec multiselect([item, ...], [multiselect_option()]) :: [item] when item: any()
Select multiple values from the given nonempty list.
Input item numbers must be separated by any non-digit character. Most likely you'd want to use spaces or commas. It is possible to specify a range of numbers using hyphen.
Options
:label
- a text label. Defaults tonil
(no label).:render_as
- a function that renders given item. Defaults toFunction.identity/1
.:min
- a minimum output list length. Defaults tonil
(no lower bound).:max
- a maximum output list length. Defaults tonil
(no upper bound).
Examples
Owl.IO.multiselect(["one", "two", "three"], min: 2, label: "Select 2 numbers:", render_as: &String.upcase/1)
#=> 1. ONE
#=> 2. TWO
#=> 3. THREE
#=>
#=> Select 2 numbers:
#=> > 1
#=> the number of elements must be greater than or equal to 2
#=> Select 2 numbers:
#=> > 1 3
#=>
["one", "three"]
Owl.IO.multiselect(Enum.to_list(1..5), render_as: &to_string/1)
#=> 1. 1
#=> 2. 2
#=> 3. 3
#=> 4. 4
#=> 5. 5
#=>
#=> > 1-3 5
#=>
[1, 2, 3, 5]
open_in_editor(data, elixir_editor \\ System.fetch_env!("ELIXIR_EDITOR"))
View SourceOpens data
in editor for editing.
Returns updated data when file is saved and editor is closed.
Similarly to IEx.Helpers.open/1
, this function uses ELIXIR_EDITOR
environment variable by default.
__FILE__
notation is supported as well.
Example
# use neovim in alacritty terminal emulator as an editor
$ export ELIXIR_EDITOR="alacritty -e nvim"
# open editor from Elixir code
Owl.IO.open_in_editor("hello\nworld")
# specify editor explicitly
Owl.IO.open_in_editor("hello\nworld", "alacritty -e nvim")
@spec puts(Owl.Data.t(), device :: IO.device()) :: :ok
Wrapper around IO.puts/2
that accepts Owl.Data.t/0
.
The other difference is that device
argument is moved to second argument.
Examples
Owl.IO.puts(["Hello ", Owl.Data.tag("world", :green)])
#=> Hello world
# specify Owl.LiveScreen as a device in order to print data above rendered live blocks
Owl.IO.puts(["Hello ", Owl.Data.tag("world", :green)], Owl.LiveScreen)
#=> Hello world
@spec rows(IO.device()) :: pos_integer() | nil
Returns a height of a terminal.
A wrapper around :io.rows/1
, but returns nil
if terminal is not found.
This is useful for convenient falling back to other value using ||/2
operator.
Example
Owl.IO.rows() || 20
@spec select([item, ...], [select_option()]) :: item when item: any()
Selects one item from the given nonempty list.
Returns value immediately if list contains only 1 element.
Options
:label
- a text label. Defaults tonil
(no label).:render_as
- a function that renders given item. Defaults toFunction.identity/1
.
Examples
Owl.IO.select(["one", "two", "three"])
#=> 1. one
#=> 2. two
#=> 3. three
#=>
#=> > 1
#=>
"one"
~D[2001-01-01]
|> Date.range(~D[2001-01-03])
|> Enum.to_list()
|> Owl.IO.select(render_as: &Date.to_iso8601/1, label: "Please select a date")
#=> 1. 2001-01-01
#=> 2. 2001-01-02
#=> 3. 2001-01-03
#=>
#=> Please select a date
#=> > 2
#=>
~D[2001-01-02]
packages = [
%{name: "elixir", description: "programming language"},
%{name: "asdf", description: "version manager"},
%{name: "neovim", description: "fork of vim"}
]
Owl.IO.select(packages,
render_as: fn %{name: name, description: description} ->
[Owl.Data.tag(name, :cyan), "\n ", Owl.Data.tag(description, :light_black)]
end
)
#=> 1. elixir
#=> programming language
#=> 2. asdf
#=> version manager
#=> 3. neovim
#=> fork of vim
#=>
#=> > 3
#=>
%{description: "fork of vim", name: "neovim"}