]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-mode.el
Merge branch 'master' of git://github.com/prunedtree/factor
[factor.git] / misc / fuel / fuel-mode.el
1 ;;; fuel-mode.el -- Minor mode enabling FUEL niceties
2
3 ;; Copyright (C) 2008, 2009 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, fuel, factor
8 ;; Start date: Sat Dec 06, 2008 00:52
9
10 ;;; Comentary:
11
12 ;; Enhancements to vanilla factor-mode (notably, listener interaction)
13 ;; enabled by means of a minor mode.
14
15 ;;; Code:
16
17 (require 'fuel-listener)
18 (require 'fuel-completion)
19 (require 'fuel-debug)
20 (require 'fuel-debug-uses)
21 (require 'fuel-eval)
22 (require 'fuel-help)
23 (require 'fuel-xref)
24 (require 'fuel-refactor)
25 (require 'fuel-stack)
26 (require 'fuel-autodoc)
27 (require 'fuel-font-lock)
28 (require 'fuel-edit)
29 (require 'fuel-syntax)
30 (require 'fuel-base)
31
32 \f
33 ;;; Customization:
34
35 (defgroup fuel-mode nil
36   "Mode enabling FUEL's ultimate abilities."
37   :group 'fuel)
38
39 (defcustom fuel-mode-autodoc-p t
40   "Whether `fuel-autodoc-mode' gets enabled by default in factor buffers."
41   :group 'fuel-mode
42   :group 'fuel-autodoc
43   :type 'boolean)
44
45 (defcustom fuel-mode-stack-p nil
46   "Whether `fuel-stack-mode' gets enabled by default in factor buffers."
47   :group 'fuel-mode
48   :group 'fuel-stack
49   :type 'boolean)
50
51 \f
52 ;;; User commands
53
54 (defun fuel-mode--read-file (arg)
55   (let* ((file (or (and arg (read-file-name "File: " nil (buffer-file-name) t))
56                    (buffer-file-name)))
57          (file (expand-file-name file))
58          (buffer (find-file-noselect file)))
59     (when (and  buffer
60                 (buffer-modified-p buffer)
61                 (y-or-n-p "Save file? "))
62       (save-buffer buffer))
63     (cons file buffer)))
64
65 (defun fuel-run-file (&optional arg)
66   "Sends the current file to Factor for compilation.
67 With prefix argument, ask for the file to run."
68   (interactive "P")
69   (let* ((f/b (fuel-mode--read-file arg))
70          (file (car f/b))
71          (buffer (cdr f/b)))
72     (when buffer
73       (with-current-buffer buffer
74         (let ((msg (format "Compiling %s ..." file)))
75           (fuel-debug--prepare-compilation file msg)
76           (message msg)
77           (fuel-eval--send `(:fuel (,file fuel-run-file))
78                            `(lambda (r) (fuel--run-file-cont r ,file))))))))
79
80 (defun fuel--run-file-cont (ret file)
81   (if (fuel-debug--display-retort ret (format "%s successfully compiled" file))
82       (message "Compiling %s ... OK!" file)
83     (message "")))
84
85 (defun fuel-eval-region (begin end &optional arg)
86   "Sends region to Fuel's listener for evaluation.
87 Unless called with a prefix, switches to the compilation results
88 buffer in case of errors."
89   (interactive "r\nP")
90   (let* ((rstr (buffer-substring begin end))
91          (lines (split-string (substring-no-properties rstr)
92                               "[\f\n\r\v]+"
93                               t))
94          (cmd `(:fuel (,(mapcar (lambda (l) `(:factor ,l)) lines))))
95          (cv (fuel-syntax--current-vocab)))
96     (fuel-debug--prepare-compilation (buffer-file-name)
97                                      (format "Evaluating:\n\n%s" rstr))
98     (fuel-debug--display-retort
99      (fuel-eval--send/wait cmd 10000)
100      (format "%s%s"
101              (if cv (format "IN: %s " cv) "")
102              (fuel--shorten-region begin end 70))
103      arg)))
104
105 (defun fuel-eval-extended-region (begin end &optional arg)
106   "Sends region, extended outwards to nearest definition,
107 to Fuel's listener for evaluation.
108 Unless called with a prefix, switches to the compilation results
109 buffer in case of errors."
110   (interactive "r\nP")
111   (fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
112                     (save-excursion (goto-char end) (mark-defun) (mark))
113                     arg))
114
115 (defun fuel-eval-definition (&optional arg)
116   "Sends definition around point to Fuel's listener for evaluation.
117 Unless called with a prefix, switches to the compilation results
118 buffer in case of errors."
119   (interactive "P")
120   (save-excursion
121     (mark-defun)
122     (let* ((begin (point))
123            (end (mark)))
124       (unless (< begin end) (error "No evaluable definition around point"))
125       (fuel-eval-region begin end arg))))
126
127 (defun fuel-update-usings (&optional arg)
128   "Asks factor for the vocabularies needed by this file,
129 optionally updating the its USING: line.
130 With prefix argument, ask for the file name."
131   (interactive "P")
132   (let ((file (car (fuel-mode--read-file arg))))
133     (when file (fuel-debug--uses-for-file file))))
134
135 (defun fuel-load-usings ()
136   "Loads all vocabularies in the current buffer's USING: from.
137 Useful to activate autodoc help messages in a vocabulary not yet
138 loaded. See documentation for `fuel-autodoc-eval-using-form-p'
139 for details."
140   (interactive)
141   (message "Loading all vocabularies in USING: form ...")
142   (let ((err (fuel-eval--retort-error
143               (fuel-eval--send/wait '(:fuel* (t .) t :usings) 120000))))
144     (message (if err "Warning: some vocabularies failed to load"
145                "All vocabularies loaded"))))
146
147 \f
148 ;;; Minor mode definition:
149
150 (make-variable-buffer-local
151  (defvar fuel-mode-string " F"
152    "Modeline indicator for fuel-mode"))
153
154 (defvar fuel-mode-map (make-sparse-keymap)
155   "Key map for fuel-mode")
156
157 (define-minor-mode fuel-mode
158   "Toggle Fuel's mode.
159 With no argument, this command toggles the mode.
160 Non-null prefix argument turns on the mode.
161 Null prefix argument turns off the mode.
162
163 When Fuel mode is enabled, a host of nice utilities for
164 interacting with a factor listener is at your disposal.
165 \\{fuel-mode-map}"
166   :init-value nil
167   :lighter fuel-mode-string
168   :group 'fuel
169   :keymap fuel-mode-map
170
171   (setq fuel-autodoc-mode-string "/A")
172   (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode))
173
174   (setq fuel-stack-mode-string "/S")
175   (when fuel-mode-stack-p (fuel-stack-mode fuel-mode))
176
177   (when (and fuel-mode (not (file-exists-p (buffer-file-name))))
178     (fuel-scaffold--maybe-insert)))
179
180 \f
181 ;;; Keys:
182
183 (defun fuel-mode--key-1 (k c)
184   (define-key fuel-mode-map (vector '(control ?c) k) c)
185   (define-key fuel-mode-map (vector '(control ?c) `(control ,k))  c))
186
187 (defun fuel-mode--key (p k c)
188   (define-key fuel-mode-map (vector '(control ?c) `(control ,p) k) c)
189   (define-key fuel-mode-map (vector '(control ?c) `(control ,p) `(control ,k)) c))
190
191 (fuel-mode--key-1 ?k 'fuel-run-file)
192 (fuel-mode--key-1 ?l 'fuel-run-file)
193 (fuel-mode--key-1 ?r 'fuel-refresh-all)
194 (fuel-mode--key-1 ?z 'run-factor)
195 (fuel-mode--key-1 ?s 'fuel-switch-to-buffer)
196 (define-key fuel-mode-map "\C-x4s" 'fuel-switch-to-buffer-other-window)
197 (define-key fuel-mode-map "\C-x5s" 'fuel-switch-to-buffer-other-frame)
198
199 (define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
200 (define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
201 (define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
202 (define-key fuel-mode-map "\M-," 'fuel-edit-pop-edit-word-stack)
203 (define-key fuel-mode-map "\C-c\M-<" 'fuel-show-callers)
204 (define-key fuel-mode-map "\C-c\M->" 'fuel-show-callees)
205 (define-key fuel-mode-map (kbd "M-TAB") 'fuel-completion--complete-symbol)
206
207 (fuel-mode--key ?e ?d 'fuel-edit-word-doc-at-point)
208 (fuel-mode--key ?e ?e 'fuel-eval-extended-region)
209 (fuel-mode--key ?e ?k 'fuel-run-file)
210 (fuel-mode--key ?e ?l 'fuel-load-usings)
211 (fuel-mode--key ?e ?r 'fuel-eval-region)
212 (fuel-mode--key ?e ?u 'fuel-update-usings)
213 (fuel-mode--key ?e ?v 'fuel-edit-vocabulary)
214 (fuel-mode--key ?e ?w 'fuel-edit-word)
215 (fuel-mode--key ?e ?x 'fuel-eval-definition)
216
217 (fuel-mode--key ?x ?a 'fuel-refactor-extract-article)
218 (fuel-mode--key ?x ?i 'fuel-refactor-inline-word)
219 (fuel-mode--key ?x ?g 'fuel-refactor-make-generic)
220 (fuel-mode--key ?x ?r 'fuel-refactor-extract-region)
221 (fuel-mode--key ?x ?s 'fuel-refactor-extract-sexp)
222 (fuel-mode--key ?x ?v 'fuel-refactor-extract-vocab)
223 (fuel-mode--key ?x ?w 'fuel-refactor-rename-word)
224
225 (fuel-mode--key ?d ?> 'fuel-show-callees)
226 (fuel-mode--key ?d ?< 'fuel-show-callers)
227 (fuel-mode--key ?d ?v 'fuel-show-file-words)
228 (fuel-mode--key ?d ?a 'fuel-autodoc-mode)
229 (fuel-mode--key ?d ?p 'fuel-apropos)
230 (fuel-mode--key ?d ?d 'fuel-help)
231 (fuel-mode--key ?d ?e 'fuel-stack-effect-sexp)
232 (fuel-mode--key ?d ?s 'fuel-help-short)
233
234 \f
235 (provide 'fuel-mode)
236 ;;; fuel-mode.el ends here