Open DanielCardonaRojas opened 4 years ago
I think there's a --line-range
option in bat, which might does what you need 😄
...
-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
...
Kind of does but does not let scroll to lines previous to start of range.
You can try to use --pager=…
to pass explicit options to less. Something like:
bat --pager="less -FR +10" src/assets_metadata.rs
You will need to add an offset of 3 lines for the bat header.
It would be beneficial if bat let line offset arguments pass through to less (or another pager, I think all of the most common ones use similar line offset argument syntax). This would allow users to easily get syntax highlighting from bat when an external program runs a command like $PAGER +263 /foo/bar/baz
.
I specifically ran into this issue with Julia's less function -- as it stands you'd need to set $PAGER to quite an impressive bash spell in order to make this work.
@sharkdp That doesn't seem to work:
rg --vimgrep _files | fzf --delimiter=: --preview='bat --color always -H {2} --pager "less -RF +{2}" {1}'
Page never jumps down to the line needed to start at. {2} is the correct line number because -H
does work
If you run that with a echo
in front of the bat
command, you can see what the problem is. This calls less
with something like
less -RF +'17'
because fzf
seems to include these single quotes. Unfortunately, since there is the +
in front, the whole +'17'
string will be sent to less
as an argument. This causes less to run the command '17'
which does not scroll to line 17.
You somehow need to either teach fzf
to skip adding these quotes. Or teach less
to run you command anyway. I couldn't find a solution after a quick search.
It seems that --pager="less -FR +10"
cannot correctly handle wrappings. When there are wrapping lines, less
jumps to a wrong position. This also happens when we want to set line offset in fzf
because fzf
doesn't know what is the actual "line". We still need a starting line number flag.
When there are wrapping lines,
less
jumps to a wrong position. This also happens when we want to set line offset infzf
becausefzf
doesn't know what is the actual "line". We still need a starting line number flag.
Fair point. If we would add a feature like --scroll-to <LINE>
, that would be less
-specific. So far, we have avoided pager-specific features. Or do you have any other ideas on how to implement this?
@sharkdp Can we pass the calculated line number to the --pager
flag like fzf
? For example, --pager="less -FR +{l}"
.
That sounds like a cool idea. Maybe there would be more variables that could be useful:
{effective-scroll-line}
for the bat
-computed LINE that needs to be passed to the +…
command{scroll-line}
for the actual user-provided <LINE>
argument{file-name}
{detected-syntax}
However, how can we provide this feature by default? We would need to modify the default value for --pager
to be something like
less --other --default --options +{effective-scroll-line}
But what if --scroll-to
isn't used? Should we simply set effective-scroll-line = 0
? What other side-effects would this have?
Also, this would require every bat user with a custom --pager
command in their config to now add the new +{effective-scroll-line}
argument to make --scroll-to
work.
If we don't add +{effective-scroll-line}
by default, users of --scroll-to
would be required to specify --pager="… +{effective-scroll-line}"
themselves.
@sharkdp I have another proposal: make the content of --pager
flag a shell script statement, and provide those variables as environment variables, so that we don't need to create one more DSL to deal with complex situations.
For example, bat --pager='less -FR ${line:++$line}'
. When $line
is set, this is equivalent to bat --pager='less -FR +$line'
. Otherwise, this is equivalent to bat --pager='less -FR '
. We can also give $line
a default value 0
or 1
, which will make the default --pager
flag simpler. If someone's pager cannot handle these values, he can use shell script to solve this problem.
As far as I know, the configuration of fzf-tab
is done this way. See https://github.com/Aloxaf/fzf-tab/wiki/Configuration
Also, this would require every bat user with a custom
--pager
command in their config to now add the new+{effective-scroll-line}
argument to make--scroll-to
work.
Maybe we can add some hints to the help message of --scroll-to
to reduce confusion. Besides, if the shell that executes the pager command is fixed, it is possible to detect which variables are set but not used and prompt some warnings. But I rather not do that.
@QuarticCat Thank you. I think I also like this better.
Unfortunately, the questions from my comment still remain, right?
Maybe this also opens up some new problems though. Especially concerning cross-platform. Which shell do you call on Windows, on macOS, etc.?
@sharkdp
Unfortunately, the questions from my comment still remain, right?
That's right. I have no idea how to solve them.
Which shell do you call on Windows, on macOS, etc.?
Maybe get the current shell from $SHELL
env variable, and provide default config for common shells. For other shells, we fall back to a less powerful config that has no variable usage.
I don't know whether Windows has $SHELL
. If not, there must be some way to determine which shell we are using.
Apart from that, users can use $BAT_SHELL
to override this value, just as $BAT_PAGER
and $PAGER
.
Honestly, I don't like this solution. fzf-tab
is a Zsh plugin so it doesn't need to consider this problem. I can't find a similar example of the situation of bat
.
I have a new idea. If bat
has a utility to print the actual line number, we don't need to modify any flags. For example:
$ bat --pager="sh -c 'less -FR +$(bat-line --flags --line-at=15)'" --flags
Users can shorten this command by defining their own functions.
I know this is absolutely not elegant. Hope it can bring you some inspiration.
For fzf users, there is actually no need for such an option. fzf's --preview-window
actually solves that issue very well.
To open a preview with a fixed header (the title) and the highlighted-line in sight (at the first quarter of the preview):
rg --line-number some_regex |
fzf \
--delimiter=: \
--preview='bat --color=always {1} --highlight-line={2}' \
--preview-window='~3,+{2}+3/4'
And here's a bit more advanced function to open vscode with a similar command.
And after reading the doc, here's the explanation in fzf repo
Related topic: regex-search line of file I want to open (and open it).
fzf Ctrl+T is used to search a file (or dir) based on a pattern in its name, what about to search a file based on a pattern in its written text?
:Rg [PATTERN]
in Vim with fzf.vimrga-fzf function is great! Though, thanks @BuonOmo, I coded a short function (here) to search regex and vim open it directly at line of match
@juanMarinero thank you for mentioning rga-fzf, it's really great! It is coded directly in rga now as a separate executable. But how can I use bat as preview now? Seems there is no way...
Hi @QtRoS ! I edited the short function I coded (here) to add a MWE and the output I see (right window is the bat preview window).
how can I use bat as preview now?
--preview='batcat --color=always {1} --highlight-line={2}'
This line commands "bat" for preview in my function.
For more fzf preview-window please check the specific docu and its wiki.
About the function you mentioned of rga, I guess the answer must be related to:
"--preview={preproc_exe} --pretty --context 5 {{q}} --rga-fzf-path=_{{}}"
I read it diagonal, --context 5
tells rga to show 5 lines of context around each match (I think), so maybe fixing that shows whole file preview. If your question is specific to that function, please search for FAQ or issues in that rga repo.
Note: rga has "a" for "all", so it's coded to be quite general purpose. For example one cannot vim a PDF result (of rga), my function can vim all (though accordingly it just rip-greps text-code files).
First of all great work! Loving this CLI
I checked the man page and did not see an option to open a file starting a line number, otherwise if this feature does exist please document.