1 ;; haskell-mode.el. Major mode for editing Haskell.
2 ;; Copyright (C) 1989, Free Software Foundation, Inc., Lars Bo Nielsen
3 ;; and Lennart Augustsson
4 ;; modified by Peter Thiemann, March 1994
6 ;; This file is not officially part of GNU Emacs.
8 ;; GNU Emacs is distributed in the hope that it will be useful,
9 ;; but WITHOUT ANY WARRANTY. No author or distributor
10 ;; accepts responsibility to anyone for the consequences of using it
11 ;; or for whether it serves any particular purpose or works at all,
12 ;; unless he says so in writing. Refer to the GNU Emacs General Public
13 ;; License for full details.
15 ;; Everyone is granted permission to copy, modify and redistribute
16 ;; GNU Emacs, but only under the conditions described in the
17 ;; GNU Emacs General Public License. A copy of this license is
18 ;; supposed to have been given to you along with GNU Emacs so you
19 ;; can know your rights and responsibilities. It should be in a
20 ;; file named COPYING. Among other things, the copyright notice
21 ;; and this notice must be preserved on all copies.
23 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;; Haskell Mode. A major mode for editing and running Haskell. (Version 0.0)
26 ;; =================================================================
28 ;; This is a mode for editing and running Haskell.
29 ;; It is very much based on the sml mode for GNU Emacs. It
32 ;; - Inferior shell running Haskell. No need to leave emacs, just
33 ;; keep right on editing while Haskell runs in another window.
35 ;; - Automatic "load file" in inferior shell. Send regions of code
36 ;; to the Haskell program.
39 ;; 1. HOW TO USE THE Haskell-MODE
40 ;; ==========================
42 ;; Here is a short introduction to the mode.
44 ;; 1.1 GETTING STARTED
45 ;; -------------------
47 ;; If you are an experienced user of Emacs, just skip this section.
49 ;; To use the haskell-mode, insert this in your "~/.emacs" file (Or ask your
50 ;; emacs-administrator to help you.):
52 ;; (setq auto-mode-alist (cons '("\\.hs$" . haskell-mode) (cons '("\\.lhs$" . haskell-mode)
54 ;; (autoload 'haskell-mode "haskell-mode" "Major mode for editing Haskell." t)
56 ;; Now every time a file with the extension `.hs' or `.lhs' is found, it is
57 ;; automatically started up in haskell-mode.
59 ;; You will also have to specify the path to this file, so you will have
60 ;; to add this as well:
62 ;; (setq load-path (cons "/usr/me/emacs" load-path))
64 ;; where "/usr/me/emacs" is the directory where this file is.
66 ;; You may also want to compile the this file (M-x byte-compile-file)
69 ;; You are now ready to start using haskell-mode. If you have tried other
70 ;; language modes (like lisp-mode or C-mode), you should have no
71 ;; problems. There are only a few extra functions in this mode.
73 ;; 1.2. EDITING COMMANDS.
74 ;; ----------------------
76 ;; The following editing and inferior-shell commands can ONLY be issued
77 ;; from within a buffer in haskell-mode.
79 ;; LFD (haskell-newline-and-indent).
80 ;; This is probably the function you will be using the most (press
81 ;; CTRL while you press Return, press C-j or press Newline). It
82 ;; makes a new line and performs indentation based on the last
83 ;; preceding non-comment line.
85 ;; M-; (indent-for-comment).
86 ;; Like in other language modes, this command will give you a comment
87 ;; at the of the current line. The column where the comment starts is
88 ;; determined by the variable comment-column (default: 40).
90 ;; C-c C-v (haskell-mode-version).
91 ;; Get the version of the haskell-mode.
94 ;; 1.3. COMMANDS RELATED TO THE INFERIOR SHELL
95 ;; -------------------------------------------
97 ;; C-c C-s (haskell-pop-to-shell).
98 ;; This command starts up an inferior shell running haskell. If the shell
99 ;; is running, it will just pop up the shell window.
101 ;; C-c C-u (haskell-save-buffer-use-file).
102 ;; This command will save the current buffer and send a "load file",
103 ;; where file is the file visited by the current buffer, to the
104 ;; inferior shell running haskell.
106 ;; C-c C-f (haskell-run-on-file).
107 ;; Will send a "load file" to the inferior shell running haskell,
108 ;; prompting you for the file name.
110 ;; C-c C-r (haskell-send-region).
111 ;; Will send region, from point to mark, to the inferior shell
114 ;; C-c C-b (haskell-send-buffer).
115 ;; Will send whole buffer to inferior shell running haskell.
120 ;; The first indentation command (using C-j or TAB) on a given line
121 ;; indents like the last preceding non-comment line. The next TAB
122 ;; indents to the indentation of the innermost enclosing scope. Further
123 ;; TABs get you to further enclosing scopes. After indentation has
124 ;; reached the first column, the process restarts using the indentation
125 ;; of the preceding non-comment line, again.
127 ;; 3. INFERIOR SHELL.
128 ;; ==================
130 ;; The mode for Standard ML also contains a mode for an inferior shell
131 ;; running haskell. The mode is the same as the shell-mode, with just one
134 ;; 3.1. INFERIOR SHELL COMMANDS
135 ;; ----------------------------
137 ;; C-c C-f (haskell-run-on-file). Send a `load file' to the process running
140 ;; 3.2. CONSTANTS CONTROLLING THE INFERIOR SHELL MODE
141 ;; --------------------------------------------------
143 ;; Because haskell is called differently on various machines, and the
144 ;; haskell-systems have their own command for reading in a file, a set of
145 ;; constants controls the behavior of the inferior shell running haskell (to
146 ;; change these constants: See CUSTOMIZING YOUR Haskell-MODE below).
148 ;; haskell-prog-name (default "hbi").
149 ;; This constant is a string, containing the command to invoke
150 ;; Standard ML on your system.
152 ;; haskell-use-right-delim (default "\"")
153 ;; haskell-use-left-delim (default "\"")
154 ;; The left and right delimiter used by your version of haskell, for
157 ;; haskell-process-name (default "Haskell").
158 ;; The name of the process running haskell. (This will be the name
159 ;; appearing on the mode line of the buffer)
161 ;; NOTE: The haskell-mode functions: haskell-send-buffer, haskell-send-function and
162 ;; haskell-send-region, creates temporary files (I could not figure out how
163 ;; to send large amounts of data to a process). These files will be
164 ;; removed when you leave emacs.
168 ;; There is support for Jamie Zawinski's font-lock-mode through the
169 ;; variable "haskell-font-lock-keywords".
171 ;; 5. CUSTOMIZING YOUR Haskell-MODE
172 ;; ============================
174 ;; If you have to change some of the constants, you will have to add a
175 ;; `hook' to the haskell-mode. Insert this in your "~/.emacs" file.
177 ;; (setq haskell-mode-hook 'my-haskell-constants)
179 ;; Your function "my-haskell-constants" will then be executed every time
180 ;; "haskell-mode" is invoked. Now you only have to write the emacs-lisp
181 ;; function "my-haskell-constants", and put it in your "~/.emacs" file.
183 ;; Say you are running a version of haskell that uses the syntax `load
184 ;; ["file"]', is invoked by the command "OurHaskell" and you don't want the
185 ;; indentation algorithm to indent according to open parenthesis, your
186 ;; function should look like this:
188 ;; (defun my-haskell-constants ()
189 ;; (setq haskell-prog-name "OurHaskell")
190 ;; (setq haskell-use-left-delim "[\"")
191 ;; (setq haskell-use-right-delim "\"]")
192 ;; (setq haskell-paren-lookback nil))
194 ;; The haskell-shell also runs a `hook' (haskell-shell-hook) when it is invoked.
198 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
203 ;; Aalborg University
204 ;; Computer Science Dept.
209 ;; or: ...!mcvax!diku!iesd!lbn
210 ;; or: mcvax!diku!iesd!lbn@uunet.uu.net
212 ;; MODIFIED FOR Haskell BY
213 ;; Lennart Augustsson
214 ;; indentation stuff by Peter Thiemann
217 ;; Please let me know if you come up with any ideas, bugs, or fixes.
219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
221 (defconst haskell-mode-version-string
222 "HASKELL-MODE, Version 0.2, PJT indentation")
224 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
226 ;;; CONSTANTS CONTROLLING THE MODE.
228 ;;; These are the constants you might want to change
231 ;; The command used to start up the haskell-program.
232 (defconst haskell-prog-name "hbi" "*Name of program to run as haskell.")
234 ;; The left delimmitter for `load file'
235 (defconst haskell-use-left-delim "\""
236 "*The left delimiter for the filename when using \"load\".")
238 ;; The right delimmitter for `load file'
239 (defconst haskell-use-right-delim "\""
240 "*The right delimiter for the filename when using \"load\".")
242 ;; A regular expression matching the prompt pattern in the inferior
244 (defconst haskell-shell-prompt-pattern "^> *"
245 "*The prompt pattern for the inferion shell running haskell.")
247 ;; The template used for temporary files, created when a region is
248 ;; send to the inferior process running haskell.
249 (defconst haskell-tmp-template "/tmp/haskell.tmp."
250 "*Template for the temporary file, created by haskell-simulate-send-region.")
252 ;; The name of the process running haskell (This will also be the name of
254 (defconst haskell-process-name "Haskell" "*The name of the Haskell-process")
257 ;;; END OF CONSTANTS CONTROLLING THE MODE.
259 ;;; If you change anything below, you are on your own.
261 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264 (defvar haskell-mode-syntax-table nil "The syntax table used in haskell-mode.")
266 (defvar haskell-mode-map nil "The mode map used in haskell-mode.")
268 (defvar haskell-mode-abbrev-table nil "The abbrev-table used in haskell-mode.")
270 (defvar haskell-old-kill-emacs-hook nil "Old value of kill-emacs-hook")
272 (defun haskell-mode ()
273 "Major mode for editing Haskell code.
274 Tab indents for Haskell code.
275 Comments are delimited with --
276 Paragraphs are separated by blank lines only.
277 Delete converts tabs to spaces as it moves back.
282 \\[haskell-pop-to-shell]\t Pop to the haskell window.
283 \\[haskell-save-buffer-use-file]\t Save the buffer, and send a \"load file\".
284 \\[haskell-send-region]\t Send region (point and mark) to haskell.
285 \\[haskell-run-on-file]\t Send a \"load file\" to haskell.
286 \\[haskell-send-buffer]\t Send whole buffer to haskell.
287 \\[haskell-mode-version]\t Get the version of haskell-mode.
288 \\[haskell-evaluate-expression]\t Prompt for an expression and evalute it.
294 Runs haskell-mode-hook if non nil."
296 (kill-all-local-variables)
299 (setq haskell-mode-map (make-sparse-keymap))
300 (define-key haskell-mode-map "\C-c\C-v" 'haskell-mode-version)
301 (define-key haskell-mode-map "\C-c\C-u" 'haskell-save-buffer-use-file)
302 (define-key haskell-mode-map "\C-c\C-s" 'haskell-pop-to-shell)
303 (define-key haskell-mode-map "\C-c\C-r" 'haskell-send-region)
304 (define-key haskell-mode-map "\C-c\C-m" 'haskell-region)
305 (define-key haskell-mode-map "\C-c\C-f" 'haskell-run-on-file)
306 (define-key haskell-mode-map "\C-c\C-b" 'haskell-send-buffer)
307 (define-key haskell-mode-map "\C-ce" 'haskell-evaluate-expression)
308 (define-key haskell-mode-map "\C-j" 'haskell-newline-and-indent)
309 (define-key haskell-mode-map "\177" 'backward-delete-char-untabify))
310 (use-local-map haskell-mode-map)
311 (setq major-mode 'haskell-mode)
312 (setq mode-name "Haskell")
313 (define-abbrev-table 'haskell-mode-abbrev-table ())
314 (setq local-abbrev-table haskell-mode-abbrev-table)
315 (if haskell-mode-syntax-table
317 (setq haskell-mode-syntax-table (make-syntax-table))
318 (modify-syntax-entry ?{ "(}1" haskell-mode-syntax-table)
319 (modify-syntax-entry ?} "){4" haskell-mode-syntax-table)
321 ; (modify-syntax-entry ?- "_ 2356" haskell-mode-syntax-table)
322 ; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
323 ; (modify-syntax-entry ?\n "> b" haskell-mode-syntax-table)
326 (modify-syntax-entry ?- "_ 23" haskell-mode-syntax-table)
327 ; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
328 ; (modify-syntax-entry ?\n "> b" haskell-mode-syntax-table)
330 (modify-syntax-entry ?\\ "\\" haskell-mode-syntax-table)
331 (modify-syntax-entry ?* "_" haskell-mode-syntax-table)
332 (modify-syntax-entry ?_ "_" haskell-mode-syntax-table)
333 (modify-syntax-entry ?' "_" haskell-mode-syntax-table)
334 (modify-syntax-entry ?: "_" haskell-mode-syntax-table)
335 (modify-syntax-entry ?| "." haskell-mode-syntax-table)
337 (set-syntax-table haskell-mode-syntax-table)
338 (make-local-variable 'require-final-newline) ; Always put a new-line
339 (setq require-final-newline t) ; in the end of file
340 (make-local-variable 'indent-line-function)
341 (setq indent-line-function 'haskell-indent-line)
342 (make-local-variable 'comment-start)
343 (setq comment-start "-- ")
344 (make-local-variable 'comment-end)
345 (setq comment-end "")
346 (make-local-variable 'comment-column)
347 (setq comment-column 60) ; Start of comment in this column
348 (make-local-variable 'comment-start-skip)
349 (setq comment-start-skip "--[^a-zA-Z0-9]*") ; This matches a start of comment
350 (make-local-variable 'comment-indent-function)
351 (setq comment-indent-function 'haskell-comment-indent)
353 ;; Adding these will fool the matching of parens. I really don't
354 ;; know why. It would be nice to have comments treated as
357 ;; (make-local-variable 'parse-sexp-ignore-comments)
358 ;; (setq parse-sexp-ignore-comments t)
360 (run-hooks 'haskell-mode-hook)) ; Run the hook
362 (defun haskell-mode-version ()
364 (message haskell-mode-version-string))
367 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
373 ;;; some variables for later use
375 (defvar haskell-open-comment "{-")
376 (defvar haskell-close-comment "-}")
377 (defvar haskell-indentation-counter 0
378 "count repeated invocations of indent-for-tab-command")
379 (defvar haskell-literate-flag nil
380 "used to guide literate/illiterate behavior, set automagically")
382 (defun haskell-newline-and-indent ()
384 (setq haskell-literate-flag
387 (= (following-char) ?>)))
389 (if haskell-literate-flag (insert ">"))
390 (haskell-indent-line))
392 (defun haskell-indent-line ()
393 "Indent current line of ordinary or literate Haskell code."
395 (let ((indent (haskell-calculate-indentation-pjt-2)))
396 (if (/= (current-indentation) indent)
399 (if (= (following-char) ?>) (forward-char 1)) ;LITERATE
401 (skip-chars-forward "\t ")
402 (delete-region beg (point))
404 ;; If point is before indentation, move point to indentation
405 (if (< (current-column) (current-indentation))
406 (skip-chars-forward "\t ")))))
408 (defun haskell-calculate-indentation ()
410 (let ((col (current-column)))
411 (while (and (not (bobp)) ;skip over empty and comment-only lines
412 (= col (current-column)))
414 (beginning-of-line) ; Go to first non whitespace
415 (if (= (following-char) ?>) ;LITERATE
417 (if haskell-literate-flag ;ignore illiterate lines
419 (skip-chars-forward "\t ") ; on the line.
420 (setq col (current-column))
421 (search-forward-regexp (concat haskell-open-comment "\\|--\\|\n") nil 0)
422 (goto-char (match-beginning 0)))
423 (search-backward-regexp "\\b\\(where\\|let\\|of\\|in\\)\\b\\|\n" nil 0)
424 (if (looking-at "\n")
426 (setq col (current-column))
428 (skip-chars-forward "\t ")
429 (if (looking-at "\\w")
430 (setq col (current-column))
431 (setq col (+ 2 col))))
434 (defun haskell-calculate-indentation-pjt-2 ()
435 "Calculate indentation for Haskell program code, versatile version"
437 (if (eq last-command 'haskell-indentation)
438 (setq haskell-indentation-counter (1+ haskell-indentation-counter))
439 (setq haskell-indentation-counter -1))
440 (setq this-command 'haskell-indentation)
441 (let* ((simple-indent (haskell-calculate-indentation))
442 (count haskell-indentation-counter)
443 (min-indent simple-indent) ; minimum indentation found in a non-comment line
444 (last-indent simple-indent) ; indentation of the following non-comment line
445 (return-indent nil) ; computed indentation
448 (if (< haskell-indentation-counter 0) ; 1st tab gives simple indentation
449 (setq return-indent simple-indent))
450 (while (not return-indent)
451 (if (search-backward-regexp "\\b\\(where\\|let\\|of\\)\\b\\|\n\\|{-\\|-}" nil t 1)
453 ((looking-at haskell-open-comment)
454 (setq comment-depth (1- comment-depth)))
455 ((looking-at haskell-close-comment)
456 (setq comment-depth (1+ comment-depth)))
462 (if (= (following-char) ?>)
464 (if haskell-literate-flag
465 (end-of-line))) ;LITERATE: ignore lines w/o >
466 (skip-chars-forward "\t ")
467 (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
469 (setq last-indent (current-column))
470 (if (< last-indent min-indent)
471 (setq min-indent last-indent)))))
472 (t ; looking at a keyword
475 (skip-chars-forward " \t")
476 (if (and haskell-literate-flag ;LITERATE: ignore lines w/o >
479 (/= (following-char) ?>)))
481 (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
483 (setq last-indent (current-column)))
484 (if (<= last-indent min-indent)
486 (setq count (1- count))
487 (setq return-indent last-indent)))
488 (if (< last-indent min-indent)
489 (setq min-indent last-indent)))))))
490 (setq return-indent simple-indent)
491 (setq haskell-indentation-counter -1)))
494 (defun haskell-skip-nested-comment ()
495 ;; point looks at opening {-, move over closing -}
496 ;; todo: specify what happens on failure, bounds check ...
498 (let ((comment-depth 1))
499 (while (> comment-depth 0)
500 (search-forward-regexp "{-\\|-}")
501 (goto-char (match-beginning 0))
503 (if (= (following-char) 123) ; code for opening brace
506 (goto-char (match-end 0)))))
509 ;;;seemingly obsolete functions
510 (defun haskell-inside-of-inline-comment ()
511 (let ((bolp (save-excursion
514 (search-backward comment-start bolp t 1)))
516 (defun haskell-inside-of-nested-comment ()
520 (search-backward-regexp "\\({-\\|-}\\)" 0 t 1)
521 (if (haskell-inside-of-inline-comment)
523 (if (looking-at haskell-open-comment)
524 (setq count (1+ count))
525 (setq count (1- count)))))
528 (defun haskell-inside-of-comment ()
529 (or (haskell-inside-of-inline-comment)
530 (haskell-inside-of-nested-comment)))
532 ;;;stolen from sml-mode.el
533 (defun haskell-comment-indent ()
534 "Compute indentation for Haskell comments"
535 (if (looking-at "^--")
538 (skip-chars-backward " \t")
539 (max (1+ (current-column))
542 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
546 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
548 (defvar haskell-shell-map nil "The mode map for haskell-shell.")
550 (defun haskell-shell ()
551 "Inferior shell invoking Haskell.
552 It is not possible to have more than one shell running Haskell.
553 Like the shell mode with the additional command:
555 \\[haskell-run-on-file]\t Runs haskell on the file.
556 \\{haskell-shell-map}
557 Variables controlling the mode:
559 haskell-prog-name (default \"hbi\")
560 The string used to invoke the haskell program.
562 haskell-use-right-delim (default \"\\\"\")
563 haskell-use-left-delim (default \"\\\"\")
564 The left and right delimiter used by your version of haskell, for
567 haskell-process-name (default \"Haskell\")
568 The name of the process running haskell.
570 haskell-shell-prompt-pattern (default \"^> *\")
573 Runs haskell-shell-hook if not nil."
575 (if (not (process-status haskell-process-name))
576 (save-excursion ; Process is not running
577 (message "Starting Haskell...") ; start up a new process
579 (set-buffer (make-comint haskell-process-name haskell-prog-name))
580 (erase-buffer) ; Erase the buffer if a previous
581 (if haskell-shell-map ; process died in there
583 (setq haskell-shell-map (copy-keymap shell-mode-map))
584 (define-key haskell-shell-map "\C-c\C-f" 'haskell-run-on-file))
585 (use-local-map haskell-shell-map)
586 (make-local-variable 'shell-prompt-pattern)
587 (setq shell-prompt-pattern haskell-shell-prompt-pattern)
588 (setq major-mode 'haskell-shell)
589 (setq mode-name "Haskell Shell")
590 (setq mode-line-format
591 "-----Emacs: %17b %M %[(%m: %s)%]----%3p--%-")
592 (set-process-filter (get-process haskell-process-name) 'haskell-process-filter)
593 (message "Starting Haskell...done.")
594 (run-hooks 'haskell-shell-hook))))
596 (defun haskell-process-filter (proc str)
597 (let ((cur (current-buffer))
599 (pop-to-buffer (concat "*" haskell-process-name "*"))
600 (goto-char (point-max))
601 (if (string= str "\b\b\b \b\b\b")
602 (backward-delete-char 4)
604 (set-marker (process-mark proc) (point-max))
605 (pop-to-buffer cur)))
607 (defun haskell-pop-to-shell ()
610 (pop-to-buffer (concat "*" haskell-process-name "*")))
612 (defun haskell-run-on-file (fil)
613 (interactive "FRun Haskell on : ")
616 (process-send-string haskell-process-name
617 (concat "load " haskell-use-left-delim (expand-file-name fil)
618 haskell-use-right-delim ";\n")))
620 (defun haskell-save-buffer-use-file ()
621 "Save the buffer, and send a `use file' to the inferior shell
625 (if (setq file (buffer-file-name)) ; Is the buffer associated
629 (process-send-string haskell-process-name
630 (concat "load " haskell-use-left-delim
631 (expand-file-name file)
632 haskell-use-right-delim ";\n")))
633 (error "Buffer not associated with file."))))
635 (defvar haskell-tmp-files-list nil
636 "List of all temporary files created by haskell-simulate-send-region.
637 Each element in the list is a list with the format:
639 (\"tmp-filename\" buffer start-line)")
641 (defvar haskell-simulate-send-region-called-p nil
642 "Has haskell-simulate-send-region been called previously.")
644 (defun haskell-make-temp-name (pre)
645 (concat (make-temp-name pre) ".m"))
647 (defun haskell-simulate-send-region (point1 point2)
648 "Simulate send region. As send-region only can handle what ever the
649 system sets as the default, we have to make a temporary file.
650 Updates the list of temporary files (haskell-tmp-files-list)."
651 (let ((file (expand-file-name (haskell-make-temp-name haskell-tmp-template))))
652 ;; Remove temporary files when we leave emacs
653 (if (not haskell-simulate-send-region-called-p)
655 (setq haskell-old-kill-emacs-hook kill-emacs-hook)
656 (setq kill-emacs-hook 'haskell-remove-tmp-files)
657 (setq haskell-simulate-send-region-called-p t)))
660 (setq haskell-tmp-files-list
663 (save-excursion ; Calculate line no.
665 (1+ (count-lines 1 (point)))))
666 haskell-tmp-files-list)))
667 (write-region point1 point2 file nil 'dummy)
669 (message "Using temporary file: %s" file)
672 ;; string to send: load file;
673 (concat "load " haskell-use-left-delim file haskell-use-right-delim ";\n"))))
675 (defun haskell-remove-tmp-files ()
676 "Remove the temporary files, created by haskell-simulate-send-region, if
677 they still exist. Only files recorded in haskell-tmp-files-list are removed."
678 (message "Removing temporary files created by haskell-mode...")
679 (while haskell-tmp-files-list
681 (delete-file (car (car haskell-tmp-files-list)))
683 (setq haskell-tmp-files-list (cdr haskell-tmp-files-list)))
684 (message "Removing temporary files created by haskell-mode...done.")
685 (run-hooks 'haskell-old-kill-emacs-hook))
687 (defun haskell-send-region ()
693 (exchange-point-and-mark)
694 (setq start (point)))
695 (haskell-simulate-send-region start end)))
697 (defun haskell-send-buffer ()
700 (haskell-simulate-send-region (point-min) (point-max)))
702 (defun haskell-evaluate-expression (h-expr)
703 "Prompt for and evaluate an expression"
704 (interactive "sExpression: ")
705 (let ((str (concat h-expr ";\n"))
706 (buf (current-buffer)))
707 (haskell-pop-to-shell)
709 (process-send-string haskell-process-name str)
710 (pop-to-buffer buf)))
712 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
714 ;;; keywords for jwz's font-look-mode (lemacs 19)
716 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
717 (setq haskell-font-lock-keywords
718 (list (concat "\\b\\("
720 '("case" "class" "data" "default" "deriving" "else" "hiding"
721 "if" "import" "in" "infix" "infixl" "infixr" "instance"
722 "interface" "let" "module" "of" "renaming" "then" "to"
726 (list "^\\(#[ \t]*\\(if\\|ifdef\\|ifndef\\|else\\|endif\\|include\\)\\)")
727 (list "\\(^>?\\|\\bwhere\\b\\|\\blet\\b\\)[ \t]*\\(\\(\\w\\|\\s_\\)+\\)\\(\\([^=\n]*\\S.\\)?=\\(\\S.\\|$\\)\\|[ \t]*::\\S.\\).*$"
728 2 'font-lock-function-name-face)
729 (list "\\b\\(data\\|type\\)\\b[ \t]+\\(\\(\\w\\|\\s_\\)+\\)"
730 2 'font-lock-type-face)
731 (list (concat "'\\([^\\]\\|\\\\\\([0-9]+\\|"
733 '("a" "b" "f" "n" "r" "t" "v" "\\\\" "\"" "'" "&")
735 "\\|\\^\\([][_^A-Z@\\\\]\\)"
736 "\\)\\)'") 1 'font-lock-string-face)))
738 ;;; font-lock-keywords for literate style files
740 (setq haskell-font-lock-keywords-2
741 (list (concat "^>.*\\b\\("
743 '("case" "class" "data" "default" "deriving" "else" "hiding"
744 "if" "import" "in" "infix" "infixl" "infixr" "instance"
745 "interface" "let" "module" "of" "renaming" "then" "to"
749 (list "^>\\(.*\\(\\bwhere\\b\\|\\blet\\b\\)\\|\\)[ \t]*\\(\\(\\w\\|\\s_\\)+\\)\\(\\([^=\n]*\\S.\\)?=\\(\\S.\\|$\\)\\|[ \t]*::\\S.\\).*$"
750 3 'font-lock-function-name-face)
751 (list "^>.*\\b\\(data\\|type\\)\\b[ \t]+\\(\\(\\w\\|\\s_\\)+\\)"
752 2 'font-lock-type-face)
753 (list (concat "^>.*'\\([^\\]\\|\\\\\\([0-9]+\\|"
755 '("a" "b" "f" "n" "r" "t" "v" "\\\\" "\"" "'" "&")
757 "\\|\\^\\([][_^A-Z@\\\\]\\)"
758 "\\)\\)'") 1 'font-lock-string-face)))
759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
761 ;;; END OF Haskell-MODE
763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
764 (provide 'haskell-mode)