
The good reason is that you do not actually want to have to specify all the options that you need to get your program to compile, merely to get tag information. To generate the tags for dazzle using ghci I need to use echo ":ctags"| ghci -v0 Main.hs -i../lib -i../lib/DData/ -fglasgow-exts -L../ -lsmilec whereas with hasktags I'd just use hasktags *.hs
yes, that's a general problem with using ghci in real projects. of course, *.hs isn't always sufficient to find the files for a project, and the files might need pre-processing, etc. but there are advantages to not having a proper parser and just treating a project as a collection of files, to be found by globbing or find, and to be scanned for some simple patterns. it means that one can get tags for incomplete projects, even with errors in the files. but as far as the extra options are concerned, i tend to create a miniscript to set the options for a project, and use the fact that --make/--interactive switch between ghc and ghci: #!/bin/sh ghc ${mode:-"--make"} $@ -i../lib -i../lib/DData/ -fglasgow-exts -L../ -lsmilec then, to build with ghc: ./myghc.sh Main.hs or, to invoke ghci: mode="--interactive" ./myghc.sh Main.hs or, to generate tags from outside ghci (this might be worth a command alias): echo ":ctags" | mode="--interactive -v0" ./myghc.sh Main.hs such scripts wouldn't be needed if ghc/ghci could be started from cabal files - you'd just set your options and paths once and for all (there's a ticket for that somewhere). once I'm set up in ghci, as I tend to be while hacking, it is of course just :ctags rather than finding a shell and typing find . -name *hs | xargs hasktags or somesuch;-)
What I would *really* like is a Haskell parser in Exuberant Ctags... that would mean I could directly use vim's taglist extension.
another good point, but: exuberant ctags is just another tagfile generator. it is very good for other languages, but *really* teaching it about Haskell is non-trivial. whereas ghci or ghc-api already know how to type things and all the rest of Haskell's static semantics, in addition to parsing things.. as for using taglist: do you mean the vim function taglist, which gives you a dictionary with information associated with a tag? so you are probably interested in extra information about tags, beyond source location. (*) it should be a lot easier to expand the information generated by :ctags than to add a Haskell parser/type checker to exuberant ctags. the format is simply a comment (to protect old vi from choking on the extra info) followed by a list of extra fields (the dictionary) for each tag. see ":help tags-file-format" in vim, the third variant of the format. the only reasons i didn't do that right away was (a) it was my first serious attempt at using ghc api/extending ghci (Simon M had to do some reworking of my submitted code;-) and (b) i don't know how to use that kind of info in the emacs branch. have a look at ghc/compiler/ghci/InteractiveUI.hs, around listTags/TagInfo. if one knows where to get it, one could add info there (eg, the type of the tag, or whether the tag is a type/class/function/module/whatever). and the extra info ought to be written to the tags file, in collateAndWriteTags (simply ignore the extra info when writing the emacs tag file). hth, claus (*) if you want to go for broke, try ":help cursorhold-example" in vim. that will keep a preview window with the source-location of any tag your cursor remains on for long enough. so you might see the type declaration, or you might see the data type constructors belonging to a type, or .. i haven't used this as a default myself, but it is worth looking at at least once!-)

On 21-feb-2007, at 20:18, Claus Reinke wrote:
The good reason is that you do not actually want to have to specify all the options that you need to get your program to compile, merely to get tag information. To generate the tags for dazzle using ghci I need to use echo ":ctags"| ghci -v0 Main.hs -i../lib -i../lib/DData/ - fglasgow-exts -L../ -lsmilec whereas with hasktags I'd just use hasktags *.hs
yes, that's a general problem with using ghci in real projects. of course, *.hs isn't always sufficient to find the files for a project, and the files might need pre-processing, etc. but there are advantages to not having a proper parser and just treating a project as a collection of files, to be found by globbing or find, and to be scanned for some simple patterns. it means that one can get tags for incomplete projects, even with errors in the files.
I fully concur. And the examples I gave do in fact work for the code
for Dazzle (some 14000 loc). hasktags is quite a bit faster than ghci
as well.
What I would *really* like is a Haskell parser in Exuberant Ctags... that would mean I could directly use vim's taglist extension.
another good point, but:
exuberant ctags is just another tagfile generator. it is very good for other languages, but *really* teaching it about Haskell is non-trivial. whereas ghci or ghc-api already know how to type things and all the rest of Haskell's static semantics, in addition to parsing things..
My current thoughts lean toward linking exuberant ctags with ghc-api in JustTypecheck mode, which would give me huge flexibility, allowing for e.g. multiple-language projects including Haskell code (one thing I didn't mention is that Dazzle builds against a C library... :)).
as for using taglist: do you mean the vim function taglist, which gives you a dictionary with information associated with a tag? so you are probably interested in extra information about tags, beyond source location. (*)
I meant http://vim-taglist.sourceforge.net/ which provides a neat interface and some extra convenience. It is somewhat dependent on exuberant ctags.
it should be a lot easier to expand the information generated by :ctags than to add a Haskell parser/type checker to exuberant ctags. the format is simply a comment (to protect old vi from choking on the extra info) followed by a list of extra fields (the dictionary) for each tag. see ":help tags-file-format" in vim, the third variant of the format.
I understand the tags file format. My vim fu is not as strong yours, but I have been using vim since it was at version 4.something and run into wanting to improve the tags at my disposal before. One of the things a custom tag generator could do is generate not just hardcoded locations in the tags file, but search patterns. This should make the tags file itself quite a bit more robust against changes, thereby obviating much of the need for dynamic regeneration.
have a look at ghc/compiler/ghci/InteractiveUI.hs, around listTags/ TagInfo. if one knows where to get it, one could add info there (eg, the type of the tag, or whether the tag is a type/class/function/module/ whatever). and the extra info ought to be written to the tags file, in collateAndWriteTags (simply ignore the extra info when writing the emacs tag file).
Thanks for the pointer, I'll look into it.
(*) if you want to go for broke, try ":help cursorhold-example" in vim. that will keep a preview window with the source-location of any tag your cursor remains on for long enough. so you might see the type declaration, or you might see the data type constructors belonging to a type, or .. i haven't used this as a default myself, but it is worth looking at at least once!-)
Hm. This would actually be much more useful if it were to follow the Visual Haskell method where hovering over a selection will show you the type of the selected subexpression. Good ideas sprouting again... pity it's almost bedtime. :) Doei, Arthur. -- /\ / | arthurvl@cs.uu.nl | Work like you don't need the money /__\ / | A friend is someone with whom | Love like you have never been hurt / \/__ | you can dare to be yourself | Dance like there's nobody watching

I meant http://vim-taglist.sourceforge.net/ which provides a neat interface and some extra convenience. It is somewhat dependent on exuberant ctags.
thanks for the pointer. it also seems to depend on rerunning ex-ctags on a file every time a buffer on it is opened (possibly also when the file changes on disk?). the faq says it won't use existing tags files generated in any other way. in view of that, perhaps ghc-api-based approaches won't combine well with the existing plugin (speed/frequent reruns, incomplete projects, files in non-compilable state, ..). pity. perhaps one could take the interface code from the plugin and combine it with a more ghc-friendly backend. or it is back to quick&dirty pattern-based tag generators.
I understand the tags file format. My vim fu is not as strong yours, but I have been using vim since it was at version 4.something and run into wanting to improve the tags at my disposal before.
my vim fu is lacking, but not my wanting;-) i used to have a pattern-based tag generator for my first non-trivial haskell project, but my coding styles (and hence the patterns) keep changing. afaik, hasktags is just one of many attempts to address the same problem - i tried it, but found myself looking for more complete tag files. ghc-api based generators seemed to be the way to go, and embedding one into ghci made the task a lot easier. since nobody seems to know what the best trade-off is between quick&flexible on one side and big&precise on the other, it is probably a good thing to try several approaches. i was just worried that people might continue writing more hasktags style generators when their needs might be met by one of the ghc-api-based ones. or that valuable time might be invested on sub-optimal routes. but as your explanation shows, the ideal solution is not necessarily the best one, given context constraints.
One of the things a custom tag generator could do is generate not just hardcoded locations in the tags file, but search patterns. This should make the tags file itself quite a bit more robust against changes, thereby obviating much of the need for dynamic regeneration.
yes, in principle. emacs even mixes the two styles (jump to position, then search for the tag outwards, starting from there), though without proper search patterns. in practice, the search patterns need to have enough context to distinguish, eg, class, type, module, but not enough context to be fooled by the kind of extensive refactoring/reordering/code cleaning that tends to accompany active haskell program development; also, incremental regeneration could be as fast as reloading one module into ghci.
Hm. This would actually be much more useful if it were to follow the Visual Haskell method where hovering over a selection will show you the type of the selected subexpression.
should be possible these days. before vim had tooltips, i used the status line to show hugs' :type output for the identifier under cursor, but i found that so intrusive that i switched it off. the interface between editor and haskell system is still a big question mark, with various more or less non-portable approaches, but nothing really satisfying. for emacs, the subprocess idea almost works, for vim, dynamic linking might be more direct, perhaps. problems, problems,..
Good ideas sprouting again... pity it's almost bedtime. :)
hey, what is dreamtime good for, but to process and nurture good ideas:) good luck with your experiments, claus

I didn't knew about :ctags of ghci. Some time ago I've tweaked cabal to start ghci with package options given in the .cabal file. Perhaps it might be useful for someone: module Main where import Distribution.Simple import Distribution.Simple.Configure import Distribution.Simple.LocalBuildInfo import System import System.Process import System.Exit import Monad main= do args <- getArgs -- check args to launch ghci when (length args > 0) $ do when ((args!!0) == "ghci") $ do lbi <- getPersistBuildConfig let packageArgs = (concat.concat) [ [" -package ", showPackageId pkg] | pkg <- packageDeps lbi ] system("ghci " ++ packageArgs) exitWith ExitSuccess defaultMain -- fallback to defaultMain Then you can use ./setup ghci to start ghci It is incomplete but should work for default packages.. Marc

[cc-ed to libraries, as they seem to be more appropriate for cabal topics]
Some time ago I've tweaked cabal to start ghci with package options given in the .cabal file.
Perhaps it might be useful for someone:
yes, i'd like to see something like this in cabal. cf also http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg11101.html claus
module Main where import Distribution.Simple import Distribution.Simple.Configure import Distribution.Simple.LocalBuildInfo import System import System.Process import System.Exit import Monad
main= do args <- getArgs -- check args to launch ghci when (length args > 0) $ do when ((args!!0) == "ghci") $ do lbi <- getPersistBuildConfig let packageArgs = (concat.concat) [ [" -package ", showPackageId pkg] | pkg <- packageDeps lbi ] system("ghci " ++ packageArgs) exitWith ExitSuccess defaultMain -- fallback to defaultMain
Then you can use ./setup ghci to start ghci It is incomplete but should work for default packages..
Marc _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (3)
-
Arthur van Leeuwen
-
Claus Reinke
-
Marc Weber