Owl.IO (Owl v0.1.0) View Source

A set of functions for handling IO with support of Owl.Data.t/0.

Link to this section 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.

Select multiple values from the given nonempty list.

Opens data in editor for editing.

Selects one item from the given nonempty list.

Link to this section Types

Specs

cast_input() ::
  (String.t() | nil ->
     {:ok, value :: any()} | {:error, reason :: String.Chars.t()})

Specs

confirm_option() :: {:message, Owl.Data.t()} | {:default, boolean()}

Specs

input_option() ::
  {:label, Owl.Data.t()}
  | {:cast, atom() | {atom(), Keyword.t()} | cast_input()}

Specs

multiselect_option() ::
  {:label, Owl.Data.t() | nil}
  | {:render_as, (any() -> Owl.Data.t())}
  | {:min, non_neg_integer() | nil}
  | {:max, non_neg_integer() | nil}

Specs

select_option() ::
  {:label, Owl.Data.t() | nil} | {:render_as, (any() -> Owl.Data.t())}

Link to this section Functions

Specs

columns() :: pos_integer() | nil

Returns a width of a terminal.

A wrapper around :io.columns/0, but returns nil if terminal is not found. This is useful for convinient falling back to other value using ||/2 operator.

Example

Owl.IO.columns() || 80

Specs

confirm([confirm_option()]) :: boolean()

Asks user to type a confirmation.

Valid inputs are y, Y, n, N and blank string. 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 to false.

Examples

Owl.IO.confirm()
#=> Are you sure? [yN] n
false

Owl.IO.confirm(message: Owl.Tag.new("Really?", :red), default: true)
#=> Really? [Yn]
true

Specs

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 to true if you want to make input invisible. Defaults to false.
  • :label - a text label. Defaults to nil (no label).
  • :optional - a boolean that sets whether value is optional. Defaults to false.
  • :cast - casts a value after reading it from stdio. 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 to nil (no lower bound).
        • :max - a maximum allowed value. Defaults to nil (no upper bound).
      • :string, options:
        • no options
    • an atom which is simply an alias to {atom(), []}

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]
Link to this function

multiselect(list, opts \\ [])

View Source

Specs

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.

Options

  • :label - a text label. Defaults to nil (no label).
  • :render_as - a function that renders given item. Defaults to Function.identity/1.
  • :min - a minimum output list length. Defaults to nil (no lower bound).
  • :max - a maximum output list length. Defaults to nil (no upper bound).

Example

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"]

Specs

open_in_editor(iodata()) :: String.t()

Opens 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. __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")
Link to this function

puts(device \\ :stdio, data)

View Source

Wrapper around IO.puts/2 that accepts Owl.Data.t/0

Example

Owl.IO.puts(["Hello ", Owl.Tag.new("world", :green)])
#=> Hello world
Link to this function

select(list, opts \\ [])

View Source

Specs

select([item, ...], [select_option()]) :: item when item: any()

Selects one item from the given nonempty list.

Returns value immediatelly if list contains only 1 element.

Options

  • :label - a text label. Defaults to nil (no label).
  • :render_as - a function that renders given item. Defaults to Function.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.Tag.new(name, :cyan), "\n  ", Owl.Tag.new(description, :light_black)]
  end
)
#=> 1. elixir
#=>      programming language
#=> 2. asdf
#=>      version manager
#=> 3. neovim
#=>      fork of vim
#=>
#=> > 3
%{description: "fork of vim", name: "neovim"}