2
votes

I can move up and down the history with the respective arrow keys, but that is cumbersome with a large history, and CTRL-R doesn't seem to work.

Looked at Erlang's shell module and Elixir's IEx module documentation, but they don't mention anything about this. The latter at least tells how to enable it:

It is possible to get shell history by passing some options that enable it in the VM. This can be done on a per-need basis when starting IEx:

iex --erl "-kernel shell_history enabled"

If you would rather enable it on your system as a whole, you can use the ERL_AFLAGS environment variable and make sure that it is set accordingly on your terminal/shell configuration.

On Unix-like / Bash:

export ERL_AFLAGS="-kernel shell_history enabled"

On Windows:

set ERL_AFLAGS "-kernel shell_history enabled"

On Windows 10 / PowerShell:

$env:ERL_AFLAGS = "-kernel shell_history enabled"
2

2 Answers

3
votes

Quoting what is said in Erlang patches mailing list

Search mode can be entered by pressing ctrl-r. Enter terms and press ctrl-r again to search backwards, or ctrl-s to then search forward (if you terminal doesn't eat up that one).

Notably, the OP mentions ctrl-r is not working, and the linked message says the same about Windows environment. There seem to be some caveats to this function depending on the environment.

It is difficult to tell more about the OP's case, but FWIW, the function does work as described under macOS 10.14, iTerm2, and Elixir 1.10.4-otp-22.

2
votes

A quick and dirty solution:

  1. As history can be enabled via Erlang's kernel flags, found the following flags in the kernel docs:

    shell_history = enabled | disabled
    Specifies whether shell history should be logged to disk between usages of erl.

    shell_history_drop = [string()]
    Specific log lines that should not be persisted. For example ["q().", "init:stop()."] will allow to ignore commands that shut the node down. Defaults to [].

    shell_history_file_bytes = integer()
    how many bytes the shell should remember. By default, the value is set to 512kb, and the minimal value is 50kb.

    shell_history_path = string()
    Specifies where the shell history files will be stored. defaults to the user's cache directory as returned by filename:basedir(user_cache, "erlang-history").

  2. Looking up the shell history file's path in iex

    iex(27)> :filename.basedir(:user_cache, "erlang-history")             
    "/home/user/.cache/erlang-history"
    
  3. Using less in the system shell

    $ ll /home/user/.cache/erlang-history/
    total 100
    drwxr-xr-x  2 user users  4096 Aug 18 07:59 ./
    drwxr-xr-x 14 user users  4096 Aug  2 15:52 ../
    -rw-r--r--  1 user users 52415 Aug 10 08:13 erlang-shell-log.1
    -rw-r--r--  1 user users 29992 Aug 18 08:00 erlang-shell-log.2
    -rw-r--r--  1 user users    26 Aug 18 07:59 erlang-shell-log.idx
    -rw-r--r--  1 user users    13 Aug 18 07:59 erlang-shell-log.siz
    
    $ less /home/user/.cache/erlang-history/erlang-shell-log.1
    "/home/user/.cache/erlang-history/erlang-shell-log.1" may be a binary file.  
    See it anyway?
    # Hit y
    

I'm sure that there are more sophisticated ways, but didn't have time to explore them, and also couldn't find any projects that would specifically query the history from iex (or erl).