ggreer / the_silver_searcher

A code-searching tool similar to ack, but faster.
http://geoff.greer.fm/ag/
Apache License 2.0
26.14k stars 1.43k forks source link

`ag --filename pattern singlefile` doesn't print singlefile #1164

Open HaleTom opened 7 years ago

HaleTom commented 7 years ago

man page says:

       --[no]filename
              Print file names. Enabled by default, except when searching a
              single file.

Observed behaviour:

$ echo pattern > singlefile
$ ag --filename pattern singlefile
1:pattern

Expected output:

singlefile
1:pattern
talwrii commented 6 years ago

A workaround is to include a placeholder filename as an argument on the command line.

Unfortunately, ag errors out when passed /dev/null. But if using bash we can use the "fish operator", <(), to create an anonymous empty file:

echo pattern > singlefile
ag --filename pattern singlefile <() | cat
singlefile:1:pattern

A named pipe or temporary file could be used if ag was wrapped programmatically. (For python NamedTempororaryFile)

alphapapa commented 6 years ago

@talwrii Are you sure that isn't because you're sending ag's output to a pipe instead of to the terminal? I'm observing that ag ignores some output settings depending on whether its output goes to a pty or a pipe.

nifisher commented 4 years ago

So this would be an easy fix I'd think, but I'm trying to wrap my head around the philosophy of this approach....

If we expressly set the flag, it sets the option to DEFAULT

src/options.c                                                                                                                                                                                                                                       
525                 } else if (strcmp(longopts[opt_index].name, "filename") == 0) {
526                     opts.print_path = PATH_PRINT_DEFAULT;
527                     opts.print_line_numbers = TRUE;
528                     break;

Which later the program overrides if there is only one file

src/search.c
568             /* Not a directory. Probably a file. */
569             if (depth == 0 && opts.paths_len == 1) {
570                 /* If we're only searching one file, don't print the filename header at the top. */
571                 if (opts.print_path == PATH_PRINT_DEFAULT || opts.print_path == PATH_PRINT_DEFAULT_EACH_LINE) {
572                     opts.print_path = PATH_PRINT_NOTHING;
573                 }

Changing the forced setting to something like PATH_PRINT_ALWAYS seems like it would be an obvious fix, but what use cases expect it to work this way?

If nothing else, the current behavior breaks this documented use case when used with ack.vim: let g:ackprg = 'ag --nogroup --nocolor --column'

kylesnowschwartz commented 11 months ago

Adding my 2 cents that I would like this.

I'm trying to use ag and fzf combined to create a fuzzy finder tool that searches for text within a single file in my IDE. When searching through directories it works fine, but using it when limiting the search to a single file means I don't get file hyperlinks in my output.

agf is my alias and it echoes the output command. You'll see I'm piping through fzf to perform the search.

~/Code/marketplace (main)$ agf /Users/kyle/.bashrc --filename
ag --filename . /Users/kyle/.bashrc <() | fzf --multi --height=70% --layout=reverse-list --border=rounded --info=inline --prompt='$> ' --pointer='→' --marker='♡' --header='CTRL-c or ESC to quit' --color='dark' --delimiter=':' --nth='3..'
1:# ~/.bashrc: executed by bash(1) for non-login shells.
~/Code/marketplace (main)$ agf /Users/kyle/ --filename
ag --filename . /Users/kyle/ <() | fzf --multi --height=70% --layout=reverse-list --border=rounded --info=inline --prompt='$> ' --pointer='→' --marker='♡' --header='CTRL-c or ESC to quit' --color='dark' --delimiter=':' --nth='3..'
/Users/kyle/last_update_spike.md:1:
gigamonkey commented 3 months ago

I just stumbled across this. It was surprising to me that --filename was a no-op when I happened to be searching a single file. I wanted the filename because I have some other tools that can jump me to the specified line in a file when it's formatted with the filename. It certainly seems like an explicit request from the user shouldn't be overridden by a default behavior. (The default makes sense as a default but it shouldn't be an immovable object.) So +1 on changing it to mean PATH_PRINT_ALWAYS