+++ /dev/null
-;; haskell-mode.el. Major mode for editing Haskell.
-;; Copyright (C) 1989, Free Software Foundation, Inc., Lars Bo Nielsen
-;; and Lennart Augustsson
-;; modified by Peter Thiemann, March 1994
-
-;; This file is not officially part of GNU Emacs.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY. No author or distributor
-;; accepts responsibility to anyone for the consequences of using it
-;; or for whether it serves any particular purpose or works at all,
-;; unless he says so in writing. Refer to the GNU Emacs General Public
-;; License for full details.
-
-;; Everyone is granted permission to copy, modify and redistribute
-;; GNU Emacs, but only under the conditions described in the
-;; GNU Emacs General Public License. A copy of this license is
-;; supposed to have been given to you along with GNU Emacs so you
-;; can know your rights and responsibilities. It should be in a
-;; file named COPYING. Among other things, the copyright notice
-;; and this notice must be preserved on all copies.
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Haskell Mode. A major mode for editing and running Haskell. (Version 0.0)
-;; =================================================================
-;;
-;; This is a mode for editing and running Haskell.
-;; It is very much based on the sml mode for GNU Emacs. It
-;; features:
-;;
-;; - Inferior shell running Haskell. No need to leave emacs, just
-;; keep right on editing while Haskell runs in another window.
-;;
-;; - Automatic "load file" in inferior shell. Send regions of code
-;; to the Haskell program.
-;;
-;;
-;; 1. HOW TO USE THE Haskell-MODE
-;; ==========================
-;;
-;; Here is a short introduction to the mode.
-;;
-;; 1.1 GETTING STARTED
-;; -------------------
-;;
-;; If you are an experienced user of Emacs, just skip this section.
-;;
-;; To use the haskell-mode, insert this in your "~/.emacs" file (Or ask your
-;; emacs-administrator to help you.):
-;;
-;; (setq auto-mode-alist (cons '("\\.hs$" . haskell-mode) (cons '("\\.lhs$" . haskell-mode)
-;; auto-mode-alist)))
-;; (autoload 'haskell-mode "haskell-mode" "Major mode for editing Haskell." t)
-;;
-;; Now every time a file with the extension `.hs' or `.lhs' is found, it is
-;; automatically started up in haskell-mode.
-;;
-;; You will also have to specify the path to this file, so you will have
-;; to add this as well:
-;;
-;; (setq load-path (cons "/usr/me/emacs" load-path))
-;;
-;; where "/usr/me/emacs" is the directory where this file is.
-;;
-;; You may also want to compile the this file (M-x byte-compile-file)
-;; for speed.
-;;
-;; You are now ready to start using haskell-mode. If you have tried other
-;; language modes (like lisp-mode or C-mode), you should have no
-;; problems. There are only a few extra functions in this mode.
-;;
-;; 1.2. EDITING COMMANDS.
-;; ----------------------
-;;
-;; The following editing and inferior-shell commands can ONLY be issued
-;; from within a buffer in haskell-mode.
-;;
-;; LFD (haskell-newline-and-indent).
-;; This is probably the function you will be using the most (press
-;; CTRL while you press Return, press C-j or press Newline). It
-;; makes a new line and performs indentation based on the last
-;; preceding non-comment line.
-;;
-;; M-; (indent-for-comment).
-;; Like in other language modes, this command will give you a comment
-;; at the of the current line. The column where the comment starts is
-;; determined by the variable comment-column (default: 40).
-;;
-;; C-c C-v (haskell-mode-version).
-;; Get the version of the haskell-mode.
-;;
-;;
-;; 1.3. COMMANDS RELATED TO THE INFERIOR SHELL
-;; -------------------------------------------
-;;
-;; C-c C-s (haskell-pop-to-shell).
-;; This command starts up an inferior shell running haskell. If the shell
-;; is running, it will just pop up the shell window.
-;;
-;; C-c C-u (haskell-save-buffer-use-file).
-;; This command will save the current buffer and send a "load file",
-;; where file is the file visited by the current buffer, to the
-;; inferior shell running haskell.
-;;
-;; C-c C-f (haskell-run-on-file).
-;; Will send a "load file" to the inferior shell running haskell,
-;; prompting you for the file name.
-;;
-;; C-c C-r (haskell-send-region).
-;; Will send region, from point to mark, to the inferior shell
-;; running haskell.
-;;
-;; C-c C-b (haskell-send-buffer).
-;; Will send whole buffer to inferior shell running haskell.
-;;
-;; 2. INDENTATION
-;; ================
-;;
-;; The first indentation command (using C-j or TAB) on a given line
-;; indents like the last preceding non-comment line. The next TAB
-;; indents to the indentation of the innermost enclosing scope. Further
-;; TABs get you to further enclosing scopes. After indentation has
-;; reached the first column, the process restarts using the indentation
-;; of the preceding non-comment line, again.
-;;
-;; 3. INFERIOR SHELL.
-;; ==================
-;;
-;; The mode for Standard ML also contains a mode for an inferior shell
-;; running haskell. The mode is the same as the shell-mode, with just one
-;; extra command.
-;;
-;; 3.1. INFERIOR SHELL COMMANDS
-;; ----------------------------
-;;
-;; C-c C-f (haskell-run-on-file). Send a `load file' to the process running
-;; haskell.
-;;
-;; 3.2. CONSTANTS CONTROLLING THE INFERIOR SHELL MODE
-;; --------------------------------------------------
-;;
-;; Because haskell is called differently on various machines, and the
-;; haskell-systems have their own command for reading in a file, a set of
-;; constants controls the behavior of the inferior shell running haskell (to
-;; change these constants: See CUSTOMIZING YOUR Haskell-MODE below).
-;;
-;; haskell-prog-name (default "hbi").
-;; This constant is a string, containing the command to invoke
-;; Standard ML on your system.
-;;
-;; haskell-use-right-delim (default "\"")
-;; haskell-use-left-delim (default "\"")
-;; The left and right delimiter used by your version of haskell, for
-;; `use file-name'.
-;;
-;; haskell-process-name (default "Haskell").
-;; The name of the process running haskell. (This will be the name
-;; appearing on the mode line of the buffer)
-;;
-;; NOTE: The haskell-mode functions: haskell-send-buffer, haskell-send-function and
-;; haskell-send-region, creates temporary files (I could not figure out how
-;; to send large amounts of data to a process). These files will be
-;; removed when you leave emacs.
-;;
-;; 4. FONTIFICATION
-;;
-;; There is support for Jamie Zawinski's font-lock-mode through the
-;; variable "haskell-font-lock-keywords".
-;;
-;; 5. CUSTOMIZING YOUR Haskell-MODE
-;; ============================
-;;
-;; If you have to change some of the constants, you will have to add a
-;; `hook' to the haskell-mode. Insert this in your "~/.emacs" file.
-;;
-;; (setq haskell-mode-hook 'my-haskell-constants)
-;;
-;; Your function "my-haskell-constants" will then be executed every time
-;; "haskell-mode" is invoked. Now you only have to write the emacs-lisp
-;; function "my-haskell-constants", and put it in your "~/.emacs" file.
-;;
-;; Say you are running a version of haskell that uses the syntax `load
-;; ["file"]', is invoked by the command "OurHaskell" and you don't want the
-;; indentation algorithm to indent according to open parenthesis, your
-;; function should look like this:
-;;
-;; (defun my-haskell-constants ()
-;; (setq haskell-prog-name "OurHaskell")
-;; (setq haskell-use-left-delim "[\"")
-;; (setq haskell-use-right-delim "\"]")
-;; (setq haskell-paren-lookback nil))
-;;
-;; The haskell-shell also runs a `hook' (haskell-shell-hook) when it is invoked.
-;;
-;;
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;
-;; ORIGINAL AUTHOR
-;; Lars Bo Nielsen
-;; Aalborg University
-;; Computer Science Dept.
-;; 9000 Aalborg
-;; Denmark
-;;
-;; lbn@iesd.dk
-;; or: ...!mcvax!diku!iesd!lbn
-;; or: mcvax!diku!iesd!lbn@uunet.uu.net
-;;
-;; MODIFIED FOR Haskell BY
-;; Lennart Augustsson
-;; indentation stuff by Peter Thiemann
-;;
-;;
-;; Please let me know if you come up with any ideas, bugs, or fixes.
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defconst haskell-mode-version-string
- "HASKELL-MODE, Version 0.2, PJT indentation")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;
-;;; CONSTANTS CONTROLLING THE MODE.
-;;;
-;;; These are the constants you might want to change
-;;;
-
-;; The command used to start up the haskell-program.
-(defconst haskell-prog-name "hbi" "*Name of program to run as haskell.")
-
-;; The left delimmitter for `load file'
-(defconst haskell-use-left-delim "\""
- "*The left delimiter for the filename when using \"load\".")
-
-;; The right delimmitter for `load file'
-(defconst haskell-use-right-delim "\""
- "*The right delimiter for the filename when using \"load\".")
-
-;; A regular expression matching the prompt pattern in the inferior
-;; shell
-(defconst haskell-shell-prompt-pattern "^> *"
- "*The prompt pattern for the inferion shell running haskell.")
-
-;; The template used for temporary files, created when a region is
-;; send to the inferior process running haskell.
-(defconst haskell-tmp-template "/tmp/haskell.tmp."
- "*Template for the temporary file, created by haskell-simulate-send-region.")
-
-;; The name of the process running haskell (This will also be the name of
-;; the buffer).
-(defconst haskell-process-name "Haskell" "*The name of the Haskell-process")
-
-;;;
-;;; END OF CONSTANTS CONTROLLING THE MODE.
-;;;
-;;; If you change anything below, you are on your own.
-;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defvar haskell-mode-syntax-table nil "The syntax table used in haskell-mode.")
-
-(defvar haskell-mode-map nil "The mode map used in haskell-mode.")
-
-(defvar haskell-mode-abbrev-table nil "The abbrev-table used in haskell-mode.")
-
-(defvar haskell-old-kill-emacs-hook nil "Old value of kill-emacs-hook")
-
-(defun haskell-mode ()
- "Major mode for editing Haskell code.
-Tab indents for Haskell code.
-Comments are delimited with --
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-
-Key bindings:
-=============
-
-\\[haskell-pop-to-shell]\t Pop to the haskell window.
-\\[haskell-save-buffer-use-file]\t Save the buffer, and send a \"load file\".
-\\[haskell-send-region]\t Send region (point and mark) to haskell.
-\\[haskell-run-on-file]\t Send a \"load file\" to haskell.
-\\[haskell-send-buffer]\t Send whole buffer to haskell.
-\\[haskell-mode-version]\t Get the version of haskell-mode.
-\\[haskell-evaluate-expression]\t Prompt for an expression and evalute it.
-
-
-Mode map
-========
-\\{haskell-mode-map}
-Runs haskell-mode-hook if non nil."
- (interactive)
- (kill-all-local-variables)
- (if haskell-mode-map
- ()
- (setq haskell-mode-map (make-sparse-keymap))
- (define-key haskell-mode-map "\C-c\C-v" 'haskell-mode-version)
- (define-key haskell-mode-map "\C-c\C-u" 'haskell-save-buffer-use-file)
- (define-key haskell-mode-map "\C-c\C-s" 'haskell-pop-to-shell)
- (define-key haskell-mode-map "\C-c\C-r" 'haskell-send-region)
- (define-key haskell-mode-map "\C-c\C-m" 'haskell-region)
- (define-key haskell-mode-map "\C-c\C-f" 'haskell-run-on-file)
- (define-key haskell-mode-map "\C-c\C-b" 'haskell-send-buffer)
- (define-key haskell-mode-map "\C-c\C-l" 'comment-line)
- (define-key haskell-mode-map "\C-ce" 'haskell-evaluate-expression)
-; (define-key haskell-mode-map "\C-j" 'haskell-newline-and-indent)
- (define-key haskell-mode-map [S-tab] 'tab-to-tab-stop)
- (define-key haskell-mode-map "\177" 'backward-delete-char-untabify))
- (use-local-map haskell-mode-map)
- (setq major-mode 'haskell-mode)
- (setq mode-name "Haskell")
- (define-abbrev-table 'haskell-mode-abbrev-table ())
- (setq local-abbrev-table haskell-mode-abbrev-table)
- (if haskell-mode-syntax-table
- ()
- (setq haskell-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?{ "(}1" haskell-mode-syntax-table)
- (modify-syntax-entry ?} "){4" haskell-mode-syntax-table)
-; partain: out
-; (modify-syntax-entry ?- "_ 2356" haskell-mode-syntax-table)
-; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
-; (modify-syntax-entry ?\n "> b" haskell-mode-syntax-table)
-; partain: end out
-; partain: in
- (modify-syntax-entry ?- "_ 23" haskell-mode-syntax-table)
-; (modify-syntax-entry ?\f "> b" haskell-mode-syntax-table)
-; (modify-syntax-entry ?\n "> b" haskell-mode-syntax-table)
-; partain: end in
- (modify-syntax-entry ?\\ "\\" haskell-mode-syntax-table)
- (modify-syntax-entry ?* "_" haskell-mode-syntax-table)
- (modify-syntax-entry ?_ "_" haskell-mode-syntax-table)
- (modify-syntax-entry ?' "_" haskell-mode-syntax-table)
- (modify-syntax-entry ?: "_" haskell-mode-syntax-table)
- (modify-syntax-entry ?| "." haskell-mode-syntax-table)
- )
- (set-syntax-table haskell-mode-syntax-table)
- (make-local-variable 'require-final-newline) ; Always put a new-line
- (setq require-final-newline t) ; in the end of file
-; (make-local-variable 'change-major-mode-hook)
-; (setq change-major-mode-hook nil)
-; (make-local-variable 'indent-line-function)
-; (setq indent-line-function 'haskell-indent-line)
- (make-local-variable 'comment-start)
- (setq comment-start "-- ")
-; (setq comment-start "{- ")
- (make-local-variable 'comment-end)
- (setq comment-end "")
-; (setq comment-end " -}")
- (make-local-variable 'comment-column)
- (setq comment-column 60) ; Start of comment in this column
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "{-+ *\\|--+ *") ; This matches a start of comment
- (make-local-variable 'comment-multi-line)
- (setq comment-multi-line nil)
-; (make-local-variable 'comment-indent-function)
-; (setq comment-indent-function 'haskell-comment-indent)
- ;;
- ;; Adding these will fool the matching of parens. I really don't
- ;; know why. It would be nice to have comments treated as
- ;; white-space
- ;;
- ;; (make-local-variable 'parse-sexp-ignore-comments)
- ;; (setq parse-sexp-ignore-comments t)
- ;;
- (run-hooks 'haskell-mode-hook)) ; Run the hook
-
-(defun haskell-mode-version ()
- (interactive)
- (message haskell-mode-version-string))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;
-;;; INDENTATION
-;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;; some variables for later use
-
-(defvar haskell-open-comment "{-")
-(defvar haskell-close-comment "-}")
-(defvar haskell-indentation-counter 0
- "count repeated invocations of indent-for-tab-command")
-(defvar haskell-literate-flag nil
- "used to guide literate/illiterate behavior, set automagically")
-
-(defun haskell-newline-and-indent ()
- (interactive)
- (setq haskell-literate-flag
- (save-excursion
- (beginning-of-line)
- (= (following-char) ?>)))
- (newline)
- (if haskell-literate-flag (insert ">"))
- (haskell-indent-line))
-
-(defun haskell-indent-line ()
- "Indent current line of ordinary or literate Haskell code."
- (interactive)
- (let ((indent (haskell-calculate-indentation-pjt-2)))
- (if (/= (current-indentation) indent)
- (let ((beg (progn
- (beginning-of-line)
- (if (= (following-char) ?>) (forward-char 1)) ;LITERATE
- (point))))
- (skip-chars-forward "\t ")
- (delete-region beg (point))
- (indent-to indent))
- ;; If point is before indentation, move point to indentation
- (if (< (current-column) (current-indentation))
- (skip-chars-forward "\t ")))))
-
-(defun haskell-calculate-indentation ()
- (save-excursion
- (let ((col (current-column)))
- (while (and (not (bobp)) ;skip over empty and comment-only lines
- (= col (current-column)))
- (previous-line 1)
- (beginning-of-line) ; Go to first non whitespace
- (if (= (following-char) ?>) ;LITERATE
- (forward-char 1)
- (if haskell-literate-flag ;ignore illiterate lines
- (end-of-line)))
- (skip-chars-forward "\t ") ; on the line.
- (setq col (current-column))
- (search-forward-regexp (concat haskell-open-comment "\\|--\\|\n") nil 0)
- (goto-char (match-beginning 0)))
- (search-backward-regexp "\\b\\(where\\|let\\|of\\|in\\)\\b\\|\n" nil 0)
- (if (looking-at "\n")
- ()
- (setq col (current-column))
- (forward-word 1)
- (skip-chars-forward "\t ")
- (if (looking-at "\\w")
- (setq col (current-column))
- (setq col (+ 2 col))))
- col)))
-
-(defun haskell-calculate-indentation-pjt-2 ()
- "Calculate indentation for Haskell program code, versatile version"
- (save-excursion
- (if (eq last-command 'haskell-indentation)
- (setq haskell-indentation-counter (1+ haskell-indentation-counter))
- (setq haskell-indentation-counter -1))
- (setq this-command 'haskell-indentation)
- (let* ((simple-indent (haskell-calculate-indentation))
- (count haskell-indentation-counter)
- (min-indent simple-indent) ; minimum indentation found in a non-comment line
- (last-indent simple-indent) ; indentation of the following non-comment line
- (return-indent nil) ; computed indentation
- (comment-depth 0))
- (previous-line 1)
- (if (< haskell-indentation-counter 0) ; 1st tab gives simple indentation
- (setq return-indent simple-indent))
- (while (not return-indent)
- (if (search-backward-regexp "\\b\\(where\\|let\\|of\\)\\b\\|\n\\|{-\\|-}" nil t 1)
- (cond
- ((looking-at haskell-open-comment)
- (setq comment-depth (1- comment-depth)))
- ((looking-at haskell-close-comment)
- (setq comment-depth (1+ comment-depth)))
- ((= 0 comment-depth)
- (cond
- ((looking-at "\n")
- (save-excursion
- (forward-char 1)
- (if (= (following-char) ?>)
- (forward-char 1)
- (if haskell-literate-flag
- (end-of-line))) ;LITERATE: ignore lines w/o >
- (skip-chars-forward "\t ")
- (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
- ()
- (setq last-indent (current-column))
- (if (< last-indent min-indent)
- (setq min-indent last-indent)))))
- (t ; looking at a keyword
- (save-excursion
- (forward-word 1)
- (skip-chars-forward " \t")
- (if (and haskell-literate-flag ;LITERATE: ignore lines w/o >
- (save-excursion
- (beginning-of-line)
- (/= (following-char) ?>)))
- (end-of-line))
- (if (looking-at (concat haskell-open-comment "\\|--\\|\n"))
- ()
- (setq last-indent (current-column)))
- (if (<= last-indent min-indent)
- (if (> count 0)
- (setq count (1- count))
- (setq return-indent last-indent)))
- (if (< last-indent min-indent)
- (setq min-indent last-indent)))))))
- (setq return-indent simple-indent)
- (setq haskell-indentation-counter -1)))
- return-indent)))
-
-(defun haskell-skip-nested-comment ()
- ;; point looks at opening {-, move over closing -}
- ;; todo: specify what happens on failure, bounds check ...
- (forward-char 2)
- (let ((comment-depth 1))
- (while (> comment-depth 0)
- (search-forward-regexp "{-\\|-}")
- (goto-char (match-beginning 0))
- (setq comment-depth
- (if (= (following-char) 123) ; code for opening brace
- (1+ comment-depth)
- (1- comment-depth)))
- (goto-char (match-end 0)))))
-
-
-;;;seemingly obsolete functions
-(defun haskell-inside-of-inline-comment ()
- (let ((bolp (save-excursion
- (beginning-of-line)
- (point))))
- (search-backward comment-start bolp t 1)))
-
-(defun haskell-inside-of-nested-comment ()
- (save-excursion
- (let ((count 0))
- (while
- (search-backward-regexp "\\({-\\|-}\\)" 0 t 1)
- (if (haskell-inside-of-inline-comment)
- ()
- (if (looking-at haskell-open-comment)
- (setq count (1+ count))
- (setq count (1- count)))))
- (> count 0))))
-
-(defun haskell-inside-of-comment ()
- (or (haskell-inside-of-inline-comment)
- (haskell-inside-of-nested-comment)))
-
-;;;stolen from sml-mode.el
-(defun haskell-comment-indent ()
- "Compute indentation for Haskell comments"
- (if (looking-at "^--")
- 0
- (save-excursion
- (skip-chars-backward " \t")
- (max (1+ (current-column))
- comment-column))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;
-;;; INFERIOR SHELL
-;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar haskell-shell-map nil "The mode map for haskell-shell.")
-
-(defun haskell-shell ()
- "Inferior shell invoking Haskell.
-It is not possible to have more than one shell running Haskell.
-Like the shell mode with the additional command:
-
-\\[haskell-run-on-file]\t Runs haskell on the file.
-\\{haskell-shell-map}
-Variables controlling the mode:
-
-haskell-prog-name (default \"hbi\")
- The string used to invoke the haskell program.
-
-haskell-use-right-delim (default \"\\\"\")
-haskell-use-left-delim (default \"\\\"\")
- The left and right delimiter used by your version of haskell, for
- \"load file-name\".
-
-haskell-process-name (default \"Haskell\")
- The name of the process running haskell.
-
-haskell-shell-prompt-pattern (default \"^> *\")
- The prompt pattern.
-
-Runs haskell-shell-hook if not nil."
- (interactive)
- (if (not (process-status haskell-process-name))
- (save-excursion ; Process is not running
- (message "Starting Haskell...") ; start up a new process
- (require 'shell)
- (set-buffer (make-comint haskell-process-name haskell-prog-name))
- (erase-buffer) ; Erase the buffer if a previous
- (if haskell-shell-map ; process died in there
- ()
- (setq haskell-shell-map (copy-keymap shell-mode-map))
- (define-key haskell-shell-map "\C-c\C-f" 'haskell-run-on-file))
- (use-local-map haskell-shell-map)
- (make-local-variable 'shell-prompt-pattern)
- (setq shell-prompt-pattern haskell-shell-prompt-pattern)
- (setq major-mode 'haskell-shell)
- (setq mode-name "Haskell Shell")
- (setq mode-line-format
- "-----Emacs: %17b %M %[(%m: %s)%]----%3p--%-")
- (set-process-filter (get-process haskell-process-name) 'haskell-process-filter)
- (message "Starting Haskell...done.")
- (run-hooks 'haskell-shell-hook))))
-
-(defun haskell-process-filter (proc str)
- (let ((cur (current-buffer))
- (pop-up-windows t))
- (pop-to-buffer (concat "*" haskell-process-name "*"))
- (goto-char (point-max))
- (if (string= str "\b\b\b \b\b\b")
- (backward-delete-char 4)
- (insert str))
- (set-marker (process-mark proc) (point-max))
- (pop-to-buffer cur)))
-
-(defun haskell-pop-to-shell ()
- (interactive)
- (haskell-shell)
- (pop-to-buffer (concat "*" haskell-process-name "*")))
-
-(defun haskell-run-on-file (fil)
- (interactive "FRun Haskell on : ")
- (haskell-shell)
- (save-some-buffers)
- (process-send-string haskell-process-name
- (concat "load " haskell-use-left-delim (expand-file-name fil)
- haskell-use-right-delim ";\n")))
-
-(defun haskell-save-buffer-use-file ()
- "Save the buffer, and send a `use file' to the inferior shell
-running Haskell."
- (interactive)
- (let (file)
- (if (setq file (buffer-file-name)) ; Is the buffer associated
- (progn ; with file ?
- (save-buffer)
- (haskell-shell)
- (process-send-string haskell-process-name
- (concat "load " haskell-use-left-delim
- (expand-file-name file)
- haskell-use-right-delim ";\n")))
- (error "Buffer not associated with file."))))
-
-(defvar haskell-tmp-files-list nil
- "List of all temporary files created by haskell-simulate-send-region.
-Each element in the list is a list with the format:
-
- (\"tmp-filename\" buffer start-line)")
-
-(defvar haskell-simulate-send-region-called-p nil
- "Has haskell-simulate-send-region been called previously.")
-
-(defun haskell-make-temp-name (pre)
- (concat (make-temp-name pre) ".m"))
-
-(defun haskell-simulate-send-region (point1 point2)
- "Simulate send region. As send-region only can handle what ever the
-system sets as the default, we have to make a temporary file.
-Updates the list of temporary files (haskell-tmp-files-list)."
- (let ((file (expand-file-name (haskell-make-temp-name haskell-tmp-template))))
- ;; Remove temporary files when we leave emacs
- (if (not haskell-simulate-send-region-called-p)
- (progn
- (setq haskell-old-kill-emacs-hook kill-emacs-hook)
- (setq kill-emacs-hook 'haskell-remove-tmp-files)
- (setq haskell-simulate-send-region-called-p t)))
- (save-excursion
- (goto-char point1)
- (setq haskell-tmp-files-list
- (cons (list file
- (current-buffer)
- (save-excursion ; Calculate line no.
- (beginning-of-line)
- (1+ (count-lines 1 (point)))))
- haskell-tmp-files-list)))
- (write-region point1 point2 file nil 'dummy)
- (haskell-shell)
- (message "Using temporary file: %s" file)
- (process-send-string
- haskell-process-name
- ;; string to send: load file;
- (concat "load " haskell-use-left-delim file haskell-use-right-delim ";\n"))))
-
-(defun haskell-remove-tmp-files ()
- "Remove the temporary files, created by haskell-simulate-send-region, if
-they still exist. Only files recorded in haskell-tmp-files-list are removed."
- (message "Removing temporary files created by haskell-mode...")
- (while haskell-tmp-files-list
- (condition-case ()
- (delete-file (car (car haskell-tmp-files-list)))
- (error ()))
- (setq haskell-tmp-files-list (cdr haskell-tmp-files-list)))
- (message "Removing temporary files created by haskell-mode...done.")
- (run-hooks 'haskell-old-kill-emacs-hook))
-
-(defun haskell-send-region ()
- "Send region."
- (interactive)
- (let (start end)
- (save-excursion
- (setq end (point))
- (exchange-point-and-mark)
- (setq start (point)))
- (haskell-simulate-send-region start end)))
-
-(defun haskell-send-buffer ()
- "Send the buffer."
- (interactive)
- (haskell-simulate-send-region (point-min) (point-max)))
-
-(defun haskell-evaluate-expression (h-expr)
- "Prompt for and evaluate an expression"
- (interactive "sExpression: ")
- (let ((str (concat h-expr ";\n"))
- (buf (current-buffer)))
- (haskell-pop-to-shell)
- (insert str)
- (process-send-string haskell-process-name str)
- (pop-to-buffer buf)))
-
-
-;;
-;; font-lock-mode patterns, based on specs. in an earlier version
-;; of haskell-mode.el
-;; (these patterns have only been tested with 19.30)
-
-(defconst haskell-font-lock-keywords nil
- "Conservative highlighting of a Haskell buffer
-(using font-lock.)")
-
-(let ((haskell-id "[a-z_][a-zA-Z0-9_'#]+")
- (haskell-reserved-ids
- (concat "\\b\\("
- (mapconcat
- 'identity
- '("case" "class" "data"
- "default" "deriving" "else"
- "hiding" "if" "import" "in"
- "instance" "interface" "let"
- "module" "of" "renaming"
- "then" "to" "type" "where" "infix[rl]?")
- "\\|")
- "\\)[ \t\n:,]"))
- (haskell-basic-types
- (concat "\\b\\("
- (mapconcat 'identity
- '("Bool" "()" "String" "Char" "Int"
- "Integer" "Float" "Double" "Ratio"
- "Assoc" "Rational" "Array")
- "\\|")
- "\\)\\b"))
- (haskell-prelude-classes
- (concat "\\b\\("
- (mapconcat 'identity
- '("Eq" "Ord" "Text" "Num" "Real" "Fractional"
- "Integral" "RealFrac" "Floating" "RealFloat"
- "Complex" "Ix" "Enum"
- ;; ghc-isms
- "_CCallable" "_CReturnable")
- "\\|")
- "\\)\\b"))
- (haskell-reserved-ops
- (mapconcat 'identity
- '("\\.\\." "::"
- "=>" "/=" "@"
- "<-" "->")
- "\\|"))
- (glasgow-haskell-ops
- (concat "\\b\\("
- (mapconcat
- 'identity
- '(">>" ">>=" "thenPrimIO"
- "seqPrimIO" "returnPrimIO"
- "return" "_ccall_" "_casm_"
- "thenST" "seqST" "returnST"
- "thenStrictlyST" "seqStrictlyST" "returnStrictlyST"
- "unsafeInterleavePrimIO" "unsafePerformIO")
- "\\|")
- "\\)\\b"))
- (glasgow-haskell-types
- (concat "\\b\\("
- (mapconcat
- 'identity
- '("IO" "PrimIO" "_?ST"
- "_Word" "_Addr" "_?MVar"
- "_?IVar" "_RealWorld"
- "_?MutableByteArray"
- "_?ByteArray")
- "\\|")
- "\\)\\b")))
- (setq haskell-font-lock-keywords
- (list
- '("--.*$" . font-lock-comment-face)
- (list "[ \t\n]*\\([A-Za-z[(_][]A-Za-z0-9_$', ~@|:[)(#]*[ \t\n]*\\)=" 1 font-lock-function-name-face)
- (list (concat "^>?[ \t\n]*\\(" haskell-id "\\)[ \t]*::") 1 'font-lock-function-name-face)
- (list haskell-reserved-ids 0 'font-lock-function-name-face)
- (list glasgow-haskell-ops 0 'font-lock-function-name-face)
- (list glasgow-haskell-types 0 'font-lock-type-face)
- (list haskell-basic-types 0 'font-lock-type-face)
- (list haskell-prelude-classes 0 'font-lock-type-face)
- (list "^[ \t\n]*\\([A-Za-z[(_][]A-Za-z0-9_$', @:[)(#]*[ \t\n]*\\)->" 1 font-lock-variable-name-face)
- )))
-
-;;
-;; To enable font-lock-mode for Haskell buffers, add something
-;; like this to your ~/.emacs
-
-;(cond (window-system
-; (require 'font-lock)
-; (add-hook 'haskell-mode-hook
-; '(lambda () (make-local-variable 'font-lock-defaults)
-; (make-local-variable 'font-lock-mode-hook) ; don't affect other buffers
-; (setq font-lock-mode-hook nil)
-; (add-hook 'font-lock-mode-hook
-; '(lambda ()
-; (setq font-lock-keywords haskell-font-lock-keywords)))
-; (font-lock-mode 1))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;
-;;;; END OF Haskell-MODE
-;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(provide 'haskell-mode)