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-c\C-l" 'comment-line)
308 (define-key haskell-mode-map "\C-ce" 'haskell-evaluate-expression)
309 ; (define-key haskell-mode-map "\C-j" 'haskell-newline-and-indent)
310 (define-key haskell-mode-map [S-tab] 'tab-to-tab-stop)
311 (define-key haskell-mode-map "\177" 'backward-delete-char-untabify))
312 (use-local-map haskell-mode-map)
313 (setq major-mode 'haskell-mode)
314 (setq mode-name "Haskell")
315 (define-abbrev-table 'haskell-mode-abbrev-table ())
316 (setq local-abbrev-table haskell-mode-abbrev-table)
317 (if haskell-mode-syntax-table
319 (setq haskell-mode-syntax-table (make-syntax-table))
320 (modify-syntax-entry ?{ "(}1" haskell-mode-syntax-table)
321 (modify-syntax-entry ?} "){4" haskell-mode-syntax-table)
323 ; (modify-syntax-entry ?- "_ 2356" haskell-mode-syntax-table)
324 ; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
325 ; (modify-syntax-entry ?\n "> b" haskell-mode-syntax-table)
328 (modify-syntax-entry ?- "_ 23" haskell-mode-syntax-table)
329 ; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
330 ; (modify-syntax-entry ?\n "> b" 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)
336 (modify-syntax-entry ?: "_" haskell-mode-syntax-table)
337 (modify-syntax-entry ?| "." haskell-mode-syntax-table)
339 (set-syntax-table haskell-mode-syntax-table)
340 (make-local-variable 'require-final-newline) ; Always put a new-line
341 (setq require-final-newline t) ; in the end of file
342 ; (make-local-variable 'change-major-mode-hook)
343 ; (setq change-major-mode-hook nil)
344 ; (make-local-variable 'indent-line-function)
345 ; (setq indent-line-function 'haskell-indent-line)
346 (make-local-variable 'comment-start)
347 (setq comment-start "-- ")
348 ; (setq comment-start "{- ")
349 (make-local-variable 'comment-end)
350 (setq comment-end "")
351 ; (setq comment-end " -}")
352 (make-local-variable 'comment-column)
353 (setq comment-column 60) ; Start of comment in this column
354 (make-local-variable 'comment-start-skip)
355 (setq comment-start-skip "{-+ *\\|--+ *") ; This matches a start of comment
356 (make-local-variable 'comment-multi-line)
357 (setq comment-multi-line nil)
358 ; (make-local-variable 'comment-indent-function)
359 ; (setq comment-indent-function 'haskell-comment-indent)
361 ;; Adding these will fool the matching of parens. I really don't
362 ;; know why. It would be nice to have comments treated as
365 ;; (make-local-variable 'parse-sexp-ignore-comments)
366 ;; (setq parse-sexp-ignore-comments t)
368 (run-hooks 'haskell-mode-hook)) ; Run the hook
370 (defun haskell-mode-version ()
372 (message haskell-mode-version-string))
375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
379 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
381 ;;; some variables for later use
383 (defvar haskell-open-comment "{-")
384 (defvar haskell-close-comment "-}")
385 (defvar haskell-indentation-counter 0
386 "count repeated invocations of indent-for-tab-command")
387 (defvar haskell-literate-flag nil
388 "used to guide literate/illiterate behavior, set automagically")
390 (defun haskell-newline-and-indent ()
392 (setq haskell-literate-flag
395 (= (following-char) ?>)))
397 (if haskell-literate-flag (insert ">"))
398 (haskell-indent-line))
400 (defun haskell-indent-line ()
401 "Indent current line of ordinary or literate Haskell code."
403 (let ((indent (haskell-calculate-indentation-pjt-2)))
404 (if (/= (current-indentation) indent)
407 (if (= (following-char) ?>) (forward-char 1)) ;LITERATE
409 (skip-chars-forward "\t ")
410 (delete-region beg (point))
412 ;; If point is before indentation, move point to indentation
413 (if (< (current-column) (current-indentation))
414 (skip-chars-forward "\t ")))))
416 (defun haskell-calculate-indentation ()
418 (let ((col (current-column)))
419 (while (and (not (bobp)) ;skip over empty and comment-only lines
420 (= col (current-column)))
422 (beginning-of-line) ; Go to first non whitespace
423 (if (= (following-char) ?>) ;LITERATE
425 (if haskell-literate-flag ;ignore illiterate lines
427 (skip-chars-forward "\t ") ; on the line.
428 (setq col (current-column))
429 (search-forward-regexp (concat haskell-open-comment "\\|--\\|\n") nil 0)
430 (goto-char (match-beginning 0)))
431 (search-backward-regexp "\\b\\(where\\|let\\|of\\|in\\)\\b\\|\n" nil 0)
432 (if (looking-at "\n")
434 (setq col (current-column))
436 (skip-chars-forward "\t ")
437 (if (looking-at "\\w")
438 (setq col (current-column))
439 (setq col (+ 2 col))))
442 (defun haskell-calculate-indentation-pjt-2 ()
443 "Calculate indentation for Haskell program code, versatile version"
445 (if (eq last-command 'haskell-indentation)
446 (setq haskell-indentation-counter (1+ haskell-indentation-counter))
447 (setq haskell-indentation-counter -1))
448 (setq this-command 'haskell-indentation)
449 (let* ((simple-indent (haskell-calculate-indentation))
450 (count haskell-indentation-counter)
451 (min-indent simple-indent) ; minimum indentation found in a non-comment line
452 (last-indent simple-indent) ; indentation of the following non-comment line
453 (return-indent nil) ; computed indentation
456 (if (< haskell-indentation-counter 0) ; 1st tab gives simple indentation
457 (setq return-indent simple-indent))
458 (while (not return-indent)
459 (if (search-backward-regexp "\\b\\(where\\|let\\|of\\)\\b\\|\n\\|{-\\|-}" nil t 1)
461 ((looking-at haskell-open-comment)
462 (setq comment-depth (1- comment-depth)))
463 ((looking-at haskell-close-comment)
464 (setq comment-depth (1+ comment-depth)))
470 (if (= (following-char) ?>)
472 (if haskell-literate-flag
473 (end-of-line))) ;LITERATE: ignore lines w/o >
474 (skip-chars-forward "\t ")
475 (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
477 (setq last-indent (current-column))
478 (if (< last-indent min-indent)
479 (setq min-indent last-indent)))))
480 (t ; looking at a keyword
483 (skip-chars-forward " \t")
484 (if (and haskell-literate-flag ;LITERATE: ignore lines w/o >
487 (/= (following-char) ?>)))
489 (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
491 (setq last-indent (current-column)))
492 (if (<= last-indent min-indent)
494 (setq count (1- count))
495 (setq return-indent last-indent)))
496 (if (< last-indent min-indent)
497 (setq min-indent last-indent)))))))
498 (setq return-indent simple-indent)
499 (setq haskell-indentation-counter -1)))
502 (defun haskell-skip-nested-comment ()
503 ;; point looks at opening {-, move over closing -}
504 ;; todo: specify what happens on failure, bounds check ...
506 (let ((comment-depth 1))
507 (while (> comment-depth 0)
508 (search-forward-regexp "{-\\|-}")
509 (goto-char (match-beginning 0))
511 (if (= (following-char) 123) ; code for opening brace
514 (goto-char (match-end 0)))))
517 ;;;seemingly obsolete functions
518 (defun haskell-inside-of-inline-comment ()
519 (let ((bolp (save-excursion
522 (search-backward comment-start bolp t 1)))
524 (defun haskell-inside-of-nested-comment ()
528 (search-backward-regexp "\\({-\\|-}\\)" 0 t 1)
529 (if (haskell-inside-of-inline-comment)
531 (if (looking-at haskell-open-comment)
532 (setq count (1+ count))
533 (setq count (1- count)))))
536 (defun haskell-inside-of-comment ()
537 (or (haskell-inside-of-inline-comment)
538 (haskell-inside-of-nested-comment)))
540 ;;;stolen from sml-mode.el
541 (defun haskell-comment-indent ()
542 "Compute indentation for Haskell comments"
543 (if (looking-at "^--")
546 (skip-chars-backward " \t")
547 (max (1+ (current-column))
550 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
554 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
556 (defvar haskell-shell-map nil "The mode map for haskell-shell.")
558 (defun haskell-shell ()
559 "Inferior shell invoking Haskell.
560 It is not possible to have more than one shell running Haskell.
561 Like the shell mode with the additional command:
563 \\[haskell-run-on-file]\t Runs haskell on the file.
564 \\{haskell-shell-map}
565 Variables controlling the mode:
567 haskell-prog-name (default \"hbi\")
568 The string used to invoke the haskell program.
570 haskell-use-right-delim (default \"\\\"\")
571 haskell-use-left-delim (default \"\\\"\")
572 The left and right delimiter used by your version of haskell, for
575 haskell-process-name (default \"Haskell\")
576 The name of the process running haskell.
578 haskell-shell-prompt-pattern (default \"^> *\")
581 Runs haskell-shell-hook if not nil."
583 (if (not (process-status haskell-process-name))
584 (save-excursion ; Process is not running
585 (message "Starting Haskell...") ; start up a new process
587 (set-buffer (make-comint haskell-process-name haskell-prog-name))
588 (erase-buffer) ; Erase the buffer if a previous
589 (if haskell-shell-map ; process died in there
591 (setq haskell-shell-map (copy-keymap shell-mode-map))
592 (define-key haskell-shell-map "\C-c\C-f" 'haskell-run-on-file))
593 (use-local-map haskell-shell-map)
594 (make-local-variable 'shell-prompt-pattern)
595 (setq shell-prompt-pattern haskell-shell-prompt-pattern)
596 (setq major-mode 'haskell-shell)
597 (setq mode-name "Haskell Shell")
598 (setq mode-line-format
599 "-----Emacs: %17b %M %[(%m: %s)%]----%3p--%-")
600 (set-process-filter (get-process haskell-process-name) 'haskell-process-filter)
601 (message "Starting Haskell...done.")
602 (run-hooks 'haskell-shell-hook))))
604 (defun haskell-process-filter (proc str)
605 (let ((cur (current-buffer))
607 (pop-to-buffer (concat "*" haskell-process-name "*"))
608 (goto-char (point-max))
609 (if (string= str "\b\b\b \b\b\b")
610 (backward-delete-char 4)
612 (set-marker (process-mark proc) (point-max))
613 (pop-to-buffer cur)))
615 (defun haskell-pop-to-shell ()
618 (pop-to-buffer (concat "*" haskell-process-name "*")))
620 (defun haskell-run-on-file (fil)
621 (interactive "FRun Haskell on : ")
624 (process-send-string haskell-process-name
625 (concat "load " haskell-use-left-delim (expand-file-name fil)
626 haskell-use-right-delim ";\n")))
628 (defun haskell-save-buffer-use-file ()
629 "Save the buffer, and send a `use file' to the inferior shell
633 (if (setq file (buffer-file-name)) ; Is the buffer associated
637 (process-send-string haskell-process-name
638 (concat "load " haskell-use-left-delim
639 (expand-file-name file)
640 haskell-use-right-delim ";\n")))
641 (error "Buffer not associated with file."))))
643 (defvar haskell-tmp-files-list nil
644 "List of all temporary files created by haskell-simulate-send-region.
645 Each element in the list is a list with the format:
647 (\"tmp-filename\" buffer start-line)")
649 (defvar haskell-simulate-send-region-called-p nil
650 "Has haskell-simulate-send-region been called previously.")
652 (defun haskell-make-temp-name (pre)
653 (concat (make-temp-name pre) ".m"))
655 (defun haskell-simulate-send-region (point1 point2)
656 "Simulate send region. As send-region only can handle what ever the
657 system sets as the default, we have to make a temporary file.
658 Updates the list of temporary files (haskell-tmp-files-list)."
659 (let ((file (expand-file-name (haskell-make-temp-name haskell-tmp-template))))
660 ;; Remove temporary files when we leave emacs
661 (if (not haskell-simulate-send-region-called-p)
663 (setq haskell-old-kill-emacs-hook kill-emacs-hook)
664 (setq kill-emacs-hook 'haskell-remove-tmp-files)
665 (setq haskell-simulate-send-region-called-p t)))
668 (setq haskell-tmp-files-list
671 (save-excursion ; Calculate line no.
673 (1+ (count-lines 1 (point)))))
674 haskell-tmp-files-list)))
675 (write-region point1 point2 file nil 'dummy)
677 (message "Using temporary file: %s" file)
680 ;; string to send: load file;
681 (concat "load " haskell-use-left-delim file haskell-use-right-delim ";\n"))))
683 (defun haskell-remove-tmp-files ()
684 "Remove the temporary files, created by haskell-simulate-send-region, if
685 they still exist. Only files recorded in haskell-tmp-files-list are removed."
686 (message "Removing temporary files created by haskell-mode...")
687 (while haskell-tmp-files-list
689 (delete-file (car (car haskell-tmp-files-list)))
691 (setq haskell-tmp-files-list (cdr haskell-tmp-files-list)))
692 (message "Removing temporary files created by haskell-mode...done.")
693 (run-hooks 'haskell-old-kill-emacs-hook))
695 (defun haskell-send-region ()
701 (exchange-point-and-mark)
702 (setq start (point)))
703 (haskell-simulate-send-region start end)))
705 (defun haskell-send-buffer ()
708 (haskell-simulate-send-region (point-min) (point-max)))
710 (defun haskell-evaluate-expression (h-expr)
711 "Prompt for and evaluate an expression"
712 (interactive "sExpression: ")
713 (let ((str (concat h-expr ";\n"))
714 (buf (current-buffer)))
715 (haskell-pop-to-shell)
717 (process-send-string haskell-process-name str)
718 (pop-to-buffer buf)))
722 ;; font-lock-mode patterns, based on specs. in an earlier version
723 ;; of haskell-mode.el
724 ;; (these patterns have only been tested with 19.30)
726 (defconst haskell-font-lock-keywords nil
727 "Conservative highlighting of a Haskell buffer
730 (let ((haskell-id "[a-z_][a-zA-Z0-9_'#]+")
731 (haskell-reserved-ids
735 '("case" "class" "data"
736 "default" "deriving" "else"
737 "hiding" "if" "import" "in"
738 "instance" "interface" "let"
739 "module" "of" "renaming"
740 "then" "to" "type" "where" "infix[rl]?")
746 '("Bool" "()" "String" "Char" "Int"
747 "Integer" "Float" "Double" "Ratio"
748 "Assoc" "Rational" "Array")
751 (haskell-prelude-classes
754 '("Eq" "Ord" "Text" "Num" "Real" "Fractional"
755 "Integral" "RealFrac" "Floating" "RealFloat"
756 "Complex" "Ix" "Enum"
758 "_CCallable" "_CReturnable")
761 (haskell-reserved-ops
771 '(">>" ">>=" "thenPrimIO"
772 "seqPrimIO" "returnPrimIO"
773 "return" "_ccall_" "_casm_"
774 "thenST" "seqST" "returnST"
775 "thenStrictlyST" "seqStrictlyST" "returnStrictlyST"
776 "unsafeInterleavePrimIO" "unsafePerformIO")
779 (glasgow-haskell-types
783 '("IO" "PrimIO" "_?ST"
784 "_Word" "_Addr" "_?MVar"
785 "_?IVar" "_RealWorld"
790 (setq haskell-font-lock-keywords
792 '("--.*$" . font-lock-comment-face)
793 (list "[ \t\n]*\\([A-Za-z[(_][]A-Za-z0-9_$', ~@|:[)(#]*[ \t\n]*\\)=" 1 font-lock-function-name-face)
794 (list (concat "^>?[ \t\n]*\\(" haskell-id "\\)[ \t]*::") 1 'font-lock-function-name-face)
795 (list haskell-reserved-ids 0 'font-lock-function-name-face)
796 (list glasgow-haskell-ops 0 'font-lock-function-name-face)
797 (list glasgow-haskell-types 0 'font-lock-type-face)
798 (list haskell-basic-types 0 'font-lock-type-face)
799 (list haskell-prelude-classes 0 'font-lock-type-face)
800 (list "^[ \t\n]*\\([A-Za-z[(_][]A-Za-z0-9_$', @:[)(#]*[ \t\n]*\\)->" 1 font-lock-variable-name-face)
804 ;; To enable font-lock-mode for Haskell buffers, add something
805 ;; like this to your ~/.emacs
807 ;(cond (window-system
808 ; (require 'font-lock)
809 ; (add-hook 'haskell-mode-hook
810 ; '(lambda () (make-local-variable 'font-lock-defaults)
811 ; (make-local-variable 'font-lock-mode-hook) ; don't affect other buffers
812 ; (setq font-lock-mode-hook nil)
813 ; (add-hook 'font-lock-mode-hook
815 ; (setq font-lock-keywords haskell-font-lock-keywords)))
816 ; (font-lock-mode 1))))
820 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
822 ;;;; END OF Haskell-MODE
824 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
825 (provide 'haskell-mode)