Short Articles

vim-gutentags ignoring exclude parameters from ctags

vim-gutentags vimrc config

If you’re using vim-gutentags with Vim and struggling to exclude directories like node_modules, vendor, or themes from your tags file, you’re not alone—and the fix is simpler than you think.

The issue usually comes down to one thing: path format mismatch. vim-gutentags expects relative paths in your exclude patterns, but many users accidentally use absolute paths, causing ctags to ignore the exclusions entirely.

 

How to Confirm What Path Format vim-gutentags Uses

Add this line to your .vimrc to enable debug output:

let g:gutentags_trace = 1

When you open Vim, you’ll see a log like this:

...
gutentags: Running: ['/path/to/update_tags.sh', ..., '-p', '.', '-x', 'vendor/*', '-x', 'themes/*', ...]
gutentags: In: /your/project/root/
...

Notice the -p .? That means vim-gutentags is running ctags with a relative path (.). Therefore, your exclude patterns must also be relative—not absolute.

 

❌ Wrong: Using Absolute Paths

let g:gutentags_ctags_exclude = [
\ '/home/user/project/vendor/*',
\ '/home/user/project/themes/*',
\ '/home/user/project/node_modules/*'
\]

These won’t work because ctags is scanning from  “.“, and it’s comparing excludes against relative paths like `vendor/`, not `/home/user/project/vendor/`.

 

✅ Correct: Use Relative Paths

let g:gutentags_ctags_exclude = [
\ 'vendor/*',
\ 'themes/*',
\ 'node_modules/*',
\ 'build/*'
\]

This matches exactly what ctags sees during traversal.

This behavior stems from how Universal Ctags processes command-line options and paths. If you’re using ctags directly (not through gutentags), remember that all --exclude flags must appear before the source path—otherwise they’re silently ignored. Learn more in our guide: Why Universal Ctags ignores your –exclude flags .

 

Why This Happens: It’s a ctags Behavior

Universal Ctags applies --exclude patterns against the relative file paths used during recursion. If you run:

ctags -R --exclude=$PWD/node_modules .

…it fails, because $PWD/node_modules (absolute) doesn’t match the relative path ./node_modules.

But this works:

ctags -R --exclude=node_modules .

vim-gutentags follows the same rule—so always use relative patterns in g:gutentags_ctags_exclude.

 

Pro Tip

Keep your exclude list clean and generic. This makes your .vimrc portable across projects:

let g:gutentags_ctags_exclude = [
\ 'node_modules/*',
\ 'vendor/*',
\ '.git/*',
\ 'build/*',
\ 'dist/*',
\ '__pycache__/*'
\]

Now your tags file stays lean, fast, and free of third-party noise.

Happy coding—and happy tagging!

PS. If you’re serious about mastering Vim—and making tools like ctags, gutentags, and tags navigation work for you, not against you—do yourself a favor and grab a copy of Practical Vim: Edit Text at the Speed of Thought . It’s the one book that will transform how you use Vim daily, and it’ll save you hours of frustration (and Stack Overflow rabbit holes).

Tagged , , , , , , , ,

1 thought on “vim-gutentags ignoring exclude parameters from ctags

Leave a Reply

Your email address will not be published. Required fields are marked *