Skip to content
This repository
Newer
Older
100644 191 lines (165 sloc) 7.614 kb
44188717 » monnier
2004-11-24 New file.
1 ;;; inf-haskell.el --- Interaction with an inferior Haskell process.
2
225a7c54 » monnier
2005-01-26 (inferior-haskell-load-file): Quote file name.
3 ;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
44188717 » monnier
2004-11-24 New file.
4
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6 ;; Keywords: Haskell
7
8 ;; This file is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; This file is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU Emacs; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;; Commentary:
24
25 ;; The code is made of 2 parts: a major mode for the buffer that holds the
225a7c54 » monnier
2005-01-26 (inferior-haskell-load-file): Quote file name.
26 ;; inferior process's session and a minor mode for use in source buffers.
44188717 » monnier
2004-11-24 New file.
27
28 ;;; Code:
29
30 (require 'comint)
31 (require 'shell) ;For directory tracking.
32 (require 'compile)
33
34 ;; Here I depart from the inferior-haskell- prefix.
35 ;; Not sure if it's a good idea.
27cc26c3 » monnier
2004-12-10 (haskell-program-name): Use ghci if hugs is absent.
36 (defcustom haskell-program-name
37 ;; Arbitrarily give preference to hugs over ghci.
38 (or (cond
39 ((not (fboundp 'executable-find)) nil)
40 ((executable-find "hugs") "hugs \"+.\"")
41 ((executable-find "ghci") "ghci"))
42 "hugs \"+.\"")
44188717 » monnier
2004-11-24 New file.
43 "The name of the command to start the inferior Haskell process.
44 The command can include arguments."
8b661ca0 » monnier
2005-07-18 (haskell-program-name): Fix defcustom delcaration.
45 ;; Custom only supports the :options keyword for a few types, e.g. not
46 ;; for string.
47 ;; :options '("hugs \"+.\"" "ghci")
44188717 » monnier
2004-11-24 New file.
48 :group 'haskell
49 :type '(choice string (repeat string)))
50
51 (defconst inferior-haskell-error-regexp-alist
52 ;; The format of error messages used by Hugs.
53 '(("^ERROR \"\\(.+?\\)\"\\(:\\| line \\)\\([0-9]+\\) - " 1 3)
54 ;; Format of error messages used by GHCi.
55 ("^\\(.+?\\):\\([0-9]\\):\\( \\|$\\)" 1 3)
56 )
57 "Regexps for error messages generated by inferior Haskell processes.
58 The format should be the same as for `compilation-error-regexp-alist'.")
59
60 (define-derived-mode inferior-haskell-mode comint-mode "Inf-Haskell"
61 "Major mode for interacting with an inferior Haskell process."
62 (set (make-local-variable 'comint-prompt-regexp)
63 "^\\*?[A-Z][\\._a-zA-Z0-9]*\\( \\*?[A-Z][\\._a-zA-Z0-9]*\\)*> ")
64 (set (make-local-variable 'comint-input-autoexpand) nil)
65
66 ;; Setup directory tracking.
67 (set (make-local-variable 'shell-dirtrackp) t)
68 (set (make-local-variable 'shell-cd-regexp) ":cd")
69 (add-hook 'comint-input-filter-functions 'shell-directory-tracker nil 'local)
70
71 ;; Setup `compile' support so you can just use C-x ` and friends.
72 (set (make-local-variable 'compilation-error-regexp-alist)
73 inferior-haskell-error-regexp-alist)
bfd15e13 » monnier
2005-11-04 (inferior-haskell-mode): Hide compilation-mode bindings.
74 (if (and (not (boundp 'minor-mode-overriding-map-alist))
75 (fboundp 'compilation-shell-minor-mode))
76 ;; If we can't remove compilation-minor-mode bindings, at least try to
77 ;; use compilation-shell-minor-mode, so there are fewer
78 ;; annoying bindings.
79 (compilation-shell-minor-mode 1)
80 ;; Else just use compilation-minor-mode but without its bindings because
81 ;; things like mouse-2 are simply too annoying.
82 (compilation-minor-mode 1)
83 (let ((map (make-sparse-keymap)))
84 (dolist (keys '([menu-bar] [follow-link]))
85 ;; Preserve some of the bindings.
86 (define-key map keys (lookup-key compilation-minor-mode-map keys)))
87 (add-to-list 'minor-mode-overriding-map-alist
88 (cons 'compilation-minor-mode map)))))
44188717 » monnier
2004-11-24 New file.
89
90 (defun inferior-haskell-string-to-strings (string &optional separator)
91 "Split the STRING into a list of strings.
92 The SEPARATOR regexp defaults to \"\\s-+\"."
93 (let ((sep (or separator "\\s-+"))
94 (i (string-match "[\"]" string)))
95 (if (null i) (split-string string sep) ; no quoting: easy
96 (append (unless (eq i 0) (split-string (substring string 0 i) sep))
97 (let ((rfs (read-from-string string i)))
98 (cons (car rfs)
99 (inferior-haskell-string-to-strings
100 (substring string (cdr rfs)) sep)))))))
101
102 (defun inferior-haskell-command (arg)
103 (inferior-haskell-string-to-strings
104 (if (null arg) haskell-program-name
6dd0f3a0 » monnier
2005-11-11 (inferior-haskell-command): Provide a default.
105 (read-string "Command to run haskell: " haskell-program-name))))
44188717 » monnier
2004-11-24 New file.
106
107 (defvar inferior-haskell-buffer nil
108 "The buffer in which the inferior process is running.")
109
110 (defun inferior-haskell-start-process (command)
111 "Start an inferior haskell process.
112 With universal prefix \\[universal-argument], prompts for a command,
113 otherwise uses `haskell-program-name'.
114 It runs the hook `inferior-haskell-hook' after starting the process and
115 setting up the inferior-haskell buffer."
116 (interactive (list (inferior-haskell-command current-prefix-arg)))
117 (setq inferior-haskell-buffer
118 (apply 'make-comint "haskell" (car command) nil (cdr command)))
119 (with-current-buffer inferior-haskell-buffer
120 (inferior-haskell-mode)
121 (run-hooks 'inferior-haskell-hook)))
122
123 (defun inferior-haskell-process (&optional arg)
124 (or (if (buffer-live-p inferior-haskell-buffer)
125 (get-buffer-process inferior-haskell-buffer))
126 (progn
127 (let ((current-prefix-arg arg))
128 (call-interactively 'inferior-haskell-start-process))
129 ;; Try again.
130 (inferior-haskell-process arg))))
131
132 ;;;###autoload
133 (defalias 'run-haskell 'switch-to-haskell)
134 ;;;###autoload
135 (defun switch-to-haskell (&optional arg)
136 "Show the inferior-haskell buffer. Start the process if needed."
137 (interactive "P")
138 (let ((proc (inferior-haskell-process arg)))
139 (pop-to-buffer (process-buffer proc))))
140
6dd0f3a0 » monnier
2005-11-11 (inferior-haskell-command): Provide a default.
141 (unless (fboundp 'with-selected-window)
142 (defmacro with-selected-window (win &rest body)
143 `(save-selected-window
144 (select-window ,win)
145 ,@body)))
146
44188717 » monnier
2004-11-24 New file.
147 ;;;###autoload
148 (defun inferior-haskell-load-file (&optional reload)
149 "Pass the current buffer's file to the inferior haskell process."
150 (interactive)
151 (let ((file buffer-file-name)
152 (proc (inferior-haskell-process)))
153 (save-buffer)
154 (with-current-buffer (process-buffer proc)
155 ;; Not sure if it's useful/needed and if it actually works.
156 ;; (unless (equal (file-name-as-directory default-directory)
157 ;; (file-name-directory file))
8512ba1e » monnier
2004-11-25 (inferior-haskell-mode): Typo.
158 ;; (inferior-haskell-send-string
159 ;; proc (concat ":cd " (file-name-directory file) "\n")))
44188717 » monnier
2004-11-24 New file.
160 (compilation-forget-errors)
bb67690a » monnier
2004-12-10 (haskell-program-name): Use ghci if hugs is absent.
161 (if (boundp 'compilation-parsing-end)
162 (if (markerp compilation-parsing-end)
163 (set-marker compilation-parsing-end (point-max))
164 (setq compilation-parsing-end (point-max))))
8512ba1e » monnier
2004-11-25 (inferior-haskell-mode): Typo.
165 (inferior-haskell-send-command
6dd0f3a0 » monnier
2005-11-11 (inferior-haskell-command): Provide a default.
166 proc (if reload ":reload" (concat ":load \"" file "\"")))
167 (display-buffer (current-buffer))
168 (with-selected-window (get-buffer-window (current-buffer) 0)
169 (goto-char (point-max))))))
8512ba1e » monnier
2004-11-25 (inferior-haskell-mode): Typo.
170
171 (defun inferior-haskell-send-command (proc str)
172 (setq str (concat str "\n"))
173 (with-current-buffer (process-buffer proc)
174 (while (and
175 (goto-char comint-last-input-end)
176 (not (re-search-forward comint-prompt-regexp nil t))
177 (accept-process-output proc)))
178 (goto-char (process-mark proc))
179 (insert-before-markers str)
180 (move-marker comint-last-input-end (point))
181 (comint-send-string proc str)))
44188717 » monnier
2004-11-24 New file.
182
183 (defun inferior-haskell-reload-file ()
184 "Tell the inferior haskell process to reread the current buffer's file."
185 (interactive)
186 (inferior-haskell-load-file 'reload))
187
188 (provide 'inf-haskell)
bfd15e13 » monnier
2005-11-04 (inferior-haskell-mode): Hide compilation-mode bindings.
189
190 ;; arch-tag: 61804287-63dd-4052-bc0e-90f691b34b40
44188717 » monnier
2004-11-24 New file.
191 ;;; inf-haskell.el ends here
Something went wrong with that request. Please try again.