]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-listener.el
c1e8d670cf8705920c26cc8aba9fc067bfd65209
[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-completion)
18 (require 'fuel-connection)
19 (require 'fuel-syntax)
20 (require 'fuel-base)
21
22 (require 'comint)
23
24 \f
25 ;;; Customization:
26
27 (defgroup fuel-listener nil
28   "Interacting with a Factor listener inside Emacs"
29   :group 'fuel)
30
31 (defcustom fuel-listener-factor-binary "~/factor/factor"
32   "Full path to the factor executable to use when starting a listener."
33   :type '(file :must-match t)
34   :group 'fuel-listener)
35
36 (defcustom fuel-listener-factor-image "~/factor/factor.image"
37   "Full path to the factor image to use when starting a listener."
38   :type '(file :must-match t)
39   :group 'fuel-listener)
40
41 (defcustom fuel-listener-use-other-window t
42   "Use a window other than the current buffer's when switching to
43 the factor-listener buffer."
44   :type 'boolean
45   :group 'fuel-listener)
46
47 (defcustom fuel-listener-window-allow-split t
48   "Allow window splitting when switching to the fuel listener
49 buffer."
50   :type 'boolean
51   :group 'fuel-listener)
52
53 \f
54 ;;; Fuel listener buffer/process:
55
56 (defvar fuel-listener--buffer nil
57   "The buffer in which the Factor listener is running.")
58
59 (defun fuel-listener--buffer ()
60   (if (buffer-live-p fuel-listener--buffer)
61       fuel-listener--buffer
62     (with-current-buffer (get-buffer-create "*fuel listener*")
63       (fuel-listener-mode)
64       (setq fuel-listener--buffer (current-buffer)))))
65
66 (defun fuel-listener--start-process ()
67   (let ((factor (expand-file-name fuel-listener-factor-binary))
68         (image (expand-file-name fuel-listener-factor-image))
69         (comint-redirect-perform-sanity-check nil))
70     (unless (file-executable-p factor)
71       (error "Could not run factor: %s is not executable" factor))
72     (unless (file-readable-p image)
73       (error "Could not run factor: image file %s not readable" image))
74     (message "Starting FUEL listener ...")
75     (pop-to-buffer (fuel-listener--buffer))
76     (make-comint-in-buffer "fuel listener" (current-buffer) factor nil
77                            "-run=listener" (format "-i=%s" image))
78     (fuel-listener--wait-for-prompt 10000)
79     (fuel-con--send-string/wait (current-buffer)
80                                 fuel-con--init-stanza
81                                 '(lambda (s) (message "FUEL listener up and running!"))
82                                 20000)))
83
84 (defun fuel-listener--process (&optional start)
85   (or (and (buffer-live-p (fuel-listener--buffer))
86            (get-buffer-process (fuel-listener--buffer)))
87       (if (not start)
88           (error "No running factor listener (try M-x run-factor)")
89         (fuel-listener--start-process)
90         (fuel-listener--process))))
91
92 (setq fuel-eval--default-proc-function 'fuel-listener--process)
93
94 (defun fuel-listener--wait-for-prompt (timeout)
95   (let ((p (point)) (seen))
96     (while (and (not seen) (> timeout 0))
97       (sleep-for 0.1)
98       (setq timeout (- timeout 100))
99       (goto-char p)
100       (setq seen (re-search-forward comint-prompt-regexp nil t)))
101     (goto-char (point-max))
102     (unless seen (error "No prompt found!"))))
103
104 \f
105 ;;; Completion support
106
107 (defsubst fuel-listener--current-vocab () nil)
108 (defsubst fuel-listener--usings () nil)
109
110 (defun fuel-listener--setup-completion ()
111   (setq fuel-syntax--current-vocab-function 'fuel-listener--current-vocab)
112   (setq fuel-syntax--usings-function 'fuel-listener--usings)
113   (set-syntax-table fuel-syntax--syntax-table))
114
115 \f
116 ;;; Interface: starting fuel listener
117
118 (defalias 'switch-to-factor 'run-factor)
119 (defalias 'switch-to-fuel-listener 'run-factor)
120 ;;;###autoload
121 (defun run-factor (&optional arg)
122   "Show the fuel-listener buffer, starting the process if needed."
123   (interactive)
124   (let ((buf (process-buffer (fuel-listener--process t)))
125         (pop-up-windows fuel-listener-window-allow-split))
126     (if fuel-listener-use-other-window
127         (pop-to-buffer buf)
128       (switch-to-buffer buf))))
129
130 \f
131 ;;; Fuel listener mode:
132
133 (define-derived-mode fuel-listener-mode comint-mode "Fuel Listener"
134   "Major mode for interacting with an inferior Factor listener process.
135 \\{fuel-listener-mode-map}"
136   (set (make-local-variable 'comint-prompt-regexp) fuel-con--prompt-regex)
137   (set (make-local-variable 'comint-prompt-read-only) t)
138   (fuel-listener--setup-completion))
139
140 (define-key fuel-listener-mode-map "\C-cz" 'run-factor)
141 (define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor)
142 (define-key fuel-listener-mode-map "\C-ca" 'fuel-autodoc-mode)
143 (define-key fuel-listener-mode-map "\C-ch" 'fuel-help)
144 (define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point)
145 (define-key fuel-listener-mode-map "\C-cv" 'fuel-edit-vocabulary)
146 (define-key fuel-listener-mode-map "\C-c\C-v" 'fuel-edit-vocabulary)
147 (define-key fuel-listener-mode-map "\C-ck" 'fuel-run-file)
148 (define-key fuel-listener-mode-map (kbd "TAB") 'fuel-completion--complete-symbol)
149
150 \f
151 (provide 'fuel-listener)
152 ;;; fuel-listener.el ends here