Overriding (some?) key bindings in REPL does not seem to work

Hello!

I’m trying to override a default keybinding in REPL, as suggested in the manual, with the following code in startup.jl:

import REPL
import REPL.LineEdit

atreplinit() do repl
    my_keys = Dict("^w" => (s,o...) -> LineEdit.edit_kill_region(s))
    repl.interface = REPL.setup_interface(repl; extra_repl_keymap = my_keys)
end

After Julia REPL startup, however, C-w still performs its default operation. The example in the manual shows how to override up and down arrow behavior, so I’m assuming that overriding is possible, but I can’t seem to get it working. Any ideas what could have I done wrong?

When I bind a still unused key, that seems to work just fine. In fact, it works even for single key shortcuts, which would otherwise paste themselves in the input buffer (e.g., the key w).

Your example works for me, I am on Windows 10 using Windows Terminal.
To see a more clear effect I modified your code to do a clear and this works too:

import REPL
import REPL.LineEdit
import REPL.Terminals

atreplinit() do repl
	mykeys = Dict(
		"^w" => (s,o...)->(Terminals.clear(REPL.terminal(s)); LineEdit.refresh_line(s))
		#"^w" => (s,o...) -> LineEdit.edit_kill_region(s)
	)
	repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)
end

What’s your environment/OS/Terminal?

Debian 11, Gnome Terminal, zsh.

But I think I just realized what the crux of the problem was. For the sake of quicker REPL startups, I’m compiling my own system images with PackageCompiler, which include OhMyREPL as well. If I start REPL without the custom system image, then the keybinding works as documented and expected. With the precompiled system image, however, it does not. That’s odd, because startup.jl loads and runs just fine even with the system image.

I’m now trying to figure out how to embed my custom keybinding in the system image, but it isn’t trivial.

For you system image you can just change the REPL src. In your case it would be in
…\Julia-1.8.0\share\julia\stdlib\v1.8\REPL\src\LineEdit.jl
From line 1982 (setup_search_keymap) and below.

But perhaps there is a way to exclude REPL from the precompiled system image, but I don’t know how.

I finally figured this out. It was actually a combination of OhMyREPL and the system image compilation that caused the issue. But the solution is much simpler than expected, even though it is a bit fragile and could break with future releases of OhMyREPL.

This needs to go in the startup.jl, in the atreplinit() block:

        OhMyREPL.Prompt.NEW_KEYBINDINGS["^W"] = function (s,o...)
            LineEdit.edit_kill_region(s)
            OhMyREPL.Prompt.rewrite_with_ANSI(s)
        end

This is because OhMyREPL already replaces the default keybinding with its own, and we need to override that.

1 Like