Vim and Ctags: Ignoring certain files while generating tags - vim

I have a folder llvm2.9 in which i ran this command.
$> ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++
This was indexing methods in *.html files also which were present in llvm2.9/docs. I found this out because when i pressed ctrl-] for some class, it went to the html file.
How do i force ctags to use .cpp/.h files alone or ignore a particular directory.
Thanks

You can exclude a filetype using
--exclude='*.html'

If you need to exclude more than just .html files:
You can't comma separate a list inside an exclude option. This doesn't work:
ctags --exclude=*.html,*.js ./*
However, you can pass multiple exclude options:
ctags --exclude=*.html --exclude=*.js ./*
Pass the -V option to help with debugging:
ctags -V --exclude=*.html --exclude=*.js ./*
Gives the output:
Reading initial options from command line
Option: --exclude=*.html
adding exclude pattern: *.html
Option: --exclude=*.js
adding exclude pattern: *.js

The simplest way in vim would be
:!ctags {.,**}/*.{cpp,h}
Explanation: The braces expand to
:!ctags ./*.cpp **/*.cpp **/*.h **/*.h
So it looks for source or header files in the current directory (./) or any nested directory (**/). Note **/ wouldn't match the current directory (it always matches at least 1 sub directory level)
In shell:
find -iname '*.cpp' -o '*.h' -print0 | xargs -0 ctags
Explanation: This recursively finds all .cpp and .h files under the current directory and passes them to ctags on the command line.
The way print0 and -0 work together is to ensure it works correctly with weird filenames (e.g. containing whitespace or even new line characters)
I'll leave the rest of the ctags options for your own imagination :)
PS. For recent bash-es, you can use
shopt -s globstar
ctags {.,**}/*.{cpp,h}
and get much the same behaviour as in vim !

I didn't want to track down every filetype which might get processed in a large project, and I was only interested in Python, so I explicitly only processed python files using ctags --languages=Python .... The list of language names can be seen using ctags --list-languages.

Related

executing Linux sed command and version control complain

I have a folder which contains jsp files. I used find and sed to change part of the text in some files. This folder is under version control. The command successfully changed all the occurrences of the specified pattern But
The problem is when I'm synchronizing the folder with the remote repository I can see so many files listed as modified which actually nothing in that file has changed. There is sth wrong with the white space I suppose. Could anyone shed some light on this matter.
I'm trying to replace ../../images/spacer to ${pageContext.request.contextPath}/static/images/spacer in all jsp files under current folder
The command I'm using is as below
find . -name '*.jsp' -exec sed -i 's/..\/..\/images\/spacer/${pageContext.request.contextPath}\/static\/images\/spacer/g' {} \;
In most of systems, grep has an option to recursively search for files that contains a pattern, avoiding find.
So, the command would be:
grep -r -l -m1 "\.\./\.\./images/spacer" --include \*.jsp |
xargs -r sed -i 's!\.\./\.\./\(images/spacer\)!${pageContext.request.contextPath}/static/\1!g'
Explanation
Both grep and sed work with regular expression patterns, in which th dot character . represent any character including the dot itself. In order to explicit indicate a dot, it must be escaped with a \ before it. So to search .. is necessary specify \.\., or it can match texts like ab/cd/
Now, about the grep options:
-m1 stops search when finds the first occurrence avoiding search the entire file.
-r search recursively in the directories
--include \*.jsp search only in files with FILEPAT file pattern.

linux include all directories

how would I type a file path in ubuntu terminal to include all files in all sub-directories?
If I had a main directory called "books" but had a ton of subdirectories with all sorts of different names containing files, how would I type a path to include all files in all subdirectories?
/books/???
From within the books top directory, you can use the command:
find . -type f
Then, if you wanted to, say run each file through cat, you could use the xargs command:
find . -type f | xargs cat
For more info, use commands:
man find
man xargs
It is unclear what you actually want ... Probably you will get a better solution to your problem, if you ask directly for it, not for one other problem you've come accross trying to circumvent the original problem.
do you mean something like the following?
file */*
where the first * expands for all subdirectories and the second * for all contained files ?
I have chosen the file command arbitrarily. You can choose whatever command you want to run on the files you get shell-expanded.
Also note that directories will also be included (if not excluded by name, e.g. *.png or *.txt).
The wildcard * is not exactly the file path to include all files in all subdirectories but it expands to all files (or directories) matching the wildcard expression as a list, e.g. file1 file2 file3 file4. See also this tutorial on shell expansion.
Note that there may be easy solutions to related problems. Like to copy all files in all subdirectories (cp -a for example, see man cp).
I also like find very much. It's quite easy to generate more flexible search patterns in combination with grep. To provide a random example:
du `find . | grep some_pattern_to_occur | grep -v some_pattern_to_not_occur`
./books/*
For example, assuming i'm in the parent directory of 'books':
ls ./books/*
EDIT:
Actually, to list all the tree recursively you should use:
ls -R ./books/*

Searching for information in files in several directories

I need to check several files which are in different locations for a specific information.
So, how to make a script which checks for the argument word through several directories?
The directories are in different locations. For ex.
/home/check1/
/opt/log/
/var/status/
You could also do (next to ´find´)
do a
for DIR in /home/check1 /opt/log /var/status ; do
grep -R searchword $DIR;
done
At the very simplest, it boils down to
find . -name '*.c' | xargs grep word
to find a given word in all the .c files in the current directory and below.
grep -R may also work for you, but it can be a problem if you don't want to search all files.
Use the grep -R (recursive) option and give grep multiple directory arguments.
Try find http://content.hccfl.edu/pollock/Unix/FindCmd.htm using your searchwords and the directories.
The man page of grep should explain what you need. Anyway, if you need to search recursively you can use:
grep -R --include=PATTERN "string_to_search" $directory
You can also use:
--exclude=PATTERN to skip some file
--exclude-dir=PATTERN to skip some directories
The other option is use find to get the files and pipe it to grep to search the strings.

Vim: Difficulty setting up ctags. Source in subdirectories don't see tags file in project root

I'm trying to get setup with (exuberant) ctags on Vim today and am having difficulty getting it to work properly. I generate my ctags file on the command line with with:
cd myproj
ctags -R
This puts the tags file in myproj root. However, Vim only seems to read from this tags file when I'm working on source that reside in root. As I navigate to deeper directories, if I try to jump to a tag using <C-]>, I get:
E433: No tags file
E426: tag not found: MyClassName
I've verified that MyClassName does have a tag in the tags file, it's just that Vim doesn't see it. Can someone please explain how to configure Vim to reference the root's tags file?
Thanks.
add this to .vimrc file set tags=tags;/
This will check the current folder for tags file and keep going one directory up all the way to the root folder.
So you can be in any sub-folder in your project and it'll be able to find the tags files.
There is an option to tell Vim where to look for tag file.
I use the following configuration:
" search first in current directory then file directory for tag file
set tags=tags,./tags
Extract from help :
When a tag file name starts with "./", the '.' is replaced with the path of
the current file. This makes it possible to use a tags file in the directory
where the current file is (no matter what the current directory is). The idea
of using "./" is that you can define which tag file is searched first: In the
current directory ("tags,./tags") or in the directory of the current file
("./tags,tags").
For example:
:set tags=./tags,tags,/home/user/commontags
And I keep my current working directory in the top project directory where my tagsfile is generated.
Use :pwd and then :cd myproj (inside Vim) to go to the directory containing your tags file.
See :help tags-option for more information on tags path.
You issue is probably that you are either in the wrong directory, or your tags option is not properly set.
#!/bin/sh
FREEZE_NAME=/* Give some version number */
mkdir $HOME/ctags/$FREEZE_NAME
V1=/* Software Path */
find $V1 -name "*.h" | xargs /usr/local/bin/ctags -a -f $HOME/ctags/$FREEZE_NAME/h.tags
find $V1 -name "*.c" | xargs /usr/local/bin/ctags -a -f $HOME/ctags/$FREEZE_NAME/c.tags
cd $HOME/ctags/$FREEZE_NAME/
rm -f all.tags
cat c.tags h.tags >> all.tags
sort all.tags > temp.tags
mv temp.tags all.tags
rm -f c.tags h.tags
Put the above code in a .sh file and run... This will generate your tags for sure.
If you generate a tags file for every project, you might like this pattern, especially if you share your .vimrc across different machines:
let repohome=substitute($REPO_HOME, "\/", "\\\\/", "g")
let &tags=substitute(expand("%:p:h"), "\\(".repohome."/.\\{-}\/\\).*", "\\1tags", "")
You would then have to set the environment variable $REPO_HOME in your .bashrc to your main repo directory without the trailing space (e.g. /home/<yourusername>/repos) and it will automatically look for a tags file in each subdirectory of $REPO_HOME with a depth of 1, e.g. /home/<yourusername>/repos/myproj/tags.
Create a .sh file with below code. And run .sh file where you want tags.
That will work for sure.
#!/bin/sh`enter code here`
filelist=`mktemp`
find . -name \*.h >> ${filelist}
find . -name \*.c >> ${filelist}
find . -name \*.cc >> ${filelist}
find . -name \*.cpp >> ${filelist}
find . -name \*.hpp >> ${filelist}
if [ "$SDKTARGETSYSROOT" != "" ]; then
find $SDKTARGETSYSROOT/usr/include -name \*.h >> ${filelist}
fi
cat ${filelist} | ctags -L -

Match all files under all nested directories with shell globbing

Is there a way to use shell globbing to identify nested directories?
so if I have dir/dir1/dir2/dir3/dir4/dir5/.. and I have files under all of them, what is the equivalent globbing pattern to match all files under all directories, similar to - for example - ls -R
In Bash 4, with shopt -s globstar, and zsh you can use **/* which will include everything except hidden files. You can do shopt -s dotglob in Bash 4 or setopt dotglob in zsh to cause hidden files to be included.
In ksh, set -o globstar enables it. I don't think there's a way to include dot files implicitly, but I think **/{.[^.],}* works.
Specifically about git (gitignore, gitattributes, and commands that take filenames): if the pattern contains no slash, * wildcards will match deep. If it does contain a slash, git will call fnmatch with the FNM_PATHNAME flag, and simple wildcards won't match slashes. ** to match deep isn't supported. Maybe this kind of deep matching could be more widely supported with a new FNM_STARSTAR flag, and an implementation in glibc, gnulib and other places.
If you want to act on all the files returned by find, rather than just list them, you can pipe them to xargs:
find <directory> -type f | xargs ls
But this is only for commands that don't have a recursive flag.
You may try:
**/*.*
However it'll ignore hidden files (such as .git files). Sometimes it's a life-saver.
Read more at: What expands to all files in current directory recursively? at SO
You can use tree, it will show all folders recursively.
tree <path>
There is no way to do this with vanilla Bash, however most commands accept a -R or --recursive option to tell them to descend into directories.
If you simply want to list all files located anywhere within a directory or its sub-directories, you can use find.
To recursively find files (-type f) with a given directory:
find <directory> -type f

Resources