How do I add a persistent configuration option to 'ag'? - ag

I have recently begun to use the 'ag' command instead of 'ack'.
Ag is much faster, but does not seem to have a file (such as .ackrc) where one could add configuration options.
For example, I always want a pager to be used, and I don't want to have to always type in:
ag --pager "less -R"

How about putting the following in your command line configuration file (such as .bashrc or .zshrc)?
alias ag="ag $* --pager 'less -R'"

Hope this is not way too late.
Run man ag on linux box. Right at the end if the following text:
By default, ag will ignore files matched by patterns in .gitignore,
.hgignore, or .agignore. These files can be anywhere in the
directories being searched. Ag also ignores files matched by the
svn:ignore property in sub‐
version repositories. Finally, ag looks in $HOME/.agignore for ignore patterns. Binary files are ignored by default as well.
Note the part I emphasised. So just add .agignore file and ignore patterns in there
-

Related

How to use ag aka the_silver_search to search for directories only?

I like to search for directories only, and the option ag --list-file-types is not helpful with that. The reason to stick to ag is the possibility to pick a file with --path-to-ignore containing patterns to ignore.
An equivalent command would be fd --type d.
Use the -G argument, and specify a directory name.
For example, if you wanted to search for the word "foobar" in only your Downloads directory:
ag -G "Downloads/" foobar

How can I force ag to find matches in node_modules?

I'm using ag to search a git repo. It doesn't find matches under my node_modules subdirectory. Why not, and how can I control this behavior?
It turns out that ag honors the contents of the .gitignore file by default. So if node_modules is in .gitignore, ag won't search it. This is all sensible behavior, but difficult to debug if you aren't expecting it. Hopefully this post will help.
There's a good summary at the end of man ag:
IGNORING FILES
By default, ag will ignore files whose names match patterns in .gitig-
nore, .hgignore, or .agignore. These files can be anywhere in the
directories being searched. Ag also ignores files matched by the
svn:ignore property if svn --version is 1.6 or older. Finally, ag looks
in $HOME/.agignore for ignore patterns. Binary files are ignored by
default as well.
If you want to ignore .gitignore, .hgignore, and svn:ignore, but still
take .agignore into account, use -U.
Use the -t option to search all text files; -a to search all files; and
-u to search all, including hidden files.
For my purposes ag -t seems to work well.

hg: how to exclude "*.xll" file but not xll directory

In my .hgignore file, I am trying to ignore all generated xll files. I (unfortunately) have a directory called "xll" within the domain of the repository, and I do not want to ignore the directory itself.
I have tried:
syntax: regex
\.xll$
which I thought should mean "match all that ends in '.xll'"
and
syntax: regex
*.\.xll$
which I thought should mean "match all that have at least one arbitrary character, followed by '.xll'".
With either of the above, the directory is not ignored (yay) but neither is a file foobar.xll (darn). If I use a bare "xll" with regex, or "*.xll" with glob, both the directory and the file are ignored.
This is in linux (Ubuntu 10.04.4) with hg 2.6 (TortoiseHG 2.8) (I'm observing the effect in Nautilus via the presence or absence of "X" icons).
Thanks in advance!
EDIT
(adding comments in here as they are too long to fit in a comment...)
Thanks for all the responses. Turns out I was misinterpreting some things. So:
- because I used "regex" instead of "regexp" (and I had "glob" at top of file), whatever I put on the line that referred to "xll" was being interpreted by "glob", so the line did have an effect (which made me think, incorrectly, that the "syntax: regex" line was doing what I thought it was
- by coincidence, all the files in my "xll" directory were filtered out (as they should have been) by other lines in .hgignore, and not by the "*.xll" line
- consequently, in Nautilus, the xll directory was marked as "ignored", not because the filter ignoring the entire directory, but instead because other filters were filtering all files within that directory
Bottom line, the *.xll I had under "syntax: glob" was actually filtering out files exactly as desired. The feedback in Nautilus was just different than I expected.
It's .*\.xll$, not *.\.xll$.
Using glob syntax works well for me:
syntax: glob
*.xll
When I create a directory named xll with an untracked file, I still see the file in the output from hg status:
$ mkdir xll
$ touch a.xll x.txt xll/b.xll xll/y.txt
$ echo 'syntax: glob\n*.xll' > .hgignore
$ hg status
? .hgignore
? x.txt
? xll/y.txt
Using \.xll$ with syntax: regexp also works great for me.

Automatically fix filename cases in C++ codebase?

I am porting a C++ codebase which was developed on a Windows platform to Linux/GCC. It seems that the author didn't care for the case of filenames, so he used
#include "somefile.h"
instead of
#include "SomeFile.h"
to include the file which is actually called "SomeFile.h". I was wondering if there is any tool out there to automatically fix these includes? The files are all in one directory, so it would be easy for the tool to find the correct names.
EDIT: Before doing anything note that I'm assuming you either have copies of the files off ot the side or preferably that you have a baseline version in source control should you need to roll back for any reason.
You should be able to do this with sed: Something like sed -i 's/somefile\.h/SomeFile.H/I' *.[Ch]
This means take a case-insensitive somefile (trailing /I) and do an in-place (same file) replacement (-i) with the other text, SomeFile.H.
You can even do it in a loop (totally untested):
for file in *.[Ch]
do
sed -i "s/$file/$file/I" *.[Ch]
done
I should note that although I don't believe this applies to you, Solaris sed doesn't support -i and you'd have to install GNU sed or redirect to a file and rename.
Forgive my, I'm away from my linux environment right now so I can't test this myself, but I can tell you what utilities you would need to use to do it.
Open a terminal and use cd to navigate to the correct directory.
cd ~/project
Get a list of all of the .h files you need. You should be able to accomplish this with the shell's wildcard expansion without any effort.
ls include/*.h libs/include/*.h
Get a list of all of the files in the entire project (.c, .cpp, .h, .whatever), anything that can #include "header.h". Again, wildcard expansion.
ls include/*.h libs/include/*.h *.cpp libs/*.cpp
Iterate over each file in the project with a for loop
for f in ... # wildcard file list
do
echo "Looking in $f"
done
Iterate over each header file with a for loop
for h in ... # wildcard header list
do
echo "Looking for $h"
done
For each header in each project file, use sed to search for #include "headerfilename.h", and replace with #include "HeaderFileName.h" or whatever the correct case is.
Warning: Untested and probably dangerous: This stuff is a place to start and should be thoroughly tested before use.
h_escaped=$(echo $h | sed -e 's/\([[\/.*]\|\]\)/\\&/g') # escapes characters in file name
argument="(^\s*\#include\s*\")$h_escaped(\"\s*\$)" # I think this is right
sed -i -e "s/$argument/\$1$h\$2/gip"`
Yes, I know it looks awful.
Things to consider:
Rather than going straight to running this on your production codebase, test it thoroughly first.
sed can eat files like a VCR can eat tapes.
Make a backup.
Make another backup.
This is an O(N^2) operation involving hard disk access, and if your project is large it will run slowly. If your project is not gigantic, don't bother, but if it is, consider doing something to pipe sed's output to other seds.
Your search should be case insensitive: it should match #include, #INCLUDE, #iNcLuDe, and any combination of case present in the existing header filename, as well as any amount of whitespace between the include and the header. Bonus points if you preserve whitespace.
Use Notepad++ to do a 'Find in Files' and replace.
From toolbar:
Search - Find in Files.
Then complete the 'Find what' and 'Replace with'.

emacs drill down shortcut

I am new to emacs. In Netbeans, you can right click on any object and it will send you directly to the header or implementation file. Is there a shortcut key to do this in emacs?
You have to create a TAGS file first.
If you're on linux:
$ ctags -e -R *.h *.cpp
// this will create tags for all .h and .cpp files,
// starting from the current directory, and recursing into subdirectories.
// -e : emacs tags (as oposed to vi tags, the default)
// -R : recursive
You can also add to an existing tags file by using the --append flag. For example:
$ ctags --append -e -R *.h *.cpp /home/user/jdoe/thirdparty
// This will add to the TAGS file in the current directory
When you want to jump to a symbol definition, in emacs use M-x find-tag, or M-.. It'll ask you where the TAGS file is, and you're set. To pop out, use M-x pop-tag-mark, by default mapped to M-*.
Note: ctags is alright, but since it's not a compiler, sometimes it'll take you to the wrong place.
You can use etags to provide a similar functionality. Once your TAGS file is created, you can use the M-. shortcut that invokes (find-tag).
As with everything: Emacs gives you several ways to do something, in this case a bunch of them don't work out of the box. You can either use etags or if you need a really big hammer semantic, which is part of the cedet project. This will give you much more then simply jumping into a header file, but maybe that is what you need.