Julia: Pager support in the repl

Created on 22 May 2014  路  4Comments  路  Source: JuliaLang/julia

I often find myself wishing for a pager in the repl when outputting large amount of output. I see that there is a Base.less but it is only used on files and not for outputting other stuff in the repl. In fact, it would be great to have support for less, head, and tail like functionality for looking at arrays, hashes, etc. Thus to be able to do, e.g., arr |> less or less(arr) or arr |> tail.

In addition, I think having the output of show() automatically go through less if it is longer that one page would be great. I hate seeing 100's of pages of output fly by when, e.g., a huge hash gets "shown" at the prompt (I just cannot seem to get in the habit of typing the ; at the right time). This behavior could be configurable of course.

NOTE: see also https://groups.google.com/forum/#!topic/julia-users/2SbdNdW_EEM

REPL help wanted

Most helpful comment

Hello all. A pager would be useful, especially for viewing lengthy documentation. I'd like to work on this issue if no one else is. Any tips on where to start?

All 4 comments

Hello all. A pager would be useful, especially for viewing lengthy documentation. I'd like to work on this issue if no one else is. Any tips on where to start?

This is probably a bit naive (still learning Julia), but I had a similar need and asking around in Slack and wrapped up the advice I got into a function like this

function pager(text)
    run(pipeline(`echo $text`,`less`))
end

Try this example (notice that markdown doesn't get parsed though). Seems to work ok, although I am sure it can be improved.

julia> pager(@doc print)

Thanks @quipa, that's quite useful. I modified it to:

more(content) = more(reprmime("text/plain", content))
more(content::Markdown.MD) = more(Markdown.term(Core.CoreSTDOUT(), content))
function more(content::AbstractString)
    run(pipeline(`echo $(content)`, `less`))
end

which gives better output of data - Arrays, Dicts, etc. are displayed as usually done in the REPL, instead of a single-line long chain of values, and markdown output works too. (The markdown output includes an extra line at the end like (2, 52) though, which seems to be the return value of the Markdown.term function. I left it in since it's probably more work than worth it to remove that single line.)

julia> @doc(less) |> more
  less(file::AbstractString, [line::Integer])

  Show a file using the default pager, optionally providing a starting line
  number. Returns to the julia prompt when you quit the pager.

  less(function, [types])

  Show the definition of a function using the default pager, optionally
  specifying a tuple of types to indicate which method to see.
(2, 62)

julia> rand(1:99, 4, 5) |> more
4脳5 Array{Int64,2}:
 41  68  55  66  77
 61  92  27  44  17
 82  40  71  80  47
 73  94  37  33   5

(PS: my actual run(pipeline( line goes like this: inJupyter ? content : run(pipeline(`echo $(content)`, `less`)), where inJupyter is a variable I've previously defined in my startup.jl file as inJupyter = isdefined(Main, :IJulia) && Main.IJulia.inited.)

My version:

more(content) = more(repr("text/plain", content))
# using Markdown
# more(content::Markdown.MD) = more(Markdown.term(Core.CoreSTDOUT(), content))
function more(content::AbstractString)
    run(pipeline(`echo $(content)`, `less`))
    return nothing
end
macro d(body)
    :(more(Core.@doc($(esc(body)))))
end
@d rand
Was this page helpful?
0 / 5 - 0 ratings

Related issues

wilburtownsend picture wilburtownsend  路  3Comments

ararslan picture ararslan  路  3Comments

sbromberger picture sbromberger  路  3Comments

manor picture manor  路  3Comments

helgee picture helgee  路  3Comments