Is there an easy way to get at the history of REPL input?


#1

How does one get easily at the history of the input provided at the prompt?
The *nix shell has a function history which spits out numbered list of commands.
Is there something like this in Julia?


#2

Do you know this?

$ less ~/.julia_history

#3

Thanks for the suggestion. However:

/home/pkrysl/.julia_history: No such file or directory

Is it perhaps in a different folder based on the version?


#4

I have also this:

less ~/.julia/logs/repl_history.jl

It is interesting julia_history’s last command is (edit:) one day one month older than repl_history’s…

So maybe it is actual one?


#5

The location of the history file moved in 0.7, thus ~/.julia_history.jl is for versions 0.6 and prior, whereas ~/.julia/logs/repl_history.jl is for 0.7+. Apparently you last used version 0.6 a month ago.


#6

I think this will serve nicely: REPL.find_hist_file(). Then all that is required is a little macro (or function) to spit out the contents of the history file… Perhaps like this, except a lot more succinct:

InteractiveUtils.less(REPL.find_hist_file())

Maybe this?

macro history() InteractiveUtils.less(REPL.find_hist_file()); end

#7

I again tried to do something easy with Julia and it seems I am not very compatible with this language yet. :frowning:

This is just ugly (but it seems to work).

For examle I was impatient and used PyCall to implement findall function so you need to have PyCall installed.

I did not test it thoroughly so take it just as … (inspiration? I am not sure :stuck_out_tongue: ) !!

julia> macro history2(a)
       run(pipeline(```$(Sys.BINDIR)/julia -e """import PyCall
         re = PyCall.pyimport(\"re\")
         open(\"$(REPL.find_hist_file())\") do f
          data = read(f)
          aa = re[:findall]( \"(^\\\\# time.*?)(?=# time)\", String(data), re[:S] | re[:M])
          for i in aa 
            if match(Regex(\"$(a)\"), 
               i[findfirst(r\".*?\n.*?\n\", i).stop+1:end]  # ignore first two lines
               ) != nothing
               println(i)
            end
          end 
         end"""```, `less -`));
       end

You could try

julia> @history2 som.thing;  # this regex work

julia> @history2 som.*thing;  # this regex doesn't work! 

julia> @history2 "som.*thing";  # this regex work

julia> @history2 "(?i)pager";  # case insensitive example

Another warning: I used less - instead of something like InteractiveUtils.shell_split(get(ENV, "PAGER", "less")) because I am not sure if other pagers could work with output redirection and I don’t know how to nicely check this functionality…

It would be better to split it into two functionalities 1-searcher for “elements” 2-macro for pushing string (vector of strings) into “less”. But I spent too much time to this “self-homework”…


#8

I tried a simpler way of searching the history file.

open(raw"C:\\Users\chatura\\.julia\\logs\\repl_history.jl") do file
    for ln in eachline(file)
#         if endswith(ln, "jl")==true
        if occursin(r"(CSV)", ln) ==true   
            println("$(length(ln)), $(ln)")
        end
    end
end

#9

#10

Wouldn’t opening in the editor, eg with

edit(REPL.find_hist_file())

be just as convenient?


#11

But the user needs to find the way to properly write all that sentence or remember it.


#12

I have that set up as a key binding in Sublime Text (and a voice command). Similar device would work in VS Code and elsewhere.