A library and a GHC compiler plugin which generates tags for each compiled module or component.
The plugin requires at least: ghc >= 9.6.
Usage: <program> [-e|--etags] [--stream] [--debug] [file_path]
write tags from ghc abstract syntax tree
Available options:
-e,--etags produce emacs etags file
--stream stream existing tags (ctags only)
file_path tags file: default tags or TAGS (when --etags is
specified)
--debug debugging output
It can be an absolute path or relative (to the *.cabal package file rather
than cabal.project file), for example:
-fplugin-opt=Plugin.GhcTags:../tags
This is useful if for cabal packages which are located in subdirectories.
To produce etags file you will need to pass the following option
-fplugin-opt=Plugin.GhcTags:--etags
By default each generated tags file is put next to the corresponding *.cabal
package file. If you just have a repo with a cabal file in the main directory
vim default tags setting will work, if you have some modules in
subdirectories you will either need to set:
:set tags+=*/tags
or pass an option to modify where tags are written, see below.
Configuration of this plugin requires some familiarity with ghc packages.
Check out
documentation
to use -plugin-package or -plugin-package-id. In the examples below we
use -plugin-package=ghc-tags-plugin but specifying version
-package=ghc-tags-plugin-0.0.0.0 (where 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
available.
ghc -plugin-package=ghc-tags-plugin -fplugin=Plugin.GhcTags
You might also need to pass -package-db in which you installed the plugin.
Install the ghc-tags-plugin to cabal store with:
cabal install --lib ghc-tags-plugin
In cabal.project.local file add program-options stanza, which enables the plugin
for all local packages:
program-options
ghc-options: -package-db=PACKAGE_DB
-plugin-package=ghc-tags-plugin
-fplugin=Plugin.GhcTags
PACKAGE_DB is likely to be something like
(all environment variables must be expanded):
${HOME}/.cabal/store/ghc-9.12.2/package.db
or on Windows (note the "" syntax)
"C:\\Users\\USER_NAME\\AppData\\Roaming\\cabal\\store\\ghc-8.6.5\\package.db
Note that you can also configure in this way non-local projects. You will
likely want to pass -fplugin-opt=Plugin.GhcTags=PATH where PATH is an
absolute path to your tags file.
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 a VCS).
Add ghc-tags-plugin to build-depends in your *.cabal files. (You should
hide it behind a cabal flag). And add these lines to stack.yaml file:
extra-deps:
- git: https://github.com/coot/ghc-tags-plugin
commit: a841dae7fb9c335101f7fa4187d02687d306f972
test-project: -plugin-package=ghc-tags-plugin
-fplugin=Plugin.GhcTags
If you follow the cabal configuration as above (using stack should work too)
ghcid --comaand "cabal repl project"
will update tags file as you modify your project.
The Makefile
contains some useful commands, e.g. install, uninstall or reinstall the
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.
If a GHC plugin throws an exception, GHC stops. This plugin wraps
IOExceptions, to make it obvious that it filed rather than GHC. This
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-
remove the installed version from
~/.ghc/x86_64-linux-8.6.5/environments/default(or whatever is your default environment) -
unregister the installed version from cabal store (you can check what is installed in your store with
ghc-pkg --package=PACKAGE_DB list | grep ghc-tagsfor 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: $ncpusis safe. The plugin holds an exclusive (advisory) lock on a lock file. This will create synchronisation between threads / process which are using the sametagsfile. -
If you are working on a larger project, it might be better to not collect all tags in a single
tagsfile, since at every compilation step one will need to parse a largetagsfile. 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 -fplugin-trustworthyghcflag.
Such plugins can:
- run arbitrary
IO; - 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
modify/
the syntax tree.
ghc-tags-fork is a fork of ghc-tags-hackage. Both provide a standalone
ghc-tags command. Unlike the hackage version [ghc-tags-fork] is using the
latest ghc-tags-core version.