Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

methods link to code #4952

Closed
alanedelman opened this issue Nov 27, 2013 · 9 comments
Closed

methods link to code #4952

alanedelman opened this issue Nov 27, 2013 · 9 comments
Labels
REPL Julia's REPL (Read Eval Print Loop)

Comments

@alanedelman
Copy link
Contributor

methods already gives line numbers
would be nice to have hyperlinks
these days browsers and even pdf files can have hyperlinks
not sure if terminals can as well
but i'd settle for a url if need be

@ViralBShah
Copy link
Member

At least in IJulia, the URLs can be used. Perhaps mimetypes is the solution here?

@stevengj
Copy link
Member

All that is needed is to define a writemime(io, ::MIME"text/html", x::MethodTable) function that outputs the method table in nicely formatted HTML with links, and IJulia will display it.

@stevengj
Copy link
Member

(Presumably you would link to the Julia source on github, for functions in Base? Ideally you would link to the specific commit of Julia that is being executed, but I'm not sure how to get this information within Julia. Similarly, for things in the Pkg directory you could try to query Pkg to find a github URL and commit to link to.)

@StefanKarpinski
Copy link
Member

julia> Base.BUILD_INFO.commit
"dc60e18d20b999d80ea2f81552d90a61555efa2f"

The only trouble with using this blindly is if you're on a local commit that isn't on GitHub. It would be great to systematically show all line numbers as links – in errors, etc. This might make me switch from using the repl to IJulia for day-to-day work.

@stevengj
Copy link
Member

@StefanKarpinski, I thought about that, but I suspect that developers working on local commits is not the norm.

(It would be great to have a system that is flexible enough to link to local source trees, of course, but I'm not sure this is possible since many browsers seem to ignore file:// URLs for security reasons, separate from the question of identifying the correct location to link to. We'd have to build it into the IPython server or something. It looks like the browser can be configured to accept file URLs from localhost.)

@ivarne
Copy link
Member

ivarne commented Nov 27, 2013

You have Base.BUILD_INFO.fork_master_distance to tell the number of commits that are not on the (origin/)master branch. If the distance ==0, the commit is probably on github. It is not a perfect check, because some users might clone their fork as origin and commit and push to the master branch on their remote origin.

One option might be to include the relevant function definition in a hidden <div> element so that a user might click on it to see the source. That would require some javascript, and require some more file parsing.

@stevengj
Copy link
Member

Here is a prototype implementation (just paste it into your IJulia window to try it out), which links to github for functions in Base (ignoring the possibility of a local commit) or for github Pkg packages (and gives a file:// link for everything else):

import Base.writemime
inbase(m::Module) = m == Base ? true : m == Main ? false : inbase(module_parent(m))
function method_url(m::Method)
    M = m.func.code.module
    file = string(m.func.code.file)
    line = m.func.code.line
    line <= 0 || ismatch(r"In\[[0-9]+\]", file) && return ""
    if inbase(M)
        return "https://github.com/JuliaLang/julia/tree/$(Base.BUILD_INFO.commit)/base/$file#L$line"
    else 
        try
            pkg = Pkg.dir(string(M))
            file[1:length(pkg)] != pkg && return "file://$file"
            url = Base.Git.readchomp(`config remote.origin.url`, dir=pkg)
            url = match(Base.Git.GITHUB_REGEX,url).captures[1]
            commit = Base.Git.readchomp(`rev-parse HEAD`, dir=pkg)
            return "https://github.com/$url/tree/$commit/"*file[length(pkg)+2:end]*"#L$line"
        catch
            return "file://$file"
        end
    end
end
function writemime(io::IO, mime::MIME"text/html", mt::MethodTable)
    name = mt.name
    n = length(mt)
    meths = n==1 ? "method" : "methods"
    print(io, "$n $meths for generic function <b>$name</b>:<ul>")
    d = mt.defs
    while !is(d,())
        print(io, "<li> ")
        url = method_url(d)
        if isempty(url)
            print(io, name)
        else
            print(io, """<a href="$url" target="_blank">""", name, "</a>")
        end
        show(io, d)
        d = d.next
    end
    print(io, "</ul>")
end

For expedience, I'm just linking the method name to the source code. It would be better to attach the link to the file:line output text, and also to do some nicer formatting of the method signature (see #4957 ... the nice thing here is that we can probably assume IPython's default white background, and the formatting possibilities are much richer in HTML than in a TTY). But that really requires refactoring of the show(io::IO, m::Method) and argtype_decl_string(n, t) methods in Base.

Sample output (though it is more interesting if you try out the links in a live IJulia session): methods

What do you think of this approach to obtaining the links?

@nalimilan
Copy link
Member

I'd make filename:line a hyperlink, rather than the function name, as it is more explicit about what it does. One could also make function names links to the documentation.

@stevengj
Copy link
Member

@nalimilan, as I explained, linking the function name was merely a temporary expedience. I agree that filename:line should be the link, but to do that I need to refactor some code in Julia Base.

stevengj added a commit that referenced this issue Dec 23, 2013
add text/html writemime for MethodList and Method (fix #4952)
gitfoxi pushed a commit to gitfoxi/julia that referenced this issue Dec 23, 2013
* upstream/master: (89 commits)
  fix JuliaLang#5225
  update pcre
  fix off-by-1 in isqrt. closes JuliaLang#4884
  Add more keywords to ctags regex, plus README
  annotate the types of arguments for derived trigonometric & hyperbolic functions
  fix doc for && and || and update helpdb
  only show ccall literal address warning in imaging mode. closes JuliaLang#5215
  minor update of hypot to ensure consistency of output types
  Fix JuliaLang#5217
  silence compiler warning
  hopefully more robust way of getting github URL (don't assume module name is Pkg name)
  add text/html writemime for MethodList and Method (fix JuliaLang#4952)
  update NEWS
  doc: `import M: single,name` syntax, close JuliaLang#5214
  clean up native finalizers code
  specialized abs2 for bool
  remove use of callback API in REPL
  Some error message cleanup to fix segfault when transposing sparse vector with illegal values.
  test/git*.jl: don't use `echo` to read-and-write from processes.
  test/git*.jl: don't use `echo` to read-and-write from processes.
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

No branches or pull requests

6 participants