Debugger support, and Guile using it
[geiser.git] / elisp / geiser-repl.el
blobf73bd90cd25d1e38cd34016413ee4b539d3a0dbf
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-inf)
17 (require 'geiser-impl)
18 (require 'geiser-eval)
19 (require 'geiser-connection)
20 (require 'geiser-menu)
21 (require 'geiser-custom)
22 (require 'geiser-base)
24 (require 'comint)
25 (require 'compile)
26 (require 'scheme)
29 ;;; Customization:
31 (defgroup geiser-repl nil
32 "Interacting with the Geiser REPL."
33 :group 'geiser)
35 (geiser-custom--defcustom geiser-repl-use-other-window t
36 "Whether to Use a window other than the current buffer's when
37 switching to the Geiser REPL buffer."
38 :type 'boolean
39 :group 'geiser-repl)
41 (geiser-custom--defcustom geiser-repl-window-allow-split t
42 "Whether to allow window splitting when switching to the Geiser
43 REPL buffer."
44 :type 'boolean
45 :group 'geiser-repl)
47 (geiser-custom--defcustom geiser-repl-history-filename (expand-file-name "~/.geiser_history")
48 "File where REPL input history is saved, so that it persists between sessions.
49 This is actually the base name: the concrete Scheme
50 implementation name gets appended to it."
51 :type 'filename
52 :group 'geiser-repl)
54 (geiser-custom--defcustom geiser-repl-history-size comint-input-ring-size
55 "Maximum size of the saved REPL input history."
56 :type 'integer
57 :group 'geiser-repl)
59 (geiser-custom--defcustom geiser-repl-history-no-dups-p t
60 "Whether to skip duplicates when recording history."
61 :type 'boolean
62 :group 'geiser-repl)
64 (geiser-custom--defcustom geiser-repl-autodoc-p t
65 "Whether to enable `geiser-autodoc-mode' in the REPL by default."
66 :type 'boolean
67 :group 'geiser-repl)
69 (geiser-custom--defcustom geiser-repl-company-p t
70 "Whether to use company-mode for completion, if available."
71 :group 'geiser-mode
72 :type 'boolean)
74 (geiser-custom--defcustom geiser-repl-read-only-prompt-p t
75 "Whether the REPL's prompt should be read-only."
76 :type 'boolean
77 :group 'geiser-repl)
79 (geiser-custom--defcustom geiser-repl-auto-indent-p t
80 "Whether newlines for incomplete sexps are autoindented."
81 :type 'boolean
82 :group 'geiser-repl)
84 (geiser-custom--defcustom geiser-repl-forget-old-errors-p t
85 "Whether to forget old errors upon entering a new expression.
87 When on (the default), every time a new expression is entered in
88 the REPL old error messages are flushed, and using \\[next-error]
89 afterwards will jump only to error locations produced by the new
90 expression, if any."
91 :type 'boolean
92 :group 'geiser-repl)
94 (geiser-custom--defcustom geiser-repl-query-on-exit-p nil
95 "Whether to prompt for confirmation on \\[geiser-repl-exit]."
96 :type 'boolean
97 :group 'geiser-repl)
99 (geiser-custom--defcustom geiser-repl-default-host "localhost"
100 "Default host when connecting to remote REPLs."
101 :type 'string
102 :group 'geiser-repl)
104 (geiser-custom--defcustom geiser-repl-default-port 37146
105 "Default port for connecting to remote REPLs."
106 :type 'integer
107 :group 'geiser-repl)
110 ;;; Implementation-dependent parameters
112 (geiser-impl--define-caller geiser-repl--prompt-regexp prompt-regexp ()
113 "A variable (or thunk returning a value) giving the regular
114 expression for this implementation's geiser scheme prompt.")
116 (geiser-impl--define-caller
117 geiser-repl--debugger-prompt-regexp debugger-prompt-regexp ()
118 "A variable (or thunk returning a value) giving the regular
119 expression for this implementation's debugging prompt.")
121 (geiser-impl--define-caller geiser-repl--startup repl-startup (remote)
122 "Function taking no parameters that is called after the REPL
123 has been initialised. All Geiser functionality is available to
124 you at that point.")
126 (geiser-impl--define-caller geiser-repl--enter-cmd enter-command (module)
127 "Function taking a module designator and returning a REPL enter
128 module command as a string")
130 (geiser-impl--define-caller geiser-repl--import-cmd import-command (module)
131 "Function taking a module designator and returning a REPL import
132 module command as a string")
134 (geiser-impl--define-caller geiser-repl--exit-cmd exit-command ()
135 "Function returning the REPL exit command as a string")
138 ;;; Geiser REPL buffers and processes:
140 (defvar geiser-repl--repls nil)
141 (defvar geiser-repl--closed-repls nil)
143 (make-variable-buffer-local
144 (defvar geiser-repl--repl nil))
146 (defsubst geiser-repl--set-this-buffer-repl (r)
147 (setq geiser-repl--repl r))
149 (defun geiser-repl--live-p ()
150 (and geiser-repl--repl
151 (get-buffer-process geiser-repl--repl)))
153 (defun geiser-repl--repl/impl (impl &optional repls)
154 (catch 'repl
155 (dolist (repl (or repls geiser-repl--repls))
156 (when (buffer-live-p repl)
157 (with-current-buffer repl
158 (when (eq geiser-impl--implementation impl)
159 (throw 'repl repl)))))))
161 (defun geiser-repl--set-up-repl (impl)
162 (or (and (not impl) geiser-repl--repl)
163 (setq geiser-repl--repl
164 (let ((impl (or impl
165 geiser-impl--implementation
166 (geiser-impl--guess))))
167 (when impl (geiser-repl--repl/impl impl))))))
169 (defun geiser-repl--active-impls ()
170 (let ((act))
171 (dolist (repl geiser-repl--repls act)
172 (with-current-buffer repl
173 (add-to-list 'act geiser-impl--implementation)))))
175 (defsubst geiser-repl--repl-name (impl)
176 (format "%s REPL" (geiser-impl--impl-str impl)))
178 (defun geiser-repl--to-repl-buffer (impl)
179 (unless (and (eq major-mode 'geiser-repl-mode)
180 (not (get-buffer-process (current-buffer))))
181 (let* ((old (geiser-repl--repl/impl impl geiser-repl--closed-repls))
182 (old (and (buffer-live-p old)
183 (not (get-buffer-process old))
184 old)))
185 (pop-to-buffer
186 (or old
187 (generate-new-buffer (format "* %s *"
188 (geiser-repl--repl-name impl)))))
189 (unless old
190 (geiser-repl-mode)
191 (geiser-impl--set-buffer-implementation impl)))))
193 (defun geiser-repl--read-impl (prompt &optional active)
194 (geiser-impl--read-impl prompt (and active (geiser-repl--active-impls))))
196 (defsubst geiser-repl--only-impl-p ()
197 (and (null (cdr geiser-active-implementations))
198 (car geiser-active-implementations)))
200 (defun geiser-repl--get-impl (prompt)
201 (or (geiser-repl--only-impl-p)
202 (and (eq major-mode 'geiser-repl-mode) geiser-impl--implementation)
203 (geiser-repl--read-impl prompt)))
206 ;;; REPL connections
208 (make-variable-buffer-local
209 (defvar geiser-repl--address nil))
211 (make-variable-buffer-local
212 (defvar geiser-repl--connection nil))
214 (make-variable-buffer-local
215 (defvar geiser-repl--remote-p nil))
217 (make-variable-buffer-local
218 (defvar geiser-repl--inferior-buffer nil))
220 (defsubst geiser-repl--host () (car geiser-repl--address))
221 (defsubst geiser-repl--port () (cdr geiser-repl--address))
223 (defun geiser-repl--get-address (&optional host port)
224 (let ((defhost (or (geiser-repl--host) geiser-repl-default-host))
225 (defport (or (geiser-repl--port) geiser-repl-default-port)))
226 (cons (or host
227 (read-string (format "Host (default %s): " defhost)
228 nil nil defhost))
229 (or port (read-number "Port: " defport)))))
231 (defun geiser-repl--save-remote-data (address remote)
232 (setq geiser-repl--address address)
233 (setq geiser-repl--remote-p remote)
234 (setq header-line-format (and remote
235 (format "Host: %s Port: %s"
236 (geiser-repl--host)
237 (geiser-repl--port)))))
239 (defun geiser-repl--start-repl (impl host port remote)
240 (message "Starting Geiser REPL for %s ..." impl)
241 (geiser-repl--to-repl-buffer impl)
242 (goto-char (point-max))
243 (let ((address (geiser-repl--get-address host port))
244 (prompt-rx (geiser-repl--prompt-regexp impl))
245 (deb-prompt-rx (geiser-repl--debugger-prompt-regexp impl))
246 (cname (geiser-repl--repl-name impl)))
247 (unless prompt-rx
248 (error "Sorry, I don't know how to start a REPL for %s" impl))
249 (geiser-repl--save-remote-data address remote)
250 (condition-case err
251 (progn
252 (setq geiser-repl--connection
253 (geiser-con--open-connection (car address)
254 (cdr address)
255 prompt-rx
256 deb-prompt-rx))
257 (set (make-local-variable 'comint-prompt-regexp)
258 (geiser-con--combined-prompt prompt-rx deb-prompt-rx))
259 (apply 'make-comint-in-buffer `(,cname ,(current-buffer) ,address)))
260 (error (insert "Unable to start REPL:\n\n"
261 (error-message-string err) "\n")
262 (error "Couldn't start Geiser")))
263 (geiser-inf--wait-for-prompt 10000)
264 (geiser-repl--history-setup)
265 (add-to-list 'geiser-repl--repls (current-buffer))
266 (geiser-repl--set-this-buffer-repl (current-buffer))
267 (geiser-repl--startup impl remote)
268 (message "%s up and running!" (geiser-repl--repl-name impl))))
270 (defun geiser-repl--connection ()
271 (let ((buffer (geiser-repl--set-up-repl geiser-impl--implementation)))
272 (or (and (buffer-live-p buffer)
273 (get-buffer-process buffer)
274 (with-current-buffer buffer geiser-repl--connection))
275 (error "No Geiser REPL for this buffer (try M-x run-geiser)"))))
277 (setq geiser-eval--default-connection-function 'geiser-repl--connection)
279 (defun geiser-repl--swap ()
280 (let ((p (get-buffer-process (current-buffer))))
281 (when (and p geiser-repl--connection)
282 (let ((p (geiser-con--connection-swap-proc geiser-repl--connection
283 p)))
284 (goto-char (point-max))
285 (set-marker (process-mark p) (point))))))
287 (defun geiser-repl--send (cmd)
288 (when (and cmd (eq major-mode 'geiser-repl-mode))
289 (goto-char (point-max))
290 (comint-kill-input)
291 (insert cmd)
292 (let ((comint-input-filter (lambda (x) nil)))
293 (comint-send-input nil t))))
295 (defun geiser-repl--send-silent (cmd)
296 (comint-redirect-results-list cmd ".+" 0))
299 ;;; REPL history and clean-up:
301 (defsubst geiser-repl--history-file ()
302 (format "%s.%s" geiser-repl-history-filename geiser-impl--implementation))
304 (defun geiser-repl--quit-inf ()
305 (when (buffer-live-p geiser-repl--inferior-buffer)
306 (with-current-buffer geiser-repl--inferior-buffer
307 (let ((geiser-repl-query-on-exit-p nil))
308 (geiser-repl-exit)))))
310 (defun geiser-repl--on-quit ()
311 (comint-write-input-ring)
312 (let ((cb (current-buffer))
313 (impl geiser-impl--implementation)
314 (comint-prompt-read-only nil))
315 (ignore-errors (geiser-con--connection-close geiser-repl--connection))
316 (geiser-repl--quit-inf)
317 (setq geiser-repl--repls (remove cb geiser-repl--repls))
318 (dolist (buffer (buffer-list))
319 (when (buffer-live-p buffer)
320 (with-current-buffer buffer
321 (when (and (eq geiser-impl--implementation impl)
322 (equal cb geiser-repl--repl))
323 (geiser-repl--set-up-repl geiser-impl--implementation)))))))
325 (defun geiser-repl--sentinel (proc event)
326 (let ((pb (process-buffer proc)))
327 (when (buffer-live-p pb)
328 (with-current-buffer pb
329 (let ((comint-prompt-read-only nil)
330 (comint-input-ring-file-name (geiser-repl--history-file)))
331 (geiser-repl--on-quit)
332 (push pb geiser-repl--closed-repls)
333 (goto-char (point-max))
334 (comint-kill-region comint-last-input-start (point))
335 (insert "\nIt's been nice interacting with you!\n")
336 (insert "Press C-c C-z to bring me back.\n" ))))))
338 (defun geiser-repl--on-kill ()
339 (geiser-repl--on-quit)
340 (setq geiser-repl--closed-repls
341 (remove (current-buffer) geiser-repl--closed-repls)))
343 (defun geiser-repl--input-filter (str)
344 (not (or ;; (geiser-con--is-debugging)
345 (string-match "^\\s *$" str)
346 (string-match "^,quit *$" str))))
348 (defun geiser-repl--old-input ()
349 (save-excursion
350 (let ((end (point)))
351 (backward-sexp)
352 (buffer-substring (point) end))))
354 (defun geiser-repl--history-setup ()
355 (set (make-local-variable 'comint-input-ring-file-name)
356 (geiser-repl--history-file))
357 (set (make-local-variable 'comint-input-ring-size) geiser-repl-history-size)
358 (set (make-local-variable 'comint-input-filter) 'geiser-repl--input-filter)
359 (set (make-local-variable 'comint-get-old-input) 'geiser-repl--old-input)
360 (add-hook 'kill-buffer-hook 'geiser-repl--on-kill nil t)
361 (comint-read-input-ring t)
362 (set-process-sentinel (get-buffer-process (current-buffer))
363 'geiser-repl--sentinel))
366 ;;; geiser-repl mode:
368 (defun geiser-repl--bol ()
369 (interactive)
370 (when (= (point) (comint-bol)) (beginning-of-line)))
372 (defun geiser-repl--beginning-of-defun ()
373 (save-restriction
374 (when comint-last-prompt-overlay
375 (narrow-to-region (overlay-end comint-last-prompt-overlay) (point)))
376 (let ((beginning-of-defun-function nil))
377 (beginning-of-defun))))
379 (defun geiser-repl--module-function (&optional ignore) :f)
381 (defun geiser-repl--doc-module ()
382 (interactive)
383 (let ((geiser-eval--get-module-function
384 (geiser-impl--method 'find-module geiser-impl--implementation)))
385 (geiser-doc-module)))
387 (defun geiser-repl--newline-and-indent ()
388 (interactive)
389 (save-restriction
390 (narrow-to-region comint-last-input-start (point-max))
391 (insert "\n")
392 (lisp-indent-line)))
394 (defun geiser-repl--last-prompt-end ()
395 (if comint-last-prompt-overlay
396 (overlay-end comint-last-prompt-overlay)
397 (save-excursion (geiser-repl--bol) (point))))
399 (defun geiser-repl--last-prompt-start ()
400 (if comint-last-prompt-overlay
401 (overlay-start comint-last-prompt-overlay)
402 (save-excursion (geiser-repl--bol) (point))))
404 (defun geiser-repl--nesting-level ()
405 (save-restriction
406 (narrow-to-region (geiser-repl--last-prompt-end) (point-max))
407 (geiser-syntax--nesting-level)))
409 (defun geiser-repl--send-input ()
410 (let* ((proc (get-buffer-process (current-buffer)))
411 (pmark (and proc (process-mark proc)))
412 (intxt (and pmark (buffer-substring pmark (point)))))
413 (when intxt
414 (when (and geiser-repl-forget-old-errors-p
415 ;;; (not (geiser-con--is-debugging)))
417 (compilation-forget-errors))
418 (comint-send-input)
419 (when (string-match "^\\s-*$" intxt)
420 (comint-send-string proc (geiser-eval--scheme-str '(:ge no-values)))
421 (comint-send-string proc "\n")))))
423 (defun geiser-repl--maybe-send ()
424 (interactive)
425 (let ((p (point)))
426 (cond ((< p (geiser-repl--last-prompt-start))
427 (ignore-errors (compile-goto-error)))
428 ((progn (end-of-line) (<= (geiser-repl--nesting-level) 0))
429 (geiser-repl--send-input))
430 (t (goto-char p)
431 (if geiser-repl-auto-indent-p
432 (geiser-repl--newline-and-indent)
433 (insert "\n"))))))
435 (defun geiser-repl--tab (n)
436 "If we're after the last prompt, complete symbol or indent (if
437 there's no symbol at point). Otherwise, go to next error in the REPL
438 buffer."
439 (interactive "p")
440 (if (> (point) (geiser-repl--last-prompt-end))
441 (geiser-completion--maybe-complete)
442 (compilation-next-error n)))
444 (defun geiser-repl--previous-error (n)
445 "Go to previous error in the REPL buffer."
446 (interactive "p")
447 (compilation-next-error (- n)))
449 (define-derived-mode geiser-repl-mode comint-mode "REPL"
450 "Major mode for interacting with an inferior scheme repl process.
451 \\{geiser-repl-mode-map}"
452 (scheme-mode-variables)
453 (set (make-local-variable 'mode-line-process) nil)
454 (set (make-local-variable 'comint-use-prompt-regexp) nil)
455 (set (make-local-variable 'comint-prompt-read-only)
456 geiser-repl-read-only-prompt-p)
457 (set (make-local-variable 'beginning-of-defun-function)
458 'geiser-repl--beginning-of-defun)
459 (set (make-local-variable 'comint-input-ignoredups)
460 geiser-repl-history-no-dups-p)
461 (setq geiser-eval--get-module-function 'geiser-repl--module-function)
462 (when geiser-repl-autodoc-p
463 (geiser--save-msg (geiser-autodoc-mode 1)))
464 (geiser-company--setup geiser-repl-company-p)
465 ;; enabling compilation-shell-minor-mode without the annoying highlighter
466 (compilation-setup t))
468 (define-key geiser-repl-mode-map "\C-d" 'delete-char)
469 (define-key geiser-repl-mode-map "\C-m" 'geiser-repl--maybe-send)
470 (define-key geiser-repl-mode-map [return] 'geiser-repl--maybe-send)
471 (define-key geiser-repl-mode-map "\C-j" 'geiser-repl--newline-and-indent)
472 (define-key geiser-repl-mode-map (kbd "TAB") 'geiser-repl--tab)
473 (define-key geiser-repl-mode-map [backtab] 'geiser-repl--previous-error)
475 (define-key geiser-repl-mode-map "\C-a" 'geiser-repl--bol)
476 (define-key geiser-repl-mode-map (kbd "<home>") 'geiser-repl--bol)
478 (geiser-menu--defmenu repl geiser-repl-mode-map
479 ("Complete symbol" ((kbd "M-TAB"))
480 geiser-repl--tab :enable (symbol-at-point))
481 ("Complete module name" ((kbd "C-.") (kbd "M-`"))
482 geiser-completion--complete-module :enable (symbol-at-point))
483 ("Edit symbol" "\M-." geiser-edit-symbol-at-point
484 :enable (symbol-at-point))
486 ("Switch to module..." "\C-c\C-m" switch-to-geiser-module)
487 ("Import module..." "\C-c\C-i" geiser-repl-import-module)
489 ("Previous matching input" "\M-p" comint-previous-matching-input-from-input
490 "Previous input matching current")
491 ("Next matching input" "\M-n" comint-next-matching-input-from-input
492 "Next input matching current")
493 ("Previous input" "\C-c\M-p" comint-previous-input)
494 ("Next input" "\C-c\M-n" comint-next-input)
496 (mode "Autodoc mode" ("\C-c\C-da" "\C-c\C-d\C-a") geiser-autodoc-mode)
497 ("Symbol documentation" ("\C-c\C-dd" "\C-c\C-d\C-d")
498 geiser-doc-symbol-at-point
499 "Documentation for symbol at point" :enable (symbol-at-point))
500 ("Module documentation" ("\C-c\C-dm" "\C-c\C-d\C-m") geiser-repl--doc-module
501 "Documentation for module at point" :enable (symbol-at-point))
503 ("Kill Scheme interpreter" "\C-c\C-q" geiser-repl-exit
504 :enable (geiser-repl--live-p))
505 ("Restart" "\C-c\C-z" switch-to-geiser :enable (not (geiser-repl--live-p)))
507 (custom "REPL options" geiser-repl))
509 (define-key geiser-repl-mode-map [menu-bar completion] 'undefined)
512 ;;; User commands
514 (defun run-geiser (impl)
515 "Start a new Geiser REPL."
516 (interactive
517 (list (geiser-repl--get-impl "Start Geiser for scheme implementation: ")))
518 (message "Starting Scheme process...")
519 (let* ((b/p (geiser-inf--run-scheme impl))
520 (inf-buff (car b/p))
521 (port (cadr b/p)))
522 (unless port
523 (when (bufferp inf-buff) (pop-to-buffer inf-buff))
524 (error "%s" "Couldn't connect to inferior scheme process"))
525 (geiser-repl--start-repl impl "localhost" port nil)
526 (setq geiser-repl--inferior-buffer inf-buff)
527 (with-current-buffer inf-buff (setq geiser-impl--implementation impl))))
529 (defalias 'geiser 'run-geiser)
531 (defun geiser-connect (impl &optional host port)
532 "Start a new Geiser REPL connected to a remote Scheme process."
533 (interactive
534 (list (geiser-repl--get-impl "Connect to Scheme implementation: ")))
535 (geiser-repl--start-repl impl host port t))
537 (make-variable-buffer-local
538 (defvar geiser-repl--last-scm-buffer nil))
540 (defun switch-to-geiser (&optional ask impl buffer)
541 "Switch to running Geiser REPL.
542 With prefix argument, ask for which one if more than one is running.
543 If no REPL is running, execute `run-geiser' to start a fresh one."
544 (interactive "P")
545 (let* ((impl (or impl geiser-impl--implementation))
546 (in-repl (eq major-mode 'geiser-repl-mode))
547 (in-live-repl (and in-repl (get-buffer-process (current-buffer))))
548 (repl (cond ((and (not ask)
549 (not impl)
550 (not in-repl)
551 (or geiser-repl--repl (car geiser-repl--repls))))
552 ((and (not ask)
553 (not in-repl)
554 impl
555 (geiser-repl--repl/impl impl)))))
556 (pop-up-windows geiser-repl-window-allow-split))
557 (cond ((or in-live-repl
558 (and (eq (current-buffer) repl) (not (eq repl buffer))))
559 (when (buffer-live-p geiser-repl--last-scm-buffer)
560 (pop-to-buffer geiser-repl--last-scm-buffer)))
561 (repl (pop-to-buffer repl))
562 (geiser-repl--remote-p (geiser-connect impl))
563 (t (run-geiser impl)))
564 (when (and buffer (eq major-mode 'geiser-repl-mode))
565 (setq geiser-repl--last-scm-buffer buffer))))
567 (defun switch-to-geiser-module (&optional module buffer)
568 "Switch to running Geiser REPL and try to enter a given module."
569 (interactive)
570 (let* ((module (or module
571 (geiser-completion--read-module
572 "Switch to module (default top-level): ")))
573 (cmd (and module
574 (geiser-repl--enter-cmd geiser-impl--implementation
575 module))))
576 (unless (eq major-mode 'geiser-repl-mode)
577 (switch-to-geiser nil nil (or buffer (current-buffer))))
578 (geiser-repl--send cmd)))
580 (defun geiser-repl-import-module (&optional module)
581 "Import a given module in the current namespace of the REPL."
582 (interactive)
583 (let* ((module (or module
584 (geiser-completion--read-module "Import module: ")))
585 (cmd (and module
586 (geiser-repl--import-cmd geiser-impl--implementation
587 module))))
588 (switch-to-geiser nil nil (current-buffer))
589 (geiser-repl--send cmd)))
591 (defun geiser-repl-exit (&optional arg)
592 "Exit the current REPL.
593 With a prefix argument, force exit by killing the scheme process."
594 (interactive "P")
595 (when (or (not geiser-repl-query-on-exit-p)
596 (y-or-n-p "Really quit this REPL? "))
597 (let ((cmd (and (not arg)
598 (geiser-repl--exit-cmd geiser-impl--implementation))))
599 (if cmd
600 (when (stringp cmd) (geiser-repl--send cmd))
601 (comint-kill-subjob)))))
604 ;;; Unload:
606 (defun geiser-repl--repl-list ()
607 (let (lst)
608 (dolist (repl geiser-repl--repls lst)
609 (when (buffer-live-p repl)
610 (with-current-buffer repl
611 (push (cons geiser-impl--implementation
612 (when geiser-repl--remote-p
613 (list (geiser-repl--host) (geiser-repl--port))))
614 lst))))))
616 (defun geiser-repl--restore (impls)
617 (dolist (impl impls)
618 (when impl
619 (if (cdr impl)
620 (geiser-connect (car impl) (cadr impl) (caddr impl))
621 (run-geiser (car impl))))))
623 (defun geiser-repl-unload-function ()
624 (dolist (repl geiser-repl--repls)
625 (when (buffer-live-p repl)
626 (with-current-buffer repl
627 (let ((geiser-repl-query-on-exit-p nil)) (geiser-repl-exit))
628 (sit-for 0.05)
629 (kill-buffer)))))
632 (provide 'geiser-repl)