ANN: InteractiveCodeSearch.jl --- Interactively search Julia code


#1

Let me introduce my package InteractiveCodeSearch.jl. It helps you searching Julia code.

gif animation

Julia has @edit, @less, etc. which are very handy for reading the implementation of functions. However, you need to specify a “good enough” set of (type) parameters for them to find the location of the code.

Instead, InteractiveCodeSearch provides a few macros to interactively choose the code you want to read. Features:

  • Interactively choose a method signature before opening the code location in your editor.
  • Various ways to search methods, such as: by function name @search show, function call expression @search show(stdout, "hello"), function call signature @search show(::IO, ::String), module name @search Base, argument value @searchmethods 1, argument type @searchmethods ::Int, and return type @searchreturn Int.
  • Interactively search history. It works in IJulia as well.

It’s already registered so you can install it by:

]add InteractiveCodeSearch         # Julia ≥ 0.7
Pkg.add("InteractiveCodeSearch")   # Julia 0.6

EDIT: I forgot to mention that the most of the cool things are happening in the interactive matching program. I use peco (written in Go) and InteractiveCodeSearch is useful (e.g., it can handle @search Base) because peco is highly efficient.


#2

Wow, this works really well!


#3

I’m glad that you find it useful!


#4

I wasted some time thinking I need peco.jl to get this working, but now it works.

You think it would be possible to have a special key in the REPL that would trigger @search? For example ‘)’ .


#5

Ah, I guess README is not very clear about installation steps.

Yeah, that’s possible. I’ve done it in IPython.jl. Maybe it would be nice to have something context-aware like alt-e in Rebugger.jl.


#6

Putting this in ~/.julia/config/startup.jl seems to work:

using REPL
using REPL: LineEdit

@async begin
    # This is why we need https://github.com/JuliaLang/julia/pull/29896...
    for _ in 1:20
        try
            Base.repl.interface.modes[1].keymap_dict
            break
        catch
        end
        sleep(0.05)
    end

    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, ')')
        end
    end
    new_keymap = Dict{Any,Any}(')' => insert_search)

    main_mode = repl.interface.modes[1]
    main_mode.keymap_dict = LineEdit.keymap_merge(main_mode.keymap_dict,
                                                  new_keymap)
end