nhpip

nhpip

Hi,

https://github.com/nhpip/history

I wrote an initial version of this a month or 2 ago. I recently improved on it after I crashed my IEx shell at work.

Features:

1 Persist history
2 Persist the shell variable bindings (that get reloaded when you restart)
2 List history
3 Search history
4 Re-execute a command in history
5. Scoping rules
6. Update configuration

I probably broke some rules on how it was implemented, but it works for me. Feel free to play with it…Next on my list is to make it play better with the current IEx history.

Pics attached



Screen Shot 2021-09-01 at 3.55.48 PM

Display history

Showing Posts 1 to 10

nhpip

nhpip OP

Added a few improvements:

  1. Can set the max width when displaying output
  2. Copy/pasting now works
  3. If an operation in not correctly evaluated you have the option to not save it
Will-W

Will-W

Love a nice bit of code hacking.

Are you aware that you can do the following (in my case in .bashrc) and it will persist history?
export ERL_AFLAGS="-kernel shell_history enabled"

Between that and the normal readline shortcuts like ctrl+r I think most of what you’re looking for is built-in.

OTOH, if you’re building it for fun - nice work!

nhpip

nhpip OP

Thanks,

The problem withe ctrl+r is that it’s a line history, not a command history. So if, for example, you paste a large list, map or struct into the shell it renders it useless. I use the kernel flags too, but that’s a globally shared view which is fine in some cases, but not always (I also don’t think it includes date etc…plus I haven’t found a nice way to just show the history.

Still, as you said … it’s all for fun

nhpip

nhpip OP

OK, latest version:

https://github.com/nhpip/history

In addition to saving history and bindings, this version adds:

  1. Supports for aliasing the History module

  2. Copy/paste a command from history to the shell (so you can edit it)

  3. Use ctrl+u and ctrl+k to move up and down history. Unlike the standard history search with the arrow keys this is command not line based. So, for example:

Paste:

iex(1)> config = [
...(1)>   scope: :local,
...(1)>   history_limit: :infinity,
...(1)>   hide_history_commands: true,
...(1)>   prepend_identifiers: true,
...(1)>   key_buffer_history: true,
...(1)>   command_display_width: :int,
...(1)>   save_invalid_results: false,
...(1)>   show_date: true,
...(1)>   save_bindings: true,
...(1)>   colors: [
...(1)>     index: :red,
...(1)>     date: :green,
...(1)>     command: :yellow,
...(1)>     label: :red,
...(1)>     variable: :green
...(1)>   ]
...(1)> ]
[
  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
  ]
]

ctrl+u:

iex(2)> config = [ 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 ]]
nhpip

nhpip OP

OK, fixed a bad bug where it would not work on the latest version of Elixir.

dimitarvp

dimitarvp

Just now looked at this after I had it in my TODO things to check for 14 months. :smiley:

I am interested as to why are you recommending to use the dev build in your README?

Ideally we should just have a script that does something like mix do deps.get, release and then copies the final release to a well-known place and use it from there? Not sure. If you accept PRs I could look into it because I am very interested in nicer iex history, especially one that’s not line-bound but is working on complete statements that are valid Elixir code.

nhpip

nhpip OP

OMG please don’t let the code scare you, it was my first personal elixir project after over a decade of Erlang. As for the dev comment, a couple of guys from work tried it and I didn’t want (thinking of work) someone to add it to our product’s deps and pushing it to our AWS EC2 instances. I should probably edit the README. Feel free to do PRs if you want. I warn you that it does some weird back door stuff. One thing I like about it is ability to save shell variable bindings.

dimitarvp

dimitarvp

Well, 50/50, I am not sure yet I’d post PRs if you are not willing to further develop this and/or make it more current (or something).

But another question: any clue which exact Erlang module and function to use to browse history? Or is that only for Erlang and iex uses something differently? Looking at iex source code didn’t net any insights on a quick look.

nhpip

nhpip OP

I’m happy to continue to maintain it. Erlang uses the shell module and all history is saved via the disk_log module. However, the OTP team is re-writing a lot of the shell, so that may change. What I do is attach a trace to the iex shell’s iex_server process to capture and save events.

dimitarvp

dimitarvp

Tried to look into this in more detail. Is this the whole meat and potatoes of actually fetching the currently globally known shell history?

:rpc.call(:erlang.node(:erlang.group_leader()), :group_history, :load, [])

Or is there more to it? I executed this in my iex REPL and it seems to give me all history items indeed. Unfortunately it doesn’t merge multi-line expressions into one… :confused:

I am aware that the :shell and IEx.History modules allow you to have separate managed histories but I am only interested in the global one. Currently trying to find where exactly on disk is the global Erlang shell history preserved, to no avail so far. I can’t even find any mention of the group_history atom anywhere on erlang.org

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New

Other Trending Topics Top

marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews