How can I build a tag file for Django templates, in order to jump to file definitions of extends and include template tags?

Here's the script PROJECT/.git/hooks/ctags-html I've tried so far

set -e
dir="`git rev-parse --git-dir`"
trap 'rm -f "$dir/$$.tags-html"' EXIT
git ls-files | \
  # DOC: ctags --list-kinds-full | grep -i html
  ctags -R --fields=+l --languages=html \
      --regex-html='/extends \"([a-zA-Z0-9_-]+\.html)\"/\1/t,templates/' \
      --html-kinds=+at \
      -f"$dir/$$.tags-html" $(python -c "import os, sys; print(' '.join('{}'.format(d) for d in sys.path if os.path.isdir(d)))")
mv "$dir/$$.tags-html" "$dir/tags-html"

In short, the script does:

  • Find my git repo files
  • call ctags with html parser on all git repo files + other files from related python packages.
  • generate tags for anchor <a> elements and template tag {% extends "" %}

When I call ./git/hooks/ctags.html, a .git/tags-html file is generated

base.html   /home/dori/.virtualenvs/env/lib/python3.7/site-packages/wagtail/project_template/home/templates/home/home_page.html /^{% templatetag openblock %} extends "base.html" {% templatetag closeblock %}$/;"  t   language:HTML
base.html   /home/dori/.virtualenvs/env/lib/python3.7/site-packages/wagtail/project_template/project_name/templates/404.html    /^{% templatetag openblock %} extends "base.html" {% templatetag closeblock %}$/;"  t   language:HTML
base.html   /home/dori/.virtualenvs/env/lib/python3.7/site-packages/wagtail/project_template/search/templates/search/search.html    /^{% templatetag openblock %} extends "base.html" {% templatetag closeblock %}$/;"  t   language:HTML

But then, when opening a template file with vim

{% extends "base.html" %}

{% load i18n wagtailcore_tags wagtailimages_tags static %}
{% load debugger_tags %}

{% block body_class %}template-blogpage{% endblock %}

When I set the cursor on base.html and press CTRL-] to go to the definition, I only get E426: tag not found: base.

1 Answer 1


The issue you're having is that your tags are filenames with extensions (which include a ".") but searching for that tag using Ctrl-] is actually only looking for the base name of the file without the extension.

You can see that through the error message you're getting:

E426: tag not found: base

You can check whether your tags are otherwise working properly with a command such as :tag base.html, which is looking for the full tag.

You can fix the issue with Ctrl-] by adding . to the list of valid keyword characters, which you can do by modifying the 'iskeyword' option. You can add . to that option using:

set iskeyword+=.

If what you really want is to jump to files in your work tree, perhaps using the gf command is a more straightforward way to do so? You don't really have to generate a tags file to use that command. Though I can see that that would be a problem if you have many files named the same (many "base.html"s in distinct subdirectories of your tree.)

You can customize the 'path' option to control where commands like gf will look for files. For example, to search recursively through the whole subtree starting at the current directory:

set path+=**

That might be helpful if your filenames are for the most part unique (which, as mentioned before, might not be the case for you.)

(A better alternative to setting path+=** is to use a fuzzy finder plugin. Or you could be more specific about that setting for your project and file types. In any case, the general idea is that if you're looking for filenames, vim can do that for the most part without the need for an index, so using tags is not necessarily the most appropriate way to accomplish that.)

  • 1
    Setting path to **generally has unintended consequences, but there are ways to set it up appropriately.
    – D. Ben Knoble
    Commented Jun 5, 2019 at 12:40
  • 1
    I had thought about the . issue and manually removed the .html part of the tags-html file, but it still didn't show up in vim. Didn't think about gf, I thought it only worked for relative of full paths. Will give this a try tomorrow, thank you very much! Will mark completed once I get this resolved :) Commented Jun 5, 2019 at 12:44
  • @D.BenKnoble what are the issues with path+=**? I saw that recommendation in a Youtube video and used it sometimes, haven't had an issue with it... I can post a question about it if you think it's worth it!
    – filbranden
    Commented Jun 5, 2019 at 12:46
  • 1
  • @D.BenKnoble - I agree with the general point, but it's possible that for this specific case (django html templates) path+=** might really be good enough? Anyways, added a clarification suggesting a fuzzy finder plugin as an alternative. Thanks for the pointers!
    – filbranden
    Commented Jun 5, 2019 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.