bat icon indicating copy to clipboard operation
bat copied to clipboard

"CTRL-C" just kills the pager when using "less" in "tail -f" mode

Open cohml opened this issue 3 years ago • 2 comments

The background

The Unix pager less has a super useful option +F which behaves like tail -f. Specifically, it allows you to monitor the tail of a file in real time as it grows. While in this "tail mode", you cannot page through the file, and the following text is shown at the bottom:

Waiting for data... (interrupt to abort)

Entering CTRL-C will kill this "tail mode" and allow you to scroll. Entering Shift-F will re-enter "tail mode", allowing new lines to be written to the screen. You can do this as many times as you want without ever exiting less.

The problem

However, when using bat with less as the pager, you can enter "tail mode" as described with Shift-F, but you can't leave and re-enter it. Instead, CTRL-C simply kills less, returning you to the prompt.

The technical stuff

bat version: bat 0.22.1 (e5d9579)

less versions tested: 458, 608

Steps to reproduce:

  1. Run bat <filepath> --pager "less +F". You will see Waiting for data... visible at the bottom.
  2. Hit CTRL-C to exit "tail mode". This will exit less altogether, not just "tail mode".

Note that simply doing either of the following produces the desired behavior, suggesting the issue is with bat:

less +F <filepath> (followed by `CTRL-C` and then `Shift-F` from within `less`)

cat <filepath> | less +F (followed by `CTRL-C` and then `Shift-F` from within `less`)

Sorry, I'm not sure how to get --diagnostic to be helpful here. Let me know if I can clarify further.

cohml avatar Dec 20 '22 21:12 cohml

Interesting. Thank you for reporting.

I'm not sure if we can do anything about this, but note that you can do bat -f <filepath> | less +F. That should work?

sharkdp avatar Jan 17 '23 14:01 sharkdp

Thanks @sharkdp.

Piping to less does get around the issue, and I do it when I really need to use +F. But this is limiting. In particular, my bat config sets less with lots of custom arguments as my pager. To achieve the same with a pipe would require retyping all the arguments, or aliasing them to less which is undesirable. It would just be nicer to do everything from within bat.

I assume it doesn't work because the CTRL-C signal is sent to bat instead of less, killing the program. Could this SIGINT be captured and routed to less? e.g.,

if catch SIGINT:
    if pager is less and pagination is on:
        route SIGINT to pager
    else:
        throw SIGINT

Standard disclaimers apply, of course. This would require careful consideration. But I'm sure other pagers would also have limited functionality if bat eats all their control signals.

cohml avatar Jan 24 '23 02:01 cohml