One reason I haven't responded is that I have an uneasy feeling
about what you're trying to do here.
which is exactly the kind of feedback i'm interested in (apart from
concrete help/advice, that is;-): i do not want to invest time or effort
into GHCi-related projects that go against GHCi's own directions.
You want to use GHCi programmatically, and you're depending
on details of GHCi's user interface in your tool. We want to be
free to change GHCi's user interface whenever we like, without
worrying about breaking 3rd-party tools (of course we need to
document any changes).
too late for that, you've got too many users!-) and i want to use
GHCi programmatically, independent of whether i'm using it
directly, or via a tool. though writing an editor interface to GHCi
has certainly make me look more closely at what is possible in
GHCi itself.
I realise this already happens: the emacs GHCi mode talks to
GHCi directly, and GuiHaskell does too. But I hereby declare
that this is the Wrong Way To Do It. The right way is to use the
GHC API, starting from your own copy of the GHCi front-end
if you like.
that is one way of looking at it. i guess my own view differs, in
that i think of the emacs and vim haskell/ghc modes as editor
bindings to GHC(i). GHC, and GHCi in particular, are the
interactive haskell development tools provided by GHC HQ,
and emacs/vim haskell modes are the interfaces to these tools
that editor users have come to expect.
since i announced my haskell mode plugins for vim, i've had
about a hundred downloads each month, which isn't much in
the overall picture, but shows a healthy demand, given that i
don't advertize much. and while vim is not really a beginner's
editor, it seems that haskell editor modes are often asked for
by programmers new to haskell.
if you'd prefer the emacs/haskell modes to switch from being
GHCi frontends to being fully independent ides based on
separate GHC API-based code, you should probably
announce that in haskell@ (or at least ghc-users@).
i've been going to great lengths to avoid dependencies on
special tools apart from vim, ghci, and some browser, in my
haskell mode because every extra dependency decreases
the number of users, and increases the number of issues.
ghci incorporates functionality that is commonly used
(instead of emacs, vim, vs haskell, and other folks writing
their own tag generators, browse, info, debug, etc), which
is something i really like. GHC API is promising, but still
much too unstable itself to depend on in an editor mode
that beginning haskellers are meant to get running and use
on various platforms, with various ghc versions (the
experimental code i had for 6.6.1 doesn't even load in
6.7 anymore).
if you want the haskell mode developers to change course,
the first thing i'd be asking for is a way to create a ghci
prompt from within the api, to get access to the common
functionality everyone is used to, and we'd be back to
where we started!-)
Having said that, of course it's up to you if you want to use
GHCi for this purpose, and we'll certainly apply patches
within reason that help you, but I don't want to commit to
supporting features of GHCi that are only used by layered
tools, nor commit to not changing the UI.
i think of haskell modes more as extended frontends to GHCi,
rather than as ides that happen to use GHCi. but i guess both
views are correct, and perhaps the importance and use of GHCi
will wane over time. in either view, it'd be nice to have GHCi as
the repository for commonly useful functionality, both to avoid
reinventing the wheel, sharing code and momentum instead,
and to improve the commandline experience.
for instance, with command capture, i can define my own
GHCi commands for features that would otherwise require
individual extensions to GHCi, or a switch from GHCi to
GHC API, possibly losing GHCi functions.
of the top of my head, examples i can come up with that
would now be user-definable include:
:grep <pattern> <command>
only show lines matching <pattern> from <command>
:grep break :?
help for breakpoint-related commands
:grep module :?
help for module-related commands
:grep Bool :browse Data.List
Data.List items that involve Booleans
:grep class :browse Control.Monad
classes defined in Control.Monad
:find <id>
edit source at definition of <id> (as in Hugs, but here
based on filtering for -- Defined at <loc> in :info output,
and :show editor for selecting the right editor)
:breakpoints
communicate current breakpoint locations to editor, for
marking/highlighting/editing (based on :show breaks, and
:show editor)
:mkCabal
create minimal .cabal file, with current options & modules
(based on :set, :show modules)
and so on. don't you find that convincing?-)
Ok, rant over.
:-)
- :browse! a variant of :browse, that does not filter out
children, and does not display children in context of their parents
(as described; this still suffers from the issue that i have not
found a function to display the stored type of class methods
correctly; it also does not yet account for qualified names,
when their unqualified versions are available, nor does it
address the issue of not updating properly on :reload, both
issues are described in ticket #1617)
I think this is low-impact enough that it could go in. I'm not terribly
keen on the syntax - there's no precedent for a ! suffix, and it feels a
bit obscure. How about ':names'?
since the ghci interface followed hugs, which in turn followed vi,
the use of bang modifiers to access command variants is traditional
in vi-clones and avoids stealing namespace for minor variations.
[btw, how did the debugger manage to steal :b from
:browse? i think this should be changed back to the
traditional (pre 6.7) behaviour, but have not done so yet]
This was partly accidental, partly because I'm used to using 'b' to set a
breakpoint in gdb, and partly because I think it'll be used more often than
:browse. But I don't feel too strongly about it.
i guess with namespace becoming more crowded, we can no longer
rely on abbreviations :-( the debugger tests should not refer to :b etc.,
but to the full names, for instance. i just recall the lengths to which you
went to avoid replacing old short-cuts with :tags/:ctags/:etags, and i
agreed with that. otherwise, we'll end up with the windows menu
annoyance that keyboard shortcuts change their meaning when menu
entries are added/removed.
- GHCi command output capture (again, as described)
This part I'm not sure about at all. We're really getting into
"you should be using the GHC API" territory here.
funny, this is the part i find easiest to argue for!-) see above
for examples of why this would be useful for GHCi itself. it
seems a natural complement to :def/:cmd/.ghci, and it will
enable command extensions without allways requiring
changes to GHCi in future.
There are various holes in what you've done: what if the
variable "output" is already bound?
yes, as i said, i'd have preferred GHCi.output. alternatively, i'd
like to enable the user to choose the variable name, and control
redirection as well (:redir =>variable | commands | :redir END,
in vim parlance).
What if "System.IO.putStrLn" is in scope and means something
else?
that one i have no good answer to. perhaps GHCi could bind
an internal name to the right putStrLn, and use that instead of
a string name?
What if stdout has been redirected. etc.
how would that change things?
And the fact that this only applies to certain commands, and
not to output generated by ordinary expressions/statements,
means it feels too ad-hoc to me.
yes, there's that. adding other commands is mainly an issue of
their i/o being widely distributed (several statements, sometimes
in different modules..). for ordinary expressions, there is 'it',
and for statements, there isn't much chance.
but note that i'm looking for output capture, within GHCi,
rather than redirection of a whole session. one could try,
alternatively, to redirect stdout to a tmp file, then read that
into a variable (:redir >tmpfile | commands | :redir END, in
vim). perhaps that approach would give better coverage,
i'm open to suggestions/opinions.
i would still like to know how one is supposed to display
the type of class methods,
doesn't ':t (+)' work?
that seems to re-infer the type, rather than print the stored
type? although that has to do a name-lookup somewhere,
it seemed odd to call on hscTcExpr when i already have
the type at hand and just need a way to print it correctly?
is there a different type renderer i should be using, perhaps?
and why 'it' is not bound in the same naive
way i've used to bind 'output'.
Because 'it' is bound either by a let or a monadic binding,
depending on the type of the expression.
ah, thanks. i was worried that i was going about things
the wrong way. perhaps there could be a comment to
that effect in InteractiveUI.hs, for future reference (i was
surprised that i couldn't find any 'it'-related functions there)?
claus
_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc