1 ;;; fuel-listener.el --- starting the fuel listener
3 ;; Copyright (C) 2008, 2009 Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
11 ;; Utilities to maintain and switch to a factor listener comint
12 ;; buffer, with an accompanying major fuel-listener-mode.
17 (require 'fuel-completion)
20 (require 'fuel-connection)
21 (require 'fuel-syntax)
29 (defgroup fuel-listener nil
30 "Interacting with a Factor listener inside Emacs."
33 (defcustom fuel-listener-factor-binary
34 (expand-file-name (cond ((eq system-type 'windows-nt)
36 ((eq system-type 'darwin)
37 "Factor.app/Contents/MacOS/factor")
40 "Full path to the factor executable to use when starting a listener."
41 :type '(file :must-match t)
42 :group 'fuel-listener)
44 (defcustom fuel-listener-factor-image
45 (expand-file-name "factor.image" fuel-factor-root-dir)
46 "Full path to the factor image to use when starting a listener."
47 :type '(file :must-match t)
48 :group 'fuel-listener)
50 (defcustom fuel-listener-use-other-window t
51 "Use a window other than the current buffer's when switching to
52 the factor-listener buffer."
54 :group 'fuel-listener)
56 (defcustom fuel-listener-window-allow-split t
57 "Allow window splitting when switching to the fuel listener
60 :group 'fuel-listener)
63 ;;; Fuel listener buffer/process:
65 (defvar fuel-listener--buffer nil
66 "The buffer in which the Factor listener is running.")
68 (defun fuel-listener--buffer ()
69 (if (buffer-live-p fuel-listener--buffer)
71 (with-current-buffer (get-buffer-create "*fuel listener*")
73 (setq fuel-listener--buffer (current-buffer)))))
75 (defun fuel-listener--start-process ()
76 (let ((factor (expand-file-name fuel-listener-factor-binary))
77 (image (expand-file-name fuel-listener-factor-image))
78 (comint-redirect-perform-sanity-check nil))
79 (unless (file-executable-p factor)
80 (error "Could not run factor: %s is not executable" factor))
81 (unless (file-readable-p image)
82 (error "Could not run factor: image file %s not readable" image))
83 (message "Starting FUEL listener (this may take a while) ...")
84 (pop-to-buffer (fuel-listener--buffer))
85 (make-comint-in-buffer "fuel listener" (current-buffer) factor nil
86 "-run=listener" (format "-i=%s" image))
87 (fuel-listener--wait-for-prompt 10000)
88 (fuel-con--setup-connection (current-buffer))))
90 (defun fuel-listener--process (&optional start)
91 (or (and (buffer-live-p (fuel-listener--buffer))
92 (get-buffer-process (fuel-listener--buffer)))
94 (error "No running factor listener (try M-x run-factor)")
95 (fuel-listener--start-process)
96 (fuel-listener--process))))
98 (setq fuel-eval--default-proc-function 'fuel-listener--process)
100 (defun fuel-listener--wait-for-prompt (timeout)
101 (let ((p (point)) (seen))
102 (while (and (not seen) (> timeout 0))
104 (setq timeout (- timeout 100))
106 (setq seen (re-search-forward comint-prompt-regexp nil t)))
107 (goto-char (point-max))
108 (unless seen (error "No prompt found!"))))
110 (defun fuel-listener-nuke ()
112 (goto-char (point-max))
113 (comint-kill-region comint-last-input-start (point))
114 (comint-redirect-cleanup)
115 (fuel-con--setup-connection fuel-listener--buffer))
118 ;;; Interface: starting fuel listener
120 (defalias 'switch-to-factor 'run-factor)
121 (defalias 'switch-to-fuel-listener 'run-factor)
123 (defun run-factor (&optional arg)
124 "Show the fuel-listener buffer, starting the process if needed."
126 (let ((buf (process-buffer (fuel-listener--process t)))
127 (pop-up-windows fuel-listener-window-allow-split))
128 (if fuel-listener-use-other-window
130 (switch-to-buffer buf))))
133 ;;; Completion support
135 (defsubst fuel-listener--current-vocab () nil)
136 (defsubst fuel-listener--usings () nil)
138 (defun fuel-listener--setup-completion ()
139 (setq fuel-syntax--current-vocab-function 'fuel-listener--current-vocab)
140 (setq fuel-syntax--usings-function 'fuel-listener--usings))
143 ;;; Stack mode support
145 (defun fuel-listener--stack-region ()
146 (fuel--region-to-string (if (zerop (fuel-syntax--brackets-depth))
147 (comint-line-beginning-position)
148 (1+ (fuel-syntax--brackets-start)))))
150 (defun fuel-listener--setup-stack-mode ()
151 (setq fuel-stack--region-function 'fuel-listener--stack-region))
154 ;;; Fuel listener mode:
156 (defun fuel-listener--bol ()
158 (when (= (point) (comint-bol)) (beginning-of-line)))
161 (define-derived-mode fuel-listener-mode comint-mode "Fuel Listener"
162 "Major mode for interacting with an inferior Factor listener process.
163 \\{fuel-listener-mode-map}"
164 (set (make-local-variable 'comint-prompt-regexp) fuel-con--prompt-regex)
165 (set (make-local-variable 'comint-use-prompt-regexp) t)
166 (set (make-local-variable 'comint-prompt-read-only) t)
167 (fuel-listener--setup-completion)
168 (fuel-listener--setup-stack-mode))
170 (define-key fuel-listener-mode-map "\C-cz" 'run-factor)
171 (define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor)
172 (define-key fuel-listener-mode-map "\C-a" 'fuel-listener--bol)
173 (define-key fuel-listener-mode-map "\C-ca" 'fuel-autodoc-mode)
174 (define-key fuel-listener-mode-map "\C-ch" 'fuel-help)
175 (define-key fuel-listener-mode-map "\C-cs" 'fuel-stack-mode)
176 (define-key fuel-listener-mode-map "\C-cp" 'fuel-apropos)
177 (define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point)
178 (define-key fuel-listener-mode-map "\C-cv" 'fuel-edit-vocabulary)
179 (define-key fuel-listener-mode-map "\C-c\C-v" 'fuel-edit-vocabulary)
180 (define-key fuel-listener-mode-map "\C-ck" 'fuel-run-file)
181 (define-key fuel-listener-mode-map (kbd "TAB") 'fuel-completion--complete-symbol)
184 (provide 'fuel-listener)
185 ;;; fuel-listener.el ends here