Closed SimenB closed 6 years ago
Can you make do with creating an alias? Or even a script in your ~/bin
? For example, I have ~/bin/rgp
:
#!/bin/sh
exec rg -p "$@" | less -RFX
I just updated the OP with alias stuff ๐
And yes, I could, but then I have to remember my aliases (woe is me, right?). Doing rg -tzsh
is more natural when I've gotten used to types than doing rgzsh
or whatever.
rgp
makes sense, though!
Why don't you just alias rg
itself? This works, for example:
alias rg="rg --type-add 'zsh:*.zsh' --type-add 'zsh:.zshrc'"
Then you can do rg -tzsh
.
(Also, zsh
seems like a common enough type that it should be part of ripgrep proper! :-))
Aliasing rg seems pretty good!
I can provide a PR for zsh type (just add an entry here I suppose: https://github.com/BurntSushi/ripgrep/blob/master/src/types.rs)
But I'd still really like for that to be defined for rg, and not drowned amongst all of my other aliases (I still do alias | rg whatever
since I forget. I'd like to think rg --type-list
is nicer (and yes, I realize rg --type-list
would work with your suggested rg
alias)).
I can provide a PR for zsh type (just add an entry here I suppose: https://github.com/BurntSushi/ripgrep/blob/master/src/types.rs)
Sounds good!
But I'd still really like for that to be defined for rg, and not drowned amongst all of my other aliases (I still do alias | rg whatever since I forget. I'd like to think rg --type-list is nicer (and yes, I realize rg --type-list would work with your suggested rg alias)).
You can also do command -V rg
to see the alias.
Conclusion: I can achieve what I want using simple aliases. I'd still like an .rgrc
file though, to match .ackrc
, .ptconfig.toml
etc. ๐ I do understand if you feel like aliasing is enough, though
Or maybe support $RG_OPTIONS
to match grep
? It just seems more explicit than aliasing rg itself.
I do feel like aliases are a pretty good solution to this problem, and I'd like to stick with them for now.
I think we should leave this ticket open so that others can chime in. For example, aliases may not be easy to define on all platforms.
BTW, is it possible to not recurse through directories? Case in point is searching for something in a zsh file in$HOME
. Having rg
recurse through everything is slow as hell (naturally).
Additionally: Is it possible to add ignore patterns? I managed to hit chrome application cache, which is an absolutely monstrous file
BTW, is it possible to not recurse through directories?
Yes:
--maxdepth NUM
Descend at most NUM directories below the command line arguments.
A value of zero only searches the starting-points themselves.
Additionally: Is it possible to add ignore patterns? I managed to hit chrome application cache, which is an absolutely monstrous file
Yes. Create a .ignore
file and add patterns to that. (Or add them to your .gitignore
.)
Ok, but not add ignore to the execution itself?
Will an .rgignore
file be respected? I just feel having an .ignore
file in $HOME
might be confusing if it's just used for rg
Ok, but not add ignore to the execution itself?
I don't understand the question.
Will an .rgignore file be respected?
Please use .ignore
. .rgignore
is deprecated. Where did you see .rgignore
?
I just feel having an .ignore file in $HOME might be confusing if it's just used for rg
I don't understand what's confusing about it. The Silver Searcher supports the same format.
The .ignore
file can be anywhere. It could live right next to the thing you want to ignore. It works just like gitignore
.
Perhaps you're looking for the -g/--glob
flag?
I don't understand the question.
I want to do e.g. rg --ignore-dir 'Application Cache'
or something like it, not have to create a file on disk.
Where did you see
.rgignore
?
Nowhere, it was just a name proposal. I can guess you don't like it though ๐
Perhaps you're looking for the
-g
/--glob
flag?
That should work! Just rg -g '!Application Cache/'
?
BTW, using --maxdepth 0
never works, I always get
No files were searched, which means ripgrep probably applied a filter you didn't expect. Try running again with --debug
Doing --maxdepth 1
seems to just search current dir, though. Bug or should the man file get an update?
That should work! Just rg -g '!Application Cache/'?
You probably want rg -g '!**/Application Cache/**'
, since the glob is applied to the full file path.
Doing --maxdepth 1 seems to just search current dir, though. Bug or should the man file get an update?
Seems correct to me. Read the docs again please:
--maxdepth NUM
Descend at most NUM directories below the command line arguments.
A value of zero only searches the starting-points themselves.
A value of zero only searches the starting points. So if you run rg --maxdepth 0 foo
, then the starting point is the current directory, which obviously can't be searched, since it isn't file. If you do rg --maxdepth 1 foo
, then it descends one level. These are the same semantics as find
, e.g., see the output of find ./ -maxdepth 0
and find ./ -maxdepth 1
.
Ah of course, so --maxdepth 0
is only when searching a file? Makes sense when I read it again!
Thanks for answering all of my questions, super helpful! ๐ Especially the -g
one will be useful
Ah of course, so --maxdepth 0 is only when searching a file?
--maxdepth
can be used any time. All it does is control the number of times it descends into a directory. If the value is zero, then it will never descend into any directories. Therefore, since rg foo
is equivalent to rg foo ./
, the directory ./
isn't descended into, so there's nothing to search.
It's most likely that a value of 0
is only useful in a generic context, e.g., when you don't know if your file parameters will be files, directories or a mixture and you don't want to do any directory recursion.
A more useful thing for --maxdepth
doc might be "A value of one will only search files in the passed in directory" or something like it. But now I know, so I'm good ๐
I've hit one issue with using an alias: zsh completion doesn't work when I've shadowed the rg
command with a rg
alias. When I unalias rg
the completion works. There's probably some way to get the zsh completion system to handle this case, but I don't yet know how to do that.
EDIT: The answer is setopt complete_aliases
.
Just my two cents, but I really like .ackrc because it's used at the command line and when invoked by other tools like Emacs (a place that aliases don't work).
In that case, can you put a wrapper script in your $HOME/bin?
On Nov 23, 2016 00:08, "Ivan Andrus" notifications@github.com wrote:
Just my two cents, but I really like .ackrc because it's used at the command line and when invoked by other tools like Emacs (a place that aliases don't work).
โ You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/BurntSushi/ripgrep/issues/196#issuecomment-262435651, or mute the thread https://github.com/notifications/unsubscribe-auth/AAb34niAsM6kJe2XlAWQGP9sFz0-gg5dks5rA8pWgaJpZM4Kieh1 .
I know of at least one Windows user who wants this pretty badly. (cc @retep998) It sounds like the claim is that, on Windows at least, defining aliases and/or wrapper scripts is neither common nor convenient to do. Is this others' experience as well? Could someone please outline exactly what one has to do on Windows to create a wrapper script? Is it really an unreasonable expectation?
If we go down this path, we should consider the following:
clap
can give this to us for free some day: https://github.com/kbknapp/clap-rs/issues/748--context 5
in my config file, but I want to override occasionally with --context 0
on the command line." We can't just trivially merge the config with the CLI parameters since rg --context 5 --context 0 foo
is illegal today. This is probably true of several other flags, and many other flags probably need the opposites added. e.g., If --no-ignore
is in the config file, how does a user re-enable ignore functionality?IMO, the above implies significant complexity and likely an easy source of bugs. If we moved forward with this, I think I'd have to demand a rock solid specification (which I'm not inclined to work on any time soon) or some kind of conscious concessions at least (like, "not every option is overridable," for example, which seems like bad UX honestly).
(I still remain skeptical of the whole idea. See my previous comment.)
We may need to solve problems like "I set --context 5 in my config file, but I want to override occasionally with --context 0 on the command line." We can't just trivially merge the config with the CLI parameters since rg --context 5 --context 0 foo is illegal today. This is probably true of several other flags, and many other flags probably need the opposites added. e.g., If --no-ignore is in the config file, how does a user re-enable ignore functionality?
This is the primary discussion in kbknap/clap-rs#748
I've got some ideas for implementation I just haven't had to time to sit down and do it. The way it'll end up working if you use the clap
implementation for configs is ripgrep
would be responsible for reading in the config file off the disk (initially TOML) and hand off a supported struct to clap
as an "external argv" (such as a TomlTable
). clap
then handles all the merging/overriding of options where whats passed on the command line manually will override any of these "external argv"s.
Any number of these external argv's could be given to clap
(think global and per project, such as a current directory .rgrc
), and will be evaluated in order for example:
let global = /* read global .rgrc and parse into TOML */;
let project = /* read current dir .rgrc and parse into TOML */;
app.external_argv(global)
.external_argv(project)
.get_matches()
(The name external_argv
is still somewhat bikeshedable and will probably be implemented with generic fn external_arg<T: Into<ArgvExt>>(mut self, argv: T) -> Self
and providing impls to convert from TomlTable
, &str
as the two initially supported types of external argvs. The other option is to have separate methods for all the diferent types of "external argvs" which is easier to document for things like simple strings).
Where the command line overrides PROJECT and PROJECT overrides GLOBAL.
The alternative is passing clap
a Path
and having it do all the reading and such, but I personnally would rather leave that to the consuming binary since there's so much that could go wrong, or be done differently, or custom errors, just too much I don't particularly want to do with clap
. But parsing a Toml
/Yaml
/&str
/etc against the valid args seems like it's well within the scope of clap
.
There are some UX oddities which are initilaly may seem confusing, but IMO make sense when you think about them.
Most importantly, what clap
calls flags would need to be considered very carefully. Because putting --foo
in a config is impossible to "undo" unless there is a corresponding overriding or negating flag. Reason being, if the user doesn't provide the flag manually do they simply agree with the default, or did they leave off the flag becasue they don't want to use it?
Positional/Free args wouldn't be supported at all and would have to be input on the command line (although they could have default values). This is to prevent a user running rg <foo>
and not realizing it's actually running rg <bar> <foo>
because <bar>
is defined in a config somewhere.
@kbknapp Thanks for chiming in! As far as the mechanics go, all of that sounds very reasonable. It sounds like we both agree on what the essential challenges are too. For example, it would be unfortunate to have to add negations of every flag. However, the biggest reason why I'd find that unfortunate is because of the space it would take up in the output of --help
, and less because of the presence of the flag itself. (Although that's still painful, unless there's a way to encapsulate the negation on the clap
side of things.) That might suggest a possible avenue forward, but technically, a good chunk of it is possible today since clap
supports adding flags that are hidden from the output of --help
.
Although that's still painful, unless there's a way to encapsulate the negation on the clap side of things.
I see two possibilities with pros and cons to each (also, both would be possible concurrently).
Arg::overridable(bool)
which would only apply to flags and automatically creates a negation flag. There could also be a Arg::overridable_hidden(bool)
that does the same but hides the negation flag from --help
output.AppSettings::OverridableFlags
which does the above, but automatically for all flags. Again there could be a counterpart of AppSettings:OverridableFlagsHidden
which hides all these negation flags.For the specifics, a negation flag would simple take the long version of the regular flag and pre-pend no
, for exmaple --follow
would get --no-follow
. If a flag only specifies a short version (ripgrep
doesn't have any examples of this), the no
would be prepended to the short such as -L
gets --no-L
.
My personal opinion is that having hidden negation flags is best, as it doesn't clutter the --help
output and could quietly mentioned where applicable, such as when speaking of config files To override a flag specified in a config file, prepend --no to the flag, such as --no-follow
. Done. It's not something that everyone needs to know unless they're messing with things like aliases and config files.
Of course, when using something wide sweeping like OverridableFlagsHidden
you'll end up with flags that technically have corresponding negation flags that are functionally useless, but pragmatically it shouldn't affect anything.
If something like that would help this issue (of course once I finish implementing the external argv portion), I'd be happy supporting that as they'd both be technically very easy to implement.
@kbknapp That sounds plausible. But if a flag is already preceded with no-
(e.g., --no-ignore
), then you'd wind up with --no-no-ignore
. :P
Personally, I think the external argv portion is the most important. I'd be OK just starting there and seeing how it all shakes out, even if that means me adding the no
flags manually.
But if a flag is already preceded with no- (e.g., --no-ignore), then you'd wind up with --no-no-ignore. :P
Note that this could actually be reasonable. It seems funny, but it's consistent and predictable.
@SimenB If it helps, I wrote an rg
wrapper function for zsh (which should work on bash with little or no modification) which implements ~/.config/rgrc
as a way to prepend arguments onto my rg
command line.
(It also maps -G ...
to -g !...
to work around a zsh footgun regarding starting arguments with !
)
The alias: https://github.com/ssokolow/profile/blob/master/home/.zshrc.d/rg
Example rgrc: https://github.com/ssokolow/profile/blob/master/home/.config/rgrc
I'm still looking for documentation on how to generate shell completions when building from source, so I don't know what effect it'll have on completion support in its current state.
@ssokolow That's a nice hack, and I'd encourage folks to try and use it if it helps.
The shell completion files are generated automatically and placed in target/release/build/ripgrep-*/out/
.
Without vote how this should be resolved, could I at least ask that if there is any configuration could it be stored in XDG compliant location (e.g., ~/.config/ripgrep
), please?
@mcepl If ripgrep has it, then it will definitely satisfy XDG on platforms where that makes sense. On platforms where it doesn't make sense, I don't know what to do. See: https://github.com/BurntSushi/ripgrep/issues/196#issuecomment-262853109
Yeah, thatโs a problem. I have decided in jbrout that we use glib
anyway (because of Gtk
), so I can use whatever directories it gives me on Windows or Mac, but I guess you donโt want to depend on Glib.
On platforms where it doesn't make sense, I don't know what to do.
The app_dirs crate will handle that for you.
Just specify AppDataType::UserConfig
and you'll get ${XDG_CONFIG_HOME:-$HOME/.config}/ripgrep
on XDG platforms, $HOME/Library/Application Support/ripgrep
on OSX, and %APPDATA%\BurntSushi\ripgrep
on Windows.
EDIT: ...or you could step up a layer and use the preferences crate which depends on it.
I guess you donโt want to depend on Gli
You could say that. :-) perhaps we can borrow the logic that glib uses for Windows?
@ssokolow nice! Thanks for that.
No problem. I'd actually have made a mention ages ago, but I was caught in that "Judging by ripgrep, he's clearly much smarter and more knowledgeable than me. He must already know this." trap.
@ssokolow Haha. Indeed, that is a trap! Glad to be reminded of it.
Now that I think of it, I also had a kinda-sorta feeling that clap might just up and solve this problem for us. More thought still needs to be given to how config files actually work though. e.g., If you specify --no-ignore
by default, how do you override it? Do we need to add a new flag? Some flags are have that like -i
/-s
/-S
, but not all do.
I still intend to work on this issue in clap, but my bandwidth has been very limited lately with my day job. Unfortunately, I can't give a timeline for when I'll have it done. :-(
@kbknapp Oh heavens, please do no worry one little bit! I think I already owe you several <drinks-of-your-choice>. :-)
Oops, missed this issue when I filed mine. In my case, I'd be fine with a wrapper script on Linux/Mac, but on Windows, while making a .bat file "works", it's annoying in typical use because of the unfortunate "Terminate batch job (Y/N)?" prompt that happens if you Ctrl-C during a search.
So I'd enjoy an rc or an env var also. (Or just changing the default behaviour to --no-heading. ;)
Are .bat
files the only way to create simple scripts in Windows? Surely there must be something more convenient?
Oh, you asked about aliases on Windows too -- it's possible via something like doskey rg=rg-win.exe --myoptions $*
, but unfortunately there's no standard ".bashrc"-alike for cmd, so there's nowhere to put those and have them always available.
@BurntSushi In Powershell you can write a function in a Powershell script and have Powershell load the module on startup, but that's arguably more complicated than a simple batch script (not to mention it doesn't work in cmd.exe, although it does avoid the annoying "terminate batch jobs" prompt). .bat/.cmd files are essentially the equivalent of .sh scripts on Unix. Powershell scripts are nicer to use than .bat/.cmd scripts and are more integrated into the shell but require the use of Powershell over Command Prompt and are a bit more work to write if you want them to be nicely loaded as a module.
They're not really too inconvenient and work perfectly fine except for the "terminate batch jobs" prompt that gets more annoying the more you run a command, especially for search where you might terminate with ctrl+c a fair amount.
If you're fine with being restricted to Powershell, creating a wrapper function isn't actually too difficult. All you need to do is add a function to your profile, which will then automatically be loaded on starting Powershell.
So you could add a function like
function rg2 () {
rg --no-heading $args
}
and just call rg2
from the command line to get --no-heading by default (although be sure to provide the full path to rg.exe
if you want to actually name the function rg
). Command Prompt is unfortunately not as nicely integrated with anything, as far as I'm aware.
Of course, running it from Powershell with everything using the default color schemes will make the file names unreadable https://github.com/BurntSushi/ripgrep/issues/342.
@sgraham @elirnm I think what I'm hearing is that there is reasonably solid motivation for adding a config file to ripgrep, so I think I'm sold on that. (Others have mentioned Windows being difficult to write wrapper scripts in, but I don't think I ever got the full scoop.)
I think it makes sense to wait for clap to handle this.
For Windows, it sounds like part of the problem with the "just use an alias or similar customization" solution is that PowerShell is much easier to personalize than cmd.exe
, but most Windows users (including myself) are reluctant to learn a new shell (or have never used a decent shell in the first place and don't understand the benefits) and therefore either stick to cmd.exe
or use something like git-bash
or Cygwin (which come with a host of complications and oddities, but are better than raw cmd.exe
). I know that personalizing cmd.exe
with alias-like things is possible*, but every time I think about trying it and look up the steps, it seems like it's more trouble than it's worth.
As an example: recently, I learned the hard way that in git-bash
, ln -s
silently copies the target to the new "symlink" file, rather than making a true symlink. Here is complete workaround in all its gory glory. Relatedly, once a real directory symlink is made in Windows, del
(which typically behaves like rm
) will recursively delete the entire linked directory. The only way to actually delete just the symlink* is to use...rmdir
. Really. Fun times!
Another argument against using an alias is that config files might allow you to have per-project settings, as ack
lets you have by creating an .ackrc
right in your project folder.
It should be doable to do that with a bash function though, so I may be able to help myself.
Reading the above thread, it sounds like this is not a use case that's been considered or planned so far, so please consider this a feature request while planning this. :-)
@teeberg Thanks! That is a good one, and certainly seems like a logical addition. But it is good to keep in mind!
@BurntSushi really thanks for this great tool, I am author of spacevim, and I am writting a background search tools for spacevim, now we support: ag
, rg
, pt
, ack
and grep
. and I use neovim's job api to implement this feature. in ag
, pt
, ack
the line number is enable by default, but when use rg
, I need to add an extra argv -n
to jobstart().
and here is the PR https://github.com/SpaceVim/SpaceVim/pull/699 and here is the fix commit for rg support in spacevim searching tools https://github.com/SpaceVim/SpaceVim/pull/699/commits/b30a3bb7d6af71b66e89a8a2ca9e085411444b77
what I hope is -n
will be enabled by default.
sorry, I think it is not a bug, so I am not sure if I should open issue for it.
I'd love to keep different types for instance, and not have to specify
--type-add
each time.My specific case is type zsh which searches zsh config files (
.zshrc
*.zsh
, and some custom.zsh*
).Maybe it could support more stuff like
no-heading
,--heading
etc as well, which would allow people to customize rg more.(I know I can just
alias rgzsh="rg --type-add 'zsh:*.zsh' --type-add 'zsh:.zshrc' --type zsh"
, but meh)Loving the tool, btw!