A library and a GHC compiler
which generates tags for each compiled module or component.
The plugin requires at least:
ghc >= 8.8;
ghc-tags-plugin can generate tags
for template-haskell splices, but it requires:
ghc >= 8.10.
ghc-9.4 includes a fix which makes
cabal cache mechanism
● Plugin options
Usage: <program> [-e|--etags] [--stream] [--debug] [file_path]
write tags from ghc abstract syntax tree
-e,--etags produce emacs etags file
--stream stream existing tags (ctags only)
file_path tags file: default tags or TAGS (when --etags is
--debug debugging output
It can be an absolute path or relative (to the
*.cabal package file rather
cabal.project file), for example:
This is useful if for cabal packages which are located in subdirectories.
● Emacs support
etags file you will need to pass the follwing option
● Editor configuration
By default each generated tags file is put next to the corresponding
package file. If you just have a repo with a cabal file in the main directory
tags setting will work, if you have some modules in
subdirectories you will either need to set:
or pass an option to modify where tags are written, see below.
● Configuration: Ghc / Cabal / Stack
Configuration of this plugin requires some familiarity with
-plugin-package-id. In the examples below we
-plugin-package=ghc-tags-plugin but specifying version
0.0.0.0 is the version you
installed), might work better. You can use
ghc-pkg latest ghc-tags-plugin
(likely with appropriate
--package-db flag) to check which version is
ghc -plugin-package=ghc-tags-plugin -fplugin=Plugin.GhcTags
You might also need to pass
-package-db in which you installed the plugin.
ghc-tags-plugin to cabal store with:
cabal install --lib ghc-tags-plugin
cabal.project.local file add
package stanza for every local package :
PACKAGE_DB is likely to be something like (for
(all environment variables must be expanded):
or on Windows (note the
Note that you can also configure in this way non-local projects. You will
likely want to pass
PATH is an
absolute path to your
This is alternative method, which also could be modified for
cabal (but it is
not as nice as the previous method where you don't need to modify any files
checked in vcs).
build-depends in your
*.cabal files. (You should
hide it behind a cabal flag). And add these lines to
- git: https://github.com/coot/ghc-tags-plugin
If you follow the cabal configuration as above (using
stack should work too)
ghcid --comaand "cabal repl project"
tags file as you modify your project.
contains some useful commands, e.g.
package in a
package.db (by default into
cabal store). This is mostly for
development, but it could be useful in other scenarios as well.
GHC plugin throws an exception,
GHC stops. This plugin wraps
IOExceptions, to make it obvious that it filed rather than
might mean you misconfigured the plugin (by passing wrong options). The
result might look like this:
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.5 for x86_64-unknown-linux):
GhcTagsPluginIOException ../: openFile: inappropriate type (Is a directory)
If you're getting installation problems when running
cabal install --lib ghc-tags-plugin; you may need to
installed in your store with
ghc-pkg --package=PACKAGE_DB list | grep ghc-tags
for the following command):
ghc-pkg --package-db=PACKAGE_DB unregister z-ghc-tags-plugin-z-ghc-tags-library ghc-tags-plugin
The plugin is safe for concurrent compilation, i.e. setting
jobs: $ncpus is
safe. The plugin holds an exclusive (advisory) lock on a lock file. This
will create synchronisation between threads / process which are using
If you are working on a larger project, it might be better to not collect all
tags in a single
tags file, since at every compilation step one will need
to parse a large
tags file. Working with tag files of size 10000 tags (or
~1.5MB) is ok - though this will depend on the hardware.
If you're working on a project that is using
safe-haskell, you will likely
need to pass
● Security implications of compiler plugins
Such plugins can:
- run arbitrary
- modify abstract syntax tree in some way; a malicious plugin could change
some security parameter in your code exposing a security hole.
This plugin only reads & writes to
tags file (and updates a shared mutable
state) as of
IO, and does not
the syntax tree.