Skip to content

Conversation

MilesCranmer
Copy link
Member

From #39476. cc @timholy

This PR adds the following:

  1. A new function signature edit(f::Function, method_idx::Integer) that takes an array index for methods(foo).ms as input.
  2. When a user calls edit(f), and the function has >1 signatures, print out methods(foo).ms to the console, in addition to the normal ERROR: function has multiple methods.

I think this gives a much quicker experience when trying to edit functions that have many signatures, making Revise.jl even smoother.

Here's an example workflow. Say I want to edit a method of function foo:

julia> edit(foo)
ERROR: Function has multiple methods; please specify a type signature:
# 2 methods for generic function "foo":
[1] foo(lt1::LongTypeName1, lt2::LongTypeName2; lt3::LongTypeName3) in Main at REPL[5]:1
[2] foo() in Main at REPL[4]:1
...
julia> edit(foo, 1)

Editor then opens method foo(lt1::LongTypeName1, lt2::LongTypeName2; lt3::LongTypeName3), instead of needing to write out manually edit(methods(foo).ms[1]) or try to write out all the types. And edit(foo) printing the methods is nice, since then I don't need to print methods(foo).ms myself to check the signatures.

The new error message for ambiguous edit on the function less looks like this:

julia> edit(less)
ERROR: function has multiple methods; please specify a type signature:
# 5 methods for generic function "less":
[1] less(file::AbstractString) in InteractiveUtils at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/InteractiveUtils/src/editless.jl:255
[2] less(file::AbstractString, line::Integer) in InteractiveUtils at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/InteractiveUtils/src/editless.jl:242
[3] less(f) in InteractiveUtils at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/InteractiveUtils/src/editless.jl:263
[4] less(file, line::Integer) in InteractiveUtils at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/InteractiveUtils/src/editless.jl:265
[5] less(f, t) in InteractiveUtils at /Applications/Julia-1.5.app/Contents/Resources/julia/share/julia/stdlib/v1.5/InteractiveUtils/src/editless.jl:264
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at REPL[20]:1

Then one can choose a method from this list, with, e.g., edit(less, 2), instead of having to: 1) print out all the methods with methods(less), and 2) write out the tuple types or write edit(methods(less).ms[2]).

@fredrikekre
Copy link
Member

This should probably just use the ^Q functionality in the REPL. It already works for stacktraces and displayed method lists. E.g.

julia> methods(match)
# 4 methods for generic function "match":
[1] match(re::Regex, str::Union{SubString{String}, String}, idx::Integer) in Base at regex.jl:294
[2] match(re::Regex, str::Union{SubString{String}, String}, idx::Integer, add_opts::UInt32) in Base at regex.jl:294
[3] match(r::Regex, s::AbstractString) in Base at regex.jl:315
[4] match(r::Regex, s::AbstractString, i::Integer) in Base at regex.jl:316

julia> 2[^Q]

jumps to the second method in the list.

@MilesCranmer
Copy link
Member Author

MilesCranmer commented Feb 1, 2021

Nice!!! I had no idea this trick existed, thanks. I will close this PR.

I guess this is an example of Cunningham's Law but for pull requests? 🤣

@fredrikekre
Copy link
Member

I meant that it could be nice to make it work from this error too.

@MilesCranmer
Copy link
Member Author

I see what you mean; that would be a nice addition.

Maybe edit(f::Function) could catch this error from functionloc, and return methods(f) instead?

@MilesCranmer
Copy link
Member Author

How about this?

edit(f) = length(methods(f)) > 1 ? methods(f) : edit(functionloc(f)...)

@MilesCranmer
Copy link
Member Author

Moved to #39481

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants