sharkdp / bat

A cat(1) clone with wings.
Apache License 2.0
49.49k stars 1.25k forks source link

Support moving to given line number #2576

Open fenollp opened 1 year ago

fenollp commented 1 year ago
λ bat migrations/2022-04-26-081536_create_ips/up.sql:60
[bat error]: 'migrations/2022-04-26-081536_create_ips/up.sql:60': No such file or directory (os error 2)

I'd prefer that bat opens migrations/2022-04-26-081536_create_ips/up.sql with line 60 in the middle of the viewport.

Thanks!

eth-p commented 1 year ago

Bat already supports line ranges, but as a flag instead of a file name :)

From the manpage:

-r, --line-range <N:M>...

              Only print the specified range of lines for each file. For
              example:

              --line-range 30:40
                     prints lines 30 to 40

              --line-range :40
                     prints lines 1 to 40

              --line-range 40:
                     prints lines 40 to the end of the file

              --line-range 30:+10
                     prints lines 30 to 40

We could look into supporting filename:range as an option, but I'm not too sure that it would be feasible. Windows and NTFS use a colon to specify alternate data streams on files.

fenollp commented 1 year ago

I'd love for this to be supported at least for non windows platforms. Want me to open a PR?

maciejmatczak commented 1 year ago

--line-range physically cuts the file, though - no way to "scroll" up, right?

eth-p commented 1 year ago

--line-range physically cuts the file, though - no way to "scroll" up, right?

That is correct, yeah.

Looking back at this issue with a clear head, it might be possible to support printing everything while opening the pager to start a specific line. I'm not sure for other pagers, but less +5G would seek down to the 5th line when the pager is started:

  1   This is a text file.
  2   Foo
  3   Bar
  4   Baz
|----------------------------------  <-- viewport of less
| 5   Cat                         |
| 6   Dog                         |
| 7   Frog                        |
| 8   Bird                        |
| 9   Rabbit                      |
|----------------------------------
  10  Hydrogen
  11  Helium
  12  Lithium
...

For that to work with bat's output, to compensate for the file header, it would need an additional 3 lines. If bat detects less as the pager, we could add an extra argument of +123G when starting the process. It's not quite seamless, though:

And if the user doesn't use a pager at all, it would be downright impossible. AFAIK, neither ANSI nor VT___ have escape sequences that can directly influence the terminal's viewport over its scrollback buffer. The next best thing would be to buffer it ourselves and use the alternate screen mode to display the current viewport... but that's just a minimally-useful pager.

In an ideal world, we would have some other pager that works like less, but accepts control sequences over an alternate file descriptor (e.g. fd3). Then we could just send something like "annotate line 58 as 'real_line_50'" followed by "scroll to 'real_line_50'".

Honestly, I've wanted to make a standalone pager that has bidirectional communication with some host program (to facilitate use cases like this) for years, but I just haven't had the time between work and classes. It's a massive undertaking made even more complicated by (1) needing to support ANSI/VT escape sequences in the input; and (2) rendering and handling terminal inputs without using curses or other TUI libraries, which either lack support for rendering cells with certain attributes (e.g. hyperlinks, 24-bit color), or have a ton of abstraction that would overcomplicate a pager.