APPROVE COMMIT packages
I've fallen way behind in maintaining the Haskell modes package. This
catches us up to the latest released version. Note that Stefan Monnier
has taken over maintenance upstream.
Norbert, could you go ahead and roll out a new release of the
haskell-mode package? This fixes several bugs that tripped me up when I
was teaching Haskell in a programming languages class last fall.
xemacs-packages/haskell-mode/ChangeLog addition:
2006-03-14 Jerry James <james(a)xemacs.org>
* .emacs: Remove.
* ChangeLog.upstream: New file.
* Makefile: Update AUTHOR_VERSION. Add rule for new
inf-haskell.el. Put text files in EXTRA_SOURCES.
* Makefile.upstream: New file.
* NEWS: New file.
* package-info.in: Update provides.
* fontlock.hs:
* haskell-decl-scan.el:
* haskell-doc.el:
* haskell-font-lock.el:
* haskell-ghci.el:
* haskell-hugs.el:
* haskell-indent.el:
* haskell-mode.el:
* haskell-simple-indent.el:
* inf-haskell.el:
* indent.hs: Sync with upstream version 2.1.
* index.html: Ditto, with small changes to make onsgmls like it.
* installation-guide.html: Ditto, also with small changes.
packages source patch:
Diff command: cvs -q diff -uN
Files affected: xemacs-packages/haskell-mode/package-info.in
xemacs-packages/haskell-mode/installation-guide.html
xemacs-packages/haskell-mode/inf-haskell.el xemacs-packages/haskell-mode/index.html
xemacs-packages/haskell-mode/indent.hs
xemacs-packages/haskell-mode/haskell-simple-indent.el
xemacs-packages/haskell-mode/haskell-mode.el
xemacs-packages/haskell-mode/haskell-indent.el
xemacs-packages/haskell-mode/haskell-hugs.el xemacs-packages/haskell-mode/haskell-ghci.el
xemacs-packages/haskell-mode/haskell-font-lock.el
xemacs-packages/haskell-mode/haskell-doc.el
xemacs-packages/haskell-mode/haskell-decl-scan.el xemacs-packages/haskell-mode/fontlock.hs
xemacs-packages/haskell-mode/NEWS xemacs-packages/haskell-mode/Makefile.upstream
xemacs-packages/haskell-mode/Makefile xemacs-packages/haskell-mode/ChangeLog.upstream
xemacs-packages/haskell-mode/.emacs
Index: xemacs-packages/haskell-mode/.emacs
===================================================================
RCS file: .emacs
diff -N .emacs
--- /tmp/cvsAAAQHaquC Wed Mar 15 05:57:42 2006
+++ /dev/null Wed Mar 15 05:57:42 2006
@@ -1,16 +0,0 @@
-(setq load-path (cons "~/lib/emacs" load-path))
-(setq auto-mode-alist
- (append auto-mode-alist
- '(("\\.[hg]s$" . haskell-mode)
- ("\\.hi$" . haskell-mode)
- ("\\.l[hg]s$" . literate-haskell-mode))))
-(autoload 'haskell-mode "haskell-mode"
- "Major mode for editing Haskell scripts." t)
-(autoload 'literate-haskell-mode "haskell-mode"
- "Major mode for editing literate Haskell scripts." t)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
-;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-hugs)
Index: xemacs-packages/haskell-mode/ChangeLog.upstream
===================================================================
RCS file: ChangeLog.upstream
diff -N ChangeLog.upstream
--- /dev/null Wed Mar 15 05:57:42 2006
+++ ChangeLog.upstream Wed Mar 15 05:57:24 2006
@@ -0,0 +1,358 @@
+2005-11-07 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * Release version 2.1.
+
+ * haskell-indent.el (haskell-indent-inside-comment): Rename `start' arg
+ into `open' and add a new `start' arg.
+ (haskell-indent-after-keywords): Change defaults for `in'.
+ (haskell-indent-indentation-info): Fix confusion between pos and col.
+ (haskell-indent-mode): Autoload.
+
+ * haskell-indent.el (haskell-indent-find-matching-start):
+ Add `pred' and `start' arguments.
+ (haskell-indent-filter-let-no-in): New fun.
+ (haskell-indent-indentation-info): Use them to correctly match `let's
+ with `in's even when some of the `let's have no matching `in'.
+
+2005-11-06 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el: Reduce the use of dyn-bound haskell-indent-info.
+ (haskell-indent-push-col): Don't duplicate info.
+ (haskell-indent-line-indentation): Handle let-in-do. Remove dead code.
+ (haskell-indent-inside-comment): Move rest of code from
+ haskell-indent-indentation-info.
+
+ * haskell-indent.el (haskell-literate): Declare.
+ (haskell-running-xemacs, event-basic-type, read-event): Remove.
+ (haskell-indent-get-beg-of-line, haskell-indent-get-end-of-line):
+ Remove. Use line-(beginning|end)-position instead.
+ (haskell-indent-mark-active): Move the xemacs test inside the defun.
+ (haskell-indent-info): Rename from indent-info. Update users.
+ (haskell-indent-bolp, haskell-indent-inside-comment):
+ Use line-beginning-position.
+ (haskell-indent-within-literate-code): Use `case'.
+ (haskell-indent-put-region-in-literate): Bind more comment-* vars.
+ (haskell-indent-virtual-indentation): Add the missing `start' arg.
+ (haskell-indent-mode): Move before first use.
+ (haskell-indent-stand-alone-mode): Use haskell-indent-mode.
+ Rename from haskell-stand-alone-indent-mode. Use define-derived-mode.
+ (hugs-mode-map, hugs-syntax-table):
+ Rename to haskell-stand-alone-indent-mode-(map|syntax-table).
+
+ * haskell-doc.el (haskell-doc-xemacs-p, haskell-doc-emacs-p)
+ (haskell-doc-message): Remove.
+ (haskell-doc-is-id-char-at): Remove.
+ (haskell-doc-get-current-word): Rewrite.
+
+2005-11-04 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-indentation-info): Fix detection of
+ hanging let/if/case statements.
+
+ * haskell-mode.el (haskell-mode): Fix typo.
+
+2005-11-04 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * inf-haskell.el (inferior-haskell-mode): Hide compilation bindings.
+
+ * haskell-indent.el (haskell-indent-after-keywords): New var.
+ (haskell-indent-virtual-indentation): New fun.
+ (haskell-indent-indentation-info): Use them to indent after keywords.
+
+ * haskell-simple-indent.el (haskell-simple-indent): Minor simplif.
+ (turn-on-haskell-simple-indent): Don't bind \t and \n.
+
+ * haskell-mode.el (haskell-vars, haskell-mode-generic): Remove.
+ (haskell-mode-hook): Rename from haskell-mode-hooks.
+ (haskell-mode): Use define-derived-mode. Inline haskell-mode-generic
+ and haskell-vars.
+ (literate-haskell-mode): Use define-derived-mode.
+
+ * fontlock.hs: Add some entries for infix declarations.
+
+2005-10-12 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-start-keywords-re): Use regexp-opt.
+ (haskell-indent-type-at-point): Accept ' in identifiers.
+ (haskell-indent-find-case): Tell match-data to not generate markers.
+ (haskell-indent-line-indentation): Ignore off-side keywords in comments
+ and strings.
+ (haskell-indent-find-matching-start): Generalize.
+ Rename from haskell-indent-find-let.
+ (haskell-indent-indentation-info): Use it for of, then, and else.
+
+2005-09-28 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-in-comment): Don't fail at EOB.
+
+ * haskell-font-lock.el (haskell-font-lock-symbols-alist): Add "not".
+ (haskell-font-lock-compose-symbol): Handle alphanum identifiers.
+ Fix incorrect handling of . when used for qualified names.
+
+2005-09-26 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-font-lock.el (haskell-font-lock-symbols-alist): Prefer the
+ unicode version of lambda. Add two symbols from the Omega language and
+ from Paterson's arrow syntax.
+
+2005-08-24 Steve Chamberlain <sac(a)pobox.com> (tiny patch)
+
+ * haskell-doc.el (haskell-doc-message): Paren typo.
+
+2005-08-23 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-doc.el (haskell-doc-show-type): Assume that the availability
+ of display-message won't change at runtime.
+
+ * haskell-font-lock.el (haskell-font-lock-keywords-create): Try and
+ work around a bug that seems to be in Emacs-21.3 rather than in
+ haskell-font-lock.el. Reported by Steve Chamberlain <sac(a)pobox.com>.
+
+2005-07-18 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * inf-haskell.el (haskell-program-name): Fix defcustom delcaration.
+
+ * haskell-doc.el (haskell-doc-message): Remove.
+ (haskell-doc-show-type): Inline it. Don't do anything for if there's
+ no doc to show.
+
+2005-02-02 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-hugs.el (haskell-hugs-mode-map):
+ * haskell-ghci.el (haskell-ghci-mode-map): Remove.
+
+2005-01-26 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-inside-comment): Don't assume that
+ column(pos+2) = column(pos)+2.
+ (haskell-indent-indentation-info): Fix indentation of , and ;.
+ Add arg `start'. Restrict choice of indentation for comments.
+ (haskell-indent-event-type): Remove.
+ (haskell-indent-last-info): New var.
+ (haskell-indent-cycle): Use it to store info from one invocation to
+ the next, so we can do cycling outside of the function.
+ Don't cycle directly any more. Instead, recognize repeated invocations
+ via last-command and friends.
+ Use indent-line-function rather than hardcoding indent-to-left-margin.
+ (haskell-indent-insert-where): Don't save excursion.
+ (haskell-indent-layout-indent-info): Minor simplifications.
+ (haskell-indent-line-indentation): Don't ignore code on a line
+ before a string.
+
+ * haskell-hugs.el (haskell-hugs-last-loaded-file): Remove.
+ (haskell-hugs-start-process): Fix misuse of make-variable-buffer-local.
+ (haskell-hugs-go): Quote file name. Simplify.
+
+ * haskell-ghci.el (haskell-ghci-last-loaded-file): Remove.
+ (haskell-ghci-start-process): Fix misuse of make-variable-buffer-local.
+ (haskell-ghci-go): Quote file name. Simplify.
+
+ * haskell-mode.el (haskell-version): Keep it up-to-date.
+
+ * inf-haskell.el (inferior-haskell-load-file): Quote file name.
+
+2004-12-10 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-start-of-def): Only go backward.
+ (haskell-indent-in-string): Simplify.
+ (haskell-indent-in-comment): Simplify.
+ (haskell-indent-comment): Remove.
+ (haskell-indent-inside-comment): New fun.
+ (haskell-indent-indentation-info): Assume we're at the indentation.
+ Handle comments differently.
+ (haskell-indent-cycle): Go to indentation and then save excursion
+ around haskell-indent-indentation-info.
+
+ * haskell-doc.el (haskell-doc-minor-mode-string): Make it dynamic.
+ (haskell-doc-install-keymap): Remove conflicting C-c C-o binding.
+ (haskell-doc-mode): Make a nil arg turn the mode ON.
+ (turn-on-haskell-doc-mode): Make it an alias for haskell-doc-mode.
+ (haskell-doc-mode): Don't touch haskell-doc-minor-mode-string.
+ (haskell-doc-show-global-types): Don't touch
+ haskell-doc-minor-mode-string. Call haskell-doc-make-global-fct-index.
+ (haskell-doc-check-active): Fix message.
+ (define-key-after): Don't define.
+ (haskell-doc-install-keymap): Check existence of define-key-after.
+
+ * haskell-mode.el (haskell-literate-default): Fix custom type.
+ (haskell-vars): Ignore comments when doing C-M-f.
+
+ * indent.hs: More test cases.
+
+ * inf-haskell.el (haskell-program-name): Use ghci if hugs is absent.
+ (inferior-haskell-load-file): Reset compilation-parsing-end.
+
+2004-11-25 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * Release version 2.0.
+
+ * .emacs: Remove.
+
+ * haskell-decl-scan.el (haskell-ds-imenu-label-cmp): Undo last
+ idiotic change.
+
+ * haskell-doc.el (haskell-doc-sym-doc): Make even the last char bold.
+
+ * haskell-mode.el (haskell-mode-map): Typo.
+
+ * inf-haskell.el (inferior-haskell-mode): Typo.
+ (inferior-haskell-wait-for-output): Remove.
+ (inferior-haskell-send-command): New function.
+ (inferior-haskell-load-file): Use it.
+
+ * index.html:
+ * installation-guide.html: Partial fixup.
+
+2004-11-24 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-mode.el (turn-on-haskell-hugs, turn-on-haskell-ghci):
+ Mark them as obsolete.
+ (haskell-mode-map): Add bindings for the inferior-haskell commands.
+
+ * inf-haskell.el: New file.
+
+ * haskell-doc.el (haskell-doc-install-keymap): Don't blindly assume
+ there's a Hugs menu.
+
+2004-11-22 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (turn-on-haskell-indent, turn-off-haskell-indent):
+ Use C-c C-foo rather than C-c foo to follow coding conventions.
+
+ * haskell-font-lock.el (haskell-font-lock-symbols-alist): Add . = ○.
+
+2004-10-25 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-indentation-info): Don't use layout
+ for paren-closing elements.
+
+2004-10-20 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-indentation-info): Only use
+ the new `in' indentation rule if the `let' is on the left of the decl.
+
+2004-10-19 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-indent.el (haskell-indent-find-let): New function.
+ (haskell-indent-indentation-info): Use it to indent `in'.
+
+ * haskell-font-lock.el (haskell-default-face): Add missing declaration.
+
+ * haskell-indent.el (haskell-indent-open-structure): Simplify.
+ (haskell-indent-contour-line): Work even when `start' is in the middle
+ of a line.
+ (haskell-indent-layout-indent-info): New fun extracted from
+ haskell-indent-indentation-info.
+ (haskell-indent-indentation-info): Use it as before. Use it also to
+ handle layout-within-open-structure.
+
+2004-10-18 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-font-lock.el (haskell-font-lock-keywords-create):
+ Use explicit `symbol-value' to work around limitations in XEmacs's
+ implementation of font-lock.
+ (haskell-basic-syntactic-keywords): Fix up char-constants some more.
+
+2004-10-14 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-doc.el (turn-off-haskell-doc-mode)
+ (haskell-doc-current-info): Don't autoload.
+
+ * haskell-decl-scan.el (haskell-ds-match-string):
+ Use match-string-no-properties if available.
+ (haskell-ds-syntax-table): Use haskell-mode-syntax-table.
+ (haskell-ds-imenu-label-cmp): Use car-less-than-car if available.
+ (haskell-ds-imenu): Remove obsolete incorrect code.
+
+ * haskell-mode.el: Set things up so that mode-hook functions are not
+ necessary, and generic functions can be used instead, like
+ global-font-lock-mode.
+ (haskell-enum-from-to): Remove.
+ (turn-on-haskell-font-lock): Make obsolete.
+ (haskell-running-xemacs): Remove.
+ (haskell-mode-syntax-table): Fiddle with non-ascii chars.
+ Fix up comment syntax in XEmacs.
+ (haskell-vars): Improve comment-start-skip.
+ Add comment-end-skip. Setup imenu, eldoc, and font-lock.
+ Tweak handling of tabs to be on the safe side.
+ (haskell-mode-hooks): Declare and mention some useful ideas.
+ (literate-haskell-mode): Simplify.
+ (haskell-comment-indent): Remove. The default works as well.
+
+ * haskell-font-lock.el: Remove level 1 fontification.
+ (haskell-font-lock-keywords-1, haskell-font-lock-keywords-2)
+ (bird-literate-haskell-font-lock-keywords-1)
+ (bird-literate-haskell-font-lock-keywords-2)
+ (latex-literate-haskell-font-lock-keywords-1)
+ (latex-literate-haskell-font-lock-keywords-2): Remove.
+ (bird-literate-haskell-font-lock-keywords)
+ (latex-literate-haskell-font-lock-keywords): Rename.
+ (haskell-font-lock-keywords-create): Remove `level' arg.
+ (haskell-fl-syntax): Remove. Assume the major modes sets it right.
+ (haskell-font-lock-choose-keywords)
+ (haskell-font-lock-choose-syntactic-keywords): New funs.
+ (haskell-font-lock-defaults-create): Use them.
+ (turn-off-haskell-font-lock, turn-on-haskell-font-lock): Simplify.
+
+ * haskell-hugs.el (haskell-hugs-mode): Use define-derived-mode.
+ (run-hugs): New alias.
+ (haskell-hugs-wait-for-output): Don't loop if the process is dead.
+
+ * haskell-font-lock.el (haskell-font-lock-compose-symbol): New fun.
+ (haskell-font-lock-symbols-keywords): Use it.
+ (haskell-string-char-face): Remove.
+ (haskell-font-lock-keywords-create): Hardcode font-lock-string-face.
+ (haskell-fl-syntax): Fix typos. Keep " as a string delimiter.
+
+2004-10-13 Stefan Monnier <monnier(a)iro.umontreal.ca>
+
+ * haskell-doc.el (haskell-doc): New group.
+ (haskell-doc-show-reserved, haskell-doc-show-prelude)
+ (haskell-doc-show-strategy, haskell-doc-show-user-defined)
+ (haskell-doc-chop-off-context, haskell-doc-chop-off-fctname):
+ Make them custom vars.
+ (haskell-doc-keymap): Declare and fill it right there.
+ (haskell-doc-mode): Simplify.
+ (haskell-doc-toggle-var): Make it into what it was supposed to be.
+ (haskell-doc-mode-print-current-symbol-info): Simplify.
+ (haskell-doc-current-info): New autoloaded function.
+ (haskell-doc-sym-doc): New fun extracted from haskell-doc-show-type.
+ (haskell-doc-show-type): Use it.
+ (haskell-doc-wrapped-type-p): Remove unused var `lim'.
+ (haskell-doc-forward-sexp-safe, haskell-doc-current-symbol):
+ Remove. Unused.
+ (haskell-doc-visit-home): Don't require ange-ftp, it's autoloaded.
+ (haskell-doc-install-keymap): Simplify.
+
+ * haskell-decl-scan.el (literate-haskell-ds-create-imenu-index)
+ (haskell-ds-generic-create-imenu-index): Remove.
+ (haskell-ds-bird-p): New function.
+ (haskell-ds-backward-decl, haskell-ds-forward-decl): Use it.
+ (haskell-ds-create-imenu-index): Use it to make it generic.
+ (haskell-ds-imenu): Remove now-unused arg.
+ (turn-on-haskell-decl-scan): Fix up call to haskell-ds-imenu.
+ (haskell-ds-running-xemacs): Remove.
+ (haskell-ds-func-menu-next): Make generic.
+ (literate-haskell-ds-func-menu-next): Delete.
+ (haskell-ds-func-menu): Remove unused arg.
+ (turn-on-haskell-decl-scan): Simplify.
+
+ * haskell-indent.el: Don't load CL at runtime.
+ (haskell-indent-start-of-def, haskell-indent-type-at-point):
+ Don't hardcode point-min == 1.
+ (indent-info): Declare it.
+ (haskell-indent-empty, haskell-indent-ident, haskell-indent-other)
+ (haskell-indent-line-indentation): Use `string'.
+ (haskell-indent-valdef-indentation): Fix `case' arms syntax.
+ (haskell-indent-indentation-info): Remove unused var `pt'.
+ (haskell-indent-align-def): Remove unused var `defpos'.
+ (turn-on-haskell-indent): Don't bind TAB.
+ (turn-off-haskell-indent): Don't unbind TAB and DEL.
+ (hugs-syntax-table): Use the `n' for nested comments.
+ (haskell-stand-alone-indent-mode): Fix `comment-end'.
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+
+# arch-tag: a2606dc4-fab7-4b2f-bbe9-0a51db643511
Index: xemacs-packages/haskell-mode/Makefile
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/Makefile,v
retrieving revision 1.19
diff -d -u -r1.19 Makefile
--- xemacs-packages/haskell-mode/Makefile 2004/06/16 15:52:15 1.19
+++ xemacs-packages/haskell-mode/Makefile 2006/03/15 04:57:24
@@ -18,7 +18,7 @@
# Boston, MA 02111-1307, USA.
VERSION = 1.07
-AUTHOR_VERSION = 1.45
+AUTHOR_VERSION = 2.1
MAINTAINER = Jerry James <james(a)xemacs.org>
PACKAGE = haskell-mode
PKG_TYPE = regular
@@ -27,10 +27,12 @@
ELCS = haskell-decl-scan.elc haskell-doc.elc haskell-font-lock.elc \
haskell-ghci.elc haskell-hugs.elc haskell-indent.elc haskell-mode.elc \
- haskell-simple-indent.elc
+ haskell-simple-indent.elc inf-haskell.elc
DATA_FILES = fontlock.hs indent.hs index.html installation-guide.html
DATA_DEST = $(PACKAGE)
+
+EXTRA_SOURCES = ChangeLog.upstream Makefile.upstream NEWS
PRELOADS = -l comint -l cus-face -l font-lock -l func-menu -l imenu \
-l haskell-mode -l haskell-indent
Index: xemacs-packages/haskell-mode/Makefile.upstream
===================================================================
RCS file: Makefile.upstream
diff -N Makefile.upstream
--- /dev/null Wed Mar 15 05:57:42 2006
+++ Makefile.upstream Wed Mar 15 05:57:24 2006
@@ -0,0 +1,53 @@
+EMACS = emacs
+
+ELFILES = \
+ haskell-font-lock.el \
+ haskell-mode.el \
+ haskell-doc.el \
+ haskell-decl-scan.el \
+ inf-haskell.el \
+ haskell-indent.el
+
+ELCFILES = $(ELFILES:.el=.elc)
+# AUTOLOADS = $(PACKAGE)-startup.el
+AUTOLOADS = haskell-site-file.el
+
+%.elc: %.el
+ $(EMACS) --batch --eval '(setq load-path (cons "." load-path))' \
+ -f batch-byte-compile $<
+
+all: $(ELCFILES) $(AUTOLOADS)
+
+info:
+ # No Texinfo file, sorry.
+
+######################################################################
+### don't look below ###
+######################################################################
+
+PACKAGE=haskell-mode
+
+$(AUTOLOADS): $(ELFILES)
+ [ -f $@ ] || echo '' >$@
+ $(EMACS) --batch --eval '(setq generated-autoload-file
"'`pwd`'/$@")' -f batch-update-autoloads "."
+
+##
+
+TAG = $(shell echo v$(VERSION) | tr '.' '_')
+ftpdir=/u/monnier/html/elisp/
+cvsmodule=$(shell cat CVS/Repository)
+cvsroot=$(shell cat CVS/Root)
+
+dist:
+ cvs tag -F $(TAG) &&\
+ cd $(TMP) &&\
+ unset CVSREAD; cvs -d $(cvsroot) export -r $(TAG) -d $(PACKAGE)-$(VERSION) $(cvsmodule)
&&\
+ cd $(PACKAGE)-$(VERSION) &&\
+ make info $(AUTOLOADS) &&\
+ cd .. &&\
+ ztar $(PACKAGE)-$(VERSION) &&\
+ rm -rf $(PACKAGE)-$(VERSION)
+ mv $(TMP)/$(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/
+ ln -sf $(PACKAGE)-$(VERSION).tar.gz $(ftpdir)/$(PACKAGE).tar.gz
+
+# arch-tag: 1ab314c8-3821-44fb-b533-dd58f5d75ba4
Index: xemacs-packages/haskell-mode/NEWS
===================================================================
RCS file: NEWS
diff -N NEWS
--- /dev/null Wed Mar 15 05:57:42 2006
+++ NEWS Wed Mar 15 05:57:24 2006
@@ -0,0 +1,35 @@
+Changes since 2.0:
+
+* inf-haskell uses ghci if hugs is absent.
+
+* Fix up some binding conflicts (C-c C-o in haskell-doc)
+
+* Many (hopefully minor) changes to the indentation.
+
+* New symbols in haskell-font-lock-symbols-alist.
+
+Changes since 1.45:
+
+* keybindings C-c <char> have been replaced by C-c C-<char> so as not
+ to collide with minor modes.
+
+* The following modules are now automatically activated without having to
+ add anything to haskell-mode-hook:
+ haskell-font-lock (just turn on global-font-lock-mode).
+ haskell-decl-scan (just bind `imenu' to some key).
+
+* In recent Emacsen, haskell-doc hooks into eldoc-mode.
+
+* haskell-hugs and haskell-ghci are superceded by inf-haskell.
+
+* Indentation rules have been improved when using layout inside parens/braces.
+
+* Symbols like -> and \ can be displayed as actual arrows and lambdas.
+ See haskell-font-lock-symbols.
+
+* Tweaks to the font-lock settings. Among other things paren-matching
+ with things like \(x,y) should work correctly now.
+
+* New maintainer <monnier(a)gnu.org>.
+
+# arch-tag: e50204f2-98e4-438a-bcd1-a49afde5efa5
Index: xemacs-packages/haskell-mode/fontlock.hs
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/fontlock.hs,v
retrieving revision 1.1
diff -d -u -r1.1 fontlock.hs
--- xemacs-packages/haskell-mode/fontlock.hs 2002/04/24 09:45:06 1.1
+++ xemacs-packages/haskell-mode/fontlock.hs 2006/03/15 04:57:24
@@ -12,8 +12,20 @@
-- and module names are coloured
-- closer to ordinary code.
+recognize +++ infix :: Operator Declarations
+as `well` as = This Form
+(+) and this one = as well
+
+instance Show Toto where
+ fun1 arg1 = foo -- FIXME: `fun1' should be highlighted.
+
+constStr = "hello \
+ \asdgfasgf\
+ \asf"
+
{-
map :: (a -> b) -> [a] -> [b] -- Commenting out large sections of
map f [] = [] -- code can be misleading. Coloured
map f (x:xs) = f x : map f xs -- comments reveal unused definitions.
-}
+
Index: xemacs-packages/haskell-mode/haskell-decl-scan.el
===================================================================
RCS file:
/pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-decl-scan.el,v
retrieving revision 1.2
diff -d -u -r1.2 haskell-decl-scan.el
--- xemacs-packages/haskell-mode/haskell-decl-scan.el 2004/06/16 15:16:49 1.2
+++ xemacs-packages/haskell-mode/haskell-decl-scan.el 2006/03/15 04:57:24
@@ -1,13 +1,13 @@
;;; haskell-decl-scan.el --- Declaration scanning module for Haskell Mode
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
;; Copyright (C) 1997-1998 Graeme E Moss
;; Authors: 1997-1998 Graeme E Moss <gem(a)cs.york.ac.uk>
;; Keywords: declarations menu files Haskell
-;; Version: 1.2
-;; URL:
http://www.cs.york.ac.uk/~gem/haskell-mode/decl-scan.html
+;; URL:
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/e...
-;;; This file is not part of GNU Emacs.
+;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -52,11 +52,11 @@
;;
;; If you have any problems or suggestions, after consulting the list
;; below, email gem(a)cs.york.ac.uk quoting the version of the library
-;; you are using, the version of emacs you are using, and a small
+;; you are using, the version of Emacs you are using, and a small
;; example of the problem or suggestion. Note that this library
;; requires a reasonably recent version of Emacs.
;;
-;; Uses `imenu' under FSF Emacs, and `func-menu' under XEmacs.
+;; Uses `imenu' under Emacs, and `func-menu' under XEmacs.
;;
;; Version 1.2:
;; Added support for LaTeX-style literate scripts.
@@ -110,7 +110,7 @@
;; with spaces okay.
;;
;; . Would like to extend the goto functions given by `func-menu'
-;; under XEmacs to FSF Emacs. Would have to implement these
+;; under XEmacs to Emacs. Would have to implement these
;; ourselves as `imenu' does not provide them.
;;
;; . `func-menu' uses its own syntax table when grabbing a declaration
@@ -119,15 +119,20 @@
;; eg. "fib'" will be grabbed as "fib" since "'"
is not a word or
;; symbol constituent under the syntax table `func-menu' uses.
-;;; All functions/variables start with
-;;; `(turn-(on/off)-)haskell-decl-scan' or `haskell-ds-'.
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-decl-scan' or `haskell-ds-'.
-;;; The imenu support is based on code taken from `hugs-mode',
-;;; thanks go to Chris Van Humbeeck.
+;; The imenu support is based on code taken from `hugs-mode',
+;; thanks go to Chris Van Humbeeck.
;; Version.
-(defconst haskell-decl-scan-version "1.1"
- "haskell-decl-scan version number.")
+
+;;; Code:
+
+(require 'haskell-mode)
+
+(defconst haskell-decl-scan-version "1.9"
+ "Version number of haskell-decl-scan.")
(defun haskell-decl-scan-version ()
"Echo the current version of haskell-decl-scan in the minibuffer."
(interactive)
@@ -137,23 +142,20 @@
;; As `cl' defines macros that `imenu' uses, we must require them at
;; compile time.
(eval-when-compile
- ;; `imenu' isn't used in XEmacs.
- (if (not (string-match "Lucid\\|XEmacs" emacs-version))
- (progn
- (require 'cl)
- (require 'imenu))))
-
-;; Are we running FSF Emacs or XEmacs?
-(defvar haskell-ds-running-xemacs
- (string-match "Lucid\\|XEmacs" emacs-version)
- "non-nil if we are running XEmacs, nil otherwise.")
+ (require 'cl)
+ (condition-case nil
+ (require 'imenu)
+ (error nil)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; General declaration scanning functions.
-(defun haskell-ds-match-string (num)
- "As `match-string' except that the string is stripped of properties."
- (format "%s" (match-string num)))
+(defalias 'haskell-ds-match-string
+ (if (fboundp 'match-string-no-properties)
+ 'match-string-no-properties
+ (lambda (num)
+ "As `match-string' except that the string is stripped of
properties."
+ (format "%s" (match-string num)))))
(defvar haskell-ds-start-keywords-re
(concat "\\(\\<"
@@ -162,36 +164,14 @@
"\\)\\>")
"Keywords that may start a declaration.")
-(defvar haskell-ds-syntax-table nil
+(defvar haskell-ds-syntax-table
+ (let ((table (copy-syntax-table haskell-mode-syntax-table)))
+ (modify-syntax-entry ?\' "w" table)
+ (modify-syntax-entry ?_ "w" table)
+ (modify-syntax-entry ?\\ "_" table)
+ table)
"Syntax table used for Haskell declaration scanning.")
-(if (not haskell-ds-syntax-table)
- (progn
- (setq haskell-ds-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\ " " haskell-ds-syntax-table)
- (modify-syntax-entry ?\t " " haskell-ds-syntax-table)
- (modify-syntax-entry ?\" "\"" haskell-ds-syntax-table)
- (modify-syntax-entry ?\' "w" haskell-ds-syntax-table)
- (modify-syntax-entry ?_ "w" haskell-ds-syntax-table)
- (modify-syntax-entry ?\( "()" haskell-ds-syntax-table)
- (modify-syntax-entry ?\) ")(" haskell-ds-syntax-table)
- (modify-syntax-entry ?[ "(]" haskell-ds-syntax-table)
- (modify-syntax-entry ?] ")[" haskell-ds-syntax-table)
- (modify-syntax-entry ?{ "(}1" haskell-ds-syntax-table)
- (modify-syntax-entry ?} "){4" haskell-ds-syntax-table)
- (modify-syntax-entry ?- "_ 23" haskell-ds-syntax-table)
- (modify-syntax-entry ?\` "$`" haskell-ds-syntax-table)
- (mapcar (lambda (x)
- (modify-syntax-entry x "_" haskell-ds-syntax-table))
- (concat "!#$%&*+./:<=>?@\\^|~"
- (haskell-enum-from-to ?\241 ?\277)
- "\327\367"))
- (mapcar (lambda (x)
- (modify-syntax-entry x "w" haskell-ds-syntax-table))
- (concat (haskell-enum-from-to ?\300 ?\326)
- (haskell-enum-from-to ?\330 ?\337)
- (haskell-enum-from-to ?\340 ?\366)
- (haskell-enum-from-to ?\370 ?\377)))))
(defun haskell-ds-get-variable (prefix)
"Assuming point is looking at the regexp PREFIX followed by the
@@ -392,6 +372,10 @@
;; Return the result.
result))
+(defun haskell-ds-bird-p ()
+ (if (boundp 'haskell-literate)
+ (eq haskell-literate 'bird) nil))
+
(defun haskell-ds-backward-decl ()
"Move point backward to the first character preceeding the current
point that starts a top-level declaration. A series of declarations
@@ -403,18 +387,12 @@
declaration, and nil otherwise, ie. because point is at the beginning
of the buffer and no declaration starts there."
(interactive)
- (haskell-ds-move-to-decl nil
- (if (boundp 'haskell-literate)
- (eq haskell-literate 'bird) nil)
- nil))
+ (haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil))
(defun haskell-ds-forward-decl ()
"As `haskell-ds-backward-decl' but forward."
(interactive)
- (haskell-ds-move-to-decl t
- (if (boundp 'haskell-literate)
- (eq haskell-literate 'bird) nil)
- nil))
+ (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil))
(defun haskell-ds-generic-find-next-decl (bird-literate)
"Find the name, position and type of the declaration at or after
@@ -524,21 +502,13 @@
;; Declaration scanning via `imenu'.
(defun haskell-ds-create-imenu-index ()
- "Non-literate Haskell version of
`haskell-ds-generic-create-menu-index'."
- (haskell-ds-generic-create-imenu-index nil))
-
-(defun literate-haskell-ds-create-imenu-index ()
- "Bird-style literate Haskell version of
-`haskell-ds-generic-create-menu-index'."
- (haskell-ds-generic-create-imenu-index t))
-
-(defun haskell-ds-generic-create-imenu-index (bird-literate)
- "Function for finding `imenu' declarations in (BIRD-LITERATE) Haskell mode.
+ "Function for finding `imenu' declarations in Haskell mode.
Finds all declarations (classes, variables, imports, instances and
datatypes) in a Haskell file for the `imenu' package."
;; Each list has elements of the form `(INDEX-NAME . INDEX-POSITION)'.
;; These lists are nested using `(INDEX-TITLE . INDEX-ALIST)'.
- (let* ((index-alist '())
+ (let* ((bird-literate (haskell-ds-bird-p))
+ (index-alist '())
(index-class-alist '()) ;; Classes
(index-var-alist '()) ;; Variables
(index-imp-alist '()) ;; Imports
@@ -603,20 +573,9 @@
`haskell-ds-create-imenu-index'."
(string< (car el1) (car el2)))
-(defun haskell-ds-imenu (bird-literate)
- "Install `imenu' for (BIRD-LITERATE) Haskell scripts."
- ;; Would prefer to toggle imenu but can't see how to turn it off...
- (require 'imenu)
- ;; In emacs-20's imenu we have to bind some functions first -- HWL
- (if (and (not haskell-ds-running-xemacs)
- (>= (string-to-number (substring emacs-version 0 2)) 20)
- (not (fboundp 'imenu-extract-index-name-function)))
- (setq imenu-extract-index-name-function
- (if bird-literate (function literate-haskell-ds-create-imenu-index)
- (function haskell-ds-create-imenu-index))))
- (setq imenu-create-index-function
- (if bird-literate (function literate-haskell-ds-create-imenu-index)
- (function haskell-ds-create-imenu-index)))
+(defun haskell-ds-imenu ()
+ "Install `imenu' for Haskell scripts."
+ (setq imenu-create-index-function 'haskell-ds-create-imenu-index)
(if (fboundp 'imenu-add-to-menubar)
(imenu-add-to-menubar "Declarations")))
@@ -625,14 +584,10 @@
(defun haskell-ds-func-menu-next (buffer)
"Non-literate Haskell version of `haskell-ds-generic-func-menu-next'."
- (haskell-ds-generic-func-menu-next nil buffer))
-
-(defun literate-haskell-ds-func-menu-next (buffer)
- "Bird-style literate Haskell version of
`haskell-ds-generic-func-menu-next'."
- (haskell-ds-generic-func-menu-next t buffer))
+ (haskell-ds-generic-func-menu-next (haskell-ds-bird-p) buffer))
(defun haskell-ds-generic-func-menu-next (bird-literate buffer)
- "Returns `(name . pos)' of next declaration."
+ "Return `(name . pos)' of next declaration."
(set-buffer buffer)
(let ((result (haskell-ds-generic-find-next-decl bird-literate)))
(if result
@@ -640,18 +595,18 @@
(name (car name-posns))
(posns (cdr name-posns))
(name-pos (cdr posns))
- ;(type (cdr result))
+ ;;(type (cdr result))
)
(cons ;(concat
;; func-menu has problems with spaces, and adding a
;; qualifying keyword will not allow the "goto fn"
;; functions to work properly. Sigh.
-; (cond
-; ((eq type 'variable) "")
-; ((eq type 'datatype) "datatype ")
-; ((eq type 'class) "class ")
-; ((eq type 'import) "import ")
-; ((eq type 'instance) "instance "))
+ ;; (cond
+ ;; ((eq type 'variable) "")
+ ;; ((eq type 'datatype) "datatype ")
+ ;; ((eq type 'class) "class ")
+ ;; ((eq type 'import) "import ")
+ ;; ((eq type 'instance) "instance "))
name;)
name-pos))
nil)))
@@ -664,22 +619,16 @@
(concat "^" literate-haskell-ds-start-decl-re)
"As `haskell-ds-func-menu-regexp' but for Bird-style literate scripts.")
-(defun haskell-ds-func-menu (bird-literate)
- "Uses `func-menu' to establish declaration scanning for (BIRD-LITERATE)
-Haskell scripts."
+(defun haskell-ds-func-menu ()
+ "Use `func-menu' to establish declaration scanning for Haskell scripts."
(require 'func-menu)
- (make-local-variable 'fume-menubar-menu-name)
- (setq fume-menubar-menu-name "Declarations")
- (make-local-variable 'fume-function-name-regexp-alist)
- (setq fume-function-name-regexp-alist
- (if bird-literate
- '((haskell-mode . literate-haskell-ds-func-menu-regexp))
- '((haskell-mode . haskell-ds-func-menu-regexp))))
- (make-local-variable 'fume-find-function-name-method-alist)
- (setq fume-find-function-name-method-alist
- (if bird-literate
- '((haskell-mode . literate-haskell-ds-func-menu-next))
- '((haskell-mode . haskell-ds-func-menu-next))))
+ (set (make-local-variable 'fume-menubar-menu-name) "Declarations")
+ (set (make-local-variable 'fume-function-name-regexp-alist)
+ (if (haskell-ds-bird-p)
+ '((haskell-mode . literate-haskell-ds-func-menu-regexp))
+ '((haskell-mode . haskell-ds-func-menu-regexp))))
+ (set (make-local-variable 'fume-find-function-name-method-alist)
+ '((haskell-mode . haskell-ds-func-menu-next)))
(fume-add-menubar-entry)
(local-set-key "\C-cl" 'fume-list-functions)
(local-set-key "\C-cg" 'fume-prompt-function-goto)
@@ -706,7 +655,7 @@
\\[fume-prompt-function-goto] prompts for a declaration to move to, and
\\[fume-mouse-function-goto] moves to the declaration whose name is at point.
-This may link with `haskell-doc' (only for FSF Emacs currently).
+This may link with `haskell-doc' (only for Emacs currently).
For non-literate and LaTeX-style literate scripts, we assume the
common convention that top-level declarations start at the first
@@ -737,15 +686,13 @@
Use `haskell-decl-scan-version' to find out what version this is."
(interactive)
(haskell-ds-keys)
- (let ((bird-literate (if (boundp 'haskell-literate)
- (eq haskell-literate 'bird) nil)))
- (if haskell-ds-running-xemacs
- (haskell-ds-func-menu bird-literate)
- (haskell-ds-imenu bird-literate)))
+ (if (fboundp 'imenu)
+ (haskell-ds-imenu)
+ (haskell-ds-func-menu))
(run-hooks 'haskell-decl-scan-hook))
-;;; Provide ourselves:
+;; Provide ourselves:
(provide 'haskell-decl-scan)
-;;; haskell-decl-scan ends here.
+;;; haskell-decl-scan.el ends here
Index: xemacs-packages/haskell-mode/haskell-doc.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-doc.el,v
retrieving revision 1.4
diff -d -u -r1.4 haskell-doc.el
--- xemacs-packages/haskell-mode/haskell-doc.el 2003/01/08 22:03:45 1.4
+++ xemacs-packages/haskell-mode/haskell-doc.el 2006/03/15 04:57:24
@@ -1,19 +1,13 @@
;;; haskell-doc.el --- show function types in echo area
-;; Time-stamp: <Thu Dec 10 1998 17:26:21 Stardate: [-30]2203.42 hwloidl>
-
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
;; Copyright (C) 1997 Hans-Wolfgang Loidl
;; Author: Hans-Wolfgang Loidl <hwloidl(a)dcs.glasgow.ac.uk>
-;; Maintainer: Hans-Wolfgang Loidl <hwloidl(a)dcs.glasgow.ac.uk>
;; Temporary Maintainer and Hacker: Graeme E Moss <gem(a)cs.york.ac.uk>
;; Keywords: extensions, minor mode, language mode, Haskell
;; Created: 1997-06-17
-;; Revision: $Revision: 1.4 $
-;; FTP archive:
/ftp@ftp.dcs.gla.ac.uk:/pub/glasgow-fp/authors/Hans_Loidl/Elisp/haskell-doc.el
-;; Status: Beta version
-
-;; $Id: haskell-doc.el,v 1.4 2002/10/14 09:55:03 simonmar Exp $
+;; URL:
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/e...
;;; Copyright:
;; ==========
@@ -37,21 +31,21 @@
;; ===========
;; This program shows the type of the Haskell function under the cursor in the
-;; minibuffer. It acts as a kind of "emacs background process", by regularly
+;; minibuffer. It acts as a kind of "emacs background process", by regularly
;; checking the word under the cursor and matching it against a list of
;; prelude, library, local and global functions.
;; The preferred usage of this package is in combination with
;; `haskell-hugs-mode'.
;; In that case `haskell-doc-mode' checks an internal variable updated by
-;; `imenu' to access the types of all local functions. In `haskell-mode' this
-;; is not possible. However, types of prelude functions are still shown.
+;; `imenu' to access the types of all local functions. In `haskell-mode' this
+;; is not possible. However, types of prelude functions are still shown.
-;; To show types of global functions, i.e. functions defined in a module
-;; imported by the current module, call the function
-;; `turn-on-haskell-doc-global-types'. This automatically loads all modules
-;; and builds `imenu' tables to get the types of all functions (again this
-;; currently requires `haskell-hugs-mode').
+;; To show types of global functions, i.e. functions defined in a module
+;; imported by the current module, call the function
+;; `turn-on-haskell-doc-global-types'. This automatically loads all modules
+;; and builds `imenu' tables to get the types of all functions (again this
+;; currently requires `haskell-hugs-mode').
;; Note: The modules are loaded recursively, so you might pull in
;; many modules by just turning on global function support.
;; This features is currently not very well supported.
@@ -83,20 +77,20 @@
;; `haskell-doc-show-user-defined' (default: t)
;; If you want to define your own strings for some identifiers define an
-;; alist of (ID . STRING) and set `haskell-doc-show-user-defined' to t.
+;; alist of (ID . STRING) and set `haskell-doc-show-user-defined' to t.
;; E.g:
;;
;; (setq haskell-doc-show-user-defined t)
-;; (setq haskell-doc-user-defined-ids
-;; (list
+;; (setq haskell-doc-user-defined-ids
+;; (list
;; '("main" . "just another pathetic main function")
;; '("foo" . "a very dummy name")
;; '("bar" . "another dummy name")))
;; The following two variables are useful to make the type fit on one line:
;; If `haskell-doc-chop-off-context' is non-nil the context part of the type
-;; of a local fct will be eliminated (default: t).
-;; If `haskell-doc-chop-off-fctname' is non-nil the function name is not
+;; of a local fct will be eliminated (default: t).
+;; If `haskell-doc-chop-off-fctname' is non-nil the function name is not
;; shown together with the type (default: nil).
;;; Internals:
@@ -118,14 +112,14 @@
;; `haskell-doc-show-prelude' ... toggle echoing of prelude id's types
;; `haskell-doc-show-strategy' ... toggle echoing of strategy id's types
;; `haskell-doc-show-user-defined' ... toggle echoing of user def id's types
-;; `haskell-doc-check-active' ... check whether haskell-doc is active via the
-;; `post-command-idle-hook' (for testing);
+;; `haskell-doc-check-active' ... check whether haskell-doc is active via the
+;; `post-command-idle-hook' (for testing);
;; Key: CTRL-c ESC-/
;;; ToDo:
;; =====
-;; - Fix byte-compile problems in `haskell-doc-prelude-types' for getArgs etc
+;; - Fix byte-compile problems in `haskell-doc-prelude-types' for getArgs etc
;; - Write a parser for .hi files and make haskell-doc independent from
;; hugs-mode. Read library interfaces via this parser.
;; - Indicate kind of object with colours
@@ -136,13 +130,81 @@
;;; Bugs:
;; =====
-;; - Some prelude fcts aren't displayed properly. This might be due to a
+;; - Some prelude fcts aren't displayed properly. This might be due to a
;; name clash of Haskell and Elisp functions (e.g. length) which
;; confuses emacs when reading `haskell-doc-prelude-types'
;;; Changelog:
;; ==========
-;; $Log: haskell-doc.el,v $
+;; haskell-doc.el,v
+;; Revision 1.16 2005/11/07 01:28:16 monnier
+;; (haskell-doc-xemacs-p, haskell-doc-emacs-p)
+;; (haskell-doc-message): Remove.
+;; (haskell-doc-is-id-char-at): Remove.
+;; (haskell-doc-get-current-word): Rewrite.
+;;
+;; Revision 1.15 2005/11/04 17:11:12 monnier
+;; Add arch-tag.
+;;
+;; Revision 1.14 2005/08/24 11:36:32 monnier
+;; (haskell-doc-message): Paren typo.
+;;
+;; Revision 1.13 2005/08/23 19:23:27 monnier
+;; (haskell-doc-show-type): Assume that the availability
+;; of display-message won't change at runtime.
+;;
+;; Revision 1.12 2005/07/18 21:04:14 monnier
+;; (haskell-doc-message): Remove.
+;; (haskell-doc-show-type): inline it. Do nothing for if there's no doc to show.
+;;
+;; Revision 1.11 2004/12/10 17:33:18 monnier
+;; (haskell-doc-minor-mode-string): Make it dynamic.
+;; (haskell-doc-install-keymap): Remove conflicting C-c C-o binding.
+;; (haskell-doc-mode): Make a nil arg turn the mode ON.
+;; (turn-on-haskell-doc-mode): Make it an alias for haskell-doc-mode.
+;; (haskell-doc-mode): Don't touch haskell-doc-minor-mode-string.
+;; (haskell-doc-show-global-types): Don't touch
+;; haskell-doc-minor-mode-string. Call haskell-doc-make-global-fct-index.
+;; (haskell-doc-check-active): Fix message.
+;; (define-key-after): Don't define.
+;; (haskell-doc-install-keymap): Check existence of define-key-after.
+;;
+;; Revision 1.10 2004/11/25 23:03:23 monnier
+;; (haskell-doc-sym-doc): Make even the last char bold.
+;;
+;; Revision 1.9 2004/11/24 22:14:36 monnier
+;; (haskell-doc-install-keymap): Don't blindly assume there's a Hugs menu.
+;;
+;; Revision 1.8 2004/11/22 10:45:35 simonmar
+;; Fix type of getLine
+;;
+;; Revision 1.7 2004/10/14 22:27:47 monnier
+;; (turn-off-haskell-doc-mode, haskell-doc-current-info): Don't autoload.
+;;
+;; Revision 1.6 2004/10/13 22:45:22 monnier
+;; (haskell-doc): New group.
+;; (haskell-doc-show-reserved, haskell-doc-show-prelude)
+;; (haskell-doc-show-strategy, haskell-doc-show-user-defined)
+;; (haskell-doc-chop-off-context, haskell-doc-chop-off-fctname):
+;; Make them custom vars.
+;; (haskell-doc-keymap): Declare and fill it right there.
+;; (haskell-doc-mode): Simplify.
+;; (haskell-doc-toggle-var): Make it into what it was supposed to be.
+;; (haskell-doc-mode-print-current-symbol-info): Simplify.
+;; (haskell-doc-current-info): New autoloaded function.
+;; (haskell-doc-sym-doc): New fun extracted from haskell-doc-show-type.
+;; (haskell-doc-show-type): Use it.
+;; (haskell-doc-wrapped-type-p): Remove unused var `lim'.
+;; (haskell-doc-forward-sexp-safe, haskell-doc-current-symbol): Remove. Unused.
+;; (haskell-doc-visit-home): Don't require ange-ftp, it's autoloaded.
+;; (haskell-doc-install-keymap): Simplify.
+;;
+;; Revision 1.5 2003/01/09 11:56:26 simonmar
+;; Patches from Ville Skytt䠼scop(a)xemacs.org>, the XEmacs maintainer of
+;; the haskell-mode:
+;;
+;; - Make the auto-mode-alist modifications autoload-only.
+;;
;; Revision 1.4 2002/10/14 09:55:03 simonmar
;; Patch to update the Prelude/libraries function names and to remove
;; support for older versions of Haskell.
@@ -186,66 +248,64 @@
;;; Code:
;; =====
-
-;@menu
-;* Constants and Variables::
-;* Install as minor mode::
-;* Menubar Support::
-;* Haskell Doc Mode::
-;* Switch it on or off::
-;* Check::
-;* Top level function::
-;* Mouse interface::
-;* Print fctsym::
-;* Movement::
-;* Bug Reports::
-;* Visit home site::
-;* Index::
-;* Token::
-;@end menu
-;@node top, Constants and Variables, (dir), (dir)
-;@top
+;;@menu
+;;* Constants and Variables::
+;;* Install as minor mode::
+;;* Menubar Support::
+;;* Haskell Doc Mode::
+;;* Switch it on or off::
+;;* Check::
+;;* Top level function::
+;;* Mouse interface::
+;;* Print fctsym::
+;;* Movement::
+;;* Bug Reports::
+;;* Visit home site::
+;;* Index::
+;;* Token::
+;;@end menu
-;@node Constants and Variables, Install as minor mode, top, top
-;@section Constants and Variables
+;;@node top, Constants and Variables, (dir), (dir)
+;;@top
-;@menu
-;* Emacs portability::
-;* Maintenance stuff::
-;* Mode Variable::
-;* Variables::
-;* Prelude types::
-;* Test membership::
-;@end menu
+;;@node Constants and Variables, Install as minor mode, top, top
+;;@section Constants and Variables
-;@node Emacs portability, Maintenance stuff, Constants and Variables, Constants and
Variables
-;@subsection Emacs portability
+;;@menu
+;;* Emacs portability::
+;;* Maintenance stuff::
+;;* Mode Variable::
+;;* Variables::
+;;* Prelude types::
+;;* Test membership::
+;;@end menu
-(defconst haskell-doc-xemacs-p (string-match "XEmacs\\|Lucid" emacs-version)
- "Running under XEmacs?")
+;;@node Emacs portability, Maintenance stuff, Constants and Variables, Constants and
Variables
+;;@subsection Emacs portability
-(defconst haskell-doc-emacs-p (and (or (string-match "^19" emacs-version)
- (string-match "^20" emacs-version))
- (not haskell-doc-xemacs-p))
- "Running under Emacs?")
+(defgroup haskell-doc nil
+ "Show Haskell function types in echo area."
+:group 'haskell
+:prefix "haskell-doc-")
-;@node Maintenance stuff, Mode Variable, Emacs portability, Constants and Variables
-;@subsection Maintenance stuff
+;;@node Maintenance stuff, Mode Variable, Emacs portability, Constants and Variables
+;;@subsection Maintenance stuff
-(defconst haskell-doc-version "$Revision: 1.4 $"
+(defconst haskell-doc-version "1.16"
"Version of `haskell-doc-mode' as RCS Revision.")
-(defconst haskell-doc-maintainer "Hans-Wolfgang Loidl
<hwloidl(a)dcs.glasgow.ac.uk>"
+(defconst haskell-doc-maintainer
+ "Hans-Wolfgang Loidl <hwloidl(a)dcs.glasgow.ac.uk>"
"Maintainer of `haskell-doc-mode'.")
-(defconst haskell-doc-ftp-site
"/ftp@ftp.dcs.gla.ac.uk:/pub/glasgow-fp/authors/Hans_Loidl/Elisp/"
+(defconst haskell-doc-ftp-site
+ "/ftp@ftp.dcs.gla.ac.uk:/pub/glasgow-fp/authors/Hans_Loidl/Elisp/"
"Main FTP site with latest version of `haskell-doc-mode' and sample
files.")
-;@node Mode Variable, Variables, Maintenance stuff, Constants and Variables
-;@subsection Mode Variable
+;;@node Mode Variable, Variables, Maintenance stuff, Constants and Variables
+;;@subsection Mode Variable
-;;;###autoload
(defvar haskell-doc-mode nil
"*If non-nil, show the type of the function near point or a related comment.
@@ -253,15 +313,15 @@
`haskell-doc-show-reserved' is non-nil show a one line summary
of the syntax.
-If the identifier near point is a Prelude or one of the standard library
+If the identifier near point is a Prelude or one of the standard library
functions and `haskell-doc-show-prelude' is non-nil show its type.
If the identifier near point is local \(i.e. defined in this module\) check
the `imenu' list of functions for the type. This obviously requires that
your language mode uses `imenu' \(`haskell-hugs-mode' 0.6 for example\).
-If the identifier near point is global \(i.e. defined in an imported module\)
-and the variable `haskell-doc-show-global-types' is non-nil show the type of its
+If the identifier near point is global \(i.e. defined in an imported module\)
+and the variable `haskell-doc-show-global-types' is non-nil show the type of its
function.
If the identifier near point is a standard strategy or a function, type related
@@ -270,7 +330,7 @@
If you're not interested in that just turn it off.
If the identifier near point is a user defined function that occurs as key
-in the alist `haskell-doc-user-defined-ids' and the variable
+in the alist `haskell-doc-user-defined-ids' and the variable
`haskell-doc-show-user-defined' is non-nil show the type of the function.
This variable is buffer-local.")
@@ -286,42 +346,49 @@
This variable is buffer-local.")
(make-variable-buffer-local 'haskell-doc-index)
-(defvar haskell-doc-show-global-types nil
- "*If non-nil, search for the types of global functions by loading the files.
-This variable is buffer-local.")
+(defcustom haskell-doc-show-global-types nil
+ "If non-nil, search for the types of global functions by loading the files.
+This variable is buffer-local."
+:type 'boolean)
(make-variable-buffer-local 'haskell-doc-show-global-types)
-(defvar haskell-doc-show-reserved t
- "*If non-nil, show a documentation string for reserved ids.
-This variable is buffer-local.")
+(defcustom haskell-doc-show-reserved t
+ "If non-nil, show a documentation string for reserved ids.
+This variable is buffer-local."
+:type 'boolean)
(make-variable-buffer-local 'haskell-doc-show-reserved)
-(defvar haskell-doc-show-prelude t
- "*If non-nil, show a documentation string for prelude functions.
-This variable is buffer-local.")
+(defcustom haskell-doc-show-prelude t
+ "If non-nil, show a documentation string for prelude functions.
+This variable is buffer-local."
+:type 'boolean)
(make-variable-buffer-local 'haskell-doc-show-prelude)
-(defvar haskell-doc-show-strategy t
- "*If non-nil, show a documentation string for strategies.
-This variable is buffer-local.")
+(defcustom haskell-doc-show-strategy t
+ "If non-nil, show a documentation string for strategies.
+This variable is buffer-local."
+:type 'boolean)
(make-variable-buffer-local 'haskell-doc-show-strategy)
-(defvar haskell-doc-show-user-defined t
- "*If non-nil, show a documentation string for user defined ids.
-This variable is buffer-local.")
+(defcustom haskell-doc-show-user-defined t
+ "If non-nil, show a documentation string for user defined ids.
+This variable is buffer-local."
+:type 'boolean)
(make-variable-buffer-local 'haskell-doc-show-user-defined)
-(defvar haskell-doc-chop-off-context t
- "*If non-nil eliminate the context part in a Haskell type.")
+(defcustom haskell-doc-chop-off-context t
+ "If non-nil eliminate the context part in a Haskell type."
+:type 'boolean)
-(defvar haskell-doc-chop-off-fctname nil
- "*If non-nil omit the function name and show only the type.")
+(defcustom haskell-doc-chop-off-fctname nil
+ "If non-nil omit the function name and show only the type."
+:type 'boolean)
(defvar haskell-doc-search-distance 40 ; distance in characters
"*How far to search when looking for the type declaration of fct under
cursor.")
-;@node Variables, Prelude types, Mode Variable, Constants and Variables
-;@subsection Variables
+;;@node Variables, Prelude types, Mode Variable, Constants and Variables
+;;@subsection Variables
(defvar haskell-doc-idle-delay 0.50
"*Number of seconds of idle time to wait before printing.
@@ -347,36 +414,35 @@
It is probably best to manipulate this data structure with the commands
`haskell-doc-add-command' and `haskell-doc-remove-command'.")
-;(cond ((null haskell-doc-mode-message-commands)
-; ;; If you increase the number of buckets, keep it a prime number.
-; (setq haskell-doc-mode-message-commands (make-vector 31 0))
-; (let ((list '("self-insert-command"
-; "next-" "previous-"
-; "forward-" "backward-"
-; "beginning-of-" "end-of-"
-; "goto-"
-; "recenter"
-; "scroll-"))
-; (syms nil))
-; (while list
-; (setq syms (all-completions (car list) obarray 'fboundp))
-; (setq list (cdr list))
-; (while syms
-; (set (intern (car syms) haskell-doc-mode-message-commands) t)
-; (setq syms (cdr syms)))))))
+;;(cond ((null haskell-doc-mode-message-commands)
+;; ;; If you increase the number of buckets, keep it a prime number.
+;; (setq haskell-doc-mode-message-commands (make-vector 31 0))
+;; (let ((list '("self-insert-command"
+;; "next-" "previous-"
+;; "forward-" "backward-"
+;; "beginning-of-" "end-of-"
+;; "goto-"
+;; "recenter"
+;; "scroll-"))
+;; (syms nil))
+;; (while list
+;; (setq syms (all-completions (car list) obarray 'fboundp))
+;; (setq list (cdr list))
+;; (while syms
+;; (set (intern (car syms) haskell-doc-mode-message-commands) t)
+;; (setq syms (cdr syms)))))))
;; Bookkeeping; the car contains the last symbol read from the buffer.
;; The cdr contains the string last displayed in the echo area, so it can
;; be printed again if necessary without reconsing.
(defvar haskell-doc-last-data '(nil . nil))
-(defvar haskell-doc-minor-mode-string " Doc" ; "
Haskell-Doc"
+(defvar haskell-doc-minor-mode-string
+ '(haskell-doc-show-global-types " DOC" " Doc")
"*String to display in mode line when Haskell-Doc Mode is enabled.")
(defconst haskell-doc-varlist
(list
- 'haskell-doc-xemacs-p
- 'haskell-doc-emacs-p
'haskell-doc-version
'haskell-doc-mode
'haskell-doc-mode-hook
@@ -392,10 +458,10 @@
)
"List of variables sent via `haskell-doc-submit-bug-report'.")
-;@node Prelude types, Test membership, Variables, Constants and Variables
-;@subsection Prelude types
+;;@node Prelude types, Test membership, Variables, Constants and Variables
+;;@subsection Prelude types
-;@cindex haskell-doc-reserved-ids
+;;@cindex haskell-doc-reserved-ids
(defvar haskell-doc-reserved-ids
(list
@@ -426,7 +492,7 @@
)
"An alist of reserved identifiers and a string describing the construct they are
used in.")
-;@cindex haskell-doc-prelude-types
+;;@cindex haskell-doc-prelude-types
(defvar haskell-doc-prelude-types
(list
@@ -513,7 +579,7 @@
'("gcd" . "(Integral a) => a -> a -> a")
'("getChar" . "IO Char")
'("getContents" . "IO String")
- '("getLine" . "IO Char")
+ '("getLine" . "IO String")
'("head" . "[a] -> a")
'("id" . "a -> a")
'("init" . "[a] -> [a]")
@@ -899,7 +965,7 @@
'("getStdRandom" . "(StdGen -> (a, StdGen)) -> IO a"))
"alist of prelude functions and their types.")
-;@cindex haskell-doc-strategy-ids
+;;@cindex haskell-doc-strategy-ids
(defvar haskell-doc-strategy-ids
(list
@@ -961,16 +1027,16 @@
(defvar haskell-doc-user-defined-ids nil
"alist of functions and strings defined by the user.")
-;@node Test membership, , Prelude types, Constants and Variables
-;@subsection Test membership
+;;@node Test membership, , Prelude types, Constants and Variables
+;;@subsection Test membership
-;@cindex haskell-doc-is-of
+;;@cindex haskell-doc-is-of
(defsubst haskell-doc-is-of (fn types)
"Check whether FN is one of the functions in the alist TYPES and return the
type."
(assoc fn types) )
-;@node Install as minor mode, Menubar Support, Constants and Variables, top
-;@section Install as minor mode
+;;@node Install as minor mode, Menubar Support, Constants and Variables, top
+;;@section Install as minor mode
;; Put this minor mode on the global minor-mode-alist.
(or (assq 'haskell-doc-mode (default-value 'minor-mode-alist))
@@ -978,253 +1044,191 @@
(append (default-value 'minor-mode-alist)
'((haskell-doc-mode haskell-doc-minor-mode-string)))))
-;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages are
-;; recorded in a log. Do not put haskell-doc messages in that log since
-;; they are Legion.
-
-;@cindex haskell-doc-message
-
-(defmacro haskell-doc-message (&rest args)
- (if (fboundp 'display-message)
- ;; XEmacs 19.13 way of preventing log messages.
- ;(list 'display-message '(quote no-log) (apply 'list 'format
args))
- ;; XEmacs 19.15 seems to be a bit different
- (list 'display-message '(quote message) (apply 'list 'format
args))
- (list 'let (list (list 'message-log-max 'nil))
- (apply 'list 'message args))))
-
-;@node Menubar Support, Haskell Doc Mode, Install as minor mode, top
-;@section Menubar Support
+;;@node Menubar Support, Haskell Doc Mode, Install as minor mode, top
+;;@section Menubar Support
-; get imenu
+;; get imenu
(require 'imenu)
-; a dummy definition needed for xemacs (I know, it's horrible :-(
-(if (and (string-match "XEmacs" emacs-version)
- (not (functionp 'define-key-after)))
- (defun define-key-after (map seq con name)))
+;; a dummy definition needed for xemacs (I know, it's horrible :-(
-;@cindex haskell-doc-install-keymap
+;;@cindex haskell-doc-install-keymap
+(defvar haskell-doc-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map [visit]
+ '("Visit FTP home site" . haskell-doc-visit-home))
+ (define-key map [submit]
+ '("Submit bug report" . haskell-doc-submit-bug-report))
+ (define-key map [dummy] '("---" . nil))
+ (define-key map [make-index]
+ '("Make global fct index" . haskell-doc-make-global-fct-index))
+ (define-key map [global-types-on]
+ '("Toggle display of global types" . haskell-doc-show-global-types))
+ (define-key map [strategy-on]
+ '("Toggle display of strategy ids" . haskell-doc-show-strategy))
+ (define-key map [user-defined-on]
+ '("Toggle display of user defined ids" .
haskell-doc-show-user-defined))
+ (define-key map [prelude-on]
+ '("Toggle display of prelude functions" . haskell-doc-show-prelude))
+ (define-key map [reserved-ids-on]
+ '("Toggle display of reserved ids" . haskell-doc-show-reserved))
+ (define-key map [haskell-doc-on]
+ '("Toggle haskell-doc mode" . haskell-doc-mode))
+ map))
+
(defun haskell-doc-install-keymap ()
"Install a menu for `haskell-doc-mode' as a submenu of
\"Hugs\"."
- (interactive)
- ; define a keymap `haskell-doc-keymap' for the derive menu
- (if nil ; (keymapp haskell-doc-keymap)
- nil
- (setq haskell-doc-keymap (make-sparse-keymap))
- (define-key haskell-doc-keymap [visit]
- '("Visit FTP home site" . haskell-doc-visit-home))
- (define-key haskell-doc-keymap [submit]
- '("Submit bug report" . haskell-doc-submit-bug-report))
- (define-key haskell-doc-keymap [dummy]
- '("---" . nil))
- (define-key haskell-doc-keymap [make-index]
- '("Make global fct index" . haskell-doc-make-global-fct-index))
- (define-key haskell-doc-keymap [global-types-on]
- '("Toggle display of global types" .
haskell-doc-show-global-types))
- (define-key haskell-doc-keymap [strategy-on]
- '("Toggle display of strategy ids" . haskell-doc-show-strategy))
- (define-key haskell-doc-keymap [user-defined-on]
- '("Toggle display of user defined ids" .
haskell-doc-show-user-defined))
- (define-key haskell-doc-keymap [prelude-on]
- '("Toggle display of prelude functions" .
haskell-doc-show-prelude))
- (define-key haskell-doc-keymap [reserved-ids-on]
- '("Toggle display of reserved ids" . haskell-doc-show-reserved))
- (define-key haskell-doc-keymap [haskell-doc-on]
- '("Toggle haskell-doc mode" . haskell-doc-mode))
- )
-
- ; add the menu to the hugs menu as last entry
- (cond
- ((eq major-mode 'haskell-hugs-mode)
- (let ((hugsmap (lookup-key haskell-hugs-mode-map [menu-bar Hugs])))
- (if (and (not haskell-doc-xemacs-p) ; XEmacs has problems here
- (not (lookup-key hugsmap [haskell-doc])))
- (define-key-after hugsmap [haskell-doc] (cons "Haskell-doc"
haskell-doc-keymap)
- [Haskell-doc mode]))
- ; add shortcuts for these commands
- (define-key haskell-hugs-mode-map "\C-c\e/" 'haskell-doc-check-active)
; for testing
- (define-key haskell-hugs-mode-map "\C-c\C-o" 'haskell-doc-mode)
- (if (not haskell-doc-xemacs-p)
- (define-key haskell-hugs-mode-map [C-S-M-mouse-3]
'haskell-doc-ask-mouse-for-type))))
- ((eq major-mode 'haskell-mode)
- ; add shortcuts for these commands
- (local-set-key "\C-c\e/" 'haskell-doc-check-active) ; for testing
- (local-set-key "\C-c\C-o" 'haskell-doc-mode)
- (if (not haskell-doc-xemacs-p)
- (local-set-key [C-S-M-mouse-3] 'haskell-doc-ask-mouse-for-type)) ) ))
+ (interactive)
+ ;; Add the menu to the hugs menu as last entry.
+ (let ((hugsmap (lookup-key (current-local-map) [menu-bar Hugs])))
+ (if (not (or (featurep 'xemacs) ; XEmacs has problems here
+ (not (keymapp hugsmap))
+ (lookup-key hugsmap [haskell-doc])))
+ (if (functionp 'define-key-after)
+ (define-key-after hugsmap [haskell-doc]
+ (cons "Haskell-doc" haskell-doc-keymap)
+ [Haskell-doc mode]))))
+ ;; Add shortcuts for these commands.
+ (local-set-key "\C-c\e/" 'haskell-doc-check-active)
+ ;; Conflicts with the binding of haskell-insert-otherwise.
+ ;; (local-set-key "\C-c\C-o" 'haskell-doc-mode)
+ (local-set-key [(control shift meta mouse-3)]
+ 'haskell-doc-ask-mouse-for-type))
-;@node Haskell Doc Mode, Switch it on or off, Menubar Support, top
-;@section Haskell Doc Mode
+;;@node Haskell Doc Mode, Switch it on or off, Menubar Support, top
+;;@section Haskell Doc Mode
-;@cindex haskell-doc-mode
+;;@cindex haskell-doc-mode
;;;###autoload
-(defun haskell-doc-mode (&optional prefix)
+(defun haskell-doc-mode (&optional arg)
"Enter `haskell-doc-mode' for showing fct types in the echo area.
See variable docstring."
- (interactive "P")
+ (interactive (list (or current-prefix-arg 'toggle)))
;; Make sure it's on the post-command-idle-hook if defined, otherwise put
;; it on post-command-hook. The former first appeared in Emacs 19.30.
(setq haskell-doc-mode
- (if prefix
- (or (listp prefix);; C-u alone
- (> (prefix-numeric-value prefix) 0))
- (not haskell-doc-mode)))
+ (cond
+ ((eq arg 'toggle) (not haskell-doc-mode))
+ (arg (> (prefix-numeric-value arg) 0))
+ (t)))
- (and haskell-doc-mode-hook
- haskell-doc-mode
- (run-hooks 'haskell-doc-mode-hook))
+ (cond
+ (haskell-doc-mode
+ ;; Turning the mode ON.
- ;; ToDo: replace binding of `post-command-idle-hook' by `run-with-idle-timer'
- (and haskell-doc-mode
- (not (memq 'haskell-doc-mode-print-current-symbol-info
- (if (boundp 'post-command-idle-hook)
- post-command-idle-hook
- post-command-hook)))
- (add-hook (if (boundp 'post-command-idle-hook)
- 'post-command-idle-hook
- 'post-command-hook)
- 'haskell-doc-mode-print-current-symbol-info))
+ ;; ToDo: replace binding of `post-command-idle-hook' by
+ ;; `run-with-idle-timer'
+ (add-hook (if (boundp 'post-command-idle-hook)
+ 'post-command-idle-hook
+ 'post-command-hook)
+ 'haskell-doc-mode-print-current-symbol-info nil 'local)
+ (and haskell-doc-show-global-types
+ (haskell-doc-make-global-fct-index)) ; build type index for global fcts
- (and (not haskell-doc-mode)
- (memq 'haskell-doc-mode-print-current-symbol-info
- (if (boundp 'post-command-idle-hook)
- post-command-idle-hook
- post-command-hook))
- (remove-hook (if (boundp 'post-command-idle-hook)
- 'post-command-idle-hook
- 'post-command-hook)
- 'haskell-doc-mode-print-current-symbol-info))
+ (haskell-doc-install-keymap)
- (and haskell-doc-mode
- haskell-doc-show-global-types
- (progn
- (setq haskell-doc-minor-mode-string " Haskell-DOC")
- (haskell-doc-make-global-fct-index)) ; build type index for global fcts
- (setq haskell-doc-minor-mode-string " Haskell-Doc"))
+ (run-hooks 'haskell-doc-mode-hook))
- (if haskell-doc-mode
- (haskell-doc-install-keymap))
+ ((not haskell-doc-mode)
+
+ (remove-hook (if (boundp 'post-command-idle-hook)
+ 'post-command-idle-hook
+ 'post-command-hook)
+ 'haskell-doc-mode-print-current-symbol-info 'local)))
(and (interactive-p)
- (if haskell-doc-mode
- (message "haskell-doc-mode is enabled")
- (message "haskell-doc-mode is disabled")))
+ (message "haskell-doc-mode is %s"
+ (if haskell-doc-mode "enabled" "disabled")))
haskell-doc-mode)
-;;@cindex haskell-doc-show-global-types
-
-;;;;###autoload
-;(defun haskell-doc-show-global-types (&optional prefix)
-; "*If non-nil, then enable display of global types in
`haskell-doc-mode'."
-; (interactive "P")
-; ;; toggle mode or set it based on prefix value
-; (setq haskell-doc-show-global-types
-; (if prefix
-; (>= (prefix-numeric-value prefix) 0)
-; (not haskell-doc-show-global-types)))
-
-; (cond (haskell-doc-show-global-types
-; ;; set mode string to reflect value of `haskell-doc-show-global-types'
-; (setq haskell-doc-minor-mode-string " Haskell-DOC")
-; ;; build index (note: this can be quite expensive)
-; (haskell-doc-make-global-fct-index))
-; (t
-; (setq haskell-doc-minor-mode-string " Haskell-Doc")) ) )
-
-
(defmacro haskell-doc-toggle-var (id prefix)
;; toggle variable or set it based on prefix value
- (setq id
- (if prefix
- (>= (prefix-numeric-value prefix) 0)
- (not id))) )
+ `(setq ,id
+ (if ,prefix
+ (>= (prefix-numeric-value ,prefix) 0)
+ (not ,id))) )
-;@cindex haskell-doc-show-global-types
+;;@cindex haskell-doc-show-global-types
(defun haskell-doc-show-global-types (&optional prefix)
"Turn on global types information in `haskell-doc-mode'."
(interactive "P")
(haskell-doc-toggle-var haskell-doc-show-global-types prefix)
(if haskell-doc-show-global-types
- (setq haskell-doc-minor-mode-string " Haskell-DOC")
- (setq haskell-doc-minor-mode-string " Haskell-Doc")) )
+ (haskell-doc-make-global-fct-index)))
-;@cindex haskell-doc-show-reserved
+;;@cindex haskell-doc-show-reserved
(defun haskell-doc-show-reserved (&optional prefix)
"Toggle the automatic display of a doc string for reserved ids."
(interactive "P")
(haskell-doc-toggle-var haskell-doc-show-reserved prefix))
-;@cindex haskell-doc-show-prelude
+;;@cindex haskell-doc-show-prelude
(defun haskell-doc-show-prelude (&optional prefix)
"Toggle the automatic display of a doc string for reserved ids."
(interactive "P")
(haskell-doc-toggle-var haskell-doc-show-prelude prefix))
-;@cindex haskell-doc-show-strategy
+;;@cindex haskell-doc-show-strategy
(defun haskell-doc-show-strategy (&optional prefix)
"Toggle the automatic display of a doc string for strategy ids."
(interactive "P")
(haskell-doc-toggle-var haskell-doc-show-strategy prefix))
-;@cindex haskell-doc-show-user-defined
+;;@cindex haskell-doc-show-user-defined
(defun haskell-doc-show-user-defined (&optional prefix)
"Toggle the automatic display of a doc string for user defined ids."
(interactive "P")
(haskell-doc-toggle-var haskell-doc-show-user-defined prefix))
-;@node Switch it on or off, Check, Haskell Doc Mode, top
-;@section Switch it on or off
+;;@node Switch it on or off, Check, Haskell Doc Mode, top
+;;@section Switch it on or off
-;@cindex turn-on-haskell-doc-mode
+;;@cindex turn-on-haskell-doc-mode
;;;###autoload
-(defun turn-on-haskell-doc-mode ()
- "Unequivocally turn on `haskell-doc-mode' (see variable documentation)."
- (interactive)
- (haskell-doc-mode 1))
+(defalias 'turn-on-haskell-doc-mode 'haskell-doc-mode)
-;@cindex turn-off-haskell-doc-mode
+;;@cindex turn-off-haskell-doc-mode
-;;;###autoload
(defun turn-off-haskell-doc-mode ()
"Unequivocally turn off `haskell-doc-mode' (see variable
documentation)."
(interactive)
(haskell-doc-mode 0))
-;@node Check, Top level function, Switch it on or off, top
-;@section Check
+;;@node Check, Top level function, Switch it on or off, top
+;;@section Check
-;@cindex haskell-doc-check-active
+;;@cindex haskell-doc-check-active
(defun haskell-doc-check-active ()
- "Check whether the print function is hooked in.
-Should be the same as the value of `haskell-doc-mode' but alas currently it
+ "Check whether the print function is hooked in.
+Should be the same as the value of `haskell-doc-mode' but alas currently it
is not."
- (interactive)
- (message
- (if (memq 'haskell-doc-mode-print-current-symbol-info
- (if (boundp 'post-command-idle-hook)
- post-command-idle-hook
- post-command-hook))
- "haskell-doc is ACTIVE"
- "haskell-doc is not ACTIVE \(Use C-u C-c C-o to turn it on\)")))
+ (interactive)
+ (message
+ (if (memq 'haskell-doc-mode-print-current-symbol-info
+ (if (boundp 'post-command-idle-hook)
+ post-command-idle-hook
+ post-command-hook))
+ "haskell-doc is ACTIVE"
+ (substitute-command-keys
+ "haskell-doc is not ACTIVE \(Use C-u \\[haskell-doc-mode] to turn it
on\)"))))
-;@node Top level function, Mouse interface, Check, top
-;@section Top level function
+;;@node Top level function, Mouse interface, Check, top
+;;@section Top level function
-;@cindex haskell-doc-mode-print-current-symbol-info
+;;@cindex haskell-doc-mode-print-current-symbol-info
;; This is the function hooked into the elisp command engine
(defun haskell-doc-mode-print-current-symbol-info ()
- "Print the type of the symbol under the cursor.
+ "Print the type of the symbol under the cursor.
This function is hooked into the `post-command-idle-hook' to print the type
-automatically if `haskell-doc-mode' is turned on. It can also be called
+automatically if `haskell-doc-mode' is turned on. It can also be called
directly to ask for the type of a function."
(interactive)
(and haskell-doc-mode
@@ -1232,25 +1236,27 @@
;; Having this mode operate in the minibuffer makes it impossible to
;; see what you're doing.
(not (eq (selected-window) (minibuffer-window)))
- ; take a nap
+ ;; take a nap
(sit-for haskell-doc-idle-delay)
- ; good morning! read the word under the cursor for breakfast
- (let ((current-symbol (haskell-doc-get-current-word)) );
(haskell-doc-current-symbol)) )
- ; (current-fnsym (haskell-doc-fnsym-in-current-sexp)))
- (haskell-doc-show-type current-symbol)) ))
+ ;; good morning! read the word under the cursor for breakfast
+ (haskell-doc-show-type)))
+ ;; ;; ToDo: find surrounding fct
+ ;; (cond ((eq current-symbol current-fnsym)
+ ;; (haskell-doc-show-type current-fnsym))
+ ;; (t
+ ;; (or nil ; (haskell-doc-print-var-docstring current-symbol)
+ ;; (haskell-doc-show-type current-fnsym)))))))
-; ; ToDo: find surrounding fct
-; (cond ((eq current-symbol current-fnsym)
-; (haskell-doc-show-type current-fnsym))
-; (t
-; (or nil ; (haskell-doc-print-var-docstring current-symbol)
-; (haskell-doc-show-type current-fnsym)))))))
+(defun haskell-doc-current-info ()
+ "Return the info about symbol at point.
+Meant for `eldoc-print-current-symbol-info-function'."
+ (haskell-doc-sym-doc (haskell-doc-get-current-word)))
-;@node Mouse interface, Print fctsym, Top level function, top
-;@section Mouse interface for interactive query
+;;@node Mouse interface, Print fctsym, Top level function, top
+;;@section Mouse interface for interactive query
-;@cindex haskell-doc-ask-mouse-for-type
+;;@cindex haskell-doc-ask-mouse-for-type
(defun haskell-doc-ask-mouse-for-type (event)
"Read the identifier under the mouse and echo its type.
This uses the same underlying function `haskell-doc-show-type' as the hooked
@@ -1259,36 +1265,56 @@
(save-excursion
(select-window (posn-window (event-end event)))
(goto-char (posn-point (event-end event)))
- (haskell-doc-show-type )))
-
+ (haskell-doc-show-type)))
-;@node Print fctsym, Movement, Mouse interface, top
-;@section Print fctsym
-;@menu
-;* Show type::
-;* Aux::
-;* Global fct type::
-;* Local fct type::
-;@end menu
+;;@node Print fctsym, Movement, Mouse interface, top
+;;@section Print fctsym
-;@node Show type, Aux, Print fctsym, Print fctsym
-;@subsection Show type
+;;@menu
+;;* Show type::
+;;* Aux::
+;;* Global fct type::
+;;* Local fct type::
+;;@end menu
-;@cindex haskell-doc-show-type
+;;@node Show type, Aux, Print fctsym, Print fctsym
+;;@subsection Show type
+;;@cindex haskell-doc-show-type
+
;;;###autoload
-(defun haskell-doc-show-type (&optional symbol)
+(defun haskell-doc-show-type (&optional sym)
"Show the type of the function near point.
For the function under point, show the type in the echo area.
This information is extracted from the `haskell-doc-prelude-types' alist
of prelude functions and their types, or from the local functions in the
current buffer."
(interactive)
- (let* ((sym (or symbol (haskell-doc-get-current-word)))
- ; (haskell-doc-current-symbol))); (haskell-doc-fnsym-in-current-sexp)))
- (printit t)
- (i-am-prelude nil)
+ (unless sym (setq sym (haskell-doc-get-current-word)))
+ ;; if printed before do not print it again
+ (unless (string= sym (car haskell-doc-last-data))
+ (let ((doc (haskell-doc-sym-doc sym)))
+ (when doc
+ ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all
+ ;; messages are recorded in a log. Do not put haskell-doc messages
+ ;; in that log since they are legion.
+ (if (eval-when-compile (fboundp 'display-message))
+ ;; XEmacs 19.13 way of preventing log messages.
+ ;;(display-message 'no-log (format <args>))
+ ;; XEmacs 19.15 seems to be a bit different.
+ (display-message 'message (format "%s" doc))
+ (let ((message-log-max nil))
+ (message "%s" doc)))))))
+
+
+(defun haskell-doc-sym-doc (sym)
+ "Show the type of the function near point.
+For the function under point, show the type in the echo area.
+This information is extracted from the `haskell-doc-prelude-types' alist
+of prelude functions and their types, or from the local functions in the
+current buffer."
+ (let ((i-am-prelude nil)
(i-am-fct nil)
(type nil)
(is-reserved (haskell-doc-is-of sym haskell-doc-reserved-ids))
@@ -1297,10 +1323,6 @@
(is-user-defined (haskell-doc-is-of sym haskell-doc-user-defined-ids))
(is-prelude (haskell-doc-is-of sym haskell-doc-prelude-types)))
(cond
- ;; if printed before do not print it again
- ((string= sym (car haskell-doc-last-data))
- (setq printit nil)
- (setq type (cdr haskell-doc-last-data)))
;; if reserved id (i.e. Haskell keyword
((and haskell-doc-show-reserved
is-reserved)
@@ -1322,7 +1344,7 @@
(setcdr haskell-doc-last-data type))
((and haskell-doc-show-user-defined
is-user-defined)
- ; (setq i-am-fct t)
+ ;; (setq i-am-fct t)
(setq type (cdr is-user-defined))
(setcdr haskell-doc-last-data type))
(t
@@ -1336,53 +1358,52 @@
(setcdr haskell-doc-last-data type)))) )
;; ToDo: encode i-am-fct info into alist of types
(and type
- printit
- ; drop `::' if it's not a fct
+ ;; drop `::' if it's not a fct
(let ( (str (cond ((and i-am-fct (not haskell-doc-chop-off-fctname))
(format "%s :: %s" sym type))
- (t
+ (t
(format "%s" type)))) )
(if i-am-prelude
- (add-text-properties 0 (1- (length str)) '(face bold) str))
- (haskell-doc-message "%s" str)))) )
+ (add-text-properties 0 (length str) '(face bold) str))
+ str))))
;; ToDo: define your own notion of `near' to find surrounding fct
-;(defun haskell-doc-fnsym-in-current-sexp ()
-; (let* ((p (point))
-; (sym (progn
-; (forward-word -1)
+;;(defun haskell-doc-fnsym-in-current-sexp ()
+;; (let* ((p (point))
+;; (sym (progn
+;; (forward-word -1)
;; (while (and (forward-word -1) ; (haskell-doc-forward-sexp-safe -1)
;; (> (point) (point-min))))
-; (cond ((or (= (point) (point-min))
-; (memq (or (char-after (point)) 0)
-; '(?\( ?\"))
-; ;; If we hit a quotation mark before a paren, we
-; ;; are inside a specific string, not a list of
-; ;; symbols.
-; (eq (or (char-after (1- (point))) 0) ?\"))
-; nil)
-; (t (condition-case nil
-; (read (current-buffer))
-; (error nil)))))))
-; (goto-char p)
-; (if sym
-; (format "%s" sym)
-; sym) ) )
+;; (cond ((or (= (point) (point-min))
+;; (memq (or (char-after (point)) 0)
+;; '(?\( ?\"))
+;; ;; If we hit a quotation mark before a paren, we
+;; ;; are inside a specific string, not a list of
+;; ;; symbols.
+;; (eq (or (char-after (1- (point))) 0) ?\"))
+;; nil)
+;; (t (condition-case nil
+;; (read (current-buffer))
+;; (error nil)))))))
+;; (goto-char p)
+;; (if sym
+;; (format "%s" sym)
+;; sym)))
;; (and (symbolp sym)
;; sym)))
-;@node Aux, Global fct type, Show type, Print fctsym
-;@subsection Aux
+;;@node Aux, Global fct type, Show type, Print fctsym
+;;@subsection Aux
;; ToDo: handle open brackets to decide if it's a wrapped type
-;@cindex haskell-doc-grab-line
+;;@cindex haskell-doc-grab-line
(defun haskell-doc-grab-line (fct-and-pos)
"Get the type of an \(FCT POSITION\) pair from the current buffer."
-; (if (null fct-and-pos)
-; "" ; fn is not a local fct
+ ;; (if (null fct-and-pos)
+ ;; "" ; fn is not a local fct
(let ( (str ""))
(goto-char (cdr fct-and-pos))
(beginning-of-line)
@@ -1396,28 +1417,28 @@
(skip-chars-forward " \t")
(setq str (concat str (haskell-doc-grab))))
(haskell-doc-string-nub-ws ; squeeze string
- (if haskell-doc-chop-off-context ; no context
+ (if haskell-doc-chop-off-context ; no context
(haskell-doc-chop-off-context str)
str)))))
- ; (concat (car fct-and-pos) "::" (haskell-doc-string-nub-ws str))))
+ ;; (concat (car fct-and-pos) "::" (haskell-doc-string-nub-ws str))))
-;@cindex haskell-doc-wrapped-type-p
+;;@cindex haskell-doc-wrapped-type-p
(defun haskell-doc-wrapped-type-p ()
"Check whether the type under the cursor is wrapped over several lines.
The cursor must be at the end of a line, which contains the type.
Currently, only the following is checked:
-If this line ends with a `->' or the next starts with an `->' it is a
+If this line ends with a `->' or the next starts with an `->' it is a
multi-line type \(same for `=>'\).
`--' comments are ignored.
ToDo: Check for matching parenthesis!. "
(save-excursion
(let ( (here (point))
(lim (progn (beginning-of-line) (point)))
- ; (foo "")
+ ;; (foo "")
(res nil)
)
(goto-char here)
- (search-backward "--" lim t) ; skip over `--' comment
+ (search-backward "--" lim t) ; skip over `--' comment
(skip-chars-backward " \t")
(if (bolp) ; skip empty lines
(progn
@@ -1425,15 +1446,13 @@
(end-of-line)
(setq res (haskell-doc-wrapped-type-p)))
(forward-char -1)
- ; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string
(following-char))))
+ ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string
(following-char))))
(if (or (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
(char-equal (following-char) ?>)) ; (or -!> =!>
(char-equal (following-char) ?,)) ; !,)
(setq res t)
(forward-line)
- (let ( (here (point))
- (lim (progn (end-of-line) (point)))
- )
+ (let ((here (point)))
(goto-char here)
(skip-chars-forward " \t")
(if (looking-at "--") ; it is a comment line
@@ -1442,14 +1461,14 @@
(end-of-line)
(setq res (haskell-doc-wrapped-type-p)))
(forward-char 1)
- ; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string
(following-char))))
- ; (message "|%s|" foo)
+ ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string
(following-char))))
+ ;; (message "|%s|" foo)
(if (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
(char-equal (following-char) ?>)) ; -!> or =!>
(setq res t))))))
res)))
-;@cindex haskell-doc-grab
+;;@cindex haskell-doc-grab
(defun haskell-doc-grab ()
"Return the text from point to the end of the line, chopping off comments.
Leaves point at end of line."
@@ -1459,7 +1478,7 @@
str
(substring str 0 i))))
-;@cindex haskell-doc-string-nub-ws
+;;@cindex haskell-doc-string-nub-ws
(defun haskell-doc-string-nub-ws (str)
"Replace all sequences of whitespaces in STR by just one whitespace.
ToDo: Also eliminate leading and trainling whitespace."
@@ -1467,66 +1486,65 @@
(let (
(res str)
(i 0)
- )
+ )
(setq i (string-match "\\(\\s-+\\)" res i))
(while (not (null i))
(setq res (replace-match " " t t res))
(setq i (string-match "\\(\\s-+\\)" res (1+ i))) )
res) )
-; ToDo: make this more efficient!!
-;(defun haskell-doc-string-nub-ws (str)
-; "Replace all sequences of whitespaces in STR by just one whitespace."
-; (let ( (res "")
-; (l (length str))
-; (i 0)
-; (j 0)
-; (in-ws nil))
-; (while (< i l)
-; (let* ( (c (string-to-char (substring str i (1+ i))))
-; (is-ws (eq (char-syntax c) ? )) )
-; (if (not (and in-ws is-ws))
-; (setq res (concat res (char-to-string c))))
-; (setq in-ws is-ws)
-; (setq i (1+ i))))
-; res))
+;; ToDo: make this more efficient!!
+;;(defun haskell-doc-string-nub-ws (str)
+;; "Replace all sequences of whitespaces in STR by just one whitespace."
+;; (let ( (res "")
+;; (l (length str))
+;; (i 0)
+;; (j 0)
+;; (in-ws nil))
+;; (while (< i l)
+;; (let* ( (c (string-to-char (substring str i (1+ i))))
+;; (is-ws (eq (char-syntax c) ? )) )
+;; (if (not (and in-ws is-ws))
+;; (setq res (concat res (char-to-string c))))
+;; (setq in-ws is-ws)
+;; (setq i (1+ i))))
+;; res))
-;@cindex haskell-doc-chop-off-context
+;;@cindex haskell-doc-chop-off-context
(defun haskell-doc-chop-off-context (str)
"Eliminate the contex in a type represented by the string STR."
- (let ((i (string-match "=>" str)) )
+ (let ((i (string-match "=>" str)) )
(if (null i)
str
(substring str (+ i 2)))))
-;@cindex haskell-doc-get-imenu-info
+;;@cindex haskell-doc-get-imenu-info
(defun haskell-doc-get-imenu-info (obj kind)
"Returns a string describing OBJ of KIND \(Variables, Types, Data\)."
(cond ((or (eq major-mode 'haskell-hugs-mode)
;; GEM: Haskell Mode does not work with Haskell Doc
;; under XEmacs 20.x
(and (eq major-mode 'haskell-mode)
- (not (and haskell-doc-xemacs-p
+ (not (and (featurep 'xemacs)
(string-match "^20" emacs-version)))))
- (let* ( (imenu-info-alist (cdr (assoc kind imenu--index-alist)))
- ; (names (mapcar (lambda (x) (car x)) imenu-info-alist))
- (x (assoc obj imenu-info-alist))
- )
+ (let* ((imenu-info-alist (cdr (assoc kind imenu--index-alist)))
+ ;; (names (mapcar 'car imenu-info-alist))
+ (x (assoc obj imenu-info-alist)))
(if x
(haskell-doc-grab-line x)
- nil)) )
+ nil)))
(t
- ; (error "Cannot get local functions in %s mode, sorry" major-mode))) )
+ ;; (error "Cannot get local functions in %s mode, sorry"
major-mode))) )
nil)))
-;@node Global fct type, Local fct type, Aux, Print fctsym
-;@subsection Global fct type
+;;@node Global fct type, Local fct type, Aux, Print fctsym
+;;@subsection Global fct type
;; ToDo:
;; - modular way of defining a mapping of module name to file
;; - use a path to search for file (not just current directory)
-;@cindex haskell-doc-imported-list
+;;@cindex haskell-doc-imported-list
(defun haskell-doc-imported-list (outer-file)
"Return a list of the imported modules in OUTER-FILE."
@@ -1552,12 +1570,12 @@
(cons file imported-file-list))))
)
(nreverse imported-file-list)
- ;(message imported-file-list)
-)))
+ ;;(message imported-file-list)
+ )))
;; ToDo: generalise this to "Types" etc (not just "Variables")
-;@cindex haskell-doc-rescan-files
+;;@cindex haskell-doc-rescan-files
(defun haskell-doc-rescan-files (filelist)
"Does an `imenu' rescan on every file in FILELIST and returns the fct-list.
@@ -1572,7 +1590,7 @@
fn-alist)) ) )
filelist ) )
-;@cindex haskell-doc-make-global-fct-index
+;;@cindex haskell-doc-make-global-fct-index
(defun haskell-doc-make-global-fct-index ()
"Scan imported files for types of global fcts and update
`haskell-doc-index'."
@@ -1586,17 +1604,17 @@
;; ToDo: use a separate munge-type function to format type concisely
-;@cindex haskell-doc-get-global-fct-type
+;;@cindex haskell-doc-get-global-fct-type
(defun haskell-doc-get-global-fct-type (&optional sym)
"Get type for function symbol SYM by examining `haskell-doc-index'."
(interactive) ; "fName of outer `include' file: \nsFct:")
(save-excursion
- ; (switch-to-buffer "*scratch*")
- ; (goto-char (point-max))
- ;; Produces a list of fct-type alists
-; (if (null sym)
-; (setq sym (progn (forward-word -1) (read (current-buffer)))))
+ ;; (switch-to-buffer "*scratch*")
+ ;; (goto-char (point-max))
+ ;; ;; Produces a list of fct-type alists
+ ;; (if (null sym)
+ ;; (setq sym (progn (forward-word -1) (read (current-buffer)))))
(or sym
(current-word))
(let* ( (fn sym) ; (format "%s" sym))
@@ -1616,10 +1634,10 @@
(setq fal (cdr fal))))
res))) ; (message res)) )
-;@node Local fct type, , Global fct type, Print fctsym
-;@subsection Local fct type
+;;@node Local fct type, , Global fct type, Print fctsym
+;;@subsection Local fct type
-;@cindex haskell-doc-get-and-format-fct-type
+;;@cindex haskell-doc-get-and-format-fct-type
(defun haskell-doc-get-and-format-fct-type (fn)
"Get the type and kind of FN by checking local and global functions."
@@ -1628,100 +1646,46 @@
(let ((docstring "")
(doc nil)
)
- ; is it a local function?
+ ;; is it a local function?
(setq docstring (haskell-doc-get-imenu-info fn "Variables"))
(if (not (null docstring))
- ; (string-match (format "^%s\\s-+::\\s-+\\(.*\\)$" fn) docstring))
+ ;; (string-match (format "^%s\\s-+::\\s-+\\(.*\\)$" fn) docstring))
(setq doc `(,docstring . "Variables"))) ; `(,(match-string 1 docstring) .
"Variables") ))
- ; is it a type declaration?
+ ;; is it a type declaration?
(setq docstring (haskell-doc-get-imenu-info fn "Types"))
(if (not (null docstring))
- ; (string-match (format "^\\s-*type\\s-+%s.*$" fn) docstring))
+ ;; (string-match (format "^\\s-*type\\s-+%s.*$" fn) docstring))
(setq doc `(,docstring . "Types"))) ; `(,(match-string 0 docstring) .
"Types")) )
(if (not (null docstring))
- ; (string-match (format "^\\s-*data.*%s.*$" fn) docstring))
+ ;; (string-match (format "^\\s-*data.*%s.*$" fn) docstring))
(setq doc `(,docstring . "Data"))) ; (setq doc `(,(match-string 0 docstring)
. "Data")) )
- ; return the result
+ ;; return the result
doc ))))
-;@node Movement, Bug Reports, Print fctsym, top
-;@section Movement
-; Functions for moving in text and extracting the current word under the cursor
-
-; prbly nukable
-
-;; forward-sexp calls scan-sexps, which returns an error if it hits the
-;; beginning or end of the sexp. This returns nil instead.
-(defun haskell-doc-forward-sexp-safe (&optional count)
- "Move forward across one balanced expression (sexp).
-With argument, do it that many times. Negative arg -COUNT means
-move backward across COUNT balanced expressions.
-Return distance in buffer moved, or nil."
- (or count (setq count 1))
- (condition-case err
- (- (- (point) (progn
- (let ((parse-sexp-ignore-comments t))
- (forward-sexp count))
- (point))))
- (error nil)))
-
-;; Do indirect function resolution if possible.
-;(defun haskell-doc-symbol-function (fsym)
-; (let ((defn (and (fboundp fsym)
-; (symbol-function fsym))))
-; (and (symbolp defn)
-; (condition-case err
-; (setq defn (indirect-function fsym))
-; (error (setq defn nil))))
-; defn))
-
-;; HWL: currently unused; this is taken from eldoc
-
-(defun haskell-doc-current-symbol ()
- (let ((c (char-after (point))))
- (and c
- (memq (char-syntax c) '(?w ?_))
- (current-word))))
+;;@node Movement, Bug Reports, Print fctsym, top
+;;@section Movement
+;; Functions for moving in text and extracting the current word under the cursor
;; HWL: my attempt at more efficient (current-word)
-;@cindex haskell-doc-is-id-char-at
-(defsubst haskell-doc-is-id-char-at (x)
- (let ( (c (char-syntax (char-after x))) )
- (or (eq c ?w) (eq c ?_))) )
-
;; NB: this function is called from within the hooked print function;
;; therefore this function must not fail, otherwise the function will
;; be de-installed;
;; if no word under the cursor return an empty string
-;@cindex haskell-doc-get-current-word
+;;@cindex haskell-doc-get-current-word
(defun haskell-doc-get-current-word ()
- "Return the word under the cursor, or empty string if no word found."
- ; (interactive)
- (if (bobp)
- ""
- (let ((x (1- (point)))
- (beg)
- (end)
- )
- ; go back to first non-word char
- (while (and (> x (point-min)) (haskell-doc-is-id-char-at x)) ; (not (bobp))
- (setq x (1- x)) )
- (if (= x (point-min))
- (setq beg x)
- (setq beg (1+ x)))
- (setq x (1+ x))
- (while (and (< x (point-max)) (haskell-doc-is-id-char-at x)) ; (not (eobp))
- (setq x (1+ x)) )
- (setq end x)
- (buffer-substring-no-properties beg end))))
+ "Return the word under the cursor, or empty string if no word found."
+ (save-excursion
+ (buffer-substring-no-properties
+ (progn (skip-syntax-backward "w_") (point))
+ (progn (skip-syntax-forward "w_") (point)))))
-;@node Bug Reports, Visit home site, Movement, top
-;@section Bug Reports
+;;@node Bug Reports, Visit home site, Movement, top
+;;@section Bug Reports
-;@cindex haskell-doc-submit-bug-report
-; send a bug report
+;;@cindex haskell-doc-submit-bug-report
+;; send a bug report
(defun haskell-doc-submit-bug-report ()
"Send email to the maintainer of `haskell-doc-mode'."
(interactive)
@@ -1741,63 +1705,60 @@
(beep)
(message "Sorry, reporter.el not found."))))
-;@node Visit home site, Index, Bug Reports, top
-;@section Visit home site
+;;@node Visit home site, Index, Bug Reports, top
+;;@section Visit home site
-;@cindex haskell-doc-visit-home
+;;@cindex haskell-doc-visit-home
(defun haskell-doc-visit-home ()
"Jump to the main FTP site for `haskell-doc-mode'."
(interactive)
- (if haskell-doc-xemacs-p
- (require 'efs)
- (require 'ange-ftp))
+ (if (featurep 'xemacs)
+ (require 'efs))
(require 'dired)
(dired-other-window haskell-doc-ftp-site))
-;@appendix
+;;@appendix
-;@node Index, Token, Visit home site, top
-;@section Index
+;;@node Index, Token, Visit home site, top
+;;@section Index
-;@index
-;* haskell-doc-ask-mouse-for-type::
-;* haskell-doc-check-active::
-;* haskell-doc-chop-off-context::
-;* haskell-doc-get-and-format-fct-type::
-;* haskell-doc-get-current-word::
-;* haskell-doc-get-global-fct-type::
-;* haskell-doc-get-imenu-info::
-;* haskell-doc-grab::
-;* haskell-doc-grab-line::
-;* haskell-doc-imported-list::
-;* haskell-doc-install-keymap::
-;* haskell-doc-is-id-char-at::
-;* haskell-doc-is-of::
-;* haskell-doc-make-global-fct-index::
-;* haskell-doc-message::
-;* haskell-doc-mode::
-;* haskell-doc-mode-print-current-symbol-info::
-;* haskell-doc-prelude-types::
-;* haskell-doc-rescan-files::
-;* haskell-doc-reserved-ids::
-;* haskell-doc-show-global-types::
-;* haskell-doc-show-prelude::
-;* haskell-doc-show-reserved::
-;* haskell-doc-show-strategy::
-;* haskell-doc-show-type::
-;* haskell-doc-show-user-defined::
-;* haskell-doc-strategy-ids::
-;* haskell-doc-string-nub-ws::
-;* haskell-doc-submit-bug-report::
-;* haskell-doc-visit-home::
-;* haskell-doc-wrapped-type-p::
-;* turn-off-haskell-doc-mode::
-;* turn-on-haskell-doc-mode::
-;@end index
+;;@index
+;;* haskell-doc-ask-mouse-for-type::
+;;* haskell-doc-check-active::
+;;* haskell-doc-chop-off-context::
+;;* haskell-doc-get-and-format-fct-type::
+;;* haskell-doc-get-current-word::
+;;* haskell-doc-get-global-fct-type::
+;;* haskell-doc-get-imenu-info::
+;;* haskell-doc-grab::
+;;* haskell-doc-grab-line::
+;;* haskell-doc-imported-list::
+;;* haskell-doc-install-keymap::
+;;* haskell-doc-is-of::
+;;* haskell-doc-make-global-fct-index::
+;;* haskell-doc-mode::
+;;* haskell-doc-mode-print-current-symbol-info::
+;;* haskell-doc-prelude-types::
+;;* haskell-doc-rescan-files::
+;;* haskell-doc-reserved-ids::
+;;* haskell-doc-show-global-types::
+;;* haskell-doc-show-prelude::
+;;* haskell-doc-show-reserved::
+;;* haskell-doc-show-strategy::
+;;* haskell-doc-show-type::
+;;* haskell-doc-show-user-defined::
+;;* haskell-doc-strategy-ids::
+;;* haskell-doc-string-nub-ws::
+;;* haskell-doc-submit-bug-report::
+;;* haskell-doc-visit-home::
+;;* haskell-doc-wrapped-type-p::
+;;* turn-off-haskell-doc-mode::
+;;* turn-on-haskell-doc-mode::
+;;@end index
-;@node Token, , Index, top
-;@section Token
+;;@node Token, , Index, top
+;;@section Token
(provide 'haskell-doc)
Index: xemacs-packages/haskell-mode/haskell-font-lock.el
===================================================================
RCS file:
/pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-font-lock.el,v
retrieving revision 1.3
diff -d -u -r1.3 haskell-font-lock.el
--- xemacs-packages/haskell-mode/haskell-font-lock.el 2004/06/16 15:16:49 1.3
+++ xemacs-packages/haskell-mode/haskell-font-lock.el 2006/03/15 04:57:24
@@ -1,15 +1,14 @@
;;; haskell-font-lock.el --- Font locking module for Haskell Mode
+;; Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
;; Copyright 1997-1998 Graeme E Moss, and Tommy Thorn
-;; Copyright 2003 Free Software Foundation, Inc.
;; Authors: 1997-1998 Graeme E Moss <gem(a)cs.york.ac.uk> and
;; Tommy Thorn <thorn(a)irisa.fr>
;; 2003 Dave Love <fx(a)gnu.org>
;; Keywords: faces files Haskell
-;; Version: 1.2
-;;; This file is not part of GNU Emacs.
+;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -55,7 +54,7 @@
;;
;; If you have any problems or suggestions, after consulting the list
;; below, email gem(a)cs.york.ac.uk and thorn(a)irisa.fr quoting the
-;; version of the mode you are using, the version of emacs you are
+;; version of the mode you are using, the version of Emacs you are
;; using, and a small example of the problem or suggestion. Note that
;; this module requires a reasonably recent version of Emacs. It
;; requires Emacs 21 to cope with Unicode characters and to do proper
@@ -95,198 +94,184 @@
;; . Support for GreenCard?
;;
-;;; All functions/variables start with
-;;; `(turn-(on/off)-)haskell-font-lock' or `haskell-fl-'.
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-font-lock' or `haskell-fl-'.
-(eval-when-compile (require 'haskell-mode))
+;;; Code:
+
+(eval-when-compile
+ (require 'haskell-mode)
+ (require 'cl))
(require 'font-lock)
;; Version.
-(defconst haskell-font-lock-version "1.3"
- "haskell-font-lock version number.")
+(defconst haskell-font-lock-version "1.17"
+ "Version number of haskell-font-lock.")
(defun haskell-font-lock-version ()
"Echo the current version of haskell-font-lock in the minibuffer."
(interactive)
(message "Using haskell-font-lock version %s" haskell-font-lock-version))
-
-(defvar haskell-font-lock-keywords ()
- "The default definitions used by font lock for fontification of
-non-literate Haskell scripts. This variable is set by
-`turn-on-haskell-font-lock' and then used by `font-lock-defaults'.")
-
-(defvar haskell-font-lock-keywords-1 ()
- "Medium level font lock definitions for non-literate Haskell.")
-
-(defvar haskell-font-lock-keywords-2 ()
- "High level font lock definitions for non-literate Haskell.")
-
-(defvar bird-literate-haskell-font-lock-keywords ()
- "The default definitions used by font lock for fontification of
-Bird-style literate Haskell scripts. This variable is set by
-`turn-on-haskell-font-lock' and then used by `font-lock-defaults'.")
-
-(defvar bird-literate-haskell-font-lock-keywords-1 ()
- "Medium level font lock definitions for Bird-style literate Haskell.")
-(defvar bird-literate-haskell-font-lock-keywords-2 ()
- "High level font lock definitions for Bird-style literate Haskell.")
-
-(defvar latex-literate-haskell-font-lock-keywords ()
- "The default definitions used by font lock for fontification of
-LaTeX-style literate Haskell scripts. This variable is set by
-`turn-on-haskell-font-lock' and then used by `font-lock-defaults'.")
+(defcustom haskell-font-lock-symbols nil
+ "Display \\ and -> and such using symbols in fonts.
+This may sound like a neat trick, but be extra careful: it changes the
+alignment and can thus lead to nasty surprises w.r.t layout.
+If t, try to use whichever font is available. Otherwise you can
+set it to a particular font of your preference among `japanese-jisx0208'
+and `unicode'."
+:group 'haskell
+:type '(choice (const nil)
+ (const t)
+ (const unicode)
+ (const japanese-jisx0208)))
-(defvar latex-literate-haskell-font-lock-keywords-1 ()
- "Medium level font lock definitions for LaTeX-style literate Haskell.")
+(defconst haskell-font-lock-symbols-alist
+ (append
+ ;; Prefer single-width Unicode font for lambda.
+ (and (fboundp 'decode-char)
+ (memq haskell-font-lock-symbols '(t unicode))
+ (list (cons "\\" (decode-char 'ucs 955))))
+ ;; The symbols can come from a JIS0208 font.
+ (and (fboundp 'make-char) (charsetp 'japanese-jisx0208)
+ (memq haskell-font-lock-symbols '(t japanese-jisx0208))
+ (list (cons "not" (make-char 'japanese-jisx0208 34 76))
+ (cons "\\" (make-char 'japanese-jisx0208 38 75))
+ (cons "->" (make-char 'japanese-jisx0208 34 42))
+ (cons "<-" (make-char 'japanese-jisx0208 34 43))
+ (cons "=>" (make-char 'japanese-jisx0208 34 77))))
+ ;; Or a unicode font.
+ (and (fboundp 'decode-char)
+ (memq haskell-font-lock-symbols '(t unicode))
+ (list (cons "not" (decode-char 'ucs 172))
+ (cons "->" (decode-char 'ucs 8594))
+ (cons "<-" (decode-char 'ucs 8592))
+ (cons "=>" (decode-char 'ucs 8658))
+ (cons "~>" (decode-char 'ucs 8669)) ;; Omega language
+ ;; (cons "~>" (decode-char 'ucs 8605)) ;; less desirable
+ (cons "-<" (decode-char 'ucs 8610)) ;; Paterson's
arrow syntax
+ ;; (cons "-<" (decode-char 'ucs 10521)) ;; nicer but
uncommon
+ (cons "::" (decode-char 'ucs 8759))
+ (cons "." (decode-char 'ucs 9675))))))
-(defvar latex-literate-haskell-font-lock-keywords-2 ()
- "High level font lock definitions for LaTeX-style literate Haskell.")
+;; Use new vars for the font-lock faces. The indirection allows people to
+;; use different faces than in other modes, as before.
+(defvar haskell-keyword-face 'font-lock-keyword-face)
+(defvar haskell-constructor-face 'font-lock-type-face)
+;; This used to be `font-lock-variable-name-face' but it doesn't result in
+;; a highlighting that's consistent with other modes (it's mostly used
+;; for function defintions).
+(defvar haskell-definition-face 'font-lock-function-name-face)
+;; This is probably just wrong, but it used to use
+;; `font-lock-function-name-face' with a result that was not consistent with
+;; other major modes, so I just exchanged with `haskell-definition-face'.
+(defvar haskell-operator-face 'font-lock-variable-name-face)
+(defvar haskell-default-face nil)
+(defvar haskell-literate-comment-face 'font-lock-doc-face
+ "Face with which to fontify literate comments.
+Set to `default' to avoid fontification of them.")
-(eval-and-compile
(defconst haskell-emacs21-features (string-match "[[:alpha:]]" "x")
"Non-nil if we have regexp char classes.
Assume this means we have other useful features from Emacs 21.")
-
- (if haskell-emacs21-features
-(defvar haskell-literate-comment-face 'haskell-comment-face
- "Face with which to fontify literate comments.
-Set to `default' to avoid fontification of them."))
-
-;; The font lock regular expressions.
- (if haskell-emacs21-features
-(defun haskell-font-lock-keywords-create (bird-literate latex-literate level)
- "Creates appropriate LEVEL (1 or 2) of fontification definitions
-for (BIRD-LITERATE or LATEX-LITERATE) Haskell scripts. Returns keywords
-suitable for `font-lock-keywords'."
- (let* (;; Bird-style literate scripts start a line of code with
- ;; "^>", otherwise a line of code starts with "^".
- (line-prefix (if bird-literate "^>" "^"))
-
- ;; Most names are borrowed from the lexical syntax of the Haskell
- ;; report.
-
- ;; We allow _ as the first char to fit GHC
- (id "\\b[[:alnum:]'_]+\\b")
- (varid "\\b[[:lower:]_][[:alnum:]'_]*\\b")
- (conid "\\b[[:upper:]][[:alnum:]'_]*\\b")
- (modid (concat "\\b" conid "\\(?:\\." conid "\\)*\\b"))
- (qconid (concat modid "\\." conid))
- (sym
- ;; Add backslash to the symbol-syntax chars. This seems to
- ;; be thrown for some reason by backslash's escape syntax.
- "\\(?:\\s_\\|\\\\\\)+")
- font-lock-keywords)
- (setq font-lock-keywords
- `(
-;;
-;; NOTICE the ordering below is significant
-;;
- ("^#.*$" 0 'font-lock-warning-face t)
- ,(eval-when-compile
- (regexp-opt
- ;; ?? `as' and `qualified' aren't in the Haskell98 list.
- ;; `_' can go in here since it has temporary word syntax.
- '("as" "case" "class" "data"
"default" "deriving" "do" "else"
- "hiding" "if" "import" "in" "infix"
"infixl" "infixr"
- "instance" "let" "module" "newtype"
"of" "qualified" "then"
- "type" "where" "_")
- 'words))
- (,(eval-when-compile
- ;; Would lose at bol.
- (concat "\\S_"
- (regexp-opt '(".." "::" "=" "\\"
"|" "<-" "->"
- "@" "~" "=>")
- t)
- "\\S_"))
- (1 'haskell-operator-face))
+(defun haskell-font-lock-compose-symbol (alist)
+ "Compose a sequence of ascii chars into a symbol.
+Regexp match data 0 points to the chars."
+ ;; Check that the chars should really be composed into a symbol.
+ (let* ((start (match-beginning 0))
+ (end (match-end 0))
+ (syntaxes (cond
+ ((eq (char-syntax (char-after start)) ?w) '(?w))
+ ;; Special case for the . used for qualified names.
+ ((and (eq (char-after start) ?\.) (= end (1+ start)))
+ '(?_ ?\\ ?w))
+ (t '(?_ ?\\)))))
+ (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
+ (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
+ (memq (get-text-property start 'face)
+ '(font-lock-doc-face font-lock-string-face
+ font-lock-comment-face)))
+ ;; No composition for you. Let's actually remove any composition
+ ;; we may have added earlier and which is now incorrect.
+ (remove-text-properties start end '(composition))
+ ;; That's a symbol alright, so add the composition.
+ (compose-region start end (cdr (assoc (match-string 0) alist)))))
+ ;; Return nil because we're not adding any face property.
+ nil)
- ;; These four are debatable...
- ("()" 0 'haskell-constructor-face)
- ("(,*)" 0 'haskell-constructor-face)
- ("\\[\\]" 0 'haskell-constructor-face)
- ("(->)" 0 'haskell-constructor-face)
- ,`(,qconid 0 'haskell-constructor-face)
- ,@(if (eq level 2)
- `(,`(,(concat "\`" varid "\`") 0 'haskell-operator-face)))
- ;; Expensive.
- ,`(,conid 0 'haskell-constructor-face)
- ,@(if (eq level 2)
- (list (list (concat "\\S_\\(:\\(?:" sym "\\)?\\)")
- '(1 'haskell-constructor-face))))
- ,@(if (eq level 2)
- (list (list sym '(0 'haskell-operator-face))))
+(defun haskell-font-lock-symbols-keywords ()
+ (when (fboundp 'compose-region)
+ (let ((alist nil))
+ (dolist (x haskell-font-lock-symbols-alist)
+ (when (and (if (fboundp 'char-displayable-p)
+ (char-displayable-p (cdr x))
+ t)
+ (not (assoc (car x) alist))) ;Not yet in alist.
+ (push x alist)))
+ (when alist
+ `((,(regexp-opt (mapcar 'car alist) t)
+ (0 (haskell-font-lock-compose-symbol ',alist))))))))
- ;; Declarations.
- (,(concat line-prefix "\\(" varid "\\)\\s-*\\(?:" varid
- "\\|::\\|=\\||\\)")
- (1 'haskell-definition-face))
- (,(concat line-prefix "\\(" varid "\\)\\s-*\\(" sym
"\\)")
- (1 'default)
- (2 'haskell-definition-face))
- (,(concat line-prefix "\\(" varid "\\)\\s-*\\s(")
- (1 'haskell-definition-face))
- (,(concat line-prefix "(\\(" sym "\\))")
- (1 'haskell-definition-face))))
- (if bird-literate
- ;; Don't colour the Bird tracks.
- (setq font-lock-keywords
- (append font-lock-keywords '(("^>" 0 'default t)))))
- font-lock-keywords))
-(defun haskell-font-lock-keywords-create (bird-literate latex-literate level)
- "Creates appropriate LEVEL (1 or 2) of fontification definitions
-for (BIRD-LITERATE or LATEX-LITERATE) Haskell scripts. Returns keywords
-suitable for `font-lock-keywords'."
+;; The font lock regular expressions.
+(defun haskell-font-lock-keywords-create (literate)
+ "Create fontification definitions for Haskell scripts.
+Returns keywords suitable for `font-lock-keywords'."
(let* (;; Bird-style literate scripts start a line of code with
;; "^>", otherwise a line of code starts with "^".
- (line-prefix (if bird-literate "^>" "^"))
+ (line-prefix (if (eq literate 'bird) "^> ?" "^"))
;; Most names are borrowed from the lexical syntax of the Haskell
;; report.
;; Some of these definitions have been superseded by using the
;; syntax table instead.
- (ASCsymbol "-!#$%&*+./<=>?@\\\\^|~")
+ ;; (ASCsymbol "-!#$%&*+./<=>?@\\\\^|~")
;; Put the minus first to make it work in ranges.
- (ISOsymbol "\241-\277\327\367")
+ ;; (ISOsymbol "\241-\277\327\367")
(ISOlarge "\300-\326\330-\337")
(ISOsmall "\340-\366\370-\377")
(small
- (concat "a-z" ISOsmall))
+ (if haskell-emacs21-features "[:lower:]" (concat "a-z"
ISOsmall)))
(large
- (concat "A-Z" ISOlarge))
- (symbol
- (concat ASCsymbol ISOsymbol))
+ (if haskell-emacs21-features "[:upper:]" (concat "A-Z"
ISOlarge)))
+ (alnum
+ (if haskell-emacs21-features "[:alnum:]" (concat small large
"0-9")))
+ ;; (symbol
+ ;; (concat ASCsymbol ISOsymbol))
;; We allow _ as the first char to fit GHC
- (id
- (concat "\\b\\([" small large "0-9'_]+\\)\\b"))
- (varid
- (concat "\\b\\([" small "_][" small large
"0-9'_]*\\)\\b"))
- (conid
- (concat "\\b\\([" large "][" small large
"0-9'_]*\\)\\b"))
- (modid
- (concat "\\b" conid "\\(\\." conid "\\)*\\b"))
- (qvarid
- (concat modid "\\." varid))
- (qconid
- (concat modid "\\." conid))
+ (varid (concat "\\b[" small "_][" alnum
"'_]*\\b"))
+ (conid (concat "\\b[" large "][" alnum
"'_]*\\b"))
+ (modid (concat "\\b" conid "\\(\\." conid "\\)*\\b"))
+ (qvarid (concat modid "\\." varid))
+ (qconid (concat modid "\\." conid))
(sym
- (concat "[" symbol ":]+"))
+ ;; We used to use the below for non-Emacs21, but I think the
+ ;; regexp based on syntax works for other emacsen as well. -- Stef
+ ;; (concat "[" symbol ":]+")
+ ;; Add backslash to the symbol-syntax chars. This seems to
+ ;; be thrown for some reason by backslash's escape syntax.
+ "\\(\\s_\\|\\\\\\)+")
;; Reserved operations
(reservedsym
- '(".." "::" "=" "\\" "|"
"<-" "->" "@" "~" "=>"))
+ (concat "\\S_"
+ ;; (regexp-opt '(".." "::" "=" "\\"
"|" "<-" "->"
+ ;; "@" "~" "=>") t)
+ "\\(->\\|\\.\\.\\|::\\|<-\\|=>\\|[=@\\|~]\\)"
+ "\\S_"))
;; Reserved identifiers
- ;(reservedid
- ; '("as" "case" "class" "data"
"default" "deriving" "do" "else"
- ; "hiding" "if" "import" "in"
"infix" "infixl" "infixr"
- ; "instance" "let" "module" "newtype"
"of" "qualified" "then"
- ; "type" "where"))
- ;; make-regexp applied to reservedid creates the following
- ;; regexp
(reservedid
-
"\\b\\(c\\(ase\\|lass\\)\\|d\\(ata\\|e\\(fault\\|riving\\)\\|o\\)\\|else\\|hiding\\|i\\([fn]\\|mport\\|n\\(fix\\(\\|[lr]\\)\\|stance\\)\\)\\|let\\|module\\|newtype\\|of\\|qualified\\|t\\(hen\\|ype\\)\\|where\\)\\b")
+ (concat "\\b"
+ ;; ?? `as' and `qualified' aren't in the Haskell98 list.
+ ;; `_' can go in here since it has temporary word syntax.
+ ;; (regexp-opt
+ ;; '("as" "case" "class" "data"
"default" "deriving" "do"
+ ;; "else" "hiding" "if" "import"
"in" "infix" "infixl"
+ ;; "infixr" "instance" "let" "module"
"newtype" "of"
+ ;; "qualified" "then" "type" "where"
"_") t)
+
"\\(_\\|as\\|c\\(ase\\|lass\\)\\|d\\(ata\\|e\\(fault\\|riving\\)\\|o\\)\\|else\\|hiding\\|i\\(mport\\|n\\(fix[lr]?\\|stance\\)\\|[fn]\\)\\|let\\|module\\|newtype\\|of\\|qualified\\|t\\(hen\\|ype\\)\\|where\\)"
+ "\\b"))
;; This unreadable regexp matches strings and character
;; constants. We need to do this with one regexp to handle
@@ -298,62 +283,68 @@
(concat "\\(\\(\"\\|" line-prefix "[
\t]*\\\\\\)\\([^\"\\\\\n]\\|\\\\.\\)*\\(\"\\|\\\\[
\t]*$\\)\\|'\\([^'\\\\\n]\\|\\\\.[^'\n]*\\)'\\)"))
;; Top-level declarations
- ;; These are not included as they don't work well (yet).
-; (topdecl1
-; (concat line-prefix "\\(" varid "\\)\\(\\s-\\|::\\|=\\||\\)"))
-; (topdecl2
-; (concat line-prefix varid "\\s-*\\(" sym "\\)"))
-; (topdecl3
-; (concat line-prefix "(\\(" sym "\\))"))
+ (topdecl-var
+ (concat line-prefix "\\(" varid "\\)\\s-*\\("
+ varid "\\|" conid "\\|::\\|=\\||\\|\\s(\\)"))
+ (topdecl-var2
+ (concat line-prefix "\\(" varid "\\|" conid
"\\)\\s-*`\\(" varid "\\)`"))
+ (topdecl-sym
+ (concat line-prefix "\\(" varid "\\|" conid
"\\)\\s-*\\(" sym "\\)"))
+ (topdecl-sym2 (concat line-prefix "(\\(" sym "\\))"))
- font-lock-keywords)
+ keywords)
- (setq font-lock-keywords
- `(
-;;
-;; NOTICE the ordering below is significant
-;;
- ("--.*$" 0 'haskell-comment-face t)
+ (setq keywords
+ `(;; NOTICE the ordering below is significant
+ ;;
("^#.*$" 0 'font-lock-warning-face t)
- ;; Expensive.
- ,`(,string-and-char 1 'haskell-string-char-face)
+ ,@(unless haskell-emacs21-features
+ ;; Expensive.
+ `((,string-and-char 1 font-lock-string-face)))
+
+ ;; This was originally at the very end (and needs to be after
+ ;; all the comment/string/doc highlighting) but it seemed to
+ ;; trigger a bug in Emacs-21.3 which caused the compositions to
+ ;; be "randomly" dropped. Moving it earlier seemed to reduce
+ ;; the occurrence of the bug.
+ ,@(haskell-font-lock-symbols-keywords)
+
+ (,reservedid 1 (symbol-value 'haskell-keyword-face))
+ (,reservedsym 1 (symbol-value 'haskell-operator-face))
+
+ ;; Toplevel Declarations.
+ ;; Place them *before* generic id-and-op highlighting.
+ (,topdecl-var (1 (symbol-value 'haskell-definition-face)))
+ (,topdecl-var2 (2 (symbol-value 'haskell-definition-face)))
+ (,topdecl-sym (2 (symbol-value 'haskell-definition-face)))
+ (,topdecl-sym2 (1 (symbol-value 'haskell-definition-face)))
+
;; These four are debatable...
- ("()" 0 'haskell-constructor-face)
- ("(,*)" 0 'haskell-constructor-face)
- ("\\[\\]" 0 'haskell-constructor-face)
- ("(->)" 0 'haskell-constructor-face)
+ ("(\\(,*\\|->\\))" 0 (symbol-value 'haskell-constructor-face))
+ ("\\[\\]" 0 (symbol-value 'haskell-constructor-face))
;; Expensive.
- ,`(,reservedid 1 'haskell-keyword-face)
- ,`(,qvarid 0 'haskell-default-face)
- ,`(,qconid 0 'haskell-constructor-face)
- ,@(if (eq level 2)
- `(,`(,(concat "\`" varid "\`") 0 'haskell-operator-face))
- '())
+ (,qvarid 0 haskell-default-face)
+ (,qconid 0 (symbol-value 'haskell-constructor-face))
+ (,(concat "\`" varid "\`") 0 (symbol-value
'haskell-operator-face))
;; Expensive.
- ,`(,conid 1 'haskell-constructor-face)
+ (,conid 0 (symbol-value 'haskell-constructor-face))
+
;; Very expensive.
- ,`(,sym 0 ,`(let ((match (match-string 0)))
- ,`(cond
- ,`(,`(member match ',reservedsym)
- 'haskell-operator-face)
- ((eq (aref match 0) ?:) 'haskell-constructor-face)
- ,@(if (eq level 2)
- '((t 'haskell-operator-face))
- '()))))
- ;; (list topdecl1 1 ''haskell-definition-face t)
- ;; (list topdecl2 1 ''haskell-definition-face t)
- ;; (list topdecl3 1 ''haskell-definition-face t)
- ))
- (if bird-literate
- (setq font-lock-keywords
- `(("^[^>\n].*$" 0 'haskell-comment-face t)
- ,@font-lock-keywords
- ("^>" 0 'haskell-default-face t)))
- (if latex-literate
- (setq font-lock-keywords
- `((haskell-fl-latex-comments 0 'font-lock-comment-face t)
- ,@font-lock-keywords))))
- font-lock-keywords))))
+ (,sym 0 (if (eq (char-after (match-beginning 0)) ?:)
+ haskell-constructor-face
+ haskell-operator-face))))
+ (unless haskell-emacs21-features
+ (case literate
+ (bird
+ (setq keywords
+ `(("^[^>\n].*$" 0 haskell-comment-face t)
+ ,@keywords
+ ("^>" 0 haskell-default-face t))))
+ (latex
+ (setq keywords
+ `((haskell-fl-latex-comments 0 'font-lock-comment-face t)
+ ,@keywords)))))
+ keywords))
;; The next three aren't used in Emacs 21.
@@ -404,200 +395,103 @@
;; If one found, mark it as a comment, otherwise finish.
(point))))))
-(eval-and-compile
- (if haskell-emacs21-features
-(defvar haskell-fl-syntax
- ;; The mode syntax table will basically DTRT. However, it's
- ;; convenient to treat the non-ASCII punctuation characters as
- ;; symbol. (We probably have to keep `,' and `;' as
- ;; punctuation, so we can't just consider sequences of
- ;; punctuation and symbol syntax. We could also use
- ;; categories.)
- `((?_ . "w") ; in case _ has normal syntax
- (?' . "w")
- ,@(let (cs i lim)
- (let ((table (make-syntax-table)))
- (map-char-table
- (lambda (k v)
- ;; The current Emacs 22 codebase can pass either a char
- ;; or a char range.
- (if (consp k)
- (setq i (car k)
- lim (cdr k))
- (setq i k
- lim k))
- (if (<= i lim)
- (when (and (> i 127)
- (equal v '(1)))
- (push (cons i "-") cs))
- (setq i (1+ i))))
- (standard-syntax-table)))
- cs))
- "Syntax required for font locking.
-Given as a list of pairs for use in `font-lock-defaults'.")
-(defvar haskell-fl-syntax
- ;; It's easier for us to manually set the ISO Latin1 syntax as I'm
- ;; not sure what libraries are available and how they differ from
- ;; Haskell, eg. the iso-syntax library of Emacs 19.34 defines \241
- ;; as punctuation for good reasons but this conflicts with Haskell
- ;; so we would have to redefine it. It's simpler for us to set the
- ;; syntax table according to the Haskell report for all of the 8-bit
- ;; characters.
- `((?\ . " ")
- (?\t . " ")
- (?\" . " ")
- (?\' . "w")
- (?_ . "w")
- (?\( . "()")
- (?\) . ")(")
- (?[ . "(]")
- (?] . ")[")
- (?{ . "(}1")
- (?} . "){4")
- (?- . "_ 23")
- (?\` . "$`")
- ,@(mapcar (lambda (x) (cons x "_"))
- (concat "!#$%&*+./:<=>?@\\^|~" (haskell-enum-from-to ?\241
?\277)
- "\327\367"))
- ,@(mapcar (lambda (x) (cons x "w"))
- (concat (haskell-enum-from-to ?\300 ?\326) (haskell-enum-from-to ?\330 ?\337)
- (haskell-enum-from-to ?\340 ?\366) (haskell-enum-from-to ?\370 ?\377))))
- "Syntax required for font locking. Given as a list of pairs for use
-in `font-lock-defaults'.")))
-
(defconst haskell-basic-syntactic-keywords
- '(
- ;; Character constants (since apostrophe can't have string syntax)
- ("\\Sw\\('\\)\\([^\\']\\|\\\\[^']+\\|\\\\'\\)\\('\\)"
(1 "|") (3 "|"))
+ '(;; Character constants (since apostrophe can't have string syntax).
+ ;; Beware: do not match something like 's-}' or '\n"+' since the
first '
+ ;; might be inside a comment or a string.
+ ;; This still gets fooled with
"'"'"'"'"'"', but ... oh well.
+ ("\\Sw\\('\\)\\([^\\'\n]\\|\\\\.[^\\'\n
\"}]*\\)\\('\\)" (1 "|") (3 "|"))
+ ;; The \ is not escaping in \(x,y) -> x + y.
+ ("\\(\\\\\\)(" (1 "."))
+ ;; The second \ in a gap does not quote the subsequent char.
+ ;; It's probably not worth the trouble, tho.
+ ;; ("^[ \t]*\\(\\\\\\)" (1 "."))
;; Deal with instances of `--' which don't form a comment.
("\\s_\\{3,\\}" (0 (if (string-match "\\`-*\\'" (match-string
0))
- nil ; Sequence of hyphens. Do nothing in
- ; case of things like `{---'.
+ ;; Sequence of hyphens. Do nothing in
+ ;; case of things like `{---'.
+ nil
"_"))))) ; other symbol sequence
(defconst haskell-bird-syntactic-keywords
- (cons '("^\\([^\n>]\\)[^\n]*\\(\n\\)" (1 "!") (2
"!"))
+ (cons '("^[^\n>]" (0 "<"))
haskell-basic-syntactic-keywords))
-(defun haskell-fl-bobp (end)
- "Find first non-newline character at beginning of buffer."
- (if (= (point) 1) ; not bobp in case of narrowing
- (re-search-forward "[^\n]" nil t)))
-
(defconst haskell-latex-syntactic-keywords
(append
'(("^\\\\begin{code}\\(\n\\)" 1 "!")
- (haskell-fl-bobp (0 "!")) ; start comment at buffer start
+ ;; Note: buffer is widened during font-locking.
+ ("\\`\\(.\\|\n\\)" (1 "!")) ; start comment at buffer
start
("^\\(\\\\\\)end{code}$" 1 "!"))
haskell-basic-syntactic-keywords))
(defun haskell-syntactic-face-function (state)
"`font-lock-syntactic-face-function' for Haskell."
- (if (nth 3 state)
- 'font-lock-string-face ; as normal
+ (cond
+ ((nth 3 state) font-lock-string-face) ; as normal
;; Else comment. If it's from syntax table, use default face.
- (if (eq 'syntax-table (nth 7 state))
- haskell-literate-comment-face
- 'haskell-comment-face)))
+ ((or (eq 'syntax-table (nth 7 state))
+ (and (eq haskell-literate 'bird)
+ (memq (char-before (nth 8 state)) '(nil ?\n))))
+ haskell-literate-comment-face)
+ (t font-lock-comment-face)))
-(defun haskell-font-lock-defaults-create (bird-literate latex-literate)
- "Locally set `font-lock-defaults' for Haskell.
-If BIRD-LITERATE is non-nil then the font locking is made
-suitable for Bird-style literate Haskell scripts, and similarly for
-LATEX-LITERATE and LaTeX-style literate Haskell scripts."
- (setq haskell-font-lock-keywords-1
- (haskell-font-lock-keywords-create nil nil 1))
- (setq haskell-font-lock-keywords-2
- (haskell-font-lock-keywords-create nil nil 2))
- (setq haskell-font-lock-keywords
- haskell-font-lock-keywords-1)
- (setq bird-literate-haskell-font-lock-keywords-1
- (haskell-font-lock-keywords-create t nil 1))
- (setq bird-literate-haskell-font-lock-keywords-2
- (haskell-font-lock-keywords-create t nil 2))
- (setq bird-literate-haskell-font-lock-keywords
- bird-literate-haskell-font-lock-keywords-1)
- (setq latex-literate-haskell-font-lock-keywords-1
- (haskell-font-lock-keywords-create nil t 1))
- (setq latex-literate-haskell-font-lock-keywords-2
- (haskell-font-lock-keywords-create nil t 2))
- (setq latex-literate-haskell-font-lock-keywords
- latex-literate-haskell-font-lock-keywords-1)
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults
- (if bird-literate
- (append (list '(bird-literate-haskell-font-lock-keywords
- bird-literate-haskell-font-lock-keywords-1
- bird-literate-haskell-font-lock-keywords-2)
- nil nil haskell-fl-syntax)
- (if haskell-emacs21-features
- (list nil
- (cons 'font-lock-syntactic-keywords
- haskell-bird-syntactic-keywords)
- '(font-lock-syntactic-face-function
- . haskell-syntactic-face-function))))
- (if latex-literate
- (append
- (list '(latex-literate-haskell-font-lock-keywords
- latex-literate-haskell-font-lock-keywords-1
- latex-literate-haskell-font-lock-keywords-2)
- nil nil haskell-fl-syntax)
- (if haskell-emacs21-features
- (list nil
- (cons 'font-lock-syntactic-keywords
- haskell-latex-syntactic-keywords)
- '(font-lock-syntactic-face-function
- . haskell-syntactic-face-function))))
- (append
- (list '(haskell-font-lock-keywords
- haskell-font-lock-keywords-1
- haskell-font-lock-keywords-2)
- nil nil haskell-fl-syntax)
- (if haskell-emacs21-features
- (list nil
- (cons 'font-lock-syntactic-keywords
- haskell-basic-syntactic-keywords))))))))
+(defconst haskell-font-lock-keywords
+ (haskell-font-lock-keywords-create nil)
+ "Font lock definitions for non-literate Haskell.")
-;; Faces required for font locking.
-(defun haskell-fl-faces ()
- "Defines faces required for Haskell font locking."
- ;; XEmacs does not have a simple function for making the faces but
- ;; makes them when `require'd which was done by
- ;; turn-on-haskell-font-lock, so we don't need to explicitly make
- ;; them for XEmacs, and in fact we shouldn't as an error will be
- ;; produced.
- (if (fboundp 'font-lock-make-faces) (font-lock-make-faces))
- (copy-face 'font-lock-keyword-face 'haskell-keyword-face)
- (copy-face 'font-lock-type-face 'haskell-constructor-face)
- (copy-face 'font-lock-string-face 'haskell-string-char-face)
- (copy-face 'font-lock-function-name-face 'haskell-operator-face)
- (copy-face 'font-lock-comment-face 'haskell-comment-face)
- (copy-face 'default 'haskell-default-face)
- (copy-face 'font-lock-variable-name-face 'haskell-definition-face)
- )
+(defconst haskell-font-lock-bird-literate-keywords
+ (haskell-font-lock-keywords-create 'bird)
+ "Font lock definitions for Bird-style literate Haskell.")
+
+(defconst haskell-font-lock-latex-literate-keywords
+ (haskell-font-lock-keywords-create 'latex)
+ "Font lock definitions for LaTeX-style literate Haskell.")
+(defun haskell-font-lock-choose-keywords ()
+ (let ((literate (if (boundp 'haskell-literate) haskell-literate)))
+ (case literate
+ (bird haskell-font-lock-bird-literate-keywords)
+ (latex haskell-font-lock-latex-literate-keywords)
+ (t haskell-font-lock-keywords))))
+
+(defun haskell-font-lock-choose-syntactic-keywords ()
+ (let ((literate (if (boundp 'haskell-literate) haskell-literate)))
+ (case literate
+ (bird haskell-bird-syntactic-keywords)
+ (latex haskell-latex-syntactic-keywords)
+ (t haskell-basic-syntactic-keywords))))
+
+(defun haskell-font-lock-defaults-create ()
+ "Locally set `font-lock-defaults' for Haskell."
+ (set (make-local-variable 'font-lock-defaults)
+ '(haskell-font-lock-choose-keywords
+ nil nil ((?\' . "w") (?_ . "w")) nil
+ (font-lock-syntactic-keywords
+ . haskell-font-lock-choose-syntactic-keywords)
+ (font-lock-syntactic-face-function
+ . haskell-syntactic-face-function)
+ ;; Get help from font-lock-syntactic-keywords.
+ (parse-sexp-lookup-properties . t))))
+
;; The main functions.
(defun turn-on-haskell-font-lock ()
"Turns on font locking in current buffer for Haskell 1.4 scripts.
Changes the current buffer's `font-lock-defaults', and adds the
-following faces:
+following variables:
`haskell-keyword-face' for reserved keywords and syntax,
`haskell-constructor-face' for data- and type-constructors, class names,
and module names,
- `haskell-string-char-face' for strings and characters,
`haskell-operator-face' for symbolic and alphanumeric operators,
- `haskell-comment-face' for comments, and
`haskell-default-face' for ordinary code.
-The faces are initialised to the following font lock defaults:
+The variables are initialised to the following font lock default faces:
`haskell-keyword-face' `font-lock-keyword-face'
`haskell-constructor-face' `font-lock-type-face'
- `haskell-string-char-face' `font-lock-string-face'
`haskell-operator-face' `font-lock-function-name-face'
- `haskell-comment-face' `font-lock-comment-face'
`haskell-default-face' <default face>
Two levels of fontification are defined: level one (the default)
@@ -641,24 +535,17 @@
Use `haskell-font-lock-version' to find out what version this is."
(interactive)
- (require 'font-lock)
- (haskell-fl-faces)
- (let ((literate (if (boundp 'haskell-literate) haskell-literate)))
- (haskell-font-lock-defaults-create (eq literate 'bird)
- (eq literate 'latex)))
- ;; Get help from font-lock-syntactic-keywords.
- (set (make-local-variable 'parse-sexp-lookup-properties) t)
+ (haskell-font-lock-defaults-create)
(run-hooks 'haskell-font-lock-hook)
(turn-on-font-lock))
(defun turn-off-haskell-font-lock ()
"Turns off font locking in current buffer."
(interactive)
- (if (and (boundp 'font-lock-mode) font-lock-mode)
- (font-lock-mode -1)))
+ (font-lock-mode -1))
-;;; Provide ourselves:
+;; Provide ourselves:
(provide 'haskell-font-lock)
-;;; haskell-font-lock ends here.
+;;; haskell-font-lock.el ends here
Index: xemacs-packages/haskell-mode/haskell-ghci.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-ghci.el,v
retrieving revision 1.3
diff -d -u -r1.3 haskell-ghci.el
--- xemacs-packages/haskell-mode/haskell-ghci.el 2004/06/16 15:16:49 1.3
+++ xemacs-packages/haskell-mode/haskell-ghci.el 2006/03/15 04:57:24
@@ -1,11 +1,10 @@
-;; haskell-ghci.el --- A GHCi interaction mode
+;;; haskell-ghci.el --- A GHCi interaction mode
-;; Copyright (C) 1999 Guy Lapalme, 2001 Chris Webb.
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+;; Copyright (C) 2001 Chris Webb
+;; Copyright (C) 1998, 1999 Guy Lapalme
-;; Authors: 1998-1999 Guy Lapalme <lapalme(a)iro.umontreal.ca>
-;; 2001 Chris Webb <chris(a)arachsys.com>
;; Keywords: inferior mode, GHCi interaction mode, Haskell
-;; Version: 1.2
;;; This file is not part of GNU Emacs.
@@ -60,14 +59,16 @@
;;
;; Arguments can be sent to the GHCi interpreter when it is started by
;; setting haskell-ghci-program-args (empty by default) to a list of
-;; string args to pass it. This value can be set interactively by
+;; string args to pass it. This value can be set interactively by
;; calling C-c C-s with an argument (i.e. C-u C-c C-s).
;;
;; `haskell-ghci-hook' is invoked in the *ghci* buffer once GHCi is
;; started.
;;
-;;; All functions/variables start with `turn-{on,off}-haskell-ghci' or
-;;; `haskell-ghci-'.
+;; All functions/variables start with `turn-{on,off}-haskell-ghci' or
+;; `haskell-ghci-'.
+
+;;; Code:
(defgroup haskell-ghci nil
"Major mode for interacting with an inferior GHCi session."
@@ -86,6 +87,7 @@
(local-set-key "\C-c\C-s" 'haskell-ghci-start-process)
(local-set-key "\C-c\C-l" 'haskell-ghci-load-file)
(local-set-key "\C-c\C-r" 'haskell-ghci-reload-file)
+ (local-set-key "\C-c\C-n" 'haskell-ghci-locate-next-error)
(local-set-key "\C-c\C-b" 'haskell-ghci-show-ghci-buffer))
(defun turn-off-haskell-ghci ()
@@ -96,8 +98,6 @@
(local-unset-key "\C-c\C-r")
(local-unset-key "\C-c\C-b"))
-(defvar haskell-ghci-mode-map nil)
-
(defun haskell-ghci-mode ()
"Major mode for interacting with an inferior GHCi session.
@@ -134,9 +134,6 @@
(defvar haskell-ghci-process-buffer nil
"*Buffer used for communication with GHCi subprocess for current buffer.")
-(defvar haskell-ghci-last-loaded-file nil
- "The last file loaded into the GHCi process.")
-
(defcustom haskell-ghci-program-name "ghci"
"*The name of the GHCi interpreter program."
:type 'string
@@ -150,6 +147,9 @@
(defvar haskell-ghci-load-end nil
"Position of the end of the last load command.")
+(defvar haskell-ghci-error-pos nil
+ "Position of the end of the last load command.")
+
(defvar haskell-ghci-send-end nil
"Position of the end of the last send command.")
@@ -177,7 +177,7 @@
;; Select GHCi buffer temporarily.
(set-buffer haskell-ghci-process-buffer)
(haskell-ghci-mode)
- (make-variable-buffer-local 'shell-cd-regexp)
+ (make-local-variable 'shell-cd-regexp)
(make-local-variable 'shell-dirtrackp)
;; Track directory changes using the `:cd' command.
@@ -221,39 +221,37 @@
If the second argument CD is non-nil, change directory in the GHCi
process to the current buffer's directory before loading the file.
-If the variable \"haskell-ghci-command\" is set then its value will be
+If the variable `haskell-ghci-command' is set then its value will be
sent to the GHCi process after the load command. This can be used for a
top-level expression to evaluate."
- (let (file)
- (hack-local-variables) ; in case they've changed
- (save-buffer)
- (if (string-equal load-command ":load ")
- (progn
- (setq file (buffer-file-name))
- (setq haskell-ghci-last-loaded-file file))
- (setq file ""))
- (let ((dir (expand-file-name default-directory))
- (cmd (and (boundp 'haskell-ghci-command)
- haskell-ghci-command
- (if (stringp haskell-ghci-command)
- haskell-ghci-command
- (symbol-name haskell-ghci-command)))))
- (if (and haskell-ghci-process-buffer
- (eq (process-status haskell-ghci-process) 'run))
- ;; Ensure the GHCi buffer is selected.
- (set-buffer haskell-ghci-process-buffer)
- ;; Start Haskell-GHCi process.
- (haskell-ghci-start-process nil))
+ (hack-local-variables) ; in case they've changed
+ (save-buffer)
+ (let ((file (if (string-equal load-command ":load ")
+ (concat "\"" buffer-file-name "\"")
+ ""))
+ (dir (expand-file-name default-directory))
+ (cmd (and (boundp 'haskell-ghci-command)
+ haskell-ghci-command
+ (if (stringp haskell-ghci-command)
+ haskell-ghci-command
+ (symbol-name haskell-ghci-command)))))
+ (if (and haskell-ghci-process-buffer
+ (eq (process-status haskell-ghci-process) 'run))
+ ;; Ensure the GHCi buffer is selected.
+ (set-buffer haskell-ghci-process-buffer)
+ ;; Start Haskell-GHCi process.
+ (haskell-ghci-start-process nil))
- (if cd (haskell-ghci-send (concat ":cd " dir)))
- ;; Wait until output arrives and go to the last input.
- (haskell-ghci-wait-for-output)
- (haskell-ghci-send load-command file)
- ;; Error message search starts from last load command.
- (setq haskell-ghci-load-end (marker-position comint-last-input-end))
- (if cmd (haskell-ghci-send cmd))
- ;; Wait until output arrives and go to the last input.
- (haskell-ghci-wait-for-output))))
+ (if cd (haskell-ghci-send (concat ":cd " dir)))
+ ;; Wait until output arrives and go to the last input.
+ (haskell-ghci-wait-for-output)
+ (haskell-ghci-send load-command file)
+ ;; Error message search starts from last load command.
+ (setq haskell-ghci-load-end (marker-position comint-last-input-end))
+ (setq haskell-ghci-error-pos haskell-ghci-load-end)
+ (if cmd (haskell-ghci-send cmd))
+ ;; Wait until output arrives and go to the last input.
+ (haskell-ghci-wait-for-output)))
(defun haskell-ghci-load-file (cd)
"Save a ghci buffer file and load its file.
@@ -297,27 +295,38 @@
;; first error in the file whilst leaving the error visible in the
;; *ghci* buffer.
(goto-char haskell-ghci-load-end)
- (if (re-search-forward
- "^\\([^:\n]+\\):\\([0-9]+\\):" nil t)
- (let ((efile (buffer-substring (match-beginning 1)
- (match-end 1)))
- (eline (string-to-int (buffer-substring (match-beginning 2)
- (match-end 2)))))
+ (haskell-ghci-locate-next-error)))
- (recenter 2)
- (message "GHCi error on line %d of %s."
+
+(defun haskell-ghci-locate-next-error ()
+ "Go to the next error shown in the *ghci* buffer."
+ (interactive)
+ (if (buffer-live-p haskell-ghci-process-buffer)
+ (progn (pop-to-buffer haskell-ghci-process-buffer)
+ (goto-char haskell-ghci-error-pos)
+ (if (re-search-forward
+ "^[^\/]*\\([^:\n]+\\):\\([0-9]+\\)" nil t)
+ (let ((efile (buffer-substring (match-beginning 1)
+ (match-end 1)))
+ (eline (string-to-int
+ (buffer-substring (match-beginning 2)
+ (match-end 2)))))
+
+ (recenter 2)
+ (setq haskell-ghci-error-pos (point))
+ (message "GHCi error on line %d of %s."
eline (file-name-nondirectory efile))
- (if (file-exists-p efile)
- (progn (find-file-other-window efile)
- (goto-line eline)
- (recenter))))
+ (if (file-exists-p efile)
+ (progn (find-file-other-window efile)
+ (goto-line eline)
+ (recenter))))
;; We got an error without a file and line number, so put the
;; point at end of the *ghci* buffer ready to deal with it.
- (pop-to-buffer haskell-ghci-process-buffer)
- (goto-char (point-max))
- (recenter -2)
- (message "GHCi error while loading."))))
+ (goto-char (point-max))
+ (recenter -2)
+ (message "No more errors found.")))
+ (message "No *ghci* buffer found.")))
(defun haskell-ghci-show-ghci-buffer ()
"Go to the *ghci* buffer."
@@ -327,5 +336,6 @@
(haskell-ghci-start-process nil))
(pop-to-buffer haskell-ghci-process-buffer))
+(provide 'haskell-ghci)
;;; haskell-ghci.el ends here
Index: xemacs-packages/haskell-mode/haskell-hugs.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-hugs.el,v
retrieving revision 1.2
diff -d -u -r1.2 haskell-hugs.el
--- xemacs-packages/haskell-mode/haskell-hugs.el 2004/06/16 15:16:49 1.2
+++ xemacs-packages/haskell-mode/haskell-hugs.el 2006/03/15 04:57:24
@@ -1,19 +1,18 @@
-;; haskell-hugs.el --- simplistic interaction mode with a
+;;; haskell-hugs.el --- simplistic interaction mode with a
+
+;; Copyright 2004, 2005 Free Software Foundation, Inc.
+;; Copyright 1998, 1999 Guy Lapalme
+
;; Hugs interpreter for Haskell developped by
;; The University of Nottingham and Yale University, 1994-1997.
;; Web:
http://www.haskell.org/hugs.
;; In standard Emacs terminology, this would be called
;; inferior-hugs-mode
-;;
-;; Copyright 1999 Guy Lapalme
-
-;; Author:1998, 1999 Guy Lapalme <lapalme(a)iro.umontreal.ca>
;; Keywords: Hugs inferior mode, Hugs interaction mode
-;; Version: 1.1
-;; URL:
http://www.iro.umontreal.ca/~lapalme/Hugs-interaction.html
+;; URL:
http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/e...
-;;; This file is not part of GNU Emacs.
+;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -103,10 +102,8 @@
(local-unset-key "\C-c\C-r")
(local-unset-key "\C-c\C-b")
)
-
-(defvar haskell-hugs-mode-map nil)
-(defun haskell-hugs-mode ()
+(define-derived-mode haskell-hugs-mode comint-mode "Haskell Hugs"
;; called by haskell-hugs-start-process,
;; itself called by haskell-hugs-load-file
;; only when the file is loaded the first time
@@ -131,15 +128,6 @@
subjob if any.
\\[comint-stop-subjob] stops, likewise.
\\[comint-quit-subjob] sends quit signal."
- (interactive)
- (comint-mode)
- (setq major-mode 'haskell-hugs-mode)
- (setq mode-name "Haskell Hugs")
- (if haskell-hugs-mode-map
- nil
- (setq haskell-hugs-mode-map (copy-keymap comint-mode-map))
- )
- (use-local-map haskell-hugs-mode-map)
)
;; Hugs-interface
@@ -153,9 +141,6 @@
(defvar haskell-hugs-process-buffer nil
"*Buffer used for communication with Hugs subprocess for current buffer.")
-(defvar haskell-hugs-last-loaded-file nil
- "The last file loaded into the Hugs process.")
-
(defcustom haskell-hugs-program-name "hugs"
"*The name of the command to start the Hugs interpreter."
:type 'string
@@ -172,6 +157,8 @@
(defvar haskell-hugs-send-end nil
"Position of the end of the last send command.")
+(defalias 'run-hugs 'haskell-hugs-start-process)
+
(defun haskell-hugs-start-process (arg)
"Start a Hugs process and invokes `haskell-hugs-hook' if not nil.
Prompts for a list of args if called with an argument."
@@ -190,7 +177,7 @@
;; Select Hugs buffer temporarily
(set-buffer haskell-hugs-process-buffer)
(haskell-hugs-mode)
- (make-variable-buffer-local 'shell-cd-regexp)
+ (make-local-variable 'shell-cd-regexp)
(make-local-variable 'shell-dirtrackp)
(setq shell-cd-regexp ":cd")
(setq shell-dirtrackp t)
@@ -205,10 +192,11 @@
(defun haskell-hugs-wait-for-output ()
"Wait until output arrives and go to the last input."
- (while (progn
+ (while (progn
(goto-char comint-last-input-end)
- (not (re-search-forward comint-prompt-regexp nil t)))
- (accept-process-output haskell-hugs-process)))
+ (and
+ (not (re-search-forward comint-prompt-regexp nil t))
+ (accept-process-output haskell-hugs-process)))))
(defun haskell-hugs-send (&rest string)
"Send `haskell-hugs-process' the arguments (one or more strings).
@@ -230,40 +218,36 @@
If the second argument CD is non-nil, change the Haskell-Hugs process to the
current buffer's directory before loading the file.
-If the variable \"haskell-hugs-command\" is set then its value will be sent to
+If the variable `haskell-hugs-command' is set then its value will be sent to
the Hugs process after the load command. This can be used for a
top-level expression to evaluate."
- (let (file)
- (hack-local-variables);; In case they've changed
- (save-buffer)
- (if (string-equal load-command ":load ")
- (progn
- (setq file (buffer-file-name))
- (setq haskell-hugs-last-loaded-file file))
- (setq file ""))
- (let ((dir (expand-file-name default-directory))
- (cmd (and (boundp 'haskell-hugs-command)
- haskell-hugs-command
- (if (stringp haskell-hugs-command)
- haskell-hugs-command
- (symbol-name haskell-hugs-command)))))
- (if (and haskell-hugs-process-buffer
- (eq (process-status haskell-hugs-process) 'run))
- ;; Ensure the Hugs buffer is selected.
- (set-buffer haskell-hugs-process-buffer)
- ;; Start Haskell-Hugs process.
- (haskell-hugs-start-process nil))
+ (hack-local-variables) ;; In case they've changed
+ (save-buffer)
+ (let ((file (if (string-equal load-command ":load ")
+ (concat "\"" buffer-file-name "\"")
+ ""))
+ (dir (expand-file-name default-directory))
+ (cmd (and (boundp 'haskell-hugs-command)
+ haskell-hugs-command
+ (if (stringp haskell-hugs-command)
+ haskell-hugs-command
+ (symbol-name haskell-hugs-command)))))
+ (if (and haskell-hugs-process-buffer
+ (eq (process-status haskell-hugs-process) 'run))
+ ;; Ensure the Hugs buffer is selected.
+ (set-buffer haskell-hugs-process-buffer)
+ ;; Start Haskell-Hugs process.
+ (haskell-hugs-start-process nil))
- (if cd (haskell-hugs-send (concat ":cd " dir)))
- ;; Wait until output arrives and go to the last input.
- (haskell-hugs-wait-for-output)
- (haskell-hugs-send load-command file)
- ;; Error message search starts from last load command.
- (setq haskell-hugs-load-end (marker-position comint-last-input-end))
- (if cmd (haskell-hugs-send cmd))
- ;; Wait until output arrives and go to the last input.
- (haskell-hugs-wait-for-output)))
- )
+ (if cd (haskell-hugs-send (concat ":cd " dir)))
+ ;; Wait until output arrives and go to the last input.
+ (haskell-hugs-wait-for-output)
+ (haskell-hugs-send load-command file)
+ ;; Error message search starts from last load command.
+ (setq haskell-hugs-load-end (marker-position comint-last-input-end))
+ (if cmd (haskell-hugs-send cmd))
+ ;; Wait until output arrives and go to the last input.
+ (haskell-hugs-wait-for-output)))
(defun haskell-hugs-load-file (cd)
"Save a hugs buffer file and load its file.
@@ -329,3 +313,7 @@
(haskell-hugs-start-process nil))
(pop-to-buffer haskell-hugs-process-buffer)
)
+
+(provide 'haskell-hugs)
+
+;;; haskell-hugs.el ends here
Index: xemacs-packages/haskell-mode/haskell-indent.el
===================================================================
RCS file:
/pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-indent.el,v
retrieving revision 1.3
diff -d -u -r1.3 haskell-indent.el
--- xemacs-packages/haskell-mode/haskell-indent.el 2004/06/16 15:16:49 1.3
+++ xemacs-packages/haskell-mode/haskell-indent.el 2006/03/15 04:57:25
@@ -1,6 +1,7 @@
-;; haskell-indent.el --- "semi-intelligent" indentation module for Haskell
Mode
+;;; haskell-indent.el --- "semi-intelligent" indentation module for Haskell
Mode
-;; Copyright 1997-1998 Guy Lapalme
+;; Copyright 2004, 2005 Free Software Foundation, Inc.
+;; Copyright 1997-1998 Guy Lapalme
;; Author: 1997-1998 Guy Lapalme <lapalme(a)iro.umontreal.ca>
@@ -35,7 +36,7 @@
;; the Haskell report. The rationale and the implementation principles
;; are described in an article to appear in Journal of Functional Programming.
;; "Dynamic tabbing for automatic indentation with the layout rule"
-;;
+;;
;; It supports literate scripts.
;; Haskell indentation is performed
;; within \begin{code}...\end{code} sections of a literate script
@@ -43,7 +44,7 @@
;; TAB aligns to the left column outside of these sections.
;;
;; Installation:
-;;
+;;
;; To turn indentation on for all Haskell buffers under the Haskell
;; mode of Moss&Thorn <
http://www.haskell.org/haskell-mode/>
;; add this to .emacs:
@@ -64,40 +65,34 @@
;;
;; `haskell-indent-hook' is invoked if not nil.
;;
-;;; All functions/variables start with
-;;; `(turn-(on/off)-)haskell-indent' or `haskell-indent-'.
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-indent' or `haskell-indent-'.
;; This file can also be used as a hook for the Hugs Mode developed by
;; Chris Van Humbeeck <chris.vanhumbeeck(a)cs.kuleuven.ac.be>
;; It can be obtained at:
;;
http://www-i2.informatik.rwth-aachen.de/Forschung/FP/Haskell/hugs-mode.el
;;
-;; For the Hugs mode put the following in your .emacs
-;;
-;;(setq auto-mode-alist (append auto-mode-alist '(("\\.hs$" .
hugs-mode))))
+;; For the Hugs mode put the following in your .emacs
+;;
+;;(setq auto-mode-alist (append auto-mode-alist '(("\\.hs\\'" .
hugs-mode))))
;;(autoload 'hugs-mode "hugs-mode" "Go into hugs mode" t)
;;
;; If only the indentation mode is used then replace the two
;; preceding lines with
;;(setq auto-mode-alist (append auto-mode-alist
-;; '(("\\.hs$" . turn-on-haskell-indent))))
+;; '(("\\.hs\\'" .
turn-on-haskell-indent))))
;;(autoload 'turn-on-haskell-indent "hindent" "Indentation mode for
Haskell" t)
;;
;; For indentation in both cases then add the following to your .emacs
-;;(setq hugs-mode-hook
-;; '(lambda ()
-;; (setq indent-line-function 'haskell-indent-cycle)
-;; (define-key hugs-mode-map "\r" 'newline)
-;; (define-key hugs-mode-map "\t" 'haskell-indent-cycle)
-;; (define-key hugs-mode-map "\C-c=" 'haskell-indent-insert-equal)
-;; (define-key hugs-mode-map "\C-c|" 'haskell-indent-insert-guard)
-;; (define-key hugs-mode-map "\C-co"
'haskell-indent-insert-otherwise)
-;; (define-key hugs-mode-map "\C-cw" 'haskell-indent-insert-where)
-;; (define-key hugs-mode-map "\C-c."
'haskell-indent-align-guards-and-rhs)))
+;;(add-hook 'hugs-mode-hook 'turn-on-haskell-indent)
;;(autoload 'haskell-indent-cycle "hindent" "Indentation cycle for
Haskell" t)
;;
-(require 'cl) ;need defs of push and pop
+;;; Code:
+
+(eval-when-compile (require 'cl)) ;need defs of push and pop
+(defvar haskell-literate)
(defgroup haskell-indent nil
"Haskell indentation."
@@ -105,77 +100,61 @@
:prefix "haskell-indent-")
(defcustom haskell-indent-offset 4
- "*Indentation of Haskell statements with respect to containing block."
+ "Indentation of Haskell statements with respect to containing block."
:type 'integer
:group 'haskell-indent)
(defcustom haskell-indent-literate-Bird-default-offset 1
- "*Default number of blanks after > in a Bird style literate script."
+ "Default number of blanks after > in a Bird style literate script."
:type 'integer
:group 'haskell-indent)
-(defcustom haskell-indent-rhs-align-column 0
- "*Column on which to align right-hand sides (use 0 for ad-hoc alignment)."
-:type 'integer
-:group 'haskell-indent)
-
-(defsubst haskell-indent-get-beg-of-line (&optional arg)
- (save-excursion
- (beginning-of-line arg)
- (point)))
-
-(defsubst haskell-indent-get-end-of-line (&optional arg)
- (save-excursion
- (end-of-line arg)
- (point)))
+(defcustom haskell-indent-rhs-align-column 0
+ "Column on which to align right-hand sides (use 0 for ad-hoc alignment)."
+:type 'integer
+:group 'haskell-indent)
(defun haskell-indent-point-to-col (apoint)
- "Returns the column number of APOINT."
+ "Return the column number of APOINT."
(save-excursion
(goto-char apoint)
(current-column)))
-(defconst haskell-indent-start-keywords-re
- (concat "\\<\\("
- "class\\|data\\|i\\(mport\\|n\\(fix\\(\\|[lr]\\)\\|stance\\)\\)\\|"
- "module\\|newtype\\|primitive\\|type"
- "\\)\\>")
+(defconst haskell-indent-start-keywords-re
+ (concat "\\<"
+ (regexp-opt '("class" "data" "import"
"infix" "infixl" "infixr"
+ "instance" "module" "newtype"
"primitive" "type") t)
+ "\\>")
"Regexp describing keywords to complete when standing at the first word
of a line.")
-(defconst haskell-running-xemacs
- (string-match "Lucid\\|XEmacs" emacs-version)
- "t when using XEmacs or Lucid.")
-;;; customizations for different kinds of environments
-;;; in which dealing with low-level events are different
-(if haskell-running-xemacs
- (progn ;;; for XEmacs
- (fset 'event-basic-type 'event-key)
- (fset 'read-event 'next-command-event)
- (defun haskell-indent-mark-active ()
- (if zmacs-regions
- zmacs-region-active-p
- t)))
- ;; in Gnu Emacs
- (defun haskell-indent-mark-active ()
- mark-active)
- )
+;; Customizations for different kinds of environments
+;; in which dealing with low-level events are different.
+(defun haskell-indent-mark-active ()
+ (if (featurep 'xemacs)
+ (if zmacs-regions
+ zmacs-region-active-p
+ t)
+ mark-active))
;; for pushing indentation information
+(defvar haskell-indent-info) ;Used with dynamic scoping.
+
(defun haskell-indent-push-col (col &optional name)
- "Pushes indentation information for the column COL
-followed by NAME (if present). Makes sure that the same indentation info
-is not pushed twice in a row. Uses free var `indent-info'."
+ "Push indentation information for the column COL.
+The info is followed by NAME (if present).
+Makes sure that the same indentation info is not pushed twice.
+Uses free var `haskell-indent-info'."
(let ((tmp (cons col name)))
- (if (and indent-info (equal tmp (car indent-info)))
- indent-info
- (push tmp indent-info))))
+ (if (member tmp haskell-indent-info)
+ haskell-indent-info
+ (push tmp haskell-indent-info))))
(defun haskell-indent-push-pos (pos &optional name)
"Pushes indentation information for the column corresponding to POS
-followed by NAME (if present). "
+followed by NAME (if present)."
(haskell-indent-push-col (haskell-indent-point-to-col pos) name))
(defun haskell-indent-push-pos-offset (pos &optional offset)
@@ -185,17 +164,15 @@
(haskell-indent-push-col (+ (haskell-indent-point-to-col pos)
(or offset haskell-indent-offset))))
-;;; redefinition of some Emacs function for dealing with
-;;; Bird Style literate scripts
+;; redefinition of some Emacs function for dealing with
+;; Bird Style literate scripts
(defun haskell-indent-bolp ()
"`bolp' but dealing with Bird-style literate scripts."
(or (bolp)
(and (eq haskell-literate 'bird)
(<= (current-column) (1+ haskell-indent-literate-Bird-default-offset))
- (eq (save-excursion (beginning-of-line) (following-char)) ?\>))
- )
- )
+ (eq (char-after (line-beginning-position)) ?\>))))
(defun haskell-indent-empty-line-p ()
"Checks if the current line is empty; deals with Bird style scripts."
@@ -204,12 +181,10 @@
(if (and (eq haskell-literate 'bird)
(eq (following-char) ?\>))
(forward-char 1))
- (looking-at "[ \t]*$"))
- )
+ (looking-at "[ \t]*$")))
(defun haskell-indent-back-to-indentation ()
- "`back-to-indentation' function but dealing with Bird-style literate
-scripts."
+ "`back-to-indentation' function but dealing with Bird-style literate
scripts."
(if (eq haskell-literate 'bird)
(progn
(beginning-of-line)
@@ -217,10 +192,9 @@
(progn
(forward-char 1)
(if (not (eolp))
- (skip-chars-forward " \t" (haskell-indent-get-end-of-line))))
+ (skip-chars-forward " \t" (line-end-position))))
(back-to-indentation)))
- (back-to-indentation))
- )
+ (back-to-indentation)))
(defun haskell-indent-current-indentation ()
"`current-indentation' function but dealing with Bird-style literate
@@ -229,18 +203,16 @@
(save-excursion
(haskell-indent-back-to-indentation)
(current-column))
- (current-indentation))
- )
+ (current-indentation)))
(defun haskell-indent-backward-to-indentation (n)
"`backward-to-indentation' function but dealing with Bird-style literate
scripts."
(if (eq haskell-literate 'bird)
(progn
- (forward-line (- n))
+ (forward-line (- n))
(haskell-indent-back-to-indentation))
- (backward-to-indentation n))
- )
+ (backward-to-indentation n)))
(defun haskell-indent-forward-line (&optional n)
"`forward-line' function but dealing with Bird-style literate scripts."
@@ -248,8 +220,7 @@
(forward-line n)
(if (and (eq haskell-literate 'bird) (eq (following-char) ?\>))
(progn (forward-char 1) ; skip > and initial blanks...
- (skip-chars-forward " \t"))))
- )
+ (skip-chars-forward " \t")))))
(defun haskell-indent-line-to (n)
"`indent-line-to' function but dealing with Bird-style literate
scripts."
@@ -262,10 +233,9 @@
(indent-line-to n) ; that indent-line only adds spaces
(save-excursion
(beginning-of-line)
- (if (> n 0) (delete-char 1)) ; delete the first space begore
+ (if (> n 0) (delete-char 1)) ; delete the first space before
(insert ?\>))) ; inserting a >
- (indent-line-to n))
- )
+ (indent-line-to n)))
(defun haskell-indent-skip-blanks-and-newlines-forward (end)
"Skips forward blanks, tabs and newlines until END taking
@@ -274,8 +244,7 @@
(if (eq haskell-literate 'bird)
(while (and (bolp) (eq (following-char) ?\>))
(forward-char 1) ; skip >
- (skip-chars-forward " \t\n" end)))
-)
+ (skip-chars-forward " \t\n" end))))
(defun haskell-indent-skip-blanks-and-newlines-backward (start)
"Skips backward blanks, tabs and newlines upto START
@@ -285,8 +254,7 @@
(while (and (eq (current-column) 1)
(eq (preceding-char) ?\>))
(forward-char -1) ; skip back >
- (skip-chars-backward " \t\n" start)))
-)
+ (skip-chars-backward " \t\n" start))))
;; specific functions for literate code
@@ -296,66 +264,62 @@
If it is Bird Style, then returns the position of the >
otherwise returns the ending position \\begin{code}."
(save-excursion
- (if (eq haskell-literate 'bird)
- (progn
- (beginning-of-line)
- (if (or (eq (following-char) ?\>)
- (and (bolp) (forward-line -1) (eq (following-char) ?\>)))
- (progn
- (while (and (zerop (forward-line -1))
- (eq (following-char) ?\>)))
- (if (not (eq (following-char) ?\>))
- (forward-line))
- (point))))
- ;; Look for a \begin{code} or \end{code} line.
- (if (eq haskell-literate 'latex)
- (if (re-search-backward
- "^\\(\\\\begin{code}$\\)\\|\\(\\\\end{code}$\\)" nil t)
- ;; within a literate code part if it was a \\begin{code}.
- (match-end 1))
- (error "haskell-indent-within-literate-code: should not happen!")
- )))
- )
+ (case haskell-literate
+ (bird
+ (beginning-of-line)
+ (if (or (eq (following-char) ?\>)
+ (and (bolp) (forward-line -1) (eq (following-char) ?\>)))
+ (progn
+ (while (and (zerop (forward-line -1))
+ (eq (following-char) ?\>)))
+ (if (not (eq (following-char) ?\>))
+ (forward-line))
+ (point))))
+ ;; Look for a \begin{code} or \end{code} line.
+ (latex
+ (if (re-search-backward
+ "^\\(\\\\begin{code}$\\)\\|\\(\\\\end{code}$\\)" nil t)
+ ;; within a literate code part if it was a \\begin{code}.
+ (match-end 1)))
+ (t (error "haskell-indent-within-literate-code: should not happen!")))))
(defun haskell-indent-put-region-in-literate (beg end &optional arg)
"Put lines of the region as a piece of literate code.
With C-u prefix arg, remove indication that the region is literate code.
It deals with both Bird style and non Bird-style scripts."
(interactive "r\nP")
- (if haskell-literate
- (if (eq haskell-literate 'bird)
- (let ((comment-start "> "); change dynamic bindings for
- (comment-end "")) ; comment-region
- (comment-region beg end arg))
- ;; not Bird style
- (if (consp arg) ; remove the literate indication
- (save-excursion
- (goto-char end) ; remove end
- (beginning-of-line)
- (if (looking-at "\\\\end{code}")
- (kill-line 1)
- (forward-line -1) ; perhaps the end is at the start of
- (if (looking-at "\\\\end{code}") ; of the previous line
- (kill-line 1))
- )
- (goto-char beg) ; remove end
- (beginning-of-line)
- (if (looking-at "\\\\begin{code}")
- (kill-line 1))
- )
- (save-excursion ; add the literate indication
- (goto-char end)
- (insert "\\end{code}\n")
- (goto-char beg)
- (insert "\\begin{code}\n")))
- )
- (error "Cannot put a region in literate in a non literate script"))
- )
+ (unless haskell-literate
+ (error "Cannot put a region in literate in a non literate script"))
+ (if (eq haskell-literate 'bird)
+ (let ((comment-start "> ") ; Change dynamic bindings for
+ (comment-start-skip "^> ?") ; comment-region.
+ (comment-end "")
+ (comment-end-skip "\n")
+ (comment-style 'plain))
+ (comment-region beg end arg))
+ ;; Not Bird style.
+ (if arg ; Remove the literate indication.
+ (save-excursion
+ (goto-char end) ; Remove end.
+ (if (re-search-backward "^\\\\end{code}[ \t\n]*\\="
+ (line-beginning-position -2) t)
+ (delete-region (point) (line-beginning-position 2)))
+ (goto-char beg) ; Remove end.
+ (beginning-of-line)
+ (if (looking-at "\\\\begin{code}")
+ (kill-line 1)))
+ (save-excursion ; Add the literate indication.
+ (goto-char end)
+ (unless (bolp) (newline))
+ (insert "\\end{code}\n")
+ (goto-char beg)
+ (unless (bolp) (newline))
+ (insert "\\begin{code}\n")))))
;;; Start of indentation code
(defun haskell-indent-start-of-def ()
- "Returns the position of the start of a definition.
+ "Return the position of the start of a definition.
It is at the first character which is not in a comment after nearest
preceding non-empty line."
(save-excursion
@@ -365,7 +329,7 @@
(if (setq start-code (and haskell-literate
(haskell-indent-within-literate-code)))
(setq start-code (1+ start-code))
- (setq start-code 1))
+ (setq start-code (point-min)))
;; go backward until the first preceding empty line
(haskell-indent-forward-line -1)
(while (and (not (haskell-indent-empty-line-p))
@@ -374,92 +338,76 @@
;; go forward after the empty line
(if (haskell-indent-empty-line-p)
(haskell-indent-forward-line 1))
+ (setq start-code (point))
;; find the first line of code which is not a comment
- (while (and (haskell-indent-in-comment start-code (point))
- (= 0 (haskell-indent-forward-line 1))))
- (haskell-indent-skip-blanks-and-newlines-forward save-point)
- (point)))
- )
+ (forward-comment (point-max))
+ (if (> (point) save-point)
+ start-code
+ (point)))))
+
(defun haskell-indent-open-structure (start end)
"If any structure (list or tuple) is not closed, between START and END,
returns the location of the opening symbol, nil otherwise."
(save-excursion
- (let ((pps (parse-partial-sexp start end)))
- (if (> (nth 0 pps) 0)
- (nth 1 pps))
- )))
+ (nth 1 (parse-partial-sexp start end))))
(defun haskell-indent-in-string (start end)
"If a string is not closed , between START and END, returns the
location of the opening symbol, nil otherwise."
(save-excursion
(let ((pps (parse-partial-sexp start end)))
- (if (nth 3 pps) ; we are within an open string
- (progn ; go back to the previous
- (goto-char (or (nth 1 pps); open parenthesis
- (nth 2 pps); complete sexp
- start)) ; otherwise to the start
- (skip-chars-forward "^\""); skip upto the start of the
string
- (point)))
- )))
+ (if (nth 3 pps) (nth 8 pps)))))
(defun haskell-indent-in-comment (start end)
- "Checks, starting from START, if END is within a comment, returns
-the location of the start of the comment, nil otherwise."
- (cond ((> start end) end)
- ((= start end) nil)
- ( t
- (save-excursion
- (cond
- ((looking-at "{-\\|--") ; on the first char of a comment ?
- (point))
- ((and (= (following-char) ?\-) ; on the second char ?
- (or (= (preceding-char) ?\-)
- (= (preceding-char) ?\{)))
- (1- (point)))
- (t (let ((pps (parse-partial-sexp start end)))
- (if (nth 4 pps)
- (re-search-backward "{-" (nth 2 pps) t)
- (re-search-backward "--"
- (haskell-indent-get-beg-of-line) t))))
- ))))
- )
+ "Check, starting from START, if END is at or within a comment.
+Returns the location of the start of the comment, nil otherwise."
+ (let (pps)
+ (assert (<= start end))
+ (cond ((= start end) nil)
+ ((nth 4 (save-excursion (setq pps (parse-partial-sexp start end))))
+ (nth 8 pps))
+ ;; We also want to say that we are *at* the beginning of a comment.
+ ((and (not (nth 8 pps))
+ (>= (point-max) (+ end 2))
+ (nth 4 (save-excursion
+ (setq pps (parse-partial-sexp end (+ end 2))))))
+ (nth 8 pps)))))
(defvar haskell-indent-off-side-keywords-re
"\\<\\(do\\|let\\|of\\|where\\)\\>[ \t]*")
(defun haskell-indent-type-at-point ()
- "Returns the type of the line (also puts information in `match-data')."
+ "Return the type of the line (also puts information in `match-data')."
(cond
((haskell-indent-empty-line-p) 'empty)
- ((haskell-indent-in-comment 1 (point)) 'comment)
- ((looking-at "\\(\\([a-zA-Z]\\sw*\\)\\|_\\)[ \t\n]*") 'ident)
+ ((haskell-indent-in-comment (point-min) (point)) 'comment)
+ ((looking-at "\\(\\([a-zA-Z]\\(\\sw\\|'\\)*\\)\\|_\\)[ \t\n]*")
'ident)
((looking-at "\\(|[^|]\\)[ \t\n]*") 'guard)
((looking-at "\\(=[^>=]\\|::\\|->\\|<-\\)[ \t\n]*") 'rhs)
- ( t 'other)))
+ (t 'other)))
(defvar haskell-indent-current-line-first-ident ""
"Global variable that keeps track of the first ident of the line to
indent.")
(defun haskell-indent-contour-line (start end)
- "Generates contour information between START and END points."
+ "Generate contour information between START and END points."
(if (< start end)
(save-excursion
- (let ((cur-col 1024) ; maximum column number
+ (goto-char end)
+ (haskell-indent-skip-blanks-and-newlines-backward start)
+ (let ((cur-col (current-column)) ; maximum column number
(fl 0) ; number of lines that forward-line could not advance
contour)
- (goto-char end)
- (haskell-indent-skip-blanks-and-newlines-backward start)
(while (and (> cur-col 0) (= fl 0) (>= (point) start))
(haskell-indent-back-to-indentation)
+ (if (< (point) start) (goto-char start))
(and (not (member (haskell-indent-type-at-point)
'(empty comment))) ; skip empty and comment lines
(< (current-column) cur-col) ; less indented column found
(push (point) contour) ; new contour point found
(setq cur-col (current-column)))
- (setq fl (haskell-indent-forward-line -1))
- )
+ (setq fl (haskell-indent-forward-line -1)))
contour))))
(defun haskell-indent-next-symbol (end)
@@ -470,8 +418,7 @@
(if (< (point) end)
(progn
(forward-sexp 1) ; this skips also {- comments !!!
- (haskell-indent-skip-blanks-and-newlines-forward end))
- ))
+ (haskell-indent-skip-blanks-and-newlines-forward end))))
(defun haskell-indent-separate-valdef (start end)
"Returns a list of positions for important parts of a valdef."
@@ -483,20 +430,19 @@
;; "parse" a valdef separating important parts
(goto-char start)
(setq type (haskell-indent-type-at-point))
- (if (or (eq type 'ident) (eq type 'other)) ; possible start of a value def
+ (if (or (memq type '(ident other))) ; possible start of a value def
(progn
(if (eq type 'ident)
(progn
(setq valname (match-beginning 0))
- (setq valname-string (buffer-substring (match-beginning 0)
- (match-end 0)))
+ (setq valname-string (match-string 0))
(goto-char (match-end 0)))
(skip-chars-forward " \t" end)
(setq valname (point)) ; type = other
(haskell-indent-next-symbol end))
(while (and (< (point) end)
(setq type (haskell-indent-type-at-point))
- (or (eq type 'ident) (eq type 'other)))
+ (or (memq type '(ident other))))
(if (null aft-valname)
(setq aft-valname (point)))
(haskell-indent-next-symbol end))))
@@ -517,7 +463,7 @@
(if (< (point) end)
(setq aft-rhs-sign (point)))))
(list valname valname-string aft-valname
- guard aft-guard rhs-sign aft-rhs-sign))))
+ guard aft-guard rhs-sign aft-rhs-sign))))
(defsubst haskell-indent-no-otherwise (guard)
"Check if there is no otherwise at GUARD."
@@ -529,7 +475,8 @@
(defun haskell-indent-guard (start end end-visible indent-info)
"Finds indentation information for a line starting with a guard."
(save-excursion
- (let* ((sep (haskell-indent-separate-valdef start end))
+ (let* ((haskell-indent-info indent-info)
+ (sep (haskell-indent-separate-valdef start end))
(valname (nth 0 sep))
(guard (nth 3 sep))
(rhs-sign (nth 5 sep)))
@@ -539,13 +486,14 @@
(if rhs-sign
(haskell-indent-push-pos rhs-sign) ; probably within a data definition...
(if valname
- (haskell-indent-push-pos-offset valname))))))
- indent-info)
+ (haskell-indent-push-pos-offset valname))))
+ haskell-indent-info)))
(defun haskell-indent-rhs (start end end-visible indent-info)
"Finds indentation information for a line starting with a rhs."
(save-excursion
- (let* ((sep (haskell-indent-separate-valdef start end))
+ (let* ((haskell-indent-info indent-info)
+ (sep (haskell-indent-separate-valdef start end))
(valname (nth 0 sep))
(guard (nth 3 sep))
(rhs-sign (nth 5 sep)))
@@ -555,30 +503,8 @@
(if (and guard (< guard end-visible))
(haskell-indent-push-pos-offset guard)
(if valname ; always visible !!
- (haskell-indent-push-pos-offset valname))))))
- indent-info)
-
-(defun haskell-indent-comment (start end indent-info)
- "Finds indentation information for a comment line.
-If the previous line (between START and END) is also a comment line
- -- comments are aligned on their start
- {- comments are aligned on the first non-blank char following the open {
-otherwise
- indent at the same indentation as the previous line."
- (save-excursion
- (let ((comment-start (haskell-indent-in-comment start end)))
- (if comment-start
- (if (eq (char-after comment-start) ?-)
- ;; -- style comment
- (haskell-indent-push-pos comment-start)
- ;; {- style comment
- (goto-char (+ 2 comment-start))
- (haskell-indent-skip-blanks-and-newlines-forward end)
- (haskell-indent-push-pos (point)))
- ;; no previous comment indent with previous line
- (haskell-indent-push-col (haskell-indent-current-indentation)))))
- indent-info)
-
+ (haskell-indent-push-pos-offset valname))))
+ haskell-indent-info)))
(defconst haskell-indent-decision-table
(let ((or "\\)\\|\\("))
@@ -597,7 +523,7 @@
"001000" or ;12= gd
"000011" or ;13= rh arh
"000010" or ;14= rh
- "000000" ;15=
+ "000000" ;15=
"\\)")))
(defun haskell-indent-find-case (test)
@@ -605,32 +531,30 @@
(if (string-match haskell-indent-decision-table test)
;; use the fact that the resulting match-data is a list of the form
;; (0 6 [2*(n-1) nil] 0 6) where n is the number of the matching regexp
- ;; so n= ((length match-date)/2)-1
- (- (/ (length (match-data)) 2) 1)
- (error "haskell-indent-find-case: impossible case: %s" test)
- ))
+ ;; so n= ((length match-data)/2)-1
+ (- (/ (length (match-data 'integers)) 2) 1)
+ (error "haskell-indent-find-case: impossible case: %s" test)))
(defun haskell-indent-empty (start end end-visible indent-info)
"Finds indentation points for an empty line."
(save-excursion
- (let*
- ((sep (haskell-indent-separate-valdef start end))
- (valname (pop sep))
- (valname-string (pop sep))
- (aft-valname (pop sep))
- (guard (pop sep))
- (aft-guard (pop sep))
- (rhs-sign (pop sep))
- (aft-rhs-sign (pop sep))
- (last-line (= end end-visible))
- (test (concat
- (if valname "1" "0")
- (if (and aft-valname (< aft-valname end-visible)) "1"
"0")
- (if (and guard (< guard end-visible)) "1" "0")
- (if (and aft-guard (< aft-guard end-visible)) "1"
"0")
- (if (and rhs-sign (< rhs-sign end-visible)) "1"
"0")
- (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) "1"
"0")))
- )
+ (let* ((haskell-indent-info indent-info)
+ (sep (haskell-indent-separate-valdef start end))
+ (valname (pop sep))
+ (valname-string (pop sep))
+ (aft-valname (pop sep))
+ (guard (pop sep))
+ (aft-guard (pop sep))
+ (rhs-sign (pop sep))
+ (aft-rhs-sign (pop sep))
+ (last-line (= end end-visible))
+ (test (string
+ (if valname ?1 ?0)
+ (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+ (if (and guard (< guard end-visible)) ?1 ?0)
+ (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+ (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+ (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
(if (and valname-string ; special case for start keywords
(string-match haskell-indent-start-keywords-re valname-string))
(progn
@@ -639,8 +563,7 @@
(if (string-match "\\<data\\>" valname-string)
(if rhs-sign (haskell-indent-push-pos rhs-sign)
(haskell-indent-push-pos-offset valname))
- (haskell-indent-push-pos-offset valname)
- ))
+ (haskell-indent-push-pos-offset valname)))
(case ; general case
(haskell-indent-find-case test)
;; "1.1.11" 1= vn gd rh arh
@@ -694,15 +617,16 @@
(13 (haskell-indent-push-pos aft-rhs-sign))
;; "000010" 14= rh
(14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2 )))
- ;; "000000" 15=
- (t (error "haskell-indent-empty: %s impossible case" test ))))))
- indent-info)
+ ;; "000000" 15=
+ (t (error "haskell-indent-empty: %s impossible case" test ))))
+ haskell-indent-info)))
(defun haskell-indent-ident (start end end-visible indent-info)
"Finds indentation points for a line starting with an identifier."
(save-excursion
(let*
- ((sep (haskell-indent-separate-valdef start end))
+ ((haskell-indent-info indent-info)
+ (sep (haskell-indent-separate-valdef start end))
(valname (pop sep))
(valname-string (pop sep))
(aft-valname (pop sep))
@@ -713,18 +637,17 @@
(last-line (= end end-visible))
(is-where
(string-match "where[ \t]*"
haskell-indent-current-line-first-ident))
- (diff-first ; not a function def with the same name
+ (diff-first ; not a function def with the same name
(not(string= valname-string haskell-indent-current-line-first-ident)))
-; (is-type-def
-; (and rhs-sign (eq (char-after rhs-sign) ?\:)))
- (test (concat
- (if valname "1" "0")
- (if (and aft-valname (< aft-valname end-visible)) "1"
"0")
- (if (and guard (< guard end-visible)) "1" "0")
- (if (and aft-guard (< aft-guard end-visible)) "1"
"0")
- (if (and rhs-sign (< rhs-sign end-visible)) "1"
"0")
- (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) "1"
"0")))
- )
+ ;; (is-type-def
+ ;; (and rhs-sign (eq (char-after rhs-sign) ?\:)))
+ (test (string
+ (if valname ?1 ?0)
+ (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+ (if (and guard (< guard end-visible)) ?1 ?0)
+ (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+ (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+ (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
(if (and valname-string ; special case for start keywords
(string-match haskell-indent-start-keywords-re valname-string))
(progn
@@ -736,8 +659,7 @@
(if (not (string-match
haskell-indent-start-keywords-re
haskell-indent-current-line-first-ident))
- (haskell-indent-push-pos-offset valname))
- ))
+ (haskell-indent-push-pos-offset valname))))
(if (string= haskell-indent-current-line-first-ident "::")
(if valname (haskell-indent-push-pos valname))
(case ; general case
@@ -768,7 +690,7 @@
;; "1.0011" 5= vn rh arh
(5 (if is-where
(haskell-indent-push-pos-offset valname)
- (haskell-indent-push-pos valname)
+ (haskell-indent-push-pos valname)
(if diff-first
(haskell-indent-push-pos aft-rhs-sign))))
;; "1.0010" 6= vn rh
@@ -807,34 +729,31 @@
(13 (haskell-indent-push-pos aft-rhs-sign))
;; "000010" 14= rh
(14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2)))
- ;; "000000" 15=
- (t (error "haskell-indent-ident: %s impossible case" test )))))))
- indent-info)
+ ;; "000000" 15=
+ (t (error "haskell-indent-ident: %s impossible case" test )))))
+ haskell-indent-info)))
(defun haskell-indent-other (start end end-visible indent-info)
"Finds indentation points for a non-empty line starting with something other
than an identifier, a guard or rhs."
(save-excursion
- (let*
- ((sep (haskell-indent-separate-valdef start end))
- (valname (pop sep))
- (valname-string (pop sep))
- (aft-valname (pop sep))
- (guard (pop sep))
- (aft-guard (pop sep))
- (rhs-sign (pop sep))
- (aft-rhs-sign (pop sep))
- (last-line (= end end-visible))
- (is-where
- (string-match "where[ \t]*"
haskell-indent-current-line-first-ident))
- (test (concat
- (if valname "1" "0")
- (if (and aft-valname (< aft-valname end-visible)) "1"
"0")
- (if (and guard (< guard end-visible)) "1" "0")
- (if (and aft-guard (< aft-guard end-visible)) "1"
"0")
- (if (and rhs-sign (< rhs-sign end-visible)) "1"
"0")
- (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) "1"
"0")))
- )
+ (let* ((haskell-indent-info indent-info)
+ (sep (haskell-indent-separate-valdef start end))
+ (valname (pop sep))
+ (valname-string (pop sep))
+ (aft-valname (pop sep))
+ (guard (pop sep))
+ (aft-guard (pop sep))
+ (rhs-sign (pop sep))
+ (aft-rhs-sign (pop sep))
+ (last-line (= end end-visible))
+ (test (string
+ (if valname ?1 ?0)
+ (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+ (if (and guard (< guard end-visible)) ?1 ?0)
+ (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+ (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+ (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
(if (and valname-string ; special case for start keywords
(string-match haskell-indent-start-keywords-re valname-string))
(haskell-indent-push-pos-offset valname)
@@ -876,205 +795,418 @@
(13 (haskell-indent-push-pos aft-rhs-sign))
;; "000010" 14= rh
(14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2)))
- ;; "000000" 15=
- (t (error "haskell-indent-other: %s impossible case" test ))))))
- indent-info)
+ ;; "000000" 15=
+ (t (error "haskell-indent-other: %s impossible case" test ))))
+ haskell-indent-info)))
(defun haskell-indent-valdef-indentation (start end end-visible curr-line-type
- indent-info)
- "Finds indentation information for a value definition."
- (if (< start end-visible)
- (case curr-line-type
- ('empty (haskell-indent-empty start end end-visible indent-info))
- ('ident (haskell-indent-ident start end end-visible indent-info))
- ('guard (haskell-indent-guard start end end-visible indent-info))
- ('rhs (haskell-indent-rhs start end end-visible indent-info))
- ('comment (error "Comment indent should never happen"))
- ('other (haskell-indent-other start end end-visible indent-info)))
- indent-info))
+ indent-info)
+ "Find indentation information for a value definition."
+ (let ((haskell-indent-info indent-info))
+ (if (< start end-visible)
+ (case curr-line-type
+ (empty (haskell-indent-empty start end end-visible indent-info))
+ (ident (haskell-indent-ident start end end-visible indent-info))
+ (guard (haskell-indent-guard start end end-visible indent-info))
+ (rhs (haskell-indent-rhs start end end-visible indent-info))
+ (comment (error "Comment indent should never happen"))
+ (other (haskell-indent-other start end end-visible indent-info)))
+ haskell-indent-info)))
(defun haskell-indent-line-indentation (line-start line-end end-visible
curr-line-type indent-info)
- "Separate a line of program into valdefs between offside keywords
+ "Compute indentation info between LINE-START and END-VISIBLE.
+Separate a line of program into valdefs between offside keywords
and find indentation info for each part."
(save-excursion
- (let (end-match beg-match in-string start-comment)
- ;; point is (already) at line-start
- (setq start-comment (haskell-indent-in-comment line-start line-end))
- (if start-comment ; if comment at the end
- (setq line-end (- start-comment 1))) ; end line before it
+ ;; point is (already) at line-start
+ (assert (eq (point) line-start))
+ (let ((haskell-indent-info indent-info)
+ (start (or (haskell-indent-in-comment line-start line-end)
+ (haskell-indent-in-string line-start line-end))))
+ (if start ; if comment at the end
+ (setq line-end start)) ; end line before it
;; loop on all parts separated by off-side-keywords
- (while (re-search-forward haskell-indent-off-side-keywords-re line-end t)
- (setq beg-match (match-beginning 0)); save beginning of match
- (setq end-match (match-end 0)) ; save end of match
- (if (haskell-indent-in-comment line-start (point)) ; keyword in a {- comment
- (progn
- (setq indent-info
- (haskell-indent-valdef-indentation
- line-start ; end line before comment
- (- (search-backward "{-" line-start) 1)
- end-visible curr-line-type indent-info))
- ;skip past end of comment
- (re-search-forward "-}[ \t]*" line-end 'move)
- (setq line-start (point)))
- ;; not in a comment
- (setq in-string (haskell-indent-in-string line-start (point)))
- (if in-string
- (re-search-forward ; skip past end of string
- ; line-start does not change...
- (concat (char-to-string in-string) "[ \t]*") line-end
'move)
- ;; not in a string
- (if (< line-start beg-match) ; if off-side-keyword at the start
- (setq indent-info ; do not try to find indentation points
- (haskell-indent-valdef-indentation line-start beg-match
- end-visible
- curr-line-type indent-info)))
- ;; but keep the start of the line if keyword alone on the line
- (if (= line-end end-match)
- (haskell-indent-push-pos beg-match)))
- (setq line-start end-match)
- (goto-char line-start)))
- (setq indent-info
+ (while (and (re-search-forward haskell-indent-off-side-keywords-re
+ line-end t)
+ (not (or (haskell-indent-in-comment line-start (point))
+ (haskell-indent-in-string line-start (point)))))
+ (let ((beg-match (match-beginning 0)) ; save beginning of match
+ (end-match (match-end 0))) ; save end of match
+ ;; Do not try to find indentation points if off-side-keyword at
+ ;; the start...
+ (if (or (< line-start beg-match)
+ ;; Actually, if we're looking at a "let" inside a
"do", we
+ ;; should add the corresponding indentation point.
+ (eq (char-after beg-match) ?l))
+ (setq haskell-indent-info
+ (haskell-indent-valdef-indentation line-start beg-match
+ end-visible
+ curr-line-type
+ haskell-indent-info)))
+ ;; ...but keep the start of the line if keyword alone on the line
+ (if (= line-end end-match)
+ (haskell-indent-push-pos beg-match))
+ (setq line-start end-match)
+ (goto-char line-start)))
+ (setq haskell-indent-info
(haskell-indent-valdef-indentation line-start line-end end-visible
- curr-line-type indent-info))))
- indent-info)
+ curr-line-type haskell-indent-info))
+ haskell-indent-info)))
-(defun haskell-indent-indentation-info ()
- "Returns a list of possible indentations for the current line that
-are then used by `haskell-indent-cycle'."
- (let ((start (haskell-indent-start-of-def))
- (end (progn (haskell-indent-back-to-indentation) (point)))
- indent-info open follow contour-line pt)
- ;; in string?
- (if (setq open (haskell-indent-in-string start end))
- (haskell-indent-push-pos-offset open
- (if (looking-at "\\\\") 0 1))
- ;; open structure? ie ( { [
- (if (setq open (haskell-indent-open-structure start end))
- ;; there is an open structure to complete
- (if (looking-at "\\s)\\|\\s.\\|$ ")
- (haskell-indent-push-pos open); align a ) or punct with (
- (progn
- (setq follow (save-excursion
- (goto-char (1+ open))
- (haskell-indent-skip-blanks-and-newlines-forward end)
- (point)))
- (if (= follow end)
- (haskell-indent-push-pos-offset open 1)
- (haskell-indent-push-pos follow))))
- ;; in comment ?
- (if (haskell-indent-in-comment start end)
- (save-excursion
- (end-of-line 0) ; put point at the end of preceding line before
- (setq indent-info ; computing comment indentation
- (haskell-indent-comment (haskell-indent-get-beg-of-line)
- (point) indent-info)))
- ;; full indentation
- (setq contour-line (haskell-indent-contour-line start end))
- (if contour-line
- (let* ((curr-line-type (haskell-indent-type-at-point))
- line-start line-end end-visible)
- (save-excursion
- (if (eq curr-line-type 'ident)
- (progn ; guess the type of line
- (setq sep
- (haskell-indent-separate-valdef (point)
-
(haskell-indent-get-end-of-line)))
- ;; if the first ident is where or the start of a def
- ;; keep it in a global variable
- (if (string-match "where[ \t]*" (nth 1 sep))
- (setq haskell-indent-current-line-first-ident (nth 1 sep))
- (if (nth 5 sep) ; is there a rhs-sign
- (if (= (char-after (nth 5 sep)) ?\:) ;is it a typdef
- (setq haskell-indent-current-line-first-ident
"::")
- (setq haskell-indent-current-line-first-ident
- (nth 1 sep)))
- (setq haskell-indent-current-line-first-ident
"")))))
- (while contour-line ; explore the contour points
- (setq line-start (pop contour-line))
- (goto-char line-start)
- (setq line-end (haskell-indent-get-end-of-line))
- (setq end-visible ; visible until the column of the
- (if contour-line ; next contour point
- (save-excursion
- (move-to-column
- (haskell-indent-point-to-col (car contour-line)))
- (point))
- line-end))
- (if (and (not (haskell-indent-open-structure start line-start))
- (not (haskell-indent-in-comment start line-start)))
- (setq indent-info
- (haskell-indent-line-indentation line-start line-end
- end-visible curr-line-type
- indent-info)))
- )))
- ;; simple contour just one indentation at start
- (if (and (eq haskell-literate 'bird)
- (eq (haskell-indent-point-to-col start) 1))
- ;; for a Bird style literate script put default offset
- ;; in the case of no indentation
- (haskell-indent-push-col
- (1+ haskell-indent-literate-Bird-default-offset))
- (haskell-indent-push-pos start)))))
- indent-info
- )))
-(defun haskell-indent-event-type (event)
- "Checks if EVENT is the TAB or RET key before returning the value
-of `event-basic-type'. Needed for dealing with the case that Emacs
-is not in a windowing environment."
- (cond ((eq event ?\t) 'tab)
- ((eq event ?\r) 'return)
- (t (event-basic-type event)))
- )
-
+(defun haskell-indent-layout-indent-info (start contour-line)
+ (let ((haskell-indent-info nil)
+ (curr-line-type (haskell-indent-type-at-point))
+ line-start line-end end-visible)
+ (save-excursion
+ (if (eq curr-line-type 'ident)
+ (let ; guess the type of line
+ ((sep
+ (haskell-indent-separate-valdef
+ (point) (line-end-position))))
+ ;; if the first ident is where or the start of a def
+ ;; keep it in a global variable
+ (setq haskell-indent-current-line-first-ident
+ (if (string-match "where[ \t]*" (nth 1 sep))
+ (nth 1 sep)
+ (if (nth 5 sep) ; is there a rhs-sign
+ (if (= (char-after (nth 5 sep)) ?\:) ;is it a typdef
+ "::" (nth 1 sep))
+ "")))))
+ (while contour-line ; explore the contour points
+ (setq line-start (pop contour-line))
+ (goto-char line-start)
+ (setq line-end (line-end-position))
+ (setq end-visible ; visible until the column of the
+ (if contour-line ; next contour point
+ (save-excursion
+ (move-to-column
+ (haskell-indent-point-to-col (car contour-line)))
+ (point))
+ line-end))
+ (unless (or (haskell-indent-open-structure start line-start)
+ (haskell-indent-in-comment start line-start))
+ (setq haskell-indent-info
+ (haskell-indent-line-indentation line-start line-end
+ end-visible curr-line-type
+ haskell-indent-info)))))
+ haskell-indent-info))
+
+(defun haskell-indent-find-matching-start (regexp limit &optional pred start)
+ (let ((open (haskell-indent-open-structure limit (point))))
+ (if open (setq limit (1+ open))))
+ (unless start (setq start (point)))
+ (when (re-search-backward regexp limit t)
+ (let ((nestedcase (match-end 1))
+ (outer (or (haskell-indent-in-string limit (point))
+ (haskell-indent-in-comment limit (point))
+ (haskell-indent-open-structure limit (point))
+ (if (and pred (funcall pred start)) (point)))))
+ (cond
+ (outer
+ (goto-char outer)
+ (haskell-indent-find-matching-start regexp limit pred start))
+ (nestedcase
+ ;; Nested case.
+ (and (haskell-indent-find-matching-start regexp limit pred)
+ (haskell-indent-find-matching-start regexp limit pred start)))
+ (t (point))))))
+
+(defun haskell-indent-filter-let-no-in (start)
+ "Return non-nil if point is in front of a `let' that has no `in'.
+START is the position of the presumed `in'."
+ ;; We're looking at either `in' or `let'.
+ (when (looking-at "let")
+ (ignore-errors
+ (save-excursion
+ (forward-word 1)
+ (forward-comment (point-max))
+ (if (looking-at "{")
+ (progn
+ (forward-sexp 1)
+ (forward-comment (point-max))
+ (< (point) start))
+ ;; Use the layout rule to see whether this let is already closed
+ ;; without an `in'.
+ (let ((col (current-column)))
+ (while (progn (forward-line 1) (haskell-indent-back-to-indentation)
+ (< (point) start))
+ (when (< (current-column) col)
+ (setq col nil)
+ (goto-char start)))
+ (null col)))))))
+
+(defun haskell-indent-inside-comment (open start)
+ "Compute indent info for text inside comment.
+OPEN is the start position of the comment in which point is."
+ ;; Ideally we'd want to guess whether it's commented out code or
+ ;; whether it's text. Instead, we'll assume it's text.
+ (save-excursion
+ (if (= open (point))
+ ;; We're actually just in front of a comment: align with following
+ ;; code or with comment on previous line.
+ (let ((prev-line-info
+ (cond
+ ((eq (char-after) ?\{) nil) ;Align as if it were code.
+ ((and (forward-comment -1)
+ (> (line-beginning-position 3) open))
+ ;; We're after another comment and there's no empty line
+ ;; between us.
+ (list (list (haskell-indent-point-to-col (point)))))
+ (t nil)))) ;Else align as if it were code
+ ;; Align with following code.
+ (forward-comment (point-max))
+ ;; There are several possible indentation points for this code-line,
+ ;; but the only valid indentation point for the comment is the one
+ ;; that the user will select for the code-line. Obviously we can't
+ ;; know that, so we just assume that the code-line is already at its
+ ;; proper place.
+ ;; Strictly speaking "assume it's at its proper place" would
mean
+ ;; we'd just use (current-column), but since this is using info from
+ ;; lines further down and it's common to reindent line-by-line,
+ ;; we'll align not with the current indentation, but with the
+ ;; one that auto-indentation "will" select.
+ (append
+ prev-line-info
+ (let ((indent-info (save-excursion
+ (haskell-indent-indentation-info start)))
+ (col (current-column)))
+ ;; Sort the indent-info so that the current indentation comes
+ ;; out first.
+ (setq indent-info
+ (sort indent-info
+ (lambda (x y)
+ (<= (abs (- col (car x))) (abs (- col (car y)))))))
+ indent-info)))
+
+ ;; We really are inside a comment.
+ (if (looking-at "-}")
+ (progn
+ (forward-char 2)
+ (forward-comment -1)
+ (list (list (1+ (haskell-indent-point-to-col (point))))))
+ (let ((offset (if (looking-at "--?")
+ (- (match-beginning 0) (match-end 0)))))
+ (forward-line -1) ;Go to previous line.
+ (haskell-indent-back-to-indentation)
+ (if (< (point) start) (goto-char start))
+
+ (list (list (if (looking-at comment-start-skip)
+ (if offset
+ (+ 2 offset (haskell-indent-point-to-col (point)))
+ (haskell-indent-point-to-col (match-end 0)))
+ (haskell-indent-point-to-col (point))))))))))
+
+(defcustom haskell-indent-after-keywords
+ '(("where" 2 0)
+ ("of" 2)
+ ("do" 2)
+ ("in" 2 0)
+ "if"
+ "then"
+ "else"
+ "let")
+ "Keywords after which indentation should be indented by some offset.
+Each keyword info can have the following forms:
+
+ KEYWORD | (KEYWORD OFFSET [OFFSET-HANGING])
+
+If absent OFFSET-HANGING defaults to OFFSET.
+If absent OFFSET defaults to `haskell-indent-offset'.
+
+OFFSET-HANGING is the offset to use in the case where the keyword
+is at the end of an otherwise-non-empty line."
+:type '(repeat (choice string
+ (cons :tag "" (string :tag "keyword:")
+ (cons :tag "" (integer :tag "offset")
+ (choice (const nil)
+ (list :tag ""
+ (integer :tag "offset-pending"))))))))
+
+(defun haskell-indent-virtual-indentation (start)
+ "Compute the \"virtual indentation\" of text at point.
+The \"virtual indentation\" is the indentation that text at point would have
+had, if it had been placed on its own line."
+ (let ((col (current-column)))
+ (if (save-excursion (skip-chars-backward " \t") (bolp))
+ ;; If the text is indeed on its own line, than the virtual indent is
+ ;; the current indentation.
+ col
+ ;; Else, compute the indentation that it would have had.
+ (let ((info (haskell-indent-indentation-info start))
+ (max -1))
+ ;; `info' is a list of possible indent points. Each indent point is
+ ;; assumed to correspond to a different parse. So we need to find
+ ;; the parse that corresponds to the case at hand (where there's no
+ ;; line break), which is assumed to always be the
+ ;; deepest indentation.
+ (dolist (x info)
+ (setq x (car x))
+ ;; Sometimes `info' includes the current indentation (or yet
+ ;; deeper) by mistake, because haskell-indent-indentation-info
+ ;; wasn't designed to be called on a piece of text that is not at
+ ;; BOL. So ignore points past `col'.
+ (if (and (> x max) (not (>= x col)))
+ (setq max x)))
+ ;; In case all the indent points are past `col', just use `col'.
+ (if (>= max 0) max col)))))
+
+(defun haskell-indent-indentation-info (&optional start)
+ "Return a list of possible indentations for the current line.
+These are then used by `haskell-indent-cycle'.
+START if non-nil is a presumed start pos of the current definition."
+ (unless start (setq start (haskell-indent-start-of-def)))
+ (let ((end (point))
+ open follow contour-line)
+ (cond
+ ;; in string?
+ ((setq open (haskell-indent-in-string start end))
+ (list (list (+ (haskell-indent-point-to-col open)
+ (if (looking-at "\\\\") 0 1)))))
+
+ ;; in comment ?
+ ((setq open (haskell-indent-in-comment start end))
+ (haskell-indent-inside-comment open start))
+
+ ;; Closing the declaration part of a `let' or the test exp part of a case.
+ ((and (looking-at "\\(?:in\\|of\\|then\\|else\\)\\>")
+ (setq open (save-excursion
+ (haskell-indent-find-matching-start
+ (case (char-after)
+ (?i "\\<\\(?:\\(in\\)\\|let\\)\\>")
+ (?o "\\<\\(?:\\(of\\)\\|case\\)\\>")
+ (?t "\\<\\(?:\\(then\\)\\|if\\)\\>")
+ (?e "\\<\\(?:\\(else\\)\\|if\\)\\>"))
+ start
+ (if (eq (char-after) ?i)
+ ;; Filter out the `let's that have no `in'.
+ 'haskell-indent-filter-let-no-in))))
+ ;; For a "dangling let/case/if at EOL" we should use a different
+ ;; indentation scheme.
+ (save-excursion
+ (goto-char open)
+ (let ((letcol (current-column)))
+ (forward-word 1) (forward-comment (point-max))
+ (>= (current-column) letcol))))
+ (list (list (haskell-indent-point-to-col open))))
+
+ ;; Right after a special keyword.
+ ((save-excursion
+ (forward-comment (- (point-max)))
+ (let ((id (buffer-substring (point) (progn (forward-word -1) (point)))))
+ (when (setq open (or (assoc id haskell-indent-after-keywords)
+ (car (member id haskell-indent-after-keywords))))
+ (setq open (cdr-safe open))
+ (setq open
+ (if (save-excursion (skip-syntax-backward " \t") (bolp))
+ (car open)
+ (or (cadr open) (car open))))
+ (list (list
+ (+ (haskell-indent-virtual-indentation start)
+ (or open haskell-indent-offset))))))))
+
+ ;; open structure? ie ( { [
+ ((setq open (haskell-indent-open-structure start end))
+ ;; there is an open structure to complete
+ (if (looking-at "\\s)\\|[;,]")
+ ;; A close-paren or a , or ; can only correspond syntactically to
+ ;; the open-paren at `open'. So there is no ambiguity.
+ (progn
+ (if (or (and (eq (char-after) ?\;) (eq (char-after open) ?\())
+ (and (eq (char-after) ?\,) (eq (char-after open) ?\{)))
+ (message "Mismatched punctuation: `%c' in %c...%c"
+ (char-after) (char-after open)
+ (if (eq (char-after open) ?\() ?\) ?\})))
+ (list (list (haskell-indent-point-to-col open))))
+ ;; There might still be layout within the open structure.
+ (let ((basic-indent-info
+ ;; Anything else than a ) is subject to layout.
+ (if (looking-at "\\s.\\|$ ")
+ (haskell-indent-point-to-col open) ; align a punct with (
+ (setq follow (save-excursion
+ (goto-char (1+ open))
+ (haskell-indent-skip-blanks-and-newlines-forward end)
+ (point)))
+ (if (= follow end)
+ (1+ (haskell-indent-point-to-col open))
+ (haskell-indent-point-to-col follow))))
+ (open-column (haskell-indent-point-to-col open))
+ (contour-line (haskell-indent-contour-line (1+ open) end)))
+ (if (null contour-line)
+ (list (list basic-indent-info))
+ (let ((indent-info
+ (haskell-indent-layout-indent-info
+ (1+ open) contour-line)))
+ ;; Fix up indent info.
+ (let ((base-elem (assoc open-column indent-info)))
+ (if base-elem
+ (progn (setcar base-elem basic-indent-info)
+ (setcdr base-elem nil))
+ (setq indent-info
+ (append indent-info (list (list basic-indent-info)))))
+ indent-info))))))
+
+ ;; full indentation
+ ((setq contour-line (haskell-indent-contour-line start end))
+ (haskell-indent-layout-indent-info start contour-line))
+
+ (t
+ ;; simple contour just one indentation at start
+ (list (list (if (and (eq haskell-literate 'bird)
+ (eq (haskell-indent-point-to-col start) 1))
+ ;; for a Bird style literate script put default offset
+ ;; in the case of no indentation
+ (1+ haskell-indent-literate-Bird-default-offset)
+ (haskell-indent-point-to-col start))))))))
+
+(defvar haskell-indent-last-info nil)
+
+
(defun haskell-indent-cycle ()
"Indentation cycle.
-We stay in the cycle as long as the TAB key is pressed.
-Any other key or mouse click terminates the cycle and is interpreted
-with the exception of the RET key which merely exits the cycle."
+We stay in the cycle as long as the TAB key is pressed."
(interactive "*")
(if (and haskell-literate
(not (haskell-indent-within-literate-code)))
- (indent-to-left-margin) ;; use the ordinary tab for text...
- (let (il indent-list com indent-info cdrii marker
- (last-insert-length 0))
- (if (> (current-column) (haskell-indent-current-indentation))
- (setq marker (point-marker)))
- (setq il (setq indent-list (haskell-indent-indentation-info)))
- ;;(message "Indent-list:%s" indent-list) (read-event) ; uncomment for
debug!!
- (setq indent-info (car il))
- (haskell-indent-line-to (car indent-info)) ; insert indentation
- (if (setq cdrii (cdr indent-info))
- (progn
- (insert cdrii)
- (setq last-insert-length (length cdrii)))
- (setq last-insert-length 0))
- (if (= (length indent-list) 1)
- (message "Sole indentation")
- (message (format "Indent cycle (%d)..." (length indent-list)))
- (while (equal (haskell-indent-event-type (setq com (read-event))) 'tab)
- (setq il (cdr il)) ; get next insertion
- (or il (setq il indent-list)) ; if at the end of insertion, restart
- ; from the beginning
- (setq indent-info (car il))
- (haskell-indent-line-to (car indent-info)) ; insert indentation
- (delete-char last-insert-length)
- (if (setq cdrii (cdr indent-info))
- (progn
- (insert cdrii)
- (setq last-insert-length (length cdrii)))
- (setq last-insert-length 0))
- (message "Indenting..."))
- (if (not (equal (haskell-indent-event-type com) 'return))
- (setq unread-command-events (list com)))
- (message "Done."))
- (if marker
- (goto-char (marker-position marker)))
- ))
- )
-;;; alignment functions
-;;;
+ ;; use the ordinary tab for text...
+ (funcall (default-value 'indent-line-function))
+ (let ((marker (if (> (current-column) (haskell-indent-current-indentation))
+ (point-marker)))
+ (bol (progn (beginning-of-line) (point))))
+ (haskell-indent-back-to-indentation)
+ (unless (and (eq last-command this-command)
+ (eq bol (car haskell-indent-last-info)))
+ (save-excursion
+ (setq haskell-indent-last-info
+ (list bol (haskell-indent-indentation-info) 0 0))))
+
+ (let* ((il (nth 1 haskell-indent-last-info))
+ (index (nth 2 haskell-indent-last-info))
+ (last-insert-length (nth 3 haskell-indent-last-info))
+ (indent-info (nth index il)))
+
+ (haskell-indent-line-to (car indent-info)) ; insert indentation
+ (delete-char last-insert-length)
+ (setq last-insert-length 0)
+ (let ((text (cdr indent-info)))
+ (if text
+ (progn
+ (insert text)
+ (setq last-insert-length (length text)))))
+
+ (setq haskell-indent-last-info
+ (list bol il (% (1+ index) (length il)) last-insert-length))
+
+ (if (= (length il) 1)
+ (message "Sole indentation")
+ (message "Indent cycle (%d)..." (length il)))
+
+ (if marker
+ (goto-char (marker-position marker)))))))
+
+;;; alignment functions
+
(defun haskell-indent-shift-columns (dest-column region-stack)
"Shifts columns in region-stack to go to DEST-COLUMN.
Elements of the stack are pairs of points giving the start and end
@@ -1094,37 +1226,35 @@
(end-of-line 2) ; should be (forward-line 1)
(if (eobp) ; but it adds line at the end...
(throw 'end-of-buffer nil))
- (move-to-column col)))
- ))
- ))
-
+ (move-to-column col)))))))
+
(defun haskell-indent-align-def (p-arg type)
"Align guards or rhs within the current definition before point.
If P-ARG is t align all defs up to the mark.
TYPE is either 'guard or 'rhs."
(save-excursion
(let (start-block end-block
- (maxcol (if (eq type 'rhs) haskell-indent-rhs-align-column 0))
+ (maxcol (if (eq type 'rhs) haskell-indent-rhs-align-column 0))
contour sep defname defnamepos
- defpos defcol pos lastpos
+ defcol pos lastpos
regstack eqns-start start-found)
- ;; find the starting and ending boundary points for alignment
- (if p-arg
+ ;; find the starting and ending boundary points for alignment
+ (if p-arg
(if (mark) ; aligning everything in the region
(progn
(when (> (mark) (point)) (exchange-point-and-mark))
(setq start-block
(save-excursion
(goto-char (mark))
- (haskell-indent-get-beg-of-line)))
+ (line-beginning-position)))
(setq end-block
(progn (if (haskell-indent-bolp)
(haskell-indent-forward-line -1))
- (haskell-indent-get-end-of-line))))
+ (line-end-position))))
(error "The mark is not set for aligning definitions"))
;; aligning the current definition
(setq start-block (haskell-indent-start-of-def))
- (setq end-block (haskell-indent-get-end-of-line)))
+ (setq end-block (line-end-position)))
;; find the start of the current valdef using the contour line
;; in reverse order because we need the nearest one from the end
(setq contour
@@ -1148,7 +1278,7 @@
(setq defname "\\<\\|("))
(setq defcol (haskell-indent-point-to-col defnamepos))
(goto-char pos)
- (setq end-block (haskell-indent-get-end-of-line))
+ (setq end-block (line-end-position))
(catch 'top-of-buffer
(while (and (not start-found)
(>= (point) start-block))
@@ -1165,7 +1295,7 @@
(if (and (eq (haskell-indent-type-at-point) 'guard) ; start of a
guard
(not (haskell-indent-open-structure start-block (point))))
(push (cons (point) 'gd) eqns-start)))
- (if (bobp)
+ (if (bobp)
(throw 'top-of-buffer nil)
(haskell-indent-backward-to-indentation 1))))
;; remove the spurious guards before the first equation
@@ -1173,15 +1303,14 @@
(pop eqns-start))
;; go through each equation to find the region to indent
(while eqns-start
- (setq eqn (caar eqns-start))
- (setq lastpos (if (cdr eqns-start)
- (save-excursion
- (goto-char (caadr eqns-start))
- (haskell-indent-forward-line -1)
- (haskell-indent-get-end-of-line))
- end-block))
- (setq sep (haskell-indent-separate-valdef eqn lastpos))
- (setq defpos (nth 0 sep))
+ (let ((eqn (caar eqns-start)))
+ (setq lastpos (if (cdr eqns-start)
+ (save-excursion
+ (goto-char (caadr eqns-start))
+ (haskell-indent-forward-line -1)
+ (line-end-position))
+ end-block))
+ (setq sep (haskell-indent-separate-valdef eqn lastpos)))
(if (eq type 'guard)
(setq pos (nth 3 sep))
;; check if what follows a rhs sign is more indented or not
@@ -1201,7 +1330,7 @@
(goto-char pos)
(skip-chars-backward
" \t"
- (haskell-indent-get-beg-of-line))
+ (line-beginning-position))
(if (haskell-indent-bolp)
;;if on an empty prefix
(haskell-indent-point-to-col pos) ;keep original
indent
@@ -1209,18 +1338,18 @@
(pop eqns-start))
;; now shift according to the region stack
(if regstack
- (haskell-indent-shift-columns maxcol regstack))
- ))
- )))
+ (haskell-indent-shift-columns maxcol regstack)))))))
(defun haskell-indent-align-guards-and-rhs (start end)
-"Align the guards and rhs of functions in the region which must be active."
+ "Align the guards and rhs of functions in the region which must be active."
+ ;; The `start' and `end' args are dummys right now: they're just there so
+ ;; we can use the "r" interactive spec which properly signals an error.
(interactive "*r")
(haskell-indent-align-def t 'guard)
(haskell-indent-align-def t 'rhs))
-;;; insertion functions
-;;;
+;;; insertion functions
+
(defun haskell-indent-insert-equal ()
"Insert an = sign and align the previous rhs of the current function."
(interactive "*")
@@ -1231,8 +1360,7 @@
(haskell-indent-align-def (haskell-indent-mark-active) 'rhs))
(defun haskell-indent-insert-guard (&optional text)
- "Insert a guard sign (|) followed by optional TEXT and align the
-previous guards of the current function.
+ "Insert and align a guard sign (|) followed by optional TEXT.
Alignment works only if all guards are to the south-east of their |."
(interactive "*")
(let ((pc (if (haskell-indent-bolp) ?\012
@@ -1241,7 +1369,7 @@
;; check what guard to insert depending on the previous context
(if (= pc ?\ ) ; x = any char other than blank or |
(if (/= pc1 ?\|)
- (insert "| ") ; after " x"
+ (insert "| ") ; after " x"
()) ; after " |"
(if (= pc ?\|)
(if (= pc1 ?\|)
@@ -1263,53 +1391,47 @@
line with an indentation cycle."
(interactive "*")
(insert "where ")
- (save-excursion
- (haskell-indent-cycle)))
+ (haskell-indent-cycle))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; turn-on-haskell-indent to be used in conjunction with
-;;; the haskell-mode of Graeme E Moss and Tommy Thorn
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; haskell-indent-mode
+(defvar haskell-indent-mode nil
+ "Indicates if the semi-intelligent Haskell indentation mode is in effect
+in the current buffer.")
+(make-variable-buffer-local 'haskell-indent-mode)
+
(defun turn-on-haskell-indent ()
"Turn on ``intelligent'' haskell indentation mode."
(interactive)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'haskell-indent-cycle)
-; Removed: remapping DEL seems a bit naughty --SDM
-; (local-set-key "\177" 'backward-delete-char-untabify)
- (local-set-key "\t" 'haskell-indent-cycle)
- (local-set-key "\C-c=" 'haskell-indent-insert-equal)
- (local-set-key "\C-c|" 'haskell-indent-insert-guard)
- (local-set-key "\C-co" 'haskell-indent-insert-otherwise)
- (local-set-key "\C-cw" 'haskell-indent-insert-where)
- (local-set-key "\C-c." 'haskell-indent-align-guards-and-rhs)
- (local-set-key "\C-c>" 'haskell-indent-put-region-in-literate)
+ (set (make-local-variable 'indent-line-function) 'haskell-indent-cycle)
+ ;; Removed: remapping DEL seems a bit naughty --SDM
+ ;; (local-set-key "\177" 'backward-delete-char-untabify)
+ ;; The binding to TAB is already handled by indent-line-function. --Stef
+ ;; (local-set-key "\t" 'haskell-indent-cycle)
+ (local-set-key [?\C-c ?\C-=] 'haskell-indent-insert-equal)
+ (local-set-key [?\C-c ?\C-|] 'haskell-indent-insert-guard)
+ (local-set-key [?\C-c ?\C-o] 'haskell-indent-insert-otherwise)
+ (local-set-key [?\C-c ?\C-w] 'haskell-indent-insert-where)
+ (local-set-key [?\C-c ?\C-.] 'haskell-indent-align-guards-and-rhs)
+ (local-set-key [?\C-c ?\C->] 'haskell-indent-put-region-in-literate)
(setq haskell-indent-mode t)
- (run-hooks 'haskell-indent-hook)
- )
+ (run-hooks 'haskell-indent-hook))
(defun turn-off-haskell-indent ()
"Turn off ``intelligent'' haskell indentation mode that deals with
the layout rule of Haskell."
(interactive)
- (setq indent-line-function 'indent-to-left-margin)
- (local-unset-key "\t")
- (local-unset-key "\177")
- (local-unset-key "\C-c=")
- (local-unset-key "\C-c|")
- (local-unset-key "\C-co")
- (local-unset-key "\C-cw")
- (local-unset-key "\C-c.")
- (local-unset-key "\C-c>")
- (setq haskell-indent-mode nil)
- )
-
-(defvar haskell-indent-mode nil
- "Indicates if the semi-intelligent Haskell indentation mode is in effect
-in the current buffer.")
-(make-variable-buffer-local 'haskell-indent-mode)
+ (kill-local-variable 'indent-line-function)
+ ;; (local-unset-key "\t")
+ ;; (local-unset-key "\177")
+ (local-unset-key [?\C-c ?\C-=])
+ (local-unset-key [?\C-c ?\C-|])
+ (local-unset-key [?\C-c ?\C-o])
+ (local-unset-key [?\C-c ?\C-w])
+ (local-unset-key [?\C-c ?\C-.])
+ (local-unset-key [?\C-c ?\C->])
+ (setq haskell-indent-mode nil))
;; Put this minor mode on the global minor-mode-alist.
(or (assq 'haskell-indent-mode (default-value 'minor-mode-alist))
@@ -1317,10 +1439,11 @@
(append (default-value 'minor-mode-alist)
'((haskell-indent-mode " Ind")))))
+;;;###autoload
(defun haskell-indent-mode (&optional arg)
"``intelligent'' Haskell indentation mode that deals with
the layout rule of Haskell. \\[haskell-indent-cycle] starts the cycle
-which proposes new possibilities as long as the TAB key is pressed.
+which proposes new possibilities as long as the TAB key is pressed.
Any other key or mouse click terminates the cycle and is interpreted
except for RET which merely exits the cycle.
Other special keys are:
@@ -1353,80 +1476,53 @@
(turn-on-haskell-indent)
(turn-off-haskell-indent)))
-(provide 'haskell-indent)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Haskell-stand-alone- indentation mode (vanilla version of the Hugs-mode)
-;;; in the case where only Haskell indentation is used without the hugs-mode
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Haskell stand-alone indentation mode (vanilla version of the Hugs-mode)
-(defvar hugs-syntax-table
- (let ((table (copy-syntax-table)))
- (modify-syntax-entry ?_ "w " table)
- (modify-syntax-entry ?` "w " table)
- (modify-syntax-entry ?\' "w " table)
- (modify-syntax-entry ?\( "()" table)
- (modify-syntax-entry ?\) ")(" table)
- (modify-syntax-entry ?\[ "(]" table)
- (modify-syntax-entry ?\] ")[" table)
- (modify-syntax-entry ?\" "\"" table)
- (modify-syntax-entry ?\\ "\\" table)
-
- (if haskell-running-xemacs
+(defvar haskell-indent-stand-alone-mode-syntax-table
+ (let ((st (copy-syntax-table)))
+ (modify-syntax-entry ?_ "w " st)
+ (modify-syntax-entry ?` "w " st)
+ (modify-syntax-entry ?\' "w " st)
+ (modify-syntax-entry ?\( "()" st)
+ (modify-syntax-entry ?\) ")(" st)
+ (modify-syntax-entry ?\[ "(]" st)
+ (modify-syntax-entry ?\] ")[" st)
+ (modify-syntax-entry ?\" "\"" st)
+ (modify-syntax-entry ?\\ "\\" st)
+
+ (if (featurep 'xemacs)
;; XEmacs specific syntax-table.
(progn
- (modify-syntax-entry ?- ". 2356" table) ; -- starts a comment.
- (modify-syntax-entry ?\n "> b " table) ; \n ends a comment.
- (modify-syntax-entry ?{ ". 1 " table) ; {- starts a nested comment.
- (modify-syntax-entry ?} ". 4 " table) ; -} ends a nested comment.
- )
+ (modify-syntax-entry ?- ". 2356" st) ; -- starts a comment.
+ (modify-syntax-entry ?\n "> b " st) ; \n ends a comment.
+ (modify-syntax-entry ?{ ". 1 " st) ; {- starts a nested comment.
+ (modify-syntax-entry ?} ". 4 " st)) ; -} ends a nested comment.
;; Emacs specific syntax-table.
- (modify-syntax-entry ?{ "(}1 " table)
- (modify-syntax-entry ?} "){4 " table)
- (modify-syntax-entry ?- "_ 23" table)
- ;; No alternative comment-style because they don't share the same
- ;; first character.
- )
- table)
- "Syntax table in use in `hugs-mode'")
-
-(defvar hugs-mode-map (make-sparse-keymap)
- "Keymap used in `hugs-mode'.")
+ ;; Actually the `b' is ignored, so it only works correctly in Emacs-21
+ ;; where the `n' is understood.
+ (modify-syntax-entry ?{ "(}1nb" st)
+ (modify-syntax-entry ?} "){4nb" st)
+ (modify-syntax-entry ?- "_ 123" st)
+ (modify-syntax-entry ?\n ">" st))
+ st)
+ "Syntax table in use in `haskell-indent-stand-alone-mode'.")
-(defun haskell-stand-alone-indent-mode ()
+(defalias 'haskell-stand-alone-indent-mode 'haskell-indent-stand-alone-mode)
+(define-derived-mode haskell-indent-stand-alone-mode fundamental-mode
+ "Haskell-Indent"
"Major mode for indenting Haskell source files.
COMMANDS
-\\{hugs-mode-map}\
+\\{haskell-indent-stand-alone-mode-map}\
TAB indents for Haskell code. Delete converts tabs to spaces as it moves back.
Variables controlling indentation/edit style:
`haskell-indent-offset' (default 4)
- Indentation of Haskell statements with respect to containing block.
-
-See also the user variables `hugs-type-keywords' and `hugs-start-keywords'
-
-Entry to this mode calls the value of `hugs-mode-hook' if that value
-is non-nil."
- (interactive)
- ;; Set up local variables.
- (kill-all-local-variables)
- (make-local-variable 'comment-start)
- (make-local-variable 'comment-start-skip)
- (make-local-variable 'comment-end)
- (make-local-variable 'indent-line-function)
+ Indentation of Haskell statements with respect to containing block."
+ (haskell-indent-mode 1))
- (set-syntax-table hugs-syntax-table)
- (setq major-mode 'haskell-indent-mode
- mode-name "Haskell-Indent"
- comment-start "{-"
- comment-start-skip "{-[^a-zA-Z0-9]*"
- ;; comment-end must be set because it may hold a wrong value if
- ;; this buffer had been in another mode before.
- comment-end ""
- indent-line-function 'haskell-indent-line)
- (use-local-map hugs-mode-map)
+(provide 'haskell-indent)
- (run-hooks 'hugs-mode-hook)
-)
+;;; haskell-indent.el ends here
Index: xemacs-packages/haskell-mode/haskell-mode.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-mode.el,v
retrieving revision 1.6
diff -d -u -r1.6 haskell-mode.el
--- xemacs-packages/haskell-mode/haskell-mode.el 2004/06/16 15:16:49 1.6
+++ xemacs-packages/haskell-mode/haskell-mode.el 2006/03/15 04:57:25
@@ -1,7 +1,7 @@
;;; haskell-mode.el --- A Haskell editing mode -*-coding: iso-8859-1;-*-
+;; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc
;; Copyright (C) 1992, 1997-1998 Simon Marlow, Graeme E Moss, and Tommy Thorn
-;; Copyright (C) 2003 Free Software Foundation, Inc
;; Authors: 1992 Simon Marlow
;; 1997-1998 Graeme E Moss <gem(a)cs.york.ac.uk> and
@@ -9,7 +9,7 @@
;; 2001-2002 Reuben Thomas (>=v1.4)
;; 2003 Dave Love <fx(a)gnu.org>
;; Keywords: faces files Haskell
-;; Version: 1.43
+;; Version: v2_1
;; URL:
http://www.haskell.org/haskell-mode/
;;; This file is not part of GNU Emacs.
@@ -52,11 +52,11 @@
;; `haskell-simple-indent', Graeme E Moss and Heribert Schuetz
;; Simple indentation.
;;
-;; `haskell-hugs', Guy Lapalme
-;; Interaction with Hugs interpreter.
-;;
-;; `haskell-ghci', Chris Web
-;; Interaction with GHCi interpreter.
+;; `inf-haskell'
+;; Interaction with an inferior Haskell process.
+;; It replaces the previous two modules:
+;; `haskell-hugs', Guy Lapalme
+;; `haskell-ghci', Chris Web
;;
;;
;; This mode supports full Haskell 1.4 including literate scripts.
@@ -86,12 +86,10 @@
;; To turn any of the supported modules on for all buffers, add the
;; appropriate line(s) to .emacs:
;;
-;; (add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
;; (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
-;; (add-hook 'haskell-mode-hook 'turn-on-haskell-hugs)
;;
;; Make sure the module files are also on the load-path. Note that
;; the two indentation modules are mutually exclusive: Use only one.
@@ -117,7 +115,7 @@
;; author to contact via email. For general problems or suggestions,
;; consult the list below, then email gem(a)cs.york.ac.uk and
;; thorn(a)irisa.fr quoting the version of the mode you are using, the
-;; version of emacs you are using, and a small example of the problem
+;; version of Emacs you are using, and a small example of the problem
;; or suggestion.
;;
;; Version 1.43:
@@ -194,10 +192,14 @@
;; . Support for GreenCard?
;;
-;;; All functions/variables start with `(literate-)haskell-'.
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+;; All functions/variables start with `(literate-)haskell-'.
;; Version of mode.
-(defconst haskell-version "1.43"
+(defconst haskell-version "v2_1"
"`haskell-mode' version number.")
(defun haskell-version ()
"Echo the current version of `haskell-mode' in the minibuffer."
@@ -209,15 +211,7 @@
:group 'languages
:prefix "haskell-")
-;; Haskell-like function for creating [from..to].
-(defun haskell-enum-from-to (from to)
- (if (> from to)
- ()
- (cons from (haskell-enum-from-to (1+ from) to))))
-
;; Set up autoloads for the modules we supply
-(autoload 'turn-on-haskell-font-lock "haskell-font-lock"
- "Turn on Haskell font locking." t)
(autoload 'turn-on-haskell-decl-scan "haskell-decl-scan"
"Turn on Haskell declaration scanning." t)
(autoload 'turn-on-haskell-doc-mode "haskell-doc"
@@ -226,20 +220,33 @@
"Turn on Haskell indentation." t)
(autoload 'turn-on-haskell-simple-indent "haskell-simple-indent"
"Turn on simple Haskell indentation." t)
-(autoload 'turn-on-haskell-hugs "haskell-hugs"
- "Turn on interaction with a Hugs interpreter." t)
-(autoload 'turn-on-haskell-ghci "haskell-ghci"
- "Turn on interaction with a GHCi interpreter." t)
-;; Are we running FSF Emacs or XEmacs?
-(defvar haskell-running-xemacs
- (string-match "Lucid\\|XEmacs" emacs-version)
- "non-nil if we are running XEmacs, nil otherwise.")
+;; Functionality provided in other files.
+(autoload 'haskell-ds-create-imenu-index "haskell-decl-scan")
+(autoload 'haskell-font-lock-choose-keywords "haskell-font-lock")
+(autoload 'haskell-doc-current-info "haskell-doc")
+
+;; Obsolete functions.
+(defun turn-on-haskell-font-lock ()
+ (interactive)
+ (turn-on-font-lock)
+ (message "turn-on-haskell-font-lock is obsolete. Use turn-on-font-lock
instead."))
+(defun turn-on-haskell-hugs ()
+ (interactive)
+ (message "haskell-hugs is obsolete.")
+ (load "haskell-hugs")
+ (turn-on-haskell-hugs))
+(defun turn-on-haskell-ghci ()
+ (interactive)
+ (message "haskell-ghci is obsolete.")
+ (load "haskell-ghci")
+ (turn-on-haskell-ghci))
+
;; Are we looking at a literate script?
(defvar haskell-literate nil
"*If not nil, the current buffer contains a literate Haskell script.
-Possible values are: 'bird and 'latex, for Bird-style and LaTeX-style
+Possible values are: `bird' and `latex', for Bird-style and LaTeX-style
literate scripts respectively. Set by `haskell-mode' and
`literate-haskell-mode'. For an ambiguous literate buffer -- ie. does
not contain either \"\\begin{code}\" or \"\\end{code}\" on a line on
@@ -252,17 +259,26 @@
(defcustom haskell-literate-default 'bird
"*Default value for `haskell-literate'.
Used if the style of a literate buffer is ambiguous. This variable should
-be set to the preferred literate style. For example, place within
-.emacs:
-
- (setq haskell-literate-default 'latex)"
-:type '(choice bird latex nil)
-:group 'haskell)
+be set to the preferred literate style."
+:type '(choice (const bird) (const latex) (const nil)))
;; Mode maps.
-(defvar haskell-mode-map (let ((keymap (make-sparse-keymap)))
- (define-key keymap "\C-c\C-c" 'comment-region)
- keymap)
+(defvar haskell-mode-map
+ (let ((map (make-sparse-keymap)))
+ ;; Bindings for the inferior haskell process:
+ ;; (define-key map [?\M-C-x] 'inferior-haskell-send-defun)
+ ;; (define-key map [?\C-x ?\C-e] 'inferior-haskell-send-last-sexp)
+ ;; (define-key map [?\C-c ?\C-r] 'inferior-haskell-send-region)
+ (define-key map [?\C-c ?\C-z] 'switch-to-haskell)
+ (define-key map [?\C-c ?\C-l] 'inferior-haskell-load-file)
+ ;; Non standard in other inferior-modes, but traditional in haskell.
+ (define-key map [?\C-c ?\C-r] 'inferior-haskell-reload-file)
+ (define-key map [?\C-c ?\C-b] 'switch-to-haskell)
+ ;; (define-key map [?\C-c ?\C-s] 'inferior-haskell-start-process)
+
+ ;; That's what M-; is for.
+ ;; (define-key map "\C-c\C-c" 'comment-region)
+ map)
"Keymap used in Haskell mode.")
;; Syntax table.
@@ -281,20 +297,37 @@
(cond ((featurep 'xemacs)
;; I don't know whether this is equivalent to the below
;; (modulo nesting). -- fx
- (modify-syntax-entry ?{ "(}1" table)
- (modify-syntax-entry ?} "){4" table)
- (modify-syntax-entry ?- "_ 23" table))
+ (modify-syntax-entry ?{ "(}5" table)
+ (modify-syntax-entry ?} "){8" table)
+ (modify-syntax-entry ?- "_ 1267" table))
(t
;; The following get comment syntax right, similarly to C++
- ;; (but the `b' style needs to be the other way round). In
- ;; Emacs 21, the `n' indicates that they nest. Proper
- ;; treatment of comments requires syntactic font-lock
- ;; support.
+ ;; In Emacs 21, the `n' indicates that they nest.
+ ;; The `b' annotation is actually ignored because it's only
+ ;; meaningful on the second char of a comment-starter, so
+ ;; on Emacs 20 and before we get wrong results. --Stef
(modify-syntax-entry ?\{ "(}1nb" table)
(modify-syntax-entry ?\} "){4nb" table)
- (modify-syntax-entry ?- "_ 123" table)
- (modify-syntax-entry ?\n ">" table)))
+ (modify-syntax-entry ?- "_ 123" table)))
+ (modify-syntax-entry ?\n ">" table)
+ (let (i lim)
+ (map-char-table
+ (lambda (k v)
+ (when (equal v '(1))
+ ;; The current Emacs 22 codebase can pass either a char
+ ;; or a char range.
+ (if (consp k)
+ (setq i (car k)
+ lim (cdr k))
+ (setq i k
+ lim k))
+ (while (<= i lim)
+ (when (> i 127)
+ (modify-syntax-entry i "_" table))
+ (setq i (1+ i)))))
+ (standard-syntax-table)))
+
(modify-syntax-entry ?\` "$`" table)
(modify-syntax-entry ?\\ "\\" table)
(mapcar (lambda (x)
@@ -305,40 +338,30 @@
;; Non-ASCII syntax should be OK, at least in Emacs.
(mapcar (lambda (x)
(modify-syntax-entry x "_" table))
- (concat (haskell-enum-from-to ?\241 ?\277)
- "\327\367"))
+ (concat "bäŦ?ɪ???????????
+ "?"))
(mapcar (lambda (x)
(modify-syntax-entry x "w" table))
- (concat (haskell-enum-from-to ?\300 ?\326)
- (haskell-enum-from-to ?\330 ?\337)
- (haskell-enum-from-to ?\340 ?\366)
- (haskell-enum-from-to ?\370 ?\377))))
+ (concat "?ą????ΏБ???
+ "????"
+ "?㤥槨骫???? "?
table)
"Syntax table used in Haskell mode.")
;; Various mode variables.
-(defun haskell-vars ()
- (kill-all-local-variables)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'comment-start)
- (setq comment-start "-- ")
- (make-local-variable 'comment-padding)
- (setq comment-padding 0)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "[-{]- *")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'haskell-comment-indent)
- (make-local-variable 'comment-end)
- (setq comment-end ""))
+(defcustom haskell-mode-hook nil
+ "Hook run after entering Haskell mode."
+:type 'hook
+:options '(turn-on-haskell-indent turn-on-font-lock turn-on-eldoc-mode
+ imenu-add-menubar-index))
+
+(defvar eldoc-print-current-symbol-info-function)
+
;; The main mode functions
;;;###autoload
-(defun haskell-mode ()
+(define-derived-mode haskell-mode fundamental-mode "Haskell"
"Major mode for editing Haskell programs. Last adapted for Haskell 1.4.
Blank lines separate paragraphs, comments start with `-- '.
@@ -353,9 +376,6 @@
Modules can hook in via `haskell-mode-hook'. The following modules
are supported with an `autoload' command:
- `haskell-font-lock', Graeme E Moss and Tommy Thorn
- Fontifies standard Haskell keywords, symbols, functions, etc.
-
`haskell-decl-scan', Graeme E Moss
Scans top-level declarations, and places them in a menu.
@@ -368,9 +388,6 @@
`haskell-simple-indent', Graeme E Moss and Heribert Schuetz
Simple indentation.
- `haskell-hugs', Guy Lapalme
- Interaction with Hugs interpreter.
-
Module X is activated using the command `turn-on-X'. For example,
`haskell-font-lock' is activated using `turn-on-haskell-font-lock'.
For more information on a module, see the help for its `turn-on-X'
@@ -380,53 +397,54 @@
Use `haskell-version' to find out what version this is.
Invokes `haskell-mode-hook' if not nil."
-
- (interactive)
- (haskell-mode-generic nil))
+ (set (make-local-variable 'paragraph-start) (concat "^$\\|"
page-delimiter))
+ (set (make-local-variable 'paragraph-separate) paragraph-start)
+ (set (make-local-variable 'comment-start) "-- ")
+ (set (make-local-variable 'comment-padding) 0)
+ (set (make-local-variable 'comment-start-skip) "[-{]-[ \t]*")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'comment-end-skip) "[ \t]*\\(-}\\|\\s>\\)")
+ (set (make-local-variable 'parse-sexp-ignore-comments) t)
+ ;; Set things up for eldoc-mode.
+ (set (make-local-variable 'eldoc-print-current-symbol-info-function)
+ 'haskell-doc-current-info)
+ ;; Set things up for imenu.
+ (set (make-local-variable 'imenu-create-index-function)
+ 'haskell-ds-create-imenu-index)
+ ;; Set things up for font-lock.
+ (set (make-local-variable 'font-lock-defaults)
+ '(haskell-font-lock-choose-keywords
+ nil nil ((?\' . "w") (?_ . "w")) nil
+ (font-lock-syntactic-keywords
+ . haskell-font-lock-choose-syntactic-keywords)
+ (font-lock-syntactic-face-function
+ . haskell-syntactic-face-function)
+ ;; Get help from font-lock-syntactic-keywords.
+ (parse-sexp-lookup-properties . t)))
+ ;; Haskell's layout rules mean that TABs have to be handled with extra care.
+ ;; The safer option is to avoid TABs. The second best is to make sure
+ ;; TABs stops are 8 chars apart, as mandated by the Haskell Report. --Stef
+ (set (make-local-variable 'indent-tabs-mode) nil)
+ (set (make-local-variable 'tab-width) 8)
+ (setq haskell-literate nil))
;;;###autoload
-(defun literate-haskell-mode ()
+(define-derived-mode literate-haskell-mode haskell-mode "LitHaskell"
"As `haskell-mode' but for literate scripts."
-
- (interactive)
- (haskell-mode-generic
- (save-excursion
- (goto-char (point-min))
- (if (re-search-forward "^\\\\begin{code}$\\|^\\\\end{code}$"
- (point-max) t)
- 'latex
- (if (re-search-forward "^>" (point-max) t)
- 'bird
- haskell-literate-default)))))
-
-(defun haskell-mode-generic (literate)
- "Common part of `haskell-mode' and `literate-haskell-mode'.
-Former calls this with LITERATE nil. Latter calls with LITERATE `bird' or
-`latex'."
-
- (haskell-vars)
- (setq major-mode 'haskell-mode)
- (setq mode-name "Haskell")
- (setq haskell-literate literate)
- (use-local-map haskell-mode-map)
- (set-syntax-table haskell-mode-syntax-table)
- (run-hooks 'haskell-mode-hook))
-
-;; Find the indentation level for a comment.
-(defun haskell-comment-indent ()
- (skip-chars-backward " \t")
- ;; if the line is blank, put the comment at the beginning,
- ;; else at comment-column
- (if (bolp) 0 (max (1+ (current-column)) comment-column)))
+ (setq haskell-literate
+ (save-excursion
+ (goto-char (point-min))
+ (cond
+ ((re-search-forward "^\\\\\\(begin\\|end\\){code}$" nil t)
'latex)
+ ((re-search-forward "^>" nil t) 'bird)
+ (t haskell-literate-default)))))
-;;;###autoload(add-to-list 'auto-mode-alist '("\\.\\(?:[gh]s\\|hi\\)$"
. haskell-mode))
-;;;###autoload(add-to-list 'auto-mode-alist '("\\.l[gh]s$" .
literate-haskell-mode))
-;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
-;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
+;;;###autoload(add-to-list 'auto-mode-alist
'("\\.\\(?:[gh]s\\|hi\\)\\'" . haskell-mode))
+;;;###autoload(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" .
literate-haskell-mode))
;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
-;;; Provide ourselves:
+;; Provide ourselves:
(provide 'haskell-mode)
Index: xemacs-packages/haskell-mode/haskell-simple-indent.el
===================================================================
RCS file:
/pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/haskell-simple-indent.el,v
retrieving revision 1.1
diff -d -u -r1.1 haskell-simple-indent.el
--- xemacs-packages/haskell-mode/haskell-simple-indent.el 2002/04/24 09:45:13 1.1
+++ xemacs-packages/haskell-mode/haskell-simple-indent.el 2006/03/15 04:57:25
@@ -1,6 +1,6 @@
;;; haskell-simple-indent.el --- Simple indentation module for Haskell Mode
-;; Copyright 1998 Heribert Schuetz, Graeme E Moss
+;; Copyright (C) 1998 Heribert Schuetz, Graeme E Moss
;; Authors:
;; 1998 Heribert Schuetz <Heribert.Schuetz(a)informatik.uni-muenchen.de> and
@@ -9,7 +9,7 @@
;; Version: 1.0
;; URL:
http://www.cs.york.ac.uk/~gem/haskell-mode/simple-indent.html
-;;; This file is not part of GNU Emacs.
+;; This file is not part of GNU Emacs.
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@
;;
;; If you have any problems or suggestions, after consulting the list
;; below, email gem(a)cs.york.ac.uk quoting the version of you are
-;; using, the version of emacs you are using, and a small example of
+;; using, the version of Emacs you are using, and a small example of
;; the problem or suggestion.
;;
;; Version 1.0:
@@ -63,11 +63,13 @@
;;
;; (None so far.)
-;;; All functions/variables start with
-;;; `(turn-(on/off)-)haskell-simple-indent'.
+;;; Code:
+
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-simple-indent'.
;; Version.
-(defconst haskell-simple-indent-version "1.1"
+(defconst haskell-simple-indent-version "1.2"
"`haskell-simple-indent' version number.")
(defun haskell-simple-indent-version ()
"Echo the current version of `haskell-simple-indent' in the minibuffer."
@@ -79,83 +81,75 @@
(defun haskell-simple-indent ()
"Space out to under next visible indent point.
Indent points are positions of non-whitespace following whitespace in
-lines preceeding point. A position is visible if it is to the left of
+lines preceeding point. A position is visible if it is to the left of
the first non-whitespace of every nonblank line between the position and
-the current line. If there is no visible indent point beyond the current
+the current line. If there is no visible indent point beyond the current
column, `tab-to-tab-stop' is done instead."
(interactive)
- (let ((start-column (current-column))
- (invisible-from nil) ; `nil' means infinity here
- indent )
- (catch 'haskell-simple-indent-break
- (save-excursion
- (while (progn (beginning-of-line)
- (> (point) (point-min)))
- (forward-line -1)
- (if (not (looking-at "[ \t]*\n"))
- (let ((this-indentation (current-indentation)))
- (if (or (not invisible-from)
- (< this-indentation invisible-from))
- (if (> this-indentation start-column)
- (setq invisible-from this-indentation)
- (let ((end (save-excursion (forward-line 1) (point))))
- (move-to-column start-column)
- ;; Is start-column inside a tab on this line?
- (if (> (current-column) start-column)
- (backward-char 1))
- (or (looking-at "[ \t]")
- (skip-chars-forward "^ \t" end))
- (skip-chars-forward " \t" end)
- (let ((col (current-column)))
- (setq indent
- (if (or (= (point) end)
- (and invisible-from
- (> col invisible-from)))
- invisible-from
- col ) ) )
- (throw 'haskell-simple-indent-break nil)))))))))
+ (let* ((start-column (current-column))
+ (invisible-from nil) ; `nil' means infinity here
+ (indent
+ (catch 'haskell-simple-indent-break
+ (save-excursion
+ (while (progn (beginning-of-line)
+ (not (bobp)))
+ (forward-line -1)
+ (if (not (looking-at "[ \t]*\n"))
+ (let ((this-indentation (current-indentation)))
+ (if (or (not invisible-from)
+ (< this-indentation invisible-from))
+ (if (> this-indentation start-column)
+ (setq invisible-from this-indentation)
+ (let ((end (line-beginning-position 2)))
+ (move-to-column start-column)
+ ;; Is start-column inside a tab on this line?
+ (if (> (current-column) start-column)
+ (backward-char 1))
+ (or (looking-at "[ \t]")
+ (skip-chars-forward "^ \t" end))
+ (skip-chars-forward " \t" end)
+ (let ((col (current-column)))
+ (throw 'haskell-simple-indent-break
+ (if (or (= (point) end)
+ (and invisible-from
+ (> col invisible-from)))
+ invisible-from
+ col)))))))))))))
(if indent
(let ((opoint (point-marker)))
- (delete-region (point) (progn (skip-chars-backward " \t") (point)))
- (indent-to indent 0)
+ (indent-line-to indent)
(if (> opoint (point))
(goto-char opoint))
- (move-marker opoint nil))
- (tab-to-tab-stop)) ) )
+ (set-marker opoint nil))
+ (tab-to-tab-stop))))
+
+(defvar haskell-simple-indent-old)
;; The main functions.
(defun turn-on-haskell-simple-indent ()
- "Sets `indent-line-function' to `haskell-simple-indent'---a simple
-indentation function. Ensures TAB is bound to
-`indent-for-tab-command', and LFD to `newline-and-indent'. TAB will
-now move the cursor to the next indent point in the previous nonblank
-line. An indent point is a non-whitespace character following
+ "Set `indent-line-function' to a simple indentation function.
+TAB will now move the cursor to the next indent point in the previous
+nonblank line. An indent point is a non-whitespace character following
whitespace.
-Invokes `haskell-simple-indent-hook' if not nil.
+Runs `haskell-simple-indent-hook'.
Use `haskell-simple-indent-version' to find out what version this is."
-
(interactive)
- (make-local-variable 'haskell-simple-indent-old)
- (setq haskell-simple-indent-old indent-line-function)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'haskell-simple-indent)
- (local-set-key "\t" 'indent-for-tab-command)
- (local-set-key "\n" 'newline-and-indent)
+ (set (make-local-variable 'haskell-simple-indent-old) indent-line-function)
+ (set (make-local-variable 'indent-line-function) 'haskell-simple-indent)
(run-hooks 'haskell-simple-indent-hook))
(defun turn-off-haskell-simple-indent ()
- "Returns `indent-line-function' to original value, before
-`turn-on-haskell-simple-indent' was called. Leaves TAB and LFD bound
-to `indent-for-tab-command' and `newline-and-indent' respectively."
-
+ "Return `indent-line-function' to original value.
+I.e. the value before `turn-on-haskell-simple-indent' was called."
(interactive)
- (if (boundp 'haskell-simple-indent-old)
- (setq indent-line-function haskell-simple-indent-old)))
+ (when (local-variable-p 'haskell-simple-indent-old)
+ (setq indent-line-function haskell-simple-indent-old)
+ (kill-local-variable 'haskell-simple-indent-old)))
-;;; Provide ourselves:
+;; Provide ourselves:
(provide 'haskell-simple-indent)
-;;; haskell-simple-indent ends here.
+;;; haskell-simple-indent.el ends here
Index: xemacs-packages/haskell-mode/indent.hs
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/indent.hs,v
retrieving revision 1.1
diff -d -u -r1.1 indent.hs
--- xemacs-packages/haskell-mode/indent.hs 2002/04/24 09:45:13 1.1
+++ xemacs-packages/haskell-mode/indent.hs 2006/03/15 04:57:25
@@ -1,3 +1,10 @@
+-------------------------------------------------------------------------
+-- Comments with allcaps `FIXME' indicate places where the indentation --
+-- fails to find the correct indentation, whereas comments with --
+-- lowercase `fixme' indicate places where impossible indentations --
+-- are uselessly proposed. --
+-------------------------------------------------------------------------
+
-- compute the list of binary digits corresponding to an integer
-- Note: the least significant bit is the first element of the list
bdigits :: Int -> [Int]
@@ -12,7 +19,103 @@
bvalue :: [Int]->Int
bvalue [] = error "bvalue of []"
bvalue s = bval 1 s
- where
- bval e [] = 0
- bval e (b:bs) | b==0 || b==1 = b*e + bval (2*e) bs
- | otherwise = error "illegal digit"
+ where
+ bval e [] = 0
+ bval e [] = 0 -- fixme: can't align with `where'.
+ bval e (b:bs) | b==0 || b=="dd of " = b*e + bval (2*e) bs
+ | otherwise = error "ill digit" -- Spurious 3rd step.
+ foo
+
+-- fixme: tab on the line above should insert `bvalue' at some point.
+
+{- text
+ indentation
+ inside comments
+ -}
+toto a = ( hello
+ , there -- indentation of leading , and ;
+ -- indentation of this comment.
+ , my friends )
+
+lili x = do let ofs x = 1
+ print x
+
+titi b =
+ let -- fixme: can't indent at column 0
+ x = let toto = 1
+ tata = 2 -- fixme: can't indent lower than `toto'.
+ in
+ toto in
+ do expr1
+ {- text
+ - indentation
+ - inside comments
+ -}
+ let foo s = let fro = 1
+ fri = 2 -- fixme: can't indent lower than `fro'.
+ in
+ hello
+ foo2 = bar2 -- fixme: can't align with arg `s' in foo.
+ foo1 = bar2 -- fixme: Can't be column 0.
+ expr2
+
+tata c =
+ let bar = case foo -- fixme: can't be col 0.
+ of 1 -> blabla
+ 2 -> blibli -- fixme: only one possible indentation here.
+ bar = case foo of
+ _ -> blabla
+ bar' = case foo
+ of _ -> blabla
+ toto -> plulu
+
+turlu d = if test
+ then
+ ifturl
+ else
+ adfaf
+
+turlu d = if test then
+ ifturl
+ else
+ sg
+
+turly fg = toto
+ where
+ hello = 2
+
+
+-- test from John Goerzen
+
+x myVariableThing = case myVariablething of
+ Just z -> z
+ Nothing -> 0 -- fixme: "spurious" additional indents.
+
+foo = let x = 1 in toto
+ titi -- FIXME
+
+foo = let foo x y = toto
+ where
+ toto = 2
+
+instance Show Toto where
+ foo x 4 = 50
+
+data Toto = Foo
+ | Bar
+ deriving (Show) -- FIXME
+
+foo = let toto x = do let bar = 2
+ return 1
+ in 3
+
+ eval env (Llambda x e) = -- FIXME: sole indentation is self???
+ Vfun (\v -> eval (\y -> if (x == y) then v else env y) -- FIXME
+ e) -- FIXME
+
+foo = case findprop attr props of
+ Just x -> x
+
+data T = T { granularity :: (Int, Int, Int, Int) -- FIXME: self indentation?
+ , items :: Map (Int, Int, Int, Int) [Item] }
+
Index: xemacs-packages/haskell-mode/index.html
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/index.html,v
retrieving revision 1.4
diff -d -u -r1.4 index.html
--- xemacs-packages/haskell-mode/index.html 2004/06/16 15:16:49 1.4
+++ xemacs-packages/haskell-mode/index.html 2006/03/15 04:57:25
@@ -1,73 +1,75 @@
-<HTML><HEAD>
-
-<TITLE>Haskell Mode for Emacs</TITLE>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
-</HEAD><BODY>
+<title>Haskell Mode for Emacs</title>
-<H1>Haskell Mode for Emacs</H1>
+</head><body>
-<P>The Haskell mode itself is very basic, but provides a base on which to
-build modules. The currently supported modules are:</P>
+<h1>Haskell Mode for Emacs</h1>
-<UL>
+<p>The Haskell mode itself is very basic, but provides a base on which to
+ build modules. The currently supported modules are:</p>
-<LI>Font Locking: Colours keywords, comments, strings, etc.
+<ul>
+ <li>Font Locking: Colours keywords, comments, strings, etc.
-<LI>Declaration Scanning: Scans declarations and places them in a
-menu. <em>Seems to hang on some files.</em>
+ <li>Declaration Scanning: Scans declarations and places them in a
+ menu. <em>Seems to hang on some files.</em>
-<LI>Documentation: Echoes types of functions or syntax of keywords
-when the cursor is idle. <em>Not up-to-date for Haskell-98.</em>
+ <li>Documentation: Echoes types of functions or syntax of keywords
+ when the cursor is idle. <em>Not up-to-date for Haskell-98.</em>
-<LI><A
-HREF="http://www.iro.umontreal.ca/~lapalme/layout/">Indentation</A>:
-Provides semi-automatic intelligent indentation.
+ <li><a
HREF="http://www.iro.umontreal.ca/~lapalme/layout/">Indentation</a>:
+ Provides semi-automatic intelligent indentation.
-<LI>Simple Indentation: Provides simple indentation.
+ <li>Simple Indentation: Provides simple indentation.
-<LI><A
-HREF="http://www.iro.umontreal.ca/~lapalme/Hugs-interaction.html">Hugs
-Interaction</A>: Allows interaction with the Hugs interpreter.
+ <li>Interaction with an inferior Haskell interpreter. This module
+ supersedes the previous two modules:
+ <ul>
+ <li><a
HREF="http://www.iro.umontreal.ca/~lapalme/Hugs-interaction.html">
+ Hugs Interaction</a>: Allows interaction with the Hugs interpreter.
-<LI><A
-HREF="http://home.arachsys.com/~chris/haskell-ghci.el">GHCi
-Interaction</A>: Allows interaction with the GHCi interpreter.
-</UL>
+ <li><a
HREF="http://home.arachsys.com/~chris/haskell-ghci.el">GHCi
+ Interaction</a>: Allows interaction with the GHCi interpreter.
+ </ul>
+</ul>
-<EM>Work on further modules is encouraged! Please <A
-HREF="mailto:simonmar@microsoft.com">mail</A> if you have an idea, or
a
-module we might hook into.</EM>
+<p><em>Work on further modules is encouraged! Please
+ <a HREF="mailto:monnier@iro.umontreal.ca">mail</a> if you have an
idea, or
+ a module we might hook into.</em></p>
-<P><A HREF="haskell-mode-1.45.tar.gz">The latest versions of the
basic
-mode and the above modules</A>.</P>
+<p><a HREF="haskell-mode-2.1.tar.gz">The latest versions of the
basic mode
+ and the above modules</a>.</p>
-<P>The basic mode was written by Graeme E Moss, Tommy Thorn and Simon
-Marlow. Modules with their own links above are maintained by their
-authors; the rest are looking for a maintainer (please volunteer!). These
-modules support Haskell 98, except where stated, and have been tested on
-GNU Emacs versions 19.34 and 20.7, and XEmacs versions 21.1.14 and 21.4.x.
-Please mail bugs and suggestions to the maintainer of the appropriate
-module. General comments can be mailed to <A
-HREF="mailto:simonmar@microsoft.com">Simon Marlow</a>. When mailing,
quote
-the version of the module or mode you are using, the version of Emacs you
-are using, and a small example of the problem or suggestion. Please check
-the list of known problems (towards the start of each relevant file)
-before doing so.</P>
+<p>The basic mode was written by Graeme E Moss, Tommy Thorn and Simon
+ Marlow. Modules with their own links above are maintained by their
+ authors; the rest are looking for a maintainer (please
+ volunteer!). These modules support Haskell 98, except where stated, and
+ have been tested on GNU Emacs versions 19.34 and 20.7, and XEmacs versions
+ 21.1.14 and 21.4.x. Please mail bugs and suggestions to the maintainer of
+ the appropriate module. General comments can be mailed
+ to <a HREF="mailto:monnier@iro.umontreal.ca">Stefan
+ Monnier</a>. When mailing, quote the version of the module or mode you
+ are using, the version of Emacs you are using, and a small example of the
+ problem or suggestion. Please check the list of known problems (towards
+ the start of each relevant file) before doing so.</p>
-<P><STRONG><A HREF="installation-guide.html">A guide on how
to install
-and customise the mode</A></STRONG>.</P>
+<p><strong><a HREF="installation-guide.html">A guide on how
to install
+and customise the mode</a></strong>.</p>
-<P>To test the mode:</P>
+<p>To test the mode:</p>
-<UL>
+<ul>
+ <li>To test font locking, declaration scanning, and documentation
+ modules, try them on <a HREF="fontlock.hs">the Haskell
+ script</a> used to illustrate these modules in action.
-<LI>To test font locking, declaration scanning, and documentation
-modules, try them on <A HREF="fontlock.hs">the Haskell
-script</A> used to illustrate these modules in action.
+ <li>To test indentation and simple indentation modules, try them
+ on <a HREF="indent.hs">this Haskell script</a>.
-<LI>To test indentation and simple indentation modules, try them on <A
-HREF="indent.hs">this Haskell script</A>.
+</ul>
-</UL>
+</body></html>
-</BODY></HTML>
Index: xemacs-packages/haskell-mode/inf-haskell.el
===================================================================
RCS file: inf-haskell.el
diff -N inf-haskell.el
--- /dev/null Wed Mar 15 05:57:42 2006
+++ inf-haskell.el Wed Mar 15 05:57:25 2006
@@ -0,0 +1,181 @@
+;;; inf-haskell.el --- Interaction with an inferior Haskell process.
+
+;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier(a)iro.umontreal.ca>
+;; Keywords: Haskell
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; The code is made of 2 parts: a major mode for the buffer that holds the
+;; inferior process's session and a minor mode for use in source buffers.
+
+;;; Code:
+
+(require 'comint)
+(require 'shell) ;For directory tracking.
+(require 'compile)
+
+;; Here I depart from the inferior-haskell- prefix.
+;; Not sure if it's a good idea.
+(defcustom haskell-program-name
+ ;; Arbitrarily give preference to hugs over ghci.
+ (or (cond
+ ((not (fboundp 'executable-find)) nil)
+ ((executable-find "hugs") "hugs \"+.\"")
+ ((executable-find "ghci") "ghci"))
+ "hugs \"+.\"")
+ "The name of the command to start the inferior Haskell process.
+The command can include arguments."
+ ;; Custom only supports the :options keyword for a few types, e.g. not
+ ;; for string.
+ ;; :options '("hugs \"+.\"" "ghci")
+:group 'haskell
+:type '(choice string (repeat string)))
+
+(defconst inferior-haskell-error-regexp-alist
+ ;; The format of error messages used by Hugs.
+ '(("^ERROR \"\\(.+?\\)\"\\(:\\| line \\)\\([0-9]+\\) - " 1 3)
+ ;; Format of error messages used by GHCi.
+ ("^\\(.+?\\):\\([0-9]\\):\\( \\|$\\)" 1 3)
+ )
+ "Regexps for error messages generated by inferior Haskell processes.
+The format should be the same as for `compilation-error-regexp-alist'.")
+
+(define-derived-mode inferior-haskell-mode comint-mode "Inf-Haskell"
+ "Major mode for interacting with an inferior Haskell process."
+ (set (make-local-variable 'comint-prompt-regexp)
+ "^\\*?[A-Z][\\._a-zA-Z0-9]*\\( \\*?[A-Z][\\._a-zA-Z0-9]*\\)*> ")
+ (set (make-local-variable 'comint-input-autoexpand) nil)
+
+ ;; Setup directory tracking.
+ (set (make-local-variable 'shell-dirtrackp) t)
+ (set (make-local-variable 'shell-cd-regexp) ":cd")
+ (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil
'local)
+
+ ;; Setup `compile' support so you can just use C-x ` and friends.
+ (set (make-local-variable 'compilation-error-regexp-alist)
+ inferior-haskell-error-regexp-alist)
+ (if (and (not (boundp 'minor-mode-overriding-map-alist))
+ (fboundp 'compilation-shell-minor-mode))
+ ;; If we can't remove compilation-minor-mode bindings, at least try to
+ ;; use compilation-shell-minor-mode, so there are fewer
+ ;; annoying bindings.
+ (compilation-shell-minor-mode 1)
+ ;; Else just use compilation-minor-mode but without its bindings because
+ ;; things like mouse-2 are simply too annoying.
+ (compilation-minor-mode 1)
+ (let ((map (make-sparse-keymap)))
+ (dolist (keys '([menu-bar] [follow-link]))
+ ;; Preserve some of the bindings.
+ (define-key map keys (lookup-key compilation-minor-mode-map keys)))
+ (add-to-list 'minor-mode-overriding-map-alist
+ (cons 'compilation-minor-mode map)))))
+
+(defun inferior-haskell-string-to-strings (string &optional separator)
+ "Split the STRING into a list of strings.
+The SEPARATOR regexp defaults to \"\\s-+\"."
+ (let ((sep (or separator "\\s-+"))
+ (i (string-match "[\"]" string)))
+ (if (null i) (split-string string sep) ; no quoting: easy
+ (append (unless (eq i 0) (split-string (substring string 0 i) sep))
+ (let ((rfs (read-from-string string i)))
+ (cons (car rfs)
+ (inferior-haskell-string-to-strings
+ (substring string (cdr rfs)) sep)))))))
+
+(defun inferior-haskell-command (arg)
+ (inferior-haskell-string-to-strings
+ (if (null arg) haskell-program-name
+ (read-string "Command to run haskell: "))))
+
+(defvar inferior-haskell-buffer nil
+ "The buffer in which the inferior process is running.")
+
+(defun inferior-haskell-start-process (command)
+ "Start an inferior haskell process.
+With universal prefix \\[universal-argument], prompts for a command,
+otherwise uses `haskell-program-name'.
+It runs the hook `inferior-haskell-hook' after starting the process and
+setting up the inferior-haskell buffer."
+ (interactive (list (inferior-haskell-command current-prefix-arg)))
+ (setq inferior-haskell-buffer
+ (apply 'make-comint "haskell" (car command) nil (cdr command)))
+ (with-current-buffer inferior-haskell-buffer
+ (inferior-haskell-mode)
+ (run-hooks 'inferior-haskell-hook)))
+
+(defun inferior-haskell-process (&optional arg)
+ (or (if (buffer-live-p inferior-haskell-buffer)
+ (get-buffer-process inferior-haskell-buffer))
+ (progn
+ (let ((current-prefix-arg arg))
+ (call-interactively 'inferior-haskell-start-process))
+ ;; Try again.
+ (inferior-haskell-process arg))))
+
+;;;###autoload
+(defalias 'run-haskell 'switch-to-haskell)
+;;;###autoload
+(defun switch-to-haskell (&optional arg)
+ "Show the inferior-haskell buffer. Start the process if needed."
+ (interactive "P")
+ (let ((proc (inferior-haskell-process arg)))
+ (pop-to-buffer (process-buffer proc))))
+
+;;;###autoload
+(defun inferior-haskell-load-file (&optional reload)
+ "Pass the current buffer's file to the inferior haskell process."
+ (interactive)
+ (let ((file buffer-file-name)
+ (proc (inferior-haskell-process)))
+ (save-buffer)
+ (with-current-buffer (process-buffer proc)
+ ;; Not sure if it's useful/needed and if it actually works.
+ ;; (unless (equal (file-name-as-directory default-directory)
+ ;; (file-name-directory file))
+ ;; (inferior-haskell-send-string
+ ;; proc (concat ":cd " (file-name-directory file) "\n")))
+ (compilation-forget-errors)
+ (if (boundp 'compilation-parsing-end)
+ (if (markerp compilation-parsing-end)
+ (set-marker compilation-parsing-end (point-max))
+ (setq compilation-parsing-end (point-max))))
+ (inferior-haskell-send-command
+ proc (if reload ":reload" (concat ":load \"" file
"\""))))))
+
+(defun inferior-haskell-send-command (proc str)
+ (setq str (concat str "\n"))
+ (with-current-buffer (process-buffer proc)
+ (while (and
+ (goto-char comint-last-input-end)
+ (not (re-search-forward comint-prompt-regexp nil t))
+ (accept-process-output proc)))
+ (goto-char (process-mark proc))
+ (insert-before-markers str)
+ (move-marker comint-last-input-end (point))
+ (comint-send-string proc str)))
+
+(defun inferior-haskell-reload-file ()
+ "Tell the inferior haskell process to reread the current buffer's file."
+ (interactive)
+ (inferior-haskell-load-file 'reload))
+
+(provide 'inf-haskell)
+
+;;; inf-haskell.el ends here
Index: xemacs-packages/haskell-mode/installation-guide.html
===================================================================
RCS file:
/pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/installation-guide.html,v
retrieving revision 1.4
diff -d -u -r1.4 installation-guide.html
--- xemacs-packages/haskell-mode/installation-guide.html 2004/06/16 15:16:49 1.4
+++ xemacs-packages/haskell-mode/installation-guide.html 2006/03/15 04:57:25
@@ -1,138 +1,140 @@
-<HTML><HEAD>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
-<TITLE>Haskell Mode for Emacs: Installation Guide</TITLE>
+<title>Haskell Mode for Emacs: Installation Guide</title>
-</HEAD><BODY>
+</head><body>
-<H1>Haskell Mode for Emacs: Installation Guide</H1>
+<h1>Haskell Mode for Emacs: Installation Guide</h1>
-<P>When Emacs is started up, it normally runs an file called
-<CODE>.emacs</CODE> located in your home directory. This file should
-contain all of your personal customisations written as a series of
-Elisp commands. In order to install the Haskell mode, you have to
-tell Emacs where to find it. This is done by adding some commands to
-the init file.</P>
+<p>When Emacs is started up, it normally runs a file
+ called <code>~/.emacs</code> located in your home directory. This file
+ should contain all of your personal customisations written as a series of
+ Elisp commands. In order to install the Haskell mode, you have to tell
+ Emacs where to find it. This is done by adding some commands to the init
+ file.</p>
-<H2>Installation</H2>
+<h2>Installation</h2>
-<UL>
-<LI><P>If you are using XEmacs, the haskell-mode package should be
-available for installation through the XEmacs package UI.</P></LI>
+<ul>
+ <li>If you are using XEmacs, the haskell-mode package should be
+ available for installation through the XEmacs package UI.
-<LI><P>If you are using Debian, you can install the package haskell-mode
with
-a command like "apt-get install haskell-mode".</P></LI>
-</UL>
+ <li>If you are using Debian, you can install the package haskell-mode with
+ a command like "apt-get install haskell-mode".
+</ul>
-<P>Otherwise:</P>
+<p>Otherwise:</p>
-<UL>
-<LI><P>Download the and unpack the basic mode and modules into a
-suitable directory, e.g. <CODE>~/lib/emacs</CODE> where
<CODE>~</CODE>
-stands for your home directory.</P>
+<ul>
+ <li>Download and unpack the basic mode and modules into a suitable
+ directory, e.g. <code>~/lib/emacs</code> where <code>~</code>
stands for
+ your home directory.
-<LI><P>Assuming you have placed the basic mode
-<CODE>haskell-mode.el</CODE> and the modules you want to use in the
-directory <CODE>~/lib/emacs</CODE>, add the following commands to your
-init file (<CODE>~/.emacs</CODE>):</P>
+ <li><p>Assuming you have placed the basic
+ mode <code>haskell-mode.el</code> and the modules you want to use in
+ the directory <code>~/lib/emacs</code>, add the following command to
+ your init file (<code>~/.emacs</code>):</p>
-<PRE>
-(setq load-path (cons "~/lib/emacs" load-path))
-(setq auto-mode-alist
- (append auto-mode-alist
- '(("\\.[hg]s$" . haskell-mode)
- ("\\.hi$" . haskell-mode)
- ("\\.l[hg]s$" . literate-haskell-mode))))
-(autoload 'haskell-mode "haskell-mode"
- "Major mode for editing Haskell scripts." t)
-(autoload 'literate-haskell-mode "haskell-mode"
- "Major mode for editing literate Haskell scripts." t)
-</PRE>
+ <pre>(load "~/lib/emacs/haskell-site-file")</pre>
-<P>adding the following lines according to which modules you want to
-use:</P>
+ <p>adding the following lines according to which modules you want to
+ use:</p>
-<PRE>
-(add-hook 'haskell-mode-hook 'turn-on-haskell-font-lock)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
+<pre>
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-hugs)
-(add-hook 'haskell-mode-hook 'turn-on-haskell-ghci)
-</PRE>
+</pre>
-<P>Note that the two indentation modules are mutually exclusive - add
-at most one. You can download the above <A
HREF=".emacs">code</A>.
-Note that the line of code for simple indentation is commented out
-(using a preceeding <CODE>;</CODE>) in preference for the more
-advanced indentation module. Installation is now complete!</P>
+ <p>Note that the two indentation modules are mutually exclusive - add at
+ most one. <!-- You can download the above <a
HREF=".emacs">code</a>. -->
+ Note that the line of code for simple indentation is commented out
+ (using a preceeding <code>;</code>) in preference for the more
+ advanced indentation module. Installation is now complete!</p>
-</UL>
+ <p>The other modules are automatically loaded when needed in the
+ following way:
+ <ul>
+ <li>Font locking: just turn it on
+ via <code>global-font-lock-mode</code> or do
+ <pre>(add-hook 'haskell-mode-hook 'font-lock-mode)</pre>
+ <li>Declaration scanning: just use <code>M-x imenu</code> or
+ bind <code>imenu</code> to a key. E.g.
+ <pre>(global-set-key [(control meta down-mouse-3)] 'imenu)</pre>
+ or you can also add it to the menubar with
+ <pre>(add-hook 'haskell-mode-hook 'imenu-add-menubar-index)</pre>
+ <li>Interaction with inferior Haskell interpreter:
+ just hit <code>C-c C-z</code> or <code>C-c C-l</code>.
+ </ul>
-<P>For those interested, each command above shall now be
-explained.</P>
+</ul>
-<OL>
-<LI><P>We must ensure that the directory containing
-<CODE>haskell-mode.el</CODE> is on the <CODE>load-path</CODE> of
-Emacs. You can examine the value of the <CODE>load-path</CODE> by
-typing <CODE>C-h v load-path</CODE> in an Emacs session. Supposing
-that you've placed <CODE>haskell-mode.el</CODE> in the directory
-<CODE>~/lib/emacs</CODE>, if this directory is not on the
-<CODE>load-path</CODE> we add it with:</P>
+<p>For those interested, each command above shall now be explained.</p>
-<PRE>(setq load-path (cons "~/lib/emacs" load-path))</PRE>
+<ol>
+ <li><p>We must ensure that the directory
+ containing <code>haskell-mode.el</code> is on
+ the <code>load-path</code> of Emacs. You can examine the value of
+ the <code>load-path</code> by typing <code>C-h v
load-path</code> in
+ an Emacs session. Supposing that you've
+ placed <code>haskell-mode.el</code> in the
+ directory <code>~/lib/emacs</code>, if this directory is not on
+ the <code>load-path</code> we add it with:</p>
-<P>The function <CODE>setq</CODE> sets the value of a variable, and
the
-function <CODE>cons</CODE> takes an element and a list and creates a
-new list with the former as head and the latter as tail, as in
-Haskell.</P>
+ <pre>(setq load-path (cons "~/lib/emacs" load-path))</pre>
-<LI><P>It is possible (and desirable) for Emacs to enter a specific
-mode according to the name of the file being edited/visited. The
-variable <CODE>auto-mode-alist</CODE> tells Emacs what mode to run
-according to which regular expression matches the filename. We wish
-to run the Haskell mode on all files ending in <CODE>.hs</CODE>,
-<CODE>.hi</CODE> (interface file) and <CODE>.gs</CODE> (Gofer
file),
-and to run the Haskell mode for literate scripts on all files ending
-in <CODE>.lhs</CODE> and <CODE>.lgs</CODE>. To do this, we need
to
-add pairs of the form <CODE>(<EM>regexp</EM>
-. <EM>mode-function</EM>)</CODE>. We use the function
-<CODE>append</CODE> to append a list of three such pairs to the end of
-the value of <CODE>auto-mode-alist</CODE>. A list in Elisp is written
-within round parantheses with elements separated by whitespace. A
-list is treated as a function application unless it is quoted with
-<CODE>'</CODE>, which is what we do.</P>
+ <p>The function <code>setq</code> sets the value of a variable, and
the
+ function <code>cons</code> takes an element and a list and creates
+ a new list with the former as head and the latter as tail, as in
+ Haskell.</p>
-<LI><P>In order for Emacs to know where to find the definition of our
-mode functions, <CODE>haskell-mode</CODE> and
-<CODE>literate-haskell-mode</CODE>, we must use the function
-<CODE>autoload</CODE>. Both mode functions can be found in the file
-<CODE>haskell-mode.el</CODE> which was downloaded in the first
-installation step (the <CODE>.el</CODE> extension is left off and
-assumed by Emacs). As we have already ensured that this file is on
-the <CODE>load-path</CODE> we need only give the filename and not the
-directory. Its use is quite straightforward but for further
-information, see its documentation by entering <CODE>C-h f
-autoload</CODE> in an Emacs session.</P>
+ <li><p>It is possible (and desirable) for Emacs to enter a specific mode
+ according to the name of the file being edited/visited.
+ The variable <code>auto-mode-alist</code> tells Emacs what mode to run
+ according to which regular expression matches the filename. We wish
+ to run the Haskell mode on all files ending
+ in <code>.hs</code>, <code>.hi</code> (interface file)
+ and <code>.gs</code> (Gofer file), and to run the Haskell mode for
+ literate scripts on all files ending in <code>.lhs</code>
+ and <code>.lgs</code>. To do this, we need to add pairs of the
+ form <code>(<em>regexp</em> .
<em>mode-function</em>)</code>. We use
+ the function <code>append</code> to append a list of three such pairs
+ to the end of the value of <code>auto-mode-alist</code>. A list in
+ Elisp is written within round parantheses with elements separated by
+ whitespace. A list is treated as a function application unless it is
+ quoted with <code>'</code>, which is what we do.</p>
-<LI><P>Each function
<CODE>turn-on-haskell-<EM>module</EM></CODE>
-turns on the corresponding module. Adding such a function as a hook
-to the Haskell mode will turn on that module when the mode is used.
-Note that each of these modules may slow down Emacs, especially for
-large files.</P>
+ <li><p>In order for Emacs to know where to find the definition of our mode
+ functions, <code>haskell-mode</code>
+ and <code>literate-haskell-mode</code>, we must use the
+ function <code>autoload</code>. Both mode functions can be found in
+ the file <code>haskell-mode.el</code> which was downloaded in the
+ first installation step (the <code>.el</code> extension is left off
+ and assumed by Emacs). As we have already ensured that this file is
+ on the <code>load-path</code> we need only give the filename and not
+ the directory. Its use is quite straightforward but for further
+ information, see its documentation by entering <code>C-h
+ f autoload</code> in an Emacs session.</p>
-</OL>
+ <li><p>Each function
<code>turn-on-haskell-<em>module</em></code> turns on
+ the corresponding module. Adding such a function as a hook to the
+ Haskell mode will turn on that module when the mode is used.
+ Note that each of these modules may slow down Emacs, especially for
+ large files.</p>
-<H2>Customisation</H2>
+</ol>
-<P>Most customisations are on the functionality of a particular
-module. See the documentation of that module for information on its
-customisation.</P>
+<h2>Customisation</h2>
-<H2>Support</H2>
+<p>Most customisations are on the functionality of a particular module.
+ See the documentation of that module for information on its
+ customisation.</p>
-<P>Any problems, do <A HREF=mailto:simonmar@microsoft.com>mail</A> and
we will
-try our best to help you!</P>
+<h2>Support</h2>
-<P><A HREF="./"><EM>Haskell Mode Home
Page</EM></A>.</P>
+<p>Any problems, do <a
HREF="mailto:monnier@iro.umontreal.ca">mail</a> and we
+ will try our best to help you!</p>
+
+<p><a HREF="./"><em>Haskell Mode Home
Page</em></a>.</p>
Index: xemacs-packages/haskell-mode/package-info.in
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/haskell-mode/package-info.in,v
retrieving revision 1.1
diff -d -u -r1.1 package-info.in
--- xemacs-packages/haskell-mode/package-info.in 2002/04/24 09:45:15 1.1
+++ xemacs-packages/haskell-mode/package-info.in 2006/03/15 04:57:25
@@ -13,7 +13,7 @@
filename FILENAME
md5sum MD5SUM
size SIZE
- provides (haskell-decl-scan haskell-doc haskell-font-lock haskell-indent haskell-mode
haskell-simple-indent)
+ provides (haskell-decl-scan haskell-doc haskell-font-lock haskell-ghci haskell-hugs
haskell-indent haskell-mode haskell-simple-indent inf-haskell)
requires (REQUIRES)
type regular
))
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department
http://www.cs.usu.edu/~jerry/
Utah State University