Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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**
Expand Down
6 changes: 6 additions & 0 deletions src/InteractiveCodeSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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), "#")
Expand Down Expand Up @@ -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
Expand All @@ -283,6 +286,7 @@ const CONFIG = SearchConfig(
edit, # open
`peco`, # interactive_matcher
true, # auto_open
')', # trigger_key
)

should_eval(::Any) = false
Expand Down Expand Up @@ -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
59 changes: 59 additions & 0 deletions src/keybinds.jl
Original file line number Diff line number Diff line change
@@ -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)})