]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-listener.el
Merge branch 'master' into experimental (untested!)
[factor.git] / misc / fuel / fuel-listener.el
1 ;;; fuel-listener.el --- starting the fuel listener
2
3 ;; Copyright (C) 2008  Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
5
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
7 ;; Keywords: languages
8
9 ;;; Commentary:
10
11 ;; Utilities to maintain and switch to a factor listener comint
12 ;; buffer, with an accompanying major fuel-listener-mode.
13
14 ;;; Code:
15
16 (require 'fuel-eval)
17 (require 'fuel-base)
18 (require 'comint)
19
20 \f
21 ;;; Customization:
22
23 (defgroup fuel-listener nil
24   "Interacting with a Factor listener inside Emacs"
25   :group 'fuel)
26
27 (defcustom fuel-listener-factor-binary "~/factor/factor"
28   "Full path to the factor executable to use when starting a listener."
29   :type '(file :must-match t)
30   :group 'fuel-listener)
31
32 (defcustom fuel-listener-factor-image "~/factor/factor.image"
33   "Full path to the factor image to use when starting a listener."
34   :type '(file :must-match t)
35   :group 'fuel-listener)
36
37 (defcustom fuel-listener-use-other-window t
38   "Use a window other than the current buffer's when switching to
39 the factor-listener buffer."
40   :type 'boolean
41   :group 'fuel-listener)
42
43 (defcustom fuel-listener-window-allow-split t
44   "Allow window splitting when switching to the fuel listener
45 buffer."
46   :type 'boolean
47   :group 'fuel-listener)
48
49 \f
50 ;;; Fuel listener buffer/process:
51
52 (defvar fuel-listener-buffer nil
53   "The buffer in which the Factor listener is running.")
54
55 (defun fuel-listener--start-process ()
56   (let ((factor (expand-file-name fuel-listener-factor-binary))
57         (image (expand-file-name fuel-listener-factor-image)))
58     (unless (file-executable-p factor)
59       (error "Could not run factor: %s is not executable" factor))
60     (unless (file-readable-p image)
61       (error "Could not run factor: image file %s not readable" image))
62     (setq fuel-listener-buffer (get-buffer-create "*fuel listener*"))
63     (with-current-buffer fuel-listener-buffer
64       (fuel-listener-mode)
65       (message "Starting FUEL listener ...")
66       (comint-exec fuel-listener-buffer "factor"
67                    factor nil `("-run=fuel" ,(format "-i=%s" image)))
68       (fuel-listener--wait-for-prompt 20)
69       (fuel-eval--send/wait "USE: fuel")
70       (message "FUEL listener up and running!"))))
71
72 (defun fuel-listener--process (&optional start)
73   (or (and (buffer-live-p fuel-listener-buffer)
74            (get-buffer-process fuel-listener-buffer))
75       (if (not start)
76           (error "No running factor listener (try M-x run-factor)")
77         (fuel-listener--start-process)
78         (fuel-listener--process))))
79
80 (setq fuel-eval--default-proc-function 'fuel-listener--process)
81
82 \f
83 ;;; Prompt chasing
84
85 (defun fuel-listener--wait-for-prompt (&optional timeout)
86   (let ((proc (get-buffer-process fuel-listener-buffer)))
87     (with-current-buffer fuel-listener-buffer
88       (goto-char (or comint-last-input-end (point-min)))
89       (let ((seen (re-search-forward comint-prompt-regexp nil t)))
90         (while (and (not seen)
91                     (accept-process-output proc (or timeout 10) nil t))
92           (sleep-for 0 1)
93           (goto-char comint-last-input-end)
94           (setq seen (re-search-forward comint-prompt-regexp nil t)))
95         (pop-to-buffer fuel-listener-buffer)
96         (goto-char (point-max))
97         (unless seen (error "No prompt found!"))))))
98
99 \f
100 ;;; Interface: starting fuel listener
101
102 (defalias 'switch-to-factor 'run-factor)
103 (defalias 'switch-to-fuel-listener 'run-factor)
104 ;;;###autoload
105 (defun run-factor (&optional arg)
106   "Show the fuel-listener buffer, starting the process if needed."
107   (interactive)
108   (let ((buf (process-buffer (fuel-listener--process t)))
109         (pop-up-windows fuel-listener-window-allow-split))
110     (if fuel-listener-use-other-window
111         (pop-to-buffer buf)
112       (switch-to-buffer buf))))
113
114 \f
115 ;;; Fuel listener mode:
116
117 (defconst fuel-listener--prompt-regex "( [^)]* ) ")
118
119 (define-derived-mode fuel-listener-mode comint-mode "Fuel Listener"
120   "Major mode for interacting with an inferior Factor listener process.
121 \\{fuel-listener-mode-map}"
122   (set (make-local-variable 'comint-prompt-regexp)
123        fuel-listener--prompt-regex)
124   (set (make-local-variable 'comint-prompt-read-only) t)
125   (setq fuel-listener--compilation-begin nil))
126
127 (define-key fuel-listener-mode-map "\C-cz" 'run-factor)
128 (define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor)
129 (define-key fuel-listener-mode-map "\C-ch" 'fuel-help)
130 (define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point)
131 (define-key fuel-listener-mode-map "\C-ck" 'fuel-run-file)
132
133 \f
134 (provide 'fuel-listener)
135 ;;; fuel-listener.el ends here