Initial Commit
[packages] / xemacs-packages / haskell-mode / haskell-mode.el
1 ;;; haskell-mode.el --- A Haskell editing mode
2
3 ;; Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc
4 ;; Copyright (C) 1992, 1997-1998 Simon Marlow, Graeme E Moss, and Tommy Thorn
5
6 ;; Authors: 1992      Simon Marlow
7 ;;          1997-1998 Graeme E Moss <gem@cs.york.ac.uk> and
8 ;;                    Tommy Thorn <thorn@irisa.fr>,
9 ;;          2001-2002 Reuben Thomas (>=v1.4)
10 ;;          2003      Dave Love <fx@gnu.org>
11 ;; Keywords: faces files Haskell
12 ;; Version: v2_1
13 ;; URL: http://www.haskell.org/haskell-mode/
14
15 ;;; This file is not part of GNU Emacs.
16
17 ;; This file is free software; you can redistribute it and/or modify
18 ;; it under the terms of the GNU General Public License as published by
19 ;; the Free Software Foundation; either version 2, or (at your option)
20 ;; any later version.
21
22 ;; This file is distributed in the hope that it will be useful,
23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 ;; GNU General Public License for more details.
26
27 ;; You should have received a copy of the GNU General Public License
28 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
29 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 ;; Boston, MA 02111-1307, USA.
31
32 \f
33 ;;; Commentary:
34
35 ;; Purpose:
36 ;;
37 ;; To provide a pleasant mode to browse and edit Haskell files, linking
38 ;; into the following supported modules:
39 ;;
40 ;; `haskell-font-lock', Graeme E Moss and Tommy Thorn
41 ;;   Fontifies standard Haskell keywords, symbols, functions, etc.
42 ;;
43 ;; `haskell-decl-scan', Graeme E Moss
44 ;;   Scans top-level declarations, and places them in a menu.
45 ;;
46 ;; `haskell-doc', Hans-Wolfgang Loidl
47 ;;   Echoes types of functions or syntax of keywords when the cursor is idle.
48 ;;
49 ;; `haskell-indent', Guy Lapalme
50 ;;   Intelligent semi-automatic indentation.
51 ;;
52 ;; `haskell-simple-indent', Graeme E Moss and Heribert Schuetz
53 ;;   Simple indentation.
54 ;;
55 ;; `inf-haskell'
56 ;;   Interaction with an inferior Haskell process.
57 ;;   It replaces the previous two modules:
58 ;;     `haskell-hugs', Guy Lapalme
59 ;;     `haskell-ghci', Chris Web
60 ;;
61 ;;
62 ;; This mode supports full Haskell 1.4 including literate scripts.
63 ;; In some versions of (X)Emacs it may only support Latin-1, not Unicode.
64 ;;
65 ;; Installation:
66 ;; 
67 ;; Put in your ~/.emacs:
68 ;;
69 ;;    (setq auto-mode-alist
70 ;;          (append auto-mode-alist
71 ;;                  '(("\\.[hg]s$"  . haskell-mode)
72 ;;                    ("\\.hi$"     . haskell-mode)
73 ;;                    ("\\.l[hg]s$" . literate-haskell-mode))))
74 ;;
75 ;;    (autoload 'haskell-mode "haskell-mode"
76 ;;       "Major mode for editing Haskell scripts." t)
77 ;;    (autoload 'literate-haskell-mode "haskell-mode"
78 ;;       "Major mode for editing literate Haskell scripts." t)
79 ;;
80 ;; with `haskell-mode.el' accessible somewhere on the load-path.
81 ;; To add a directory `~/lib/emacs' (for example) to the load-path,
82 ;; add the following to .emacs:
83 ;;
84 ;;    (setq load-path (cons "~/lib/emacs" load-path))
85 ;;
86 ;; To turn any of the supported modules on for all buffers, add the
87 ;; appropriate line(s) to .emacs:
88 ;;
89 ;;    (add-hook 'haskell-mode-hook 'turn-on-haskell-decl-scan)
90 ;;    (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
91 ;;    (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
92 ;;    (add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)
93 ;;
94 ;; Make sure the module files are also on the load-path.  Note that
95 ;; the two indentation modules are mutually exclusive: Use only one.
96 ;;
97 ;;
98 ;; Customisation:
99 ;;
100 ;; Set the value of `haskell-literate-default' to your preferred
101 ;; literate style: 'bird or 'latex, within .emacs as follows:
102 ;;
103 ;;    (setq haskell-literate-default 'latex)
104 ;;
105 ;; Also see the customisations of the modules.
106 ;;
107 ;;
108 ;; History:
109 ;;
110 ;; This mode is based on an editing mode by Simon Marlow 11/1/92
111 ;; and heavily modified by Graeme E Moss and Tommy Thorn 7/11/98.
112 ;; 
113 ;; If you have any problems or suggestions specific to a supported
114 ;; module, consult that module for a list of known bugs, and an
115 ;; author to contact via email.  For general problems or suggestions,
116 ;; consult the list below, then email gem@cs.york.ac.uk and
117 ;; thorn@irisa.fr quoting the version of the mode you are using, the
118 ;; version of Emacs you are using, and a small example of the problem
119 ;; or suggestion.
120 ;;
121 ;; Version 1.43:
122 ;;   Various tweaks to doc strings and customization support from
123 ;;   Ville Skyttä <scop@xemacs.org>.
124 ;;
125 ;; Version 1.42:
126 ;;   Added autoload for GHCi inferior mode (thanks to Scott
127 ;;   Williams for the bug report and fix).
128 ;;
129 ;; Version 1.41:
130 ;;   Improved packaging, and made a couple more variables
131 ;;   interactively settable.
132 ;;
133 ;; Version 1.4:
134 ;;   Added GHCi mode from Chris Webb, and tidied up a little.
135 ;;
136 ;; Version 1.3:
137 ;;   The literate or non-literate style of a buffer is now indicated
138 ;;   by just the variable haskell-literate: nil, 'bird, or 'latex.
139 ;;   For literate buffers with ambiguous style, the value of
140 ;;   haskell-literate-default is used.
141 ;;
142 ;; Version 1.2:
143 ;;   Separated off font locking, declaration scanning and simple
144 ;;   indentation, and made them separate modules.  Modules can be
145 ;;   added easily now.  Support for modules haskell-doc,
146 ;;   haskell-indent, and haskell-hugs.  Literate and non-literate
147 ;;   modes integrated into one mode, and literate buffer indicated by
148 ;;   value of haskell-literate(-bird-style).
149 ;;
150 ;; Version 1.1:
151 ;;   Added support for declaration scanning under XEmacs via
152 ;;   func-menu.  Moved operators to level two fontification.
153 ;;
154 ;; Version 1.0:
155 ;;   Added a nice indention support from Heribert Schuetz
156 ;;   <Heribert.Schuetz@informatik.uni-muenchen.de>:
157 ;;
158 ;;     I have just hacked an Emacs Lisp function which you might prefer
159 ;;     to `indent-relative' in haskell-mode.el.  See below.  It is not
160 ;;     really Haskell-specific because it does not take into account
161 ;;     keywords like `do', `of', and `let' (where the layout rule
162 ;;     applies), but I already find it useful.
163 ;;
164 ;;   Cleaned up the imenu support.  Added support for literate scripts.
165 ;;
166 ;; Version 0.103 [HWL]:
167 ;;   From Hans Wolfgang Loidl <hwloidl@dcs.gla.ac.uk>:
168 ;;
169 ;;   I (HWL) added imenu support by copying the appropriate functions
170 ;;   from hugs-mode.  A menu-bar item "Declarations" is now added in
171 ;;   haskell mode.  The new code, however, needs some clean-up.
172 ;;
173 ;; Version 0.102:
174 ;;
175 ;;   Moved C-c C-c key binding to comment-region.  Leave M-g M-g to do
176 ;;   the work.  comment-start-skip is changed to comply with comment-start.
177 ;;
178 ;; Version 0.101:
179 ;;
180 ;;   Altered indent-line-function to indent-relative.
181 ;;
182 ;; Version 0.100:
183 ;; 
184 ;;   First official release.
185
186 ;; Present Limitations/Future Work (contributions are most welcome!):
187 ;;
188 ;; . Would like RET in Bird-style literate mode to add a ">" at the
189 ;;   start of a line when previous line starts with ">".  Or would
190 ;;   "> " be better?
191 ;;
192 ;; . Support for GreenCard?
193 ;;
194
195 ;;; Code:
196
197 (eval-when-compile (require 'cl))
198
199 ;; All functions/variables start with `(literate-)haskell-'.
200
201 ;; Version of mode.
202 (defconst haskell-version "v2_1"
203   "`haskell-mode' version number.")
204 (defun haskell-version ()
205   "Echo the current version of `haskell-mode' in the minibuffer."
206   (interactive)
207   (message "Using haskell-mode version %s" haskell-version))
208
209 (defgroup haskell nil
210   "Major mode for editing Haskell programs."
211   :group 'languages
212   :prefix "haskell-")
213
214 ;; Set up autoloads for the modules we supply
215 (autoload 'turn-on-haskell-decl-scan "haskell-decl-scan"
216   "Turn on Haskell declaration scanning." t)
217 (autoload 'turn-on-haskell-doc-mode "haskell-doc"
218   "Turn on Haskell Doc minor mode." t)
219 (autoload 'turn-on-haskell-indent "haskell-indent"
220   "Turn on Haskell indentation." t)
221 (autoload 'turn-on-haskell-simple-indent "haskell-simple-indent"
222   "Turn on simple Haskell indentation." t)
223
224 ;; Functionality provided in other files.
225 (autoload 'haskell-ds-create-imenu-index "haskell-decl-scan")
226 (autoload 'haskell-font-lock-choose-keywords "haskell-font-lock")
227 (autoload 'haskell-doc-current-info "haskell-doc")
228
229 ;; Obsolete functions.
230 (defun turn-on-haskell-font-lock ()
231   (interactive)
232   (turn-on-font-lock)
233   (message "turn-on-haskell-font-lock is obsolete.  Use turn-on-font-lock instead."))
234 (defun turn-on-haskell-hugs ()
235   (interactive)
236   (message "haskell-hugs is obsolete.")
237   (load "haskell-hugs")
238   (turn-on-haskell-hugs))
239 (defun turn-on-haskell-ghci ()
240   (interactive)
241   (message "haskell-ghci is obsolete.")
242   (load "haskell-ghci")
243   (turn-on-haskell-ghci))
244
245
246 ;; Are we looking at a literate script?
247 (defvar haskell-literate nil
248   "*If not nil, the current buffer contains a literate Haskell script.
249 Possible values are: `bird' and `latex', for Bird-style and LaTeX-style
250 literate scripts respectively.  Set by `haskell-mode' and
251 `literate-haskell-mode'.  For an ambiguous literate buffer -- ie. does
252 not contain either \"\\begin{code}\" or \"\\end{code}\" on a line on
253 its own, nor does it contain \">\" at the start of a line -- the value
254 of `haskell-literate-default' is used.
255
256 Always buffer-local.")
257 (make-variable-buffer-local 'haskell-literate)
258 ;; Default literate style for ambiguous literate buffers.
259 (defcustom haskell-literate-default 'bird
260   "*Default value for `haskell-literate'.
261 Used if the style of a literate buffer is ambiguous.  This variable should
262 be set to the preferred literate style."
263   :type '(choice (const bird) (const latex) (const nil)))
264
265 ;; Mode maps.
266 (defvar haskell-mode-map
267   (let ((map (make-sparse-keymap)))
268     ;; Bindings for the inferior haskell process:
269     ;; (define-key map [?\M-C-x]     'inferior-haskell-send-defun)
270     ;; (define-key map [?\C-x ?\C-e] 'inferior-haskell-send-last-sexp)
271     ;; (define-key map [?\C-c ?\C-r] 'inferior-haskell-send-region)
272     (define-key map [?\C-c ?\C-z] 'switch-to-haskell)
273     (define-key map [?\C-c ?\C-l] 'inferior-haskell-load-file)
274     ;; Non standard in other inferior-modes, but traditional in haskell.
275     (define-key map [?\C-c ?\C-r] 'inferior-haskell-reload-file)
276     (define-key map [?\C-c ?\C-b] 'switch-to-haskell)
277     ;; (define-key map [?\C-c ?\C-s] 'inferior-haskell-start-process)
278
279     ;; That's what M-; is for.
280     ;; (define-key map "\C-c\C-c" 'comment-region)
281     map)
282   "Keymap used in Haskell mode.")
283
284 ;; Syntax table.
285 (defvar haskell-mode-syntax-table
286   (let ((table (make-syntax-table)))
287     (modify-syntax-entry ?\  " " table)
288     (modify-syntax-entry ?\t " " table)
289     (modify-syntax-entry ?\" "\"" table)
290     (modify-syntax-entry ?\' "\'" table)
291     (modify-syntax-entry ?_  "w" table)
292     (modify-syntax-entry ?\( "()" table)
293     (modify-syntax-entry ?\) ")(" table)
294     (modify-syntax-entry ?\[  "(]" table)
295     (modify-syntax-entry ?\]  ")[" table)
296
297     (cond ((featurep 'xemacs)
298            ;; I don't know whether this is equivalent to the below
299            ;; (modulo nesting).  -- fx
300            (modify-syntax-entry ?{  "(}5" table)
301            (modify-syntax-entry ?}  "){8" table)
302            (modify-syntax-entry ?-  "_ 1267" table))
303           (t
304            ;; The following get comment syntax right, similarly to C++
305            ;; In Emacs 21, the `n' indicates that they nest.
306            ;; The `b' annotation is actually ignored because it's only
307            ;; meaningful on the second char of a comment-starter, so
308            ;; on Emacs 20 and before we get wrong results.  --Stef
309            (modify-syntax-entry ?\{  "(}1nb" table)
310            (modify-syntax-entry ?\}  "){4nb" table)
311            (modify-syntax-entry ?-  "_ 123" table)))
312     (modify-syntax-entry ?\n ">" table)
313
314     (let (i lim)
315       (map-char-table
316        (lambda (k v)
317          (when (equal v '(1))
318            ;; The current Emacs 22 codebase can pass either a char
319            ;; or a char range.
320            (if (consp k)
321                (setq i (car k)
322                      lim (cdr k))
323              (setq i k 
324                    lim k))
325            (while (<= i lim)
326              (when (> i 127)
327                (modify-syntax-entry i "_" table))
328              (setq i (1+ i)))))
329        (standard-syntax-table)))
330     
331     (modify-syntax-entry ?\` "$`" table)
332     (modify-syntax-entry ?\\ "\\" table)
333     (mapcar (lambda (x)
334               (modify-syntax-entry x "_" table))
335             ;; Some of these are actually OK by default.
336             "!#$%&*+./:<=>?@^|~")
337     (unless (featurep 'mule)
338       ;; Non-ASCII syntax should be OK, at least in Emacs.
339       (mapcar (lambda (x)
340                 (modify-syntax-entry x "_" table))
341               (concat "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿"
342                       "×÷"))
343       (mapcar (lambda (x)
344                 (modify-syntax-entry x "w" table))
345               (concat "ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ"
346                       "ØÙÚÛÜÝÞß"
347                       "àáâãäåæçèéêëìíîïðñòóôõö"
348                       "øùúûüýþÿ")))
349     table)
350   "Syntax table used in Haskell mode.")
351
352 ;; Various mode variables.
353
354 (defcustom haskell-mode-hook nil
355   "Hook run after entering Haskell mode."
356   :type 'hook
357   :options '(turn-on-haskell-indent turn-on-font-lock turn-on-eldoc-mode
358              imenu-add-menubar-index))
359
360 (defvar eldoc-print-current-symbol-info-function)
361
362 ;; The main mode functions
363 ;;;###autoload
364 (define-derived-mode haskell-mode fundamental-mode "Haskell"
365   "Major mode for editing Haskell programs.  Last adapted for Haskell 1.4.
366 Blank lines separate paragraphs, comments start with `-- '.
367
368 \\<haskell-mode-map>\\[indent-for-comment] will place a comment at an appropriate place on the current line.
369 \\[comment-region] comments (or with prefix arg, uncomments) each line in the region.
370
371 Literate scripts are supported via `literate-haskell-mode'.  The
372 variable `haskell-literate' indicates the style of the script in the
373 current buffer.  See the documentation on this variable for more
374 details.
375
376 Modules can hook in via `haskell-mode-hook'.  The following modules
377 are supported with an `autoload' command:
378
379    `haskell-decl-scan', Graeme E Moss
380      Scans top-level declarations, and places them in a menu.
381
382    `haskell-doc', Hans-Wolfgang Loidl
383      Echoes types of functions or syntax of keywords when the cursor is idle.
384
385    `haskell-indent', Guy Lapalme
386      Intelligent semi-automatic indentation.
387
388    `haskell-simple-indent', Graeme E Moss and Heribert Schuetz
389      Simple indentation.
390
391 Module X is activated using the command `turn-on-X'.  For example,
392 `haskell-font-lock' is activated using `turn-on-haskell-font-lock'.
393 For more information on a module, see the help for its `turn-on-X'
394 function.  Some modules can be deactivated using `turn-off-X'.  (Note
395 that `haskell-doc' is irregular in using `turn-(on/off)-haskell-doc-mode'.)
396
397 Use `haskell-version' to find out what version this is.
398
399 Invokes `haskell-mode-hook' if not nil."
400   (set (make-local-variable 'paragraph-start) (concat "^$\\|" page-delimiter))
401   (set (make-local-variable 'paragraph-separate) paragraph-start)
402   (set (make-local-variable 'comment-start) "-- ")
403   (set (make-local-variable 'comment-padding) 0)
404   (set (make-local-variable 'comment-start-skip) "[-{]-[ \t]*")
405   (set (make-local-variable 'comment-end) "")
406   (set (make-local-variable 'comment-end-skip) "[ \t]*\\(-}\\|\\s>\\)")
407   (set (make-local-variable 'parse-sexp-ignore-comments) t)
408   ;; Set things up for eldoc-mode.
409   (set (make-local-variable 'eldoc-print-current-symbol-info-function)
410        'haskell-doc-current-info)
411   ;; Set things up for imenu.
412   (set (make-local-variable 'imenu-create-index-function)
413        'haskell-ds-create-imenu-index)
414   ;; Set things up for font-lock.
415   (set (make-local-variable 'font-lock-defaults)
416        '(haskell-font-lock-choose-keywords
417          nil nil ((?\' . "w") (?_  . "w")) nil
418          (font-lock-syntactic-keywords
419           . haskell-font-lock-choose-syntactic-keywords)
420          (font-lock-syntactic-face-function
421           . haskell-syntactic-face-function)
422          ;; Get help from font-lock-syntactic-keywords.
423          (parse-sexp-lookup-properties . t)))
424   ;; Haskell's layout rules mean that TABs have to be handled with extra care.
425   ;; The safer option is to avoid TABs.  The second best is to make sure
426   ;; TABs stops are 8 chars apart, as mandated by the Haskell Report.  --Stef
427   (set (make-local-variable 'indent-tabs-mode) nil)
428   (set (make-local-variable 'tab-width) 8)
429   (setq haskell-literate nil))
430
431 ;;;###autoload
432 (define-derived-mode literate-haskell-mode haskell-mode "LitHaskell"
433   "As `haskell-mode' but for literate scripts."
434   (setq haskell-literate
435         (save-excursion
436           (goto-char (point-min))
437           (cond
438            ((re-search-forward "^\\\\\\(begin\\|end\\){code}$" nil t) 'latex)
439            ((re-search-forward "^>" nil t) 'bird)
440            (t haskell-literate-default)))))
441
442 ;;;###autoload(add-to-list 'auto-mode-alist '("\\.\\(?:[gh]s\\|hi\\)\\'" . haskell-mode))
443 ;;;###autoload(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" . literate-haskell-mode))
444 ;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
445 ;;;###autoload(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
446
447 ;; Provide ourselves:
448
449 (provide 'haskell-mode)
450
451 ;;; haskell-mode.el ends here