IExHistory2 (IExHistory2 v5.0.0)
Saves shell history and 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.
IExHistory2 can be enabled in ~/.iex.exs
for example:
Code.append_path("~/github/iex_history2/_build/dev/lib/iex_history2/ebin")
IExHistory2.initialize(history_limit: 200, scope: :local, show_date: true, colors: [index: :red])
The application can, of course, be added as a dependency to mix.exs
functions
Functions
iex> hl() - list the entire history.
iex> hl(val) - list `val` entries from the start if val is positive, or from the end if negative.
iex> hl(start, stop) - list entries between `start` and `stop`.
iex> hs(string) - list entries that match all or part of the query string.
iex> hsi(string) - case insensitive list entries that match all or part of the query string.
iex> hsa(string) - closest match list of entries, e.g "acr.to_str" == "Macro.to_string"
iex> hx(pos) - execute the expression at position `pos`.
iex> hc(pos) - copy the expression at position pos to the shell.
iex> he(pos) - edit the expression in a text editor.
iex> hb() - show the current bindings.
iex> hi() - summary
NOTE: To use he/1
the environment variable VISUAL
must be set to point to the editor:
export VISUAL="vim"
special-functions
Special Functions
iex> IExHistory2.add_binding(var, val)
iex> IExHistory2.get_binding(var)
iex> IExHistory2.clear_history()
iex> IExHistory2.clear_bindings()
The functions IExHistory2.add_binding/2
and IExHistory2.get_binding/1
allows variables
to be set in a module that is invoked in the shell to be accessible in the shell.
navigation
Navigation
The application uses a different set of keys for navigation, and attempts to present multi-line terms and other items as a single line:
ctrl^u - move up through history.
ctrl^k - move down through history.
ctrl^e - allows the currently displayed item to be modified.
ctrl^w - opens the currently displayed item in an editor.
ctrl^[ - reset navigation, returns to the prompt.
configuration
Configuration
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 IExHistory2.*
from been 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 term or source code will only require 1 up or down key.
This mechanism also saves commands that were not properly evaluated; however there is a buffer limit of 150 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 = hx(val)
is issued.
For example:
enabled:
iex> time = Time.utc_now().second
14
iex> new_time = hx(1)
22
iex> new_time
22 # New time is assigned to variable time
iex> time
13 # However, the original date variable is unchanged
iex> hl()
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 = hx(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> hl()
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, :global
or 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"
Link to this section Summary
Functions
This helper function can be used when testing code (for example a module pasted into the shell). It allows a variable to be set that will become available in the shell. For example
Experimental. Same as add_binding/2
, but name
is the registered name of a shell pid.
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.
This helper function can be used when testing code (for example a module pasted into the shell). It allows a variable that is set in the shell to be available in a module under test. For example
Experimental. Same as get_binding/2
, but name
is the registered name of a shell pid.
Returns the current shell bindings.
Show the variable bindings.
Copies the command at index 'i' and pastes it to the shell.
Show history information summary.
Displays the entire history.
Displays the entire history from the most recent entry back (negative number), or from the oldest entry forward (positive number)
Specify a range, the atoms :start and :stop can also be used.
Returns the list of expressions where all or part of the string matches.
Like hsa/1
a case insensitive search, but also adds a closeness element to the search.
A case insensitive search the list of expressions where all or part of the string matches.
Invokes the command at index 'i'.
Initializes the IExHistory2 app. Takes the following parameters
Returns true
or false
depending on if history is enabled.
Loads the current configuration to file IExHistory2.save_config()
.
Registers the shell under the name provided.
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).
Link to this section Functions
add_binding(var, value)
This helper function can be used when testing code (for example a module pasted into the shell). It allows a variable to be set that will become available in the shell. For example:
defmodule VarTest do
def set_me(var) do
var = var * 2
IExHistory2.add_binding(:test_var, var)
var + 100
end
end
iex> VarTest.set_me(7)
iex> test_var
14
The variable can be represented as an atom or string.
add_binding(var, value, name)
Experimental. Same as add_binding/2
, but name
is the registered name of a shell pid.
See register/1
clear()
Clears the history and bindings. If scope
is :global
the IEx session needs restarting for the changes to take effect.
clear_bindings()
Clears the bindings.
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.
configuration()
Displays the current configuration.
configure(kry, val)
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:
IExHistory2.configure(:colors, [index: :blue])
IExHistory2.configure(:prepend_identifiers, true)
default_config()
Displays the default configuration.
get_binding(var)
This helper function can be used when testing code (for example a module pasted into the shell). It allows a variable that is set in the shell to be available in a module under test. For example:
defmodule VarTest do
def get_me(val) do
if IExHistory2.get_binding(:path_to_use) == :path1 do
val + 100
else
val + 200
end
end
end
iex> path_to_use = :path1
:path1
iex> VarTest.get_me(50)
150
iex> path_to_use = :path2
:path2
iex> VarTest.get_me(50)
250
The variable can be represented as an atom or string.
get_binding(var, name)
Experimental. Same as get_binding/2
, but name
is the registered name of a shell pid.
See register/1
get_bindings()
Returns the current shell bindings.
Show the variable bindings.
hc(i)
Copies the command at index 'i' and pastes it to the shell.
he(i)
Show history information summary.
Displays the entire history.
hl(val)
@spec hl(integer()) :: nil
Displays the entire history from the most recent entry back (negative number), or from the oldest entry forward (positive number)
hl(start, stop)
Specify a range, the atoms :start and :stop can also be used.
hs(match)
@spec hs(String.t()) :: nil
Returns the list of expressions where all or part of the string matches.
The original expression does not need to be a string.
hsa(match, closeness \\ 80)
Like hsa/1
a case insensitive search, but also adds a closeness element to the search.
It uses a combination of Myers Difference and Jaro Distance to get close to a match. The estimated closeness is indicated in the result with a default range of > 80%. This can be set by the user.
For large histories this command may take several seconds.
The original expression does not need to be a string.
hsi(match)
@spec hsi(String.t()) :: nil
A case insensitive search the list of expressions where all or part of the string matches.
The original expression does not need to be a string.
hx(i)
Invokes the command at index 'i'.
initialize(config_or_filename \\ [])
Initializes the IExHistory2 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,
import: 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 IExHistory2.save_config()
scope
can be one of :local, :global
or a node()
name
is_enabled?()
Returns true
or false
depending on if history is enabled.
load_config(filename)
Loads the current configuration to file IExHistory2.save_config()
.
NOTE: Not all options can be set during run-time. Instead pass the filename as a single argument to IExHistory2.initialize()
register(name)
@spec register(atom()) :: :ok
Registers the shell under the name provided.
save_config(filename)
Saves the current configuration to file.
state()
Displays the current state:
IExHistory2 version 2.0 is enabled:
Current history is 199 commands in size.
Current bindings are 153 variables in size.
stop_clear()
Clears the history and bindings then stops the service. If scope
is :global
the IEx session needs restarting for the changes to take effect.
unbind(vars)
Unbinds a variable or list of variables (specify variables as atoms, e.g. foo becomes :foo).