haskdogs: Generate tags file for Haskell project and its nearest deps

[ bsd3, development, program ] [ Propose Tags ]

Haskdogs is a 300-lines tool which creates tag file for entire Haskell project directory. It takes into account first-level dependencies by recursively scanning imports and adding matching packages to the final tag list. As a result, programmer can use his/her text editor supporting tags (vim, for example) to jump directly to definition of any standard or foreign function he/she uses. Note, that haskdogs calls some Unix shell commands like grep so this tool will likely fail to work on pure Windows platforms. Starting from 0.3, cmdline args will be passed to hasktags followed by a filelist generated. Starting from 0.4, haskdogs will use stack toolchain.


[Skip to Readme]
Versions [faq] 0.1, 0.2, 0.3, 0.3.1, 0.3.2, 0.4.0, 0.4.1, 0.4.2, 0.4.4, 0.4.5, 0.5.0, 0.5.1, 0.5.3, 0.5.4, 0.6.0
Dependencies base (>=4.8 && <5), containers, directory, filepath, hasktags, optparse-applicative, process-extras, text [details]
License BSD-3-Clause
Author Sergey Mironov
Maintainer grrwlf@gmail.com
Category Development
Home page http://github.com/grwlf/haskdogs
Source repo head: git clone http://github.com/grwlf/haskdogs
Uploaded by SergeyMironov at Fri Jan 25 23:19:24 UTC 2019
Distributions NixOS:0.6.0
Executables haskdogs
Downloads 3908 total (181 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs not available [build log]
Last success reported on 2019-01-25 [all 3 reports]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for haskdogs-0.6.0

[back to package description]

HaskDogs

Haskdogs is a shellscript-like tool which creates tag file for entire haskell project directory. It takes into account first-level dependencies by recursively scanning imports and adding matching projects to the dependency list. Next, Haskdogs uses cabal or stack to unpack their sources into a temporary directory, which is ~/.haskdogs by default. Finally, hasktags is called to produce the tags file.

As a result, programmer can use his/her text editor supporting tags (e.g. vim) to jump directly to definition of any standard or foreign function he/she uses.

Note, that haskdogs relies on some GNU programs as well as on Unix shell commands such as 'cd', 'mkdir' and so on. Also it would run 'stack' and ghc-pkg' in order to obtain package information.

INSTALL

Check the dependencies. Currently they are: stack, hasktags, GNU find, which and shell.

Please follow stack's documentation(https://github.com/commercialhaskell/stack) to install stack.

$ stack install hasktags haskdogs

Make sure that PATH contains path to your stack binaries directory ($HOME/.local/bin by default).

RUNNING

  1. Make sure yoy have installed hasktags and put it in PATH.

  2. cd to your Haskell project dir

    $ cd $HOME/my-haskell-project
    
  3. Run haskdogs without arguments to generate tags file in Vim-compatible format

    $ haskdogs
    

Emacs users would probably want to add -e hasktags option to build Emacs-compatible TAGS.

$ haskdogs --help
haskdogs - Recursive hasktags-based TAGS generator for a Haskell project

Usage: haskdogs [--version] [-d|--dir-list FILE] [-f|--file-list FILE]
                [-i|--input FILE] [--hasktags-args OPTS] [--stack-args OPTS]
                [--ghc-pkg-args OPTS] [--use-stack ARG] [--deps-dir PATH]
                [--raw] [-q|--quiet] [OPTS]

Available options:
  -h,--help                Show this help text
  --version                Show version number
  -d,--dir-list FILE       File containing directory list to process (use '-' to
                           read from stdin)
  -f,--file-list FILE      File containing Haskell sources to process (use '-'
                           to read from stdin)
  -i,--input FILE          Single Haskell file to process (use '-' to read
                           Haskell source from stdin)
  --hasktags-args OPTS     Arguments to pass to hasktags. -c -x is the default.
                           Not for raw mode.
  --stack-args OPTS        Arguments to pass to stack
  --ghc-pkg-args OPTS      Arguments to pass to ghc-pkgs
  --use-stack ARG          Execute ghc-pkg via stack, arg is ON, OFF or AUTO
                           (the default)
  --deps-dir PATH          Specify the directory PATH to place the dependencies
                           of the project. Default is [$HOME/.haskdogs]
  --raw                    Don't execute hasktags, print list of files to tag on
                           the STDOUT. The output may be piped into hasktags
                           like this: `haskdogs --raw | hasktags -c -x STDIN'
  -q,--quiet               Don't print verbose messages
  OPTS                     More hasktags options, use `--' to pass flags
                           starting with `-'. Not for raw mode.

The following error could be caused by (over)strict Haskell policy regarding Unicode locale:

haskdogs: fd:5: hGetContents: invalid argument (invalid byte sequence)

It usually happens when the program tries to print Unicode character to non-unicode console. In order to overcome, try the following setting:

export LANG=en_US.UTF8

VIM HINT

Hasdogs (and underlying Hasktags) use simple scanning algorithm so it may become confused facing functions with identical names. In this case Hasktags includes all of them in the output file so user has to decide which tag to jump to. Vim offers :tag and :ts commands to deal with such situations but it is somewhat cumbersome to type them every time.

To speedup things a bit I use the following vim binding. It iterates over all same tags quickly with just one C-] command.

" Cyclic tag navigation {{{
let g:rt_cw = ''
function! RT()
    let cw = expand('<cword>')
    try
        if cw != g:rt_cw
            execute 'tag ' . cw
            call search(cw,'c',line('.'))
        else
            try
                execute 'tnext'
            catch /.*/
                execute 'trewind'
            endtry
            call search(cw,'c',line('.'))
        endif
        let g:rt_cw = cw
    catch /.*/
        echo "no tags on " . cw
    endtry
endfunction
map <C-]> :call RT()<CR>
" }}}

Just copy the code above to your ~/.vimrc and reload the vim.

NIX NOTE

The easiest way to generate Hakell tags on Nix-machine is to run Haskdogs from nix-shell as follows:

nix-shell -p haskellPackages.haskdogs haskellPackages.hasktags haskellPackages.cabal-install ghc
(nix-shell) $ haskdogs

TIPS

  • create tags for specific package

    echo 'import Control.Lens' | haskdogs -i -

  • incremental update

    haskdogs -i % --hasktags-args "-x -c -a" | sort -u -o tags tags