REPL: remembering last connection address
[geiser.git] / elisp / geiser-repl.el
blob13b655e8c8192816b341642ca0dd565935c43c80
1 ;;; geiser-repl.el --- Geiser's REPL
3 ;; Copyright (C) 2009, 2010 Jose Antonio Ortega Ruiz
5 ;; This program is free software; you can redistribute it and/or
6 ;; modify it under the terms of the Modified BSD License. You should
7 ;; have received a copy of the license along with this program. If
8 ;; not, see <http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5>.
12 (require 'geiser-company)
13 (require 'geiser-autodoc)
14 (require 'geiser-edit)
15 (require 'geiser-completion)
16 (require 'geiser-impl)
17 (require 'geiser-eval)
18 (require 'geiser-connection)
19 (require 'geiser-menu)
20 (require 'geiser-custom)
21 (require 'geiser-base)
23 (require 'comint)
24 (require 'compile)
25 (require 'scheme)
28 ;;; Customization:
30 (defgroup geiser-repl nil
31 "Interacting with the Geiser REPL."
32 :group 'geiser)
34 (geiser-custom--defcustom geiser-repl-use-other-window t
35 "Whether to Use a window other than the current buffer's when
36 switching to the Geiser REPL buffer."
37 :type 'boolean
38 :group 'geiser-repl)
40 (geiser-custom--defcustom geiser-repl-window-allow-split t
41 "Whether to allow window splitting when switching to the Geiser
42 REPL buffer."
43 :type 'boolean
44 :group 'geiser-repl)
46 (geiser-custom--defcustom geiser-repl-history-filename (expand-file-name "~/.geiser_history")
47 "File where REPL input history is saved, so that it persists between sessions.
48 This is actually the base name: the concrete Scheme
49 implementation name gets appended to it."
50 :type 'filename
51 :group 'geiser-repl)
53 (geiser-custom--defcustom geiser-repl-history-size comint-input-ring-size
54 "Maximum size of the saved REPL input history."
55 :type 'integer
56 :group 'geiser-repl)
58 (geiser-custom--defcustom geiser-repl-history-no-dups-p t
59 "Whether to skip duplicates when recording history."
60 :type 'boolean
61 :group 'geiser-repl)
63 (geiser-custom--defcustom geiser-repl-autodoc-p t
64 "Whether to enable `geiser-autodoc-mode' in the REPL by default."
65 :type 'boolean
66 :group 'geiser-repl)
68 (geiser-custom--defcustom geiser-repl-company-p t
69 "Whether to use company-mode for completion, if available."
70 :group 'geiser-mode
71 :type 'boolean)
73 (geiser-custom--defcustom geiser-repl-read-only-prompt-p t
74 "Whether the REPL's prompt should be read-only."
75 :type 'boolean
76 :group 'geiser-repl)
78 (geiser-custom--defcustom geiser-repl-auto-indent-p t
79 "Whether newlines for incomplete sexps are autoindented."
80 :type 'boolean
81 :group 'geiser-repl)
83 (geiser-custom--defcustom geiser-repl-forget-old-errors-p t
84 "Whether to forget old errors upon entering a new expression.
86 When on (the default), every time a new expression is entered in
87 the REPL old error messages are flushed, and using \\[next-error]
88 afterwards will jump only to error locations produced by the new
89 expression, if any."
90 :type 'boolean
91 :group 'geiser-repl)
93 (geiser-custom--defcustom geiser-repl-query-on-exit-p nil
94 "Whether to prompt for confirmation on \\[geiser-repl-exit]."
95 :type 'boolean
96 :group 'geiser-repl)
98 (geiser-custom--defcustom geiser-repl-default-host "localhost"
99 "Default host when connecting to remote REPLs."
100 :type 'string
101 :group 'geiser-repl)
103 (geiser-custom--defcustom geiser-repl-default-port 37146
104 "Default port for connecting to remote REPLs."
105 :type 'integer
106 :group 'geiser-repl)
109 ;;; Geiser REPL buffers and processes:
111 (defvar geiser-repl--repls nil)
112 (defvar geiser-repl--closed-repls nil)
114 (make-variable-buffer-local
115 (defvar geiser-repl--repl nil))
117 (defsubst geiser-repl--set-this-buffer-repl (r)
118 (setq geiser-repl--repl r))
120 (defun geiser-repl--live-p ()
121 (and geiser-repl--repl
122 (get-buffer-process geiser-repl--repl)))
124 (defun geiser-repl--repl/impl (impl &optional repls)
125 (catch 'repl
126 (dolist (repl (or repls geiser-repl--repls))
127 (when (buffer-live-p repl)
128 (with-current-buffer repl
129 (when (eq geiser-impl--implementation impl)
130 (throw 'repl repl)))))))
132 (defun geiser-repl--set-up-repl (impl)
133 (or (and (not impl) geiser-repl--repl)
134 (setq geiser-repl--repl
135 (let ((impl (or impl
136 geiser-impl--implementation
137 (geiser-impl--guess))))
138 (when impl (geiser-repl--repl/impl impl))))))
140 (defun geiser-repl--active-impls ()
141 (let ((act))
142 (dolist (repl geiser-repl--repls act)
143 (with-current-buffer repl
144 (add-to-list 'act geiser-impl--implementation)))))
146 (defsubst geiser-repl--repl-name (impl)
147 (format "%s REPL" (geiser-impl--impl-str impl)))
149 (defun geiser-repl--to-repl-buffer (impl)
150 (unless (and (eq major-mode 'geiser-repl-mode)
151 (not (get-buffer-process (current-buffer))))
152 (let* ((old (geiser-repl--repl/impl impl geiser-repl--closed-repls))
153 (old (and (buffer-live-p old)
154 (not (get-buffer-process old))
155 old)))
156 (pop-to-buffer
157 (or old
158 (generate-new-buffer (format "* %s *"
159 (geiser-repl--repl-name impl)))))
160 (unless old
161 (geiser-repl-mode)
162 (geiser-impl--set-buffer-implementation impl)))))
164 (geiser-impl--define-caller geiser-repl--binary binary ()
165 "A variable or function returning the path to the scheme binary
166 for this implementation.")
168 (geiser-impl--define-caller geiser-repl--arglist arglist ()
169 "A function taking no arguments and returning a list of
170 arguments to be used when invoking the scheme binary.")
172 (geiser-impl--define-caller geiser-repl--prompt-regexp prompt-regexp ()
173 "A variable (or thunk returning a value) giving the regular
174 expression for this implementation's scheme prompt.")
176 (geiser-impl--define-caller
177 geiser-repl--debugger-prompt-regexp debugger-prompt-regexp ()
178 "A variable (or thunk returning a value) giving the regular
179 expression for this implementation's debugging prompt.")
181 (geiser-impl--define-caller
182 geiser-repl--debugger-preamble-regexp debugger-preamble-regexp ()
183 "A variable (or thunk returning a value) used to determine whether
184 the REPL has entered debugging mode.")
186 (geiser-impl--define-caller geiser-repl--startup startup ()
187 "Function taking no parameters that is called after the REPL
188 has been initialised. All Geiser functionality is available to
189 you at that point.")
191 (geiser-impl--define-caller geiser-repl--enter-cmd enter-command (module)
192 "Function taking a module designator and returning a REPL enter
193 module command as a string")
195 (geiser-impl--define-caller geiser-repl--import-cmd import-command (module)
196 "Function taking a module designator and returning a REPL import
197 module command as a string")
199 (geiser-impl--define-caller geiser-repl--exit-cmd exit-command ()
200 "Function returning the REPL exit command as a string")
202 (make-variable-buffer-local
203 (defvar geiser-repl--address nil))
205 (defsubst geiser-repl--host () (car geiser-repl--address))
206 (defsubst geiser-repl--port () (cdr geiser-repl--address))
207 (defsubst geiser-repl--remote-p () geiser-repl--address)
209 (defun geiser-repl--get-address ()
210 (let ((defhost (or (geiser-repl--host) geiser-repl-default-host))
211 (defport (or (geiser-repl--port) geiser-repl-default-port)))
212 (cons (read-string (format "Host (default %s): " defhost) nil nil defhost)
213 (read-number "Port: " defport))))
215 (defun geiser-repl--save-remote-data (remote address)
216 (setq geiser-repl--address (and remote address))
217 (when remote
218 (setq header-line-format (format "Host: %s Port: %s"
219 (geiser-repl--host)
220 (geiser-repl--port)))))
222 (defun geiser-repl--start-repl (impl &optional remote)
223 (message "Starting Geiser REPL for %s ..." impl)
224 (geiser-repl--to-repl-buffer impl)
225 (let ((program (if remote (geiser-repl--get-address)
226 (geiser-repl--binary impl)))
227 (args (geiser-repl--arglist impl))
228 (prompt-rx (geiser-repl--prompt-regexp impl))
229 (deb-prompt-rx (geiser-repl--debugger-prompt-regexp impl))
230 (deb-preamble-rx (geiser-repl--debugger-preamble-regexp impl))
231 (cname (geiser-repl--repl-name impl)))
232 (unless (and program prompt-rx)
233 (error "Sorry, I don't know how to start a REPL for %s" impl))
234 (set (make-local-variable 'comint-prompt-regexp) prompt-rx)
235 (geiser-repl--save-remote-data remote program)
236 (condition-case err
237 (apply 'make-comint-in-buffer
238 `(,cname ,(current-buffer) ,program nil ,@args))
239 (error (insert "Unable to start REPL:\n\n"
240 (error-message-string err) "\n")
241 (error "Couldn't start Geiser")))
242 (geiser-repl--wait-for-prompt 10000)
243 (geiser-repl--history-setup)
244 (geiser-con--setup-connection (current-buffer)
245 prompt-rx
246 deb-prompt-rx
247 deb-preamble-rx)
248 (add-to-list 'geiser-repl--repls (current-buffer))
249 (geiser-repl--set-this-buffer-repl (current-buffer))
250 (geiser-repl--startup impl)))
252 (defun geiser-repl--process ()
253 (let ((buffer (geiser-repl--set-up-repl geiser-impl--implementation)))
254 (or (and (buffer-live-p buffer) (get-buffer-process buffer))
255 (error "No Geiser REPL for this buffer (try M-x run-geiser)"))))
257 (setq geiser-eval--default-proc-function 'geiser-repl--process)
259 (defun geiser-repl--wait-for-prompt (timeout)
260 (let ((p (point)) (seen) (buffer (current-buffer)))
261 (while (and (not seen)
262 (> timeout 0)
263 (get-buffer-process buffer))
264 (sleep-for 0.1)
265 (setq timeout (- timeout 100))
266 (goto-char p)
267 (setq seen (re-search-forward comint-prompt-regexp nil t)))
268 (goto-char (point-max))
269 (unless seen (error "No prompt found!"))))
272 ;;; Interface: starting and interacting with geiser REPL:
274 (defun geiser-repl--read-impl (prompt &optional active)
275 (geiser-impl--read-impl prompt (and active (geiser-repl--active-impls))))
277 (defsubst geiser-repl--only-impl-p ()
278 (and (null (cdr geiser-active-implementations))
279 (car geiser-active-implementations)))
281 (defun run-geiser (impl)
282 "Start a new Geiser REPL."
283 (interactive
284 (list (or (geiser-repl--only-impl-p)
285 (and (eq major-mode 'geiser-repl-mode)
286 geiser-impl--implementation)
287 (geiser-repl--read-impl
288 "Start Geiser for scheme implementation: "))))
289 (geiser-repl--start-repl impl))
291 (defun geiser-connect (impl)
292 "Start a new Geiser REPL connected to a remote Scheme process."
293 (interactive
294 (list (or (geiser-repl--only-impl-p)
295 (and (eq major-mode 'geiser-repl-mode)
296 geiser-impl--implementation)
297 (geiser-repl--read-impl
298 "Scheme implementation: "))))
299 (geiser-repl--start-repl impl t))
301 (make-variable-buffer-local
302 (defvar geiser-repl--last-scm-buffer nil))
304 (defun switch-to-geiser (&optional ask impl buffer)
305 "Switch to running Geiser REPL.
306 With prefix argument, ask for which one if more than one is running.
307 If no REPL is running, execute `run-geiser' to start a fresh one."
308 (interactive "P")
309 (let* ((impl (or impl geiser-impl--implementation))
310 (repl (cond ((and (not ask) (not impl)
311 (or geiser-repl--repl (car geiser-repl--repls))))
312 ((and (not ask) impl (geiser-repl--repl/impl impl)))))
313 (pop-up-windows geiser-repl-window-allow-split))
314 (cond ((and (eq (current-buffer) repl)
315 (not (eq repl buffer))
316 (buffer-live-p geiser-repl--last-scm-buffer))
317 (pop-to-buffer geiser-repl--last-scm-buffer))
318 (repl (pop-to-buffer repl))
319 ((geiser-repl--remote-p) (geiser-connect impl))
320 (t (run-geiser impl)))
321 (when (and buffer (eq major-mode 'geiser-repl-mode))
322 (setq geiser-repl--last-scm-buffer buffer))))
324 (defalias 'geiser 'switch-to-geiser)
326 (defun geiser-repl--send (cmd)
327 (when (and cmd (eq major-mode 'geiser-repl-mode))
328 (goto-char (point-max))
329 (comint-kill-input)
330 (insert cmd)
331 (let ((comint-input-filter (lambda (x) nil)))
332 (comint-send-input nil t))))
334 (defun switch-to-geiser-module (&optional module buffer)
335 "Switch to running Geiser REPL and try to enter a given module."
336 (interactive)
337 (let* ((module (or module
338 (geiser-completion--read-module "Switch to module: ")))
339 (cmd (and module
340 (geiser-repl--enter-cmd geiser-impl--implementation
341 module))))
342 (unless (eq major-mode 'geiser-repl-mode)
343 (switch-to-geiser nil nil (or buffer (current-buffer))))
344 (geiser-repl--send cmd)))
346 (defun geiser-repl-import-module (&optional module)
347 "Import a given module in the current namespace of the REPL."
348 (interactive)
349 (let* ((module (or module
350 (geiser-completion--read-module "Import module: ")))
351 (cmd (and module
352 (geiser-repl--import-cmd geiser-impl--implementation
353 module))))
354 (switch-to-geiser nil nil (current-buffer))
355 (geiser-repl--send cmd)))
357 (defun geiser-repl-exit (&optional arg)
358 "Exit the current REPL.
359 With a prefix argument, force exit by killing the scheme process."
360 (interactive "P")
361 (when (or (not geiser-repl-query-on-exit-p)
362 (y-or-n-p "Really quit this REPL? "))
363 (let ((cmd (and (not arg)
364 (geiser-repl--exit-cmd geiser-impl--implementation))))
365 (if cmd
366 (when (stringp cmd) (geiser-repl--send cmd))
367 (comint-kill-subjob)))))
369 (defun geiser-repl-nuke ()
370 "Try this command if the REPL becomes unresponsive."
371 (interactive)
372 (goto-char (point-max))
373 (comint-kill-region comint-last-input-start (point))
374 (comint-redirect-cleanup)
375 (geiser-con--setup-connection (current-buffer)
376 comint-prompt-regexp
377 geiser-con--debugging-prompt-regexp
378 geiser-con--debugging-preamble-regexp))
381 ;;; REPL history and clean-up:
383 (defsubst geiser-repl--history-file ()
384 (format "%s.%s" geiser-repl-history-filename geiser-impl--implementation))
386 (defun geiser-repl--on-quit ()
387 (comint-write-input-ring)
388 (let ((cb (current-buffer))
389 (impl geiser-impl--implementation)
390 (comint-prompt-read-only nil))
391 (setq geiser-repl--repls (remove cb geiser-repl--repls))
392 (dolist (buffer (buffer-list))
393 (when (buffer-live-p buffer)
394 (with-current-buffer buffer
395 (when (and (eq geiser-impl--implementation impl)
396 (equal cb geiser-repl--repl))
397 (geiser-repl--set-up-repl geiser-impl--implementation)))))))
399 (defun geiser-repl--sentinel (proc event)
400 (let ((pb (process-buffer proc)))
401 (when (buffer-live-p pb)
402 (with-current-buffer pb
403 (let ((comint-prompt-read-only nil)
404 (comint-input-ring-file-name (geiser-repl--history-file)))
405 (geiser-repl--on-quit)
406 (push pb geiser-repl--closed-repls)
407 (when (buffer-name (current-buffer))
408 (comint-kill-region comint-last-input-start (point))
409 (insert "\nIt's been nice interacting with you!\n")
410 (insert "Press C-c C-z to bring me back.\n" )))))))
412 (defun geiser-repl--on-kill ()
413 (geiser-repl--on-quit)
414 (setq geiser-repl--closed-repls
415 (remove (current-buffer) geiser-repl--closed-repls)))
417 (defun geiser-repl--input-filter (str)
418 (not (or (geiser-con--is-debugging)
419 (string-match "^\\s *$" str)
420 (string-match "^,quit *$" str))))
422 (defun geiser-repl--old-input ()
423 (save-excursion
424 (let ((end (point)))
425 (backward-sexp)
426 (buffer-substring (point) end))))
428 (defun geiser-repl--history-setup ()
429 (set (make-local-variable 'comint-input-ring-file-name)
430 (geiser-repl--history-file))
431 (set (make-local-variable 'comint-input-ring-size) geiser-repl-history-size)
432 (set (make-local-variable 'comint-input-filter) 'geiser-repl--input-filter)
433 (set (make-local-variable 'comint-get-old-input) 'geiser-repl--old-input)
434 (add-hook 'kill-buffer-hook 'geiser-repl--on-kill nil t)
435 (comint-read-input-ring t)
436 (set-process-sentinel (get-buffer-process (current-buffer))
437 'geiser-repl--sentinel))
440 ;;; geiser-repl mode:
442 (defun geiser-repl--bol ()
443 (interactive)
444 (when (= (point) (comint-bol)) (beginning-of-line)))
446 (defun geiser-repl--beginning-of-defun ()
447 (save-restriction
448 (when comint-last-prompt-overlay
449 (narrow-to-region (overlay-end comint-last-prompt-overlay) (point)))
450 (let ((beginning-of-defun-function nil))
451 (beginning-of-defun))))
453 (defun geiser-repl--module-function (&optional ignore) :f)
455 (defun geiser-repl--doc-module ()
456 (interactive)
457 (let ((geiser-eval--get-module-function
458 (geiser-impl--method 'find-module geiser-impl--implementation)))
459 (geiser-doc-module)))
461 (defun geiser-repl--newline-and-indent ()
462 (interactive)
463 (save-restriction
464 (narrow-to-region comint-last-input-start (point-max))
465 (insert "\n")
466 (lisp-indent-line)))
468 (defun geiser-repl--last-prompt-end ()
469 (if comint-last-prompt-overlay
470 (overlay-end comint-last-prompt-overlay)
471 (save-excursion (geiser-repl--bol) (point))))
473 (defun geiser-repl--last-prompt-start ()
474 (if comint-last-prompt-overlay
475 (overlay-start comint-last-prompt-overlay)
476 (save-excursion (geiser-repl--bol) (point))))
478 (defun geiser-repl--nesting-level ()
479 (save-restriction
480 (narrow-to-region (geiser-repl--last-prompt-end) (point-max))
481 (geiser-syntax--nesting-level)))
483 (defun geiser-repl--send-input ()
484 (let* ((proc (get-buffer-process (current-buffer)))
485 (pmark (and proc (process-mark proc)))
486 (intxt (and pmark (buffer-substring pmark (point)))))
487 (when intxt
488 (when (and geiser-repl-forget-old-errors-p
489 (not (geiser-con--is-debugging)))
490 (compilation-forget-errors))
491 (comint-send-input)
492 (when (string-match "^\\s-*$" intxt)
493 (comint-send-string proc (geiser-eval--scheme-str '(:ge no-values)))
494 (comint-send-string proc "\n")))))
496 (defun geiser-repl--maybe-send ()
497 (interactive)
498 (let ((p (point)))
499 (cond ((< p (geiser-repl--last-prompt-start))
500 (ignore-errors (compile-goto-error)))
501 ((progn (end-of-line) (<= (geiser-repl--nesting-level) 0))
502 (geiser-repl--send-input))
503 (t (goto-char p)
504 (if geiser-repl-auto-indent-p
505 (geiser-repl--newline-and-indent)
506 (insert "\n"))))))
508 (defun geiser-repl--tab (n)
509 "If we're after the last prompt, complete symbol or indent (if
510 there's no symbol at point). Otherwise, go to next error in the REPL
511 buffer."
512 (interactive "p")
513 (if (> (point) (geiser-repl--last-prompt-end))
514 (geiser-completion--maybe-complete)
515 (compilation-next-error n)))
517 (defun geiser-repl--previous-error (n)
518 "Go to previous error in the REPL buffer."
519 (interactive "p")
520 (compilation-next-error (- n)))
522 (define-derived-mode geiser-repl-mode comint-mode "REPL"
523 "Major mode for interacting with an inferior scheme repl process.
524 \\{geiser-repl-mode-map}"
525 (scheme-mode-variables)
526 (set (make-local-variable 'mode-line-process) nil)
527 (set (make-local-variable 'comint-use-prompt-regexp) nil)
528 (set (make-local-variable 'comint-prompt-read-only)
529 geiser-repl-read-only-prompt-p)
530 (set (make-local-variable 'beginning-of-defun-function)
531 'geiser-repl--beginning-of-defun)
532 (set (make-local-variable 'comint-input-ignoredups)
533 geiser-repl-history-no-dups-p)
534 (setq geiser-eval--get-module-function 'geiser-repl--module-function)
535 (when geiser-repl-autodoc-p
536 (geiser--save-msg (geiser-autodoc-mode 1)))
537 (setq geiser-autodoc--inhibit-function 'geiser-con--is-debugging)
538 (geiser-company--setup geiser-repl-company-p)
539 ;; enabling compilation-shell-minor-mode without the annoying highlighter
540 (compilation-setup t))
542 (define-key geiser-repl-mode-map "\C-d" 'delete-char)
543 (define-key geiser-repl-mode-map "\C-m" 'geiser-repl--maybe-send)
544 (define-key geiser-repl-mode-map [return] 'geiser-repl--maybe-send)
545 (define-key geiser-repl-mode-map "\C-j" 'geiser-repl--newline-and-indent)
546 (define-key geiser-repl-mode-map (kbd "TAB") 'geiser-repl--tab)
547 (define-key geiser-repl-mode-map [backtab] 'geiser-repl--previous-error)
549 (define-key geiser-repl-mode-map "\C-a" 'geiser-repl--bol)
550 (define-key geiser-repl-mode-map (kbd "<home>") 'geiser-repl--bol)
552 (geiser-menu--defmenu repl geiser-repl-mode-map
553 ("Complete symbol" ((kbd "M-TAB"))
554 geiser-repl--tab :enable (symbol-at-point))
555 ("Complete module name" ((kbd "C-.") (kbd "M-`"))
556 geiser-completion--complete-module :enable (symbol-at-point))
557 ("Edit symbol" "\M-." geiser-edit-symbol-at-point
558 :enable (symbol-at-point))
560 ("Switch to module..." "\C-c\C-m" switch-to-geiser-module)
561 ("Import module..." "\C-c\C-i" geiser-repl-import-module)
563 ("Previous matching input" "\M-p" comint-previous-matching-input-from-input
564 "Previous input matching current")
565 ("Next matching input" "\M-n" comint-next-matching-input-from-input
566 "Next input matching current")
567 ("Previous input" "\C-c\M-p" comint-previous-input)
568 ("Next input" "\C-c\M-n" comint-next-input)
570 (mode "Autodoc mode" ("\C-c\C-da" "\C-c\C-d\C-a") geiser-autodoc-mode)
571 ("Symbol documentation" ("\C-c\C-dd" "\C-c\C-d\C-d")
572 geiser-doc-symbol-at-point
573 "Documentation for symbol at point" :enable (symbol-at-point))
574 ("Module documentation" ("\C-c\C-dm" "\C-c\C-d\C-m") geiser-repl--doc-module
575 "Documentation for module at point" :enable (symbol-at-point))
577 ("Kill Scheme interpreter" "\C-c\C-q" geiser-repl-exit
578 :enable (geiser-repl--live-p))
579 ("Restart" "\C-c\C-z" switch-to-geiser :enable (not (geiser-repl--live-p)))
580 ("Revive REPL" "\C-c\C-k" geiser-repl-nuke
581 "Use this command if the REPL becomes irresponsive"
582 :enable (geiser-repl--live-p))
584 (custom "REPL options" geiser-repl))
586 (define-key geiser-repl-mode-map [menu-bar completion] 'undefined)
589 ;;; Unload:
591 (defun geiser-repl--repl-list ()
592 (let (lst)
593 (dolist (repl geiser-repl--repls lst)
594 (when (buffer-live-p repl)
595 (with-current-buffer repl
596 (push geiser-impl--implementation lst))))))
598 (defun geiser-repl--restore (impls)
599 (dolist (impl impls)
600 (when impl (run-geiser impl))))
602 (defun geiser-repl-unload-function ()
603 (dolist (repl geiser-repl--repls)
604 (when (buffer-live-p repl)
605 (kill-buffer repl))))
608 (provide 'geiser-repl)
609 ;;; geiser-repl.el ends here