summaryrefslogtreecommitdiff
path: root/elisp/geiser-repl.el
diff options
context:
space:
mode:
Diffstat (limited to 'elisp/geiser-repl.el')
-rw-r--r--elisp/geiser-repl.el113
1 files changed, 113 insertions, 0 deletions
diff --git a/elisp/geiser-repl.el b/elisp/geiser-repl.el
index 3c75cfc..1353019 100644
--- a/elisp/geiser-repl.el
+++ b/elisp/geiser-repl.el
@@ -25,16 +25,129 @@
;;; Code:
+(require 'geiser-eval)
+(require 'geiser-connection)
(require 'geiser-base)
(require 'comint)
;;; Customization:
+(defgroup geiser-repl nil
+ "Interacting with a Guile process inside Emacs."
+ :group 'geiser)
+
+(defcustom geiser-repl-guile-binary
+ (cond ((eq system-type 'windows-nt) "guile.exe")
+ ((eq system-type 'darwin) "guile")
+ (t "guile"))
+ "Name to use to call the guile executable when starting a REPL."
+ :type 'string
+ :group 'geiser-repl)
+
+(defcustom geiser-repl-use-other-window t
+ "Use a window other than the current buffer's when switching to
+the Geiser REPL buffer."
+ :type 'boolean
+ :group 'geiser-repl)
+
+(defcustom geiser-repl-window-allow-split t
+ "Allow window splitting when switching to the Geiser REPL buffer."
+ :type 'boolean
+ :group 'geiser-repl)
+
+
+;;; Geiser REPL buffer/process:
+
+(defvar geiser-repl--buffer nil
+ "The buffer in which the Guile REPL is running.")
+
+(defun geiser-repl--buffer ()
+ (if (buffer-live-p geiser-repl--buffer) geiser-repl--buffer
+ (with-current-buffer (get-buffer-create "*Geiser REPL*")
+ (geiser-repl-mode)
+ (setq geiser-repl--buffer (current-buffer)))))
+
+(defun geiser-repl--start-process ()
+ (let ((guile geiser-repl-guile-binary))
+ (message "Starting Geiser REPL ...")
+ (pop-to-buffer (geiser-repl--buffer))
+ (make-comint-in-buffer "Geiser REPL"
+ (current-buffer)
+ guile
+ nil
+ "-L" geiser-scheme-dir "-q")
+ (geiser-repl--wait-for-prompt 10000)
+ (geiser-con--setup-connection (current-buffer))))
+
+(defun geiser-repl--process (&optional start)
+ (or (and (buffer-live-p (geiser-repl--buffer))
+ (get-buffer-process (geiser-repl--buffer)))
+ (if (not start)
+ (error "No running Guile REPL (try M-x run-guile)")
+ (geiser-repl--start-process)
+ (geiser-repl--process))))
+
+(setq geiser-eval--default-proc-function 'geiser-repl--process)
+
+(defun geiser-repl--wait-for-prompt (timeout)
+ (let ((p (point)) (seen))
+ (while (and (not seen) (> timeout 0))
+ (sleep-for 0.1)
+ (setq timeout (- timeout 100))
+ (goto-char p)
+ (setq seen (re-search-forward comint-prompt-regexp nil t)))
+ (goto-char (point-max))
+ (unless seen (error "No prompt found!"))))
+
+
+;;; Interface: starting and interacting with geiser REPL:
+
+(defalias 'switch-to-guile 'run-guile)
+(defalias 'switch-to-geiser-repl 'run-guile)
+
+(defun run-guile (&optional arg)
+ "Show the geiser-repl buffer, starting the process if needed."
+ (interactive)
+ (let ((buf (process-buffer (geiser-repl--process t)))
+ (pop-up-windows geiser-repl-window-allow-split))
+ (if geiser-repl-use-other-window
+ (pop-to-buffer buf)
+ (switch-to-buffer buf))))
+
+(defun geiser-repl-nuke ()
+ "Try this command if the REPL becomes unresponsive."
+ (interactive)
+ (goto-char (point-max))
+ (comint-kill-region comint-last-input-start (point))
+ (comint-redirect-cleanup)
+ (geiser-con--setup-connection geiser-repl--buffer))
+
;;; geiser-repl mode:
+(defun geiser-repl--bol ()
+ (interactive)
+ (when (= (point) (comint-bol)) (beginning-of-line)))
+;;;###autoload
+(define-derived-mode geiser-repl-mode comint-mode "Geiser REPL"
+ "Major mode for interacting with an inferior Guile repl process.
+\\{geiser-repl-mode-map}"
+ (set (make-local-variable 'comint-prompt-regexp) geiser-con--prompt-regex)
+ (set (make-local-variable 'comint-use-prompt-regexp) t)
+ (set (make-local-variable 'comint-prompt-read-only) t))
+(define-key geiser-repl-mode-map "\C-cz" 'run-guile)
+(define-key geiser-repl-mode-map "\C-c\C-z" 'run-guile)
+(define-key geiser-repl-mode-map "\C-a" 'geiser-repl--bol)
+;; (define-key geiser-repl-mode-map "\C-ca" 'geiser-autodoc-mode)
+;; (define-key geiser-repl-mode-map "\C-ch" 'geiser-help)
+;; (define-key geiser-repl-mode-map "\C-cp" 'geiser-apropos)
+;; (define-key geiser-repl-mode-map "\M-." 'geiser-edit-word-at-point)
+;; (define-key geiser-repl-mode-map "\C-ck" 'geiser-compile-file)
+;; (define-key geiser-repl-mode-map (kbd "TAB") 'geiser-completion--complete-symbol)
+
+
(provide 'geiser-repl)
;;; geiser-repl.el ends here