diff --git a/README.md b/README.md index c50c1b3..e4b7a6f 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Search functions returning type `Type` in `Module`s. As this search typically t **Limitations** + * It does not work with Julia >= 1.2. * Running `@searchreturn` for many modules may be slow for the *first* run. Thus, searching from all modules (i.e., not specifying `Module` arguments) may take tens of seconds to minutes, depending of what are loaded. Searching within `Base` takes about 30 seconds. After `DifferentialEquations` is loaded, searching for all modules takes 1.5 minutes. Note that searching from the same module for the second time is fast (a few seconds), even if different `Type` is specified. * The functions must be executed (JIT'ed) once for `@searchreturn` to find their returned by type. * Any IO operations (like printing in REPL) would be slow while the search is active in background. @@ -149,7 +150,8 @@ Configuration interface for `InteractiveCodeSearch`. ```julia using InteractiveCodeSearch -InteractiveCodeSearch.CONFIG.interactive_matcher = `peco` # default in terminal +InteractiveCodeSearch.CONFIG.interactive_matcher = `fzf ...` # default in terminal +InteractiveCodeSearch.CONFIG.interactive_matcher = `peco` InteractiveCodeSearch.CONFIG.interactive_matcher = `percol` InteractiveCodeSearch.CONFIG.interactive_matcher = `rofi -dmenu -i -p "🔎"` # use GUI matcher (default in non-terminal @@ -161,6 +163,8 @@ InteractiveCodeSearch.CONFIG.open = less # use Base.less to read code InteractiveCodeSearch.CONFIG.auto_open = true # default InteractiveCodeSearch.CONFIG.auto_open = false # open matcher even when there # is only one candidate +InteractiveCodeSearch.CONFIG.trigger_key = ')' # insert "@search" on ')' (default) +InteractiveCodeSearch.CONFIG.trigger_key = nothing # disable shortcut ``` **Using InteractiveCodeSearch.jl by default** diff --git a/src/InteractiveCodeSearch.jl b/src/InteractiveCodeSearch.jl index 318c960..66d3c3b 100644 --- a/src/InteractiveCodeSearch.jl +++ b/src/InteractiveCodeSearch.jl @@ -67,6 +67,7 @@ mutable struct SearchConfig # CONFIG open interactive_matcher::Cmd auto_open::Bool + trigger_key::Union{Nothing,Char} end maybe_identifier(s) = !startswith(string(s), "#") @@ -267,6 +268,8 @@ InteractiveCodeSearch.CONFIG.open = less # use Base.less to read code InteractiveCodeSearch.CONFIG.auto_open = true # default InteractiveCodeSearch.CONFIG.auto_open = false # open matcher even when there # is only one candidate +InteractiveCodeSearch.CONFIG.trigger_key = ')' # insert "@search" on ')' (default) +InteractiveCodeSearch.CONFIG.trigger_key = nothing # disable shortcut ``` ## Using InteractiveCodeSearch.jl by default @@ -283,6 +286,7 @@ const CONFIG = SearchConfig( edit, # open `peco`, # interactive_matcher true, # auto_open + ')', # trigger_key ) should_eval(::Any) = false @@ -551,10 +555,12 @@ end function __init__() CONFIG.interactive_matcher = choose_interactive_matcher() + setup_keybinds() end include("taskmanager.jl") include("history.jl") include("return.jl") +include("keybinds.jl") end # module diff --git a/src/keybinds.jl b/src/keybinds.jl new file mode 100644 index 0000000..c194d03 --- /dev/null +++ b/src/keybinds.jl @@ -0,0 +1,59 @@ +using REPL +using REPL: LineEdit + +function setup_keybinds() + schedule(Task(setup_keybinds_background)) + return +end + +function setup_keybinds_background() + try + setup_keybinds_impl() + catch err + @error( + "Unexpected error from `setup_keybinds_impl`", + exception = (err, catch_backtrace()), + ) + end +end + +function setup_keybinds_impl() + # This is why we need https://github.com/JuliaLang/julia/pull/29896... + for _ in 1:20 + try + Base.active_repl.interface.modes[1].keymap_dict + @goto ok + catch + end + sleep(0.05) + end + @warn "Failed to wait for REPL" + return + @label ok + + trigger_key = CONFIG.trigger_key + if trigger_key === nothing + @debug "`trigger_key` is `nothing`; not defining a shortcut key" + return + end + trigger_key::Char + + repl = Base.active_repl + repl isa REPL.LineEditREPL || return + insert_search = function(s, _...) + if isempty(s) || position(LineEdit.buffer(s)) == 0 + LineEdit.edit_insert(s, "@search") + else + LineEdit.edit_insert(s, trigger_key) + end + end + new_keymap = Dict{Any,Any}(trigger_key => insert_search) + + main_mode = repl.interface.modes[1] + main_mode.keymap_dict = LineEdit.keymap_merge(main_mode.keymap_dict, + new_keymap) + return +end + +precompile(Tuple{typeof(setup_keybinds)}) +precompile(Tuple{typeof(setup_keybinds_background)})