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?
Do you know this?
$ less ~/.julia_history
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?
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?
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.
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
I again tried to do something easy with Julia and it seems I am not very compatible with this language yet.
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 ) !!
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”…
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
Wouldn’t opening in the editor, eg with
edit(REPL.find_hist_file())
be just as convenient?
But the user needs to find the way to properly write all that sentence or remember it.
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.
@Liso, it is reassuring that all of the history is found under ~/.julia/logs/repl_history.jl
But having an easy command for getting the history in a current session would still be highly desirable (see the %history command in ipython for an example).
Note that there is IJulia.history
as a replacement for python’s %history
. (This was one of my very first Julia related PRs ! )
Also you might want to take a look at https://github.com/crstnbr/SaveREPL.jl/blob/master/src/SaveREPL.jl which contains a bit of history access logic.
That is an awesome contribution!
Another way of looking at the history. I would like to be able to just grab the output and paste it into a script or into the command line.
An example is here:
julia> include(".\\REPLHistory.jl");
julia> a = rand(3)
3-element Array{Float64,1}:
0.7650591549676755
0.37080326489156024
0.2852039006568494
shell> pwd
/c/Users/PetrKrysl/Documents/Work-in-progress/Experiments
julia> b = deepcopy(a)
3-element Array{Float64,1}:
0.7650591549676755
0.37080326489156024
0.2852039006568494
julia> b[1] = 0
0
julia> @show b
b = [0.0, 0.37080326489156024, 0.2852039006568494]
3-element Array{Float64,1}:
0.0
0.37080326489156024
0.2852039006568494
julia> @history 7
a = rand(3)
;pwd
b = deepcopy(a)
b[1] = 0
@show b
julia>
This was produced with the following little module:
module REPLHistory
using InteractiveUtils
using REPL
export @history
macro history(n)
n = n - 1
list = [];
for l in reverse(readlines(REPL.find_hist_file()))[2:end]
l = strip(l)
if n != 0
(l[1] != '#') && (n = n - 1)
push!(list, l);
else
break
end
end
next = ""
for l in reverse(list)
l = next * l
if l == "# mode: shell"
next = ";"
else
printit = false
if (l[1] != '#')
if (length(l) >= 8)
if (l[1:8] != "@history")
printit = true
end
else
printit = true
end
end
printit && println(l)
next = ""
end
end
end
end
using .REPLHistory
Is it ok to use
Base.active_repl.mistate.current_mode.hist.history
to get the history?
Well, that’s cool!
That’s awesome; I wonder if a couple more things are possible:
- distinguishing commands in the different modes (normal, pkg, shell)
- separating out commands from different REPL sessions (the command you provided interleaves them)
PetrKryslUCSD/REPLHistory.jl: Gain access to the Julia REPL history. (github.com)
$ ~/AppData/Local/Programs/Julia-1.5.3/bin/julia.exe
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.5.3 (2020-11-09)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> using REPLHistory
shell> ls
'3D Objects'
AppData
'Application Data'
Contacts
Cookies
Documents
Downloads
Favorites
...
(@v1.5) pkg> status
Status `C:\Users\pkonl\.julia\environments\v1.5\Project.toml`
[a5566ce3] REPLHistory v0.1.0
julia> pwd()
"C:\\Users\\pkonl"
julia> print(history())
using REPLHistory
;ls
]status
pwd()
julia>
I wish I could have more confidence in Base.active_repl.mistate.current_mode.hist.history
, but it looks alarmingly “internal”.