From 1edfd0c100d632d8fa87359458512910750b52ed Mon Sep 17 00:00:00 2001 From: Ronan Arraes Jardim Chagas Date: Thu, 13 Feb 2025 16:26:38 -0300 Subject: [PATCH] :bug: Bypass pager calls in pager> REPL mode If we are in pager> REPL mode, we should bypass all other pager calls. Otherwise, we freeze the REPL until the user types CTRL-D. Closes #40 --- src/TerminalPager.jl | 15 ++++++++++++++- src/helpers.jl | 15 +++++++++++---- src/repl.jl | 15 +++++++++++---- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/TerminalPager.jl b/src/TerminalPager.jl index b9806b9..548565d 100644 --- a/src/TerminalPager.jl +++ b/src/TerminalPager.jl @@ -118,7 +118,20 @@ function pager(obj::Any; kwargs...) return pager(str; kwargs...) end -pager(obj::AbstractString; kwargs...) = return _pager(obj; kwargs...) +function pager(obj::AbstractString; kwargs...) + # If we have a context key called `bypass_pager` with the value `true`, we must not call + # the pager because we are in the pager> REPL mode. Hence, we we call the pager, it + # locks the screen until the user types CTRL-D. For more information, see: + # + # https://github.com/ronisbr/TerminalPager.jl/issues/40 + # + if get(stdout, :bypass_pager, false) + print(obj) + return nothing + end + + return _pager(obj; kwargs...) +end const less = pager diff --git a/src/helpers.jl b/src/helpers.jl index 0049c99..55def41 100644 --- a/src/helpers.jl +++ b/src/helpers.jl @@ -49,10 +49,17 @@ Capture the `stdout` generated by `ex_in` and show inside a pager. """ 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) + hascolor = get(stdout, :color, true) + bypass_pager = get(stdout, :bypass_pager, false) + old_stdout = stdout + buf = IOBuffer() + + io = IOContext( + buf, + :bypass_pager => bypass_pager, + :color => hascolor, + :limit => false, + ) try Base.eval(:(stdout = $io)) diff --git a/src/repl.jl b/src/repl.jl index e85eb8f..ba1e917 100644 --- a/src/repl.jl +++ b/src/repl.jl @@ -204,12 +204,19 @@ function _tp_mode_do_cmd(repl::REPL.AbstractREPL, input::String) old_stdout = stdout try - # Create a buffer that will replace `stdout`. + # Create a buffer that will replace `stdout`. Notice that we add a context key + # called `bypass_pager` with value `true`. All the commands we call in this mode + # will have its output handled to the pager. Hence, if a command also calls a pager, + # we must only return the object. Otherwise, the section freezes until the user + # press CTRL-D. For more information, see: + # + # https://github.com/ronisbr/TerminalPager.jl/issues/40 buf = IOBuffer() - io = IOContext( + io = IOContext( IOContext(buf, stdout), - :displaysize => displaysize(stdout), - :limit => false, + :bypass_pager => true, + :displaysize => displaysize(stdout), + :limit => false, ) # Redirect `stdout` to the new buffer.