History (IEx History v4.2.0)

Saves shell history and optionally variable bindings between shell sessions.

Allows the user to display history, and re-issue historic commands, made much easier since the variable bindings are saved.

For ease History can be enabled in ~/.iex.exs for example:

Code.append_path("~/github/history/_build/dev/lib/iex_history/ebin")
History.initialize(history_limit: 200, scope: :local, show_date: true, colors: [index: :red])

Of course Code.append_path may not be required depending on how the project is imported.

The following options can be set:

[
  scope: :local,
  history_limit: :infinity,
  hide_history_commands: true,
  prepend_identifiers: true,
  command_display_width: int,
  save_invalid_results: false,
  key_buffer_history: true,
  show_date: true,
  save_bindings: true,
  colors: [
    index: :red,
    date: :green,
    command: :yellow,
    label: :red,
    variable: :green
  ]
]

:hide_history_commands This will prevent all calls to History.* from been saved.

NOTE: History.x/1 is always hidden. Scope of :global will only hide them from output, otherwise they will not be saved.

:save_invalid_results If set to false, the default, commands that were evaluated incorrectly will not be saved.

:key_buffer_history If set to true will allow the user to scroll up (ctrl+u) or down (ctrl+k) through history. Unlike the standard up/down arrow history this is command based not line based. So pasting of a large structure will only require 1 up or down. This mechanism also saves commands that were not properly evaluated; however there is a buffer limit of 75 lines, although this can be changed by updating @history_buffer_size in events_server.ex. This will also not duplicate back to back identical commands.

:prepend_identifiers If this is enabled it will prepend identifiers when a call to x = History(val) is issued.

For example:

enabled:
    iex> time = Time.utc_now().second
    14
    iex> new_time = History.x(1)
    22

    iex> new_time
    22                  # New time is assigned to variable time
    iex> time
    13                  # However, the original date variable is unchanged

    iex> History.h()
    1: 2021-09-01 17:13:13: time = Time.utc_now().second
    2: 2021-09-01 17:13:22: new_time =  time = Time.utc_now().second    # We see the binding to new_time

  disabled:
    iex> time = Time.utc_now().second
    43
    iex> new_time = History.x(1)
    50

    iex> new_time       # New time is assigned to variable time
    50
    iex> time
    50                  # However, this time the original time variable has also changed

    iex> History.h
    1: 2021-09-01 17:17:43: time = Time.utc_now().second
    2: 2021-09-01 17:17:50: time = Time.utc_now().second      # We do not see the binding to new_time

scope can be one of :local, :globalor a node name

If scope is :local (the default) history will be active on all shells, even those that are remotely connected, but the history for each shell will be unique

If scope is node() (e.g. :mgr@localhost) history will only be active on that shell

If scope is :global history will be shared between all shells. However the saving of variable bindings will be disabled along with the date/time in history

Furthermore, if a scope of :global is selected following kernel option must be set, either directly as VM options or via an environment variable:

export ERL_AFLAGS="-kernel shell_history enabled"

--erl "-kernel shell_history enabled"

A word about aliases. Rather than using something like alias History, as: H, please use History.alias(H) instead.

Link to this section Summary

Functions

If you want to setup an alias like alias History, as: H rather than using alias/2 from the shell, please use this function instead. So to create an alias of H use History.alias(H). This allows aliased functions to be handled correctly.

Copies the command at index 'i' and pastes it to the shell

Clears the history and bindings. If scope is :global the IEx session needs restarting for the changes to take effect.

Clears the bindings.

Clears the history only. If scope is :global the IEx session needs restarting for the changes to take effect. If a value is passed it will clear that many history entries from start, otherwise the entire history is cleared.

Displays the current configuration.

Allows the following options to be changed, but not saved

Displays the default configuration.

Returns the current shell bindings.

h()

Displays the entire history.

If the argument is a string it displays the history that contain or match entirely the passed argument. If the argument is a positive integer it displays the command at that index. If the argument is a negative number it displays the history that many items from the end.

Specify a range, the atoms :start and :stop can also be used.

Initializes the History app. Takes the following parameters

Returns true or false depending on if history is enabled.

Loads the current configuration to file History.save_config().

Saves the current configuration to file.

Displays the current state

Clears the history and bindings then stops the service. If `scope` is ` :global` the IEx session needs restarting for the changes to take effect.

Unbinds a variable or list of variables (specify variables as atoms, e.g. foo becomes :foo).

Invokes the command at index 'i'.

Link to this section Functions

If you want to setup an alias like alias History, as: H rather than using alias/2 from the shell, please use this function instead. So to create an alias of H use History.alias(H). This allows aliased functions to be handled correctly.

Copies the command at index 'i' and pastes it to the shell

Clears the history and bindings. If scope is :global the IEx session needs restarting for the changes to take effect.

Link to this function

clear_bindings()

Clears the bindings.

Link to this function

clear_history(val \\ :all)

Clears the history only. If scope is :global the IEx session needs restarting for the changes to take effect. If a value is passed it will clear that many history entries from start, otherwise the entire history is cleared.

Link to this function

configuration()

Displays the current configuration.

Link to this function

configure(kry, val)

@spec configure(Atom.t(), any()) :: atom()

Allows the following options to be changed, but not saved:

:show_date
:history_limit
:hide_history_commands,
:prepend_identifiers,
:save_bindings,
:command_display_width,
:save_invalid_results,
:key_buffer_history,
:colors

Examples:

History.configure(:colors, [index: :blue])
History.configure(:prepend_identifiers, true)
Link to this function

default_config()

Displays the default configuration.

Returns the current shell bindings.

Displays the entire history.

@spec h(String.t() | integer()) :: atom()

If the argument is a string it displays the history that contain or match entirely the passed argument. If the argument is a positive integer it displays the command at that index. If the argument is a negative number it displays the history that many items from the end.

Specify a range, the atoms :start and :stop can also be used.

Link to this function

initialize(config_or_filename \\ [])

Initializes the History app. Takes the following parameters:

[
  scope: :local,
  history_limit: :infinity,
  hide_history_commands: true,
  prepend_identifiers: true,
  key_buffer_history: true,
  command_display_width: :int,
  save_invalid_results: false,
  show_date: true,
  save_bindings: true,
  colors: [
    index: :red,
    date: :green,
    command: :yellow,
    label: :red,
    variable: :green
  ]
]

Alternatively a filename can be given that was saved with History.save_config()

scope can be one of :local, :global or a node() name

Returns true or false depending on if history is enabled.

Link to this function

load_config(filename)

Loads the current configuration to file History.save_config().

NOTE: Not all options can be set during run-time. Instead pass the filename as a single argument to History.initialize()

Link to this function

save_config(filename)

Saves the current configuration to file.

Displays the current state:

History version 2.0 is enabled:
  Current history is 199 commands in size.
  Current bindings are 153 variables in size.
Clears the history and bindings then stops the service. If `scope` is ` :global` the IEx session needs restarting for the changes to take effect.

Unbinds a variable or list of variables (specify variables as atoms, e.g. foo becomes :foo).

Invokes the command at index 'i'.