Changing the REPL prompt from startup file


#1

I know it’s currently possible to change the REPL prompt. The relevant mystic runes are:

julia> Base.active_repl.interface.modes[1].prompt="v$VERSION> "
"v0.5.0> "
v0.5.0> 

But I’d like to add this to the .juliarc.jl startup file, so that it automatically picks up the correct version. I think there’s something like an atreplinit() function, but I’ve not managed to get it working…

I’m currently switching between v0.4, v0.5, and v0.6, so I think this might be quite useful.


#2

It is your lucky day: https://asciinema.org/a/99fjbusj6yzgmrgw4bx8rp6be

Feel free to guinea pig: https://github.com/KristofferC/OhMyREPL.jl/pull/51

Edit: Seems like there are still some troubles putting it in the .juliarc.jl file. Will fix it.


#3

Looks pretty cool! (I love to primp my working environment…) Is it registered?


#4

Nah, I’m overwriting methods in Base left and write and the number of tests are not so good… Don’t think it would hold up to the METADATA scrutiny.

I got it working in .juliarc.jl on 0.5 but 0.6 is still a bit tricky.

The reason why you can’t just do it inside atreplinitis because the .interface field (the different prompts) are not loaded yet at that point.


#5

Yes, I see what you mean.

Currently I’m doing this in the .juliarc.jl file:

@spawn @sync begin
    sleep(5)
    Base.active_repl.interface.modes[1].prompt="v$VERSION> "
end

It’s the only way I can currently think of to evaluate the expression after the REPL starts running. There should be an easier way, though…


#6

That’s a nice workaround.


#7

Nice!

I’ve been experimenting with using powershell for shell mode on Windows, and can adapt this using modes[2] to display prompt powershell>.

But not really sure what @sync is doing. I don’t think you need or want this.


#8

So the sneaky thing to do is to put something like this:

if !isdefined(repl,:interface)
    repl.interface = Base.REPL.setup_interface(repl)
end

in the atreplinit function. Then you create the interface yourself and you can then access the prompts. Found it by looking at https://github.com/Keno/TerminalExtensions.jl/blob/master/src/TerminalExtensions.jl#L143-L150.


#9

I merged the PR. Should be no problem putting it in .juliarc.jl.

Docs at https://kristofferc.github.io/OhMyREPL.jl/latest/features/prompt.html


#10

It works great! Except that currently OhMyREPL seems to be unusable on 0.6.


#11

Yeah it is too much work to keep up to date with master all the time.


#12

I got it to work just now but the lag is substantial for invoking the REPL, so I ditched it and went back to REPL.default … sorry @kristoffer.carlsson

FWIIW: versioninfo()

Julia Version 0.6.0-dev.2836
Commit 3958491 (2017-02-17 04:31 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: AMD FX™-8320 Eight-Core Processor


#13

Yeah, you need to compile it into the sysimg.jl (as the docs say) for it to be fast. If you only want to change the REPL prompt you don’t need the package, can just use the atreplinit function.


#14

OK, I’ll stick “compile the REPL” on my list of things to do … which grows larger hourly.


#15

Great stuff! I’ll switch to OhMyREPL one day, but I wanted to explore the mechanics of this while I was at it.

For what it’s worth, with your and Keno’s help I’ve got as far as this in my juliarc.jl. It’s a bit peculiar: the prompt information is at the right side of the Terminal window. It’s odd, but I’m starting to like it:

# for versions 0.5 and above
COLOR_RED="\033[0;31m"
COLOR_YELLOW="\033[0;33m"
COLOR_GREEN="\033[0;32m"
COLOR_OCHRE="\033[38;5;95m"
COLOR_BLUE="\033[0;34m"
COLOR_WHITE="\033[0;37m"
COLOR_RESET="\033[0m"
MOVE_COL_80="\033[80C"

function prompt_prefix()
    return ""
end

function prompt_suffix()
    currentversion = "v$(VERSION.minor) "
    timestamp = Dates.format(now(), "HH:MM:SS")
    workingdirectory = last(splitdir(pwd()))
    return string("$MOVE_COL_80 $timestamp $COLOR_GREEN $currentversion $COLOR_YELLOW $workingdirectory $COLOR_RESET")
end

function customizeprompts(repl)
    if !isdefined(repl, :interface)
        repl.interface = Base.REPL.setup_interface(repl)
    end
    # prompt prefix
    prefix = repl.interface.modes[1].prompt_prefix
    repl.interface.modes[1].prompt_prefix = function ()
        (prompt_prefix() * (isa(prefix, Function) ? prefix() : prefix))
    end
    
    # actual prompt string unscathed

    # prompt suffix    
     suffix = repl.interface.modes[1].prompt_suffix
     repl.interface.modes[1].prompt_suffix = function ()
         ((isa(suffix,Function) ? suffix() : suffix) * prompt_suffix())
     end
end
 
atreplinit(customizeprompts)

Other things I’ve tried mess up the line editing a lot more…


#16

https://github.com/KristofferC/Crayons.jl might make it easier to mess around with color and styles.


#17

Awesome. Typing using Crayons is strangely pleasing… :slight_smile:


#18

For what it’s worth, the way I do it in .juliarc.jl without the lag or other tricks is this:

function myrepl(repl)
    repl.interface = REPL.setup_interface(repl)
    repl.interface.modes[1].prompt = "julia-$(VERSION.major).$(VERSION.minor)> "
    return
end

atreplinit(myrepl)

#19
function myrepl(repl)
    repl.interface = REPL.setup_interface(repl)
    repl.interface.modes[1].prompt = "julia-$(VERSION.major).$(VERSION.minor)> "
    return
end

atreplinit(myrepl)

Does anyone know the equivalent for v0.7?


#20

That works perfectly fine for me on v0.7. Just add a using REPL to avoid the deprecation warnings. (Note that .juliarc.jl have changed to .julia/config/startup.jl, perhaps thats why you don’t see the effect?)