/
helpers.jl
106 lines (84 loc) · 2.78 KB
/
helpers.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
# ==========================================================================================
#
# Helpers.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
export @help, @stdout_to_pager, @out2pr
"""
@help(f)
Open the documentation of the function `f` in pager.
# Examples
```julia-repl
julia> @help write
```
"""
macro help(f)
local f_str = string(f)
ex_out = quote
# We do not need to verify if we are in a interactive environment because this mode is
# only accessible through pager mode, which already checks it.
try
pager(TerminalPager._get_help($f_str); use_alternate_screen_buffer = true)
catch err
Base.display_error(stderr, err, Base.catch_backtrace())
end
end
return esc(ex_out)
end
"""
@stdout_to_pager(ex_in)
Capture the `stdout` generated by `ex_in` and show inside a pager.
!!! note
The command **must** write to `stdout` explicitly. For example, `@stdout_to_pager 1`
shows a blank screen since `1` does not write to `stdout`, but returns `1`.
`@stdout_to_pager show(1)`, on the other hand, shows the number `1` inside the pager.
!!! note
This macro can also be called using the shorter name `@out2pr`.
"""
macro stdout_to_pager(ex_in)
ex_out = quote
hascolor = get(stdout, :color, true)
old_stdout = stdout
buf = IOBuffer()
io = IOContext(buf, :color => hascolor, :limit => false)
try
Base.eval(:(stdout = $io))
$(esc(ex_in))
Base.eval(:(stdout = $old_stdout))
String(take!(buf)) |> pager
close(io)
finally
Base.eval(:(stdout = $old_stdout))
end
end
return ex_out
end
macro out2pr(ex)
return :(@stdout_to_pager $(esc(ex)))
end
############################################################################################
# Private Functions
############################################################################################
# Return the rendered help string of the function `f`.
function _get_help(f)
# Create a buffer that will replace `stdout`.
buf = IOBuffer()
io = IOContext(
IOContext(buf, stdout),
:displaysize => displaysize(stdout),
:limit => false,
)
# Get the AST that generates the help.
ast = Base.invokelatest(TerminalPager.REPL.helpmode, io, f)
# Evaluate the AST, which returns a Markdown object.
response = Core.eval(Main, ast)
# Render the output.
show(io, MIME("text/plain"), response)
write(io, '\n')
str = String(take!(buf))
close(io)
return str
end