]> gitweb.factorcode.org Git - factor.git/blob - misc/fuel/fuel-mode.el
Merge branch 'master' into experimental (untested!)
[factor.git] / misc / fuel / fuel-mode.el
1 ;;; fuel-mode.el -- Minor mode enabling FUEL niceties
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, 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 'factor-mode)
18 (require 'fuel-base)
19 (require 'fuel-syntax)
20 (require 'fuel-font-lock)
21 (require 'fuel-debug)
22 (require 'fuel-help)
23 (require 'fuel-eval)
24 (require 'fuel-listener)
25
26 \f
27 ;;; Customization:
28
29 (defgroup fuel-mode nil
30   "Mode enabling FUEL's ultimate abilities."
31   :group 'fuel)
32
33 (defcustom fuel-mode-autodoc-p t
34   "Whether `fuel-autodoc-mode' gets enable by default in fuel buffers."
35   :group 'fuel-mode
36   :type 'boolean)
37
38 \f
39 ;;; User commands
40
41 (defun fuel-run-file (&optional arg)
42   "Sends the current file to Factor for compilation.
43 With prefix argument, ask for the file to run."
44   (interactive "P")
45   (let* ((file (or (and arg (read-file-name "File: " nil (buffer-file-name) t))
46                    (buffer-file-name)))
47          (file (expand-file-name file))
48          (buffer (find-file-noselect file)))
49     (when buffer
50       (with-current-buffer buffer
51         (message "Compiling %s ..." file)
52         (fuel-eval--send (fuel-eval--cmd/string (format "%S fuel-run-file" file))
53                          `(lambda (r) (fuel--run-file-cont r ,file)))))))
54
55 (defun fuel--run-file-cont (ret file)
56   (if (fuel-debug--display-retort ret
57                                   (format "%s successfully compiled" file)
58                                   nil
59                                   file)
60       (message "Compiling %s ... OK!" file)
61     (message "")))
62
63 (defun fuel-eval-region (begin end &optional arg)
64   "Sends region to Fuel's listener for evaluation.
65 Unless called with a prefix, switchs to the compilation results
66 buffer in case of errors."
67   (interactive "r\nP")
68   (fuel-debug--display-retort
69    (fuel-eval--send/wait (fuel-eval--cmd/region begin end) 10000)
70    (format "%s%s"
71            (if fuel-syntax--current-vocab
72                (format "IN: %s " fuel-syntax--current-vocab)
73              "")
74            (fuel--shorten-region begin end 70))
75    arg
76    (buffer-file-name)))
77
78 (defun fuel-eval-extended-region (begin end &optional arg)
79   "Sends region extended outwards to nearest definitions,
80 to Fuel's listener for evaluation.
81 Unless called with a prefix, switchs to the compilation results
82 buffer in case of errors."
83   (interactive "r\nP")
84   (fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
85                     (save-excursion (goto-char end) (mark-defun) (mark))
86                     arg))
87
88 (defun fuel-eval-definition (&optional arg)
89   "Sends definition around point to Fuel's listener for evaluation.
90 Unless called with a prefix, switchs to the compilation results
91 buffer in case of errors."
92   (interactive "P")
93   (save-excursion
94     (mark-defun)
95     (let* ((begin (point))
96            (end (mark)))
97       (unless (< begin end) (error "No evaluable definition around point"))
98       (fuel-eval-region begin end arg))))
99
100 (defun fuel-edit-word-at-point (&optional arg)
101   "Opens a new window visiting the definition of the word at point.
102 With prefix, asks for the word to edit."
103   (interactive "P")
104   (let* ((word (fuel-syntax-symbol-at-point))
105          (ask (or arg (not word)))
106          (word (if ask
107                    (read-string nil
108                                 (format "Edit word%s: "
109                                         (if word (format " (%s)" word) ""))
110                                 word)
111                  word)))
112     (let* ((str (fuel-eval--cmd/string
113                  (format "\\ %s fuel-get-edit-location" word)))
114            (ret (fuel-eval--send/wait str))
115            (err (fuel-eval--retort-error ret))
116            (loc (fuel-eval--retort-result ret)))
117       (when (or err (not loc) (not (listp loc)) (not (stringp (car loc))))
118         (error "Couldn't find edit location for '%s'" word))
119       (unless (file-readable-p (car loc))
120         (error "Couldn't open '%s' for read" (car loc)))
121       (find-file-other-window (car loc))
122       (goto-line (if (numberp (cadr loc)) (cadr loc) 1)))))
123
124 \f
125 ;;; Minor mode definition:
126
127 (make-variable-buffer-local
128  (defvar fuel-mode-string " F"
129    "Modeline indicator for fuel-mode"))
130
131 (defvar fuel-mode-map (make-sparse-keymap)
132   "Key map for fuel-mode")
133
134 (define-minor-mode fuel-mode
135   "Toggle Fuel's mode.
136 With no argument, this command toggles the mode.
137 Non-null prefix argument turns on the mode.
138 Null prefix argument turns off the mode.
139
140 When Fuel mode is enabled, a host of nice utilities for
141 interacting with a factor listener is at your disposal.
142 \\{fuel-mode-map}"
143   :init-value nil
144   :lighter fuel-mode-string
145   :group 'fuel
146   :keymap fuel-mode-map
147
148   (setq fuel-autodoc-mode-string "/A")
149   (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode)))
150
151 \f
152 ;;; Keys:
153
154 (defun fuel-mode--key-1 (k c)
155   (define-key fuel-mode-map (vector '(control ?c) k) c)
156   (define-key fuel-mode-map (vector '(control ?c) `(control ,k))  c))
157
158 (defun fuel-mode--key (p k c)
159   (define-key fuel-mode-map (vector '(control ?c) `(control ,p) k) c)
160   (define-key fuel-mode-map (vector '(control ?c) `(control ,p) `(control ,k)) c))
161
162 (fuel-mode--key-1 ?z 'run-factor)
163
164 (fuel-mode--key-1 ?k 'fuel-run-file)
165 (fuel-mode--key ?e ?k 'fuel-run-file)
166
167 (define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
168 (fuel-mode--key ?e ?x 'fuel-eval-definition)
169
170 (fuel-mode--key-1 ?r 'fuel-eval-region)
171 (fuel-mode--key ?e ?r 'fuel-eval-region)
172
173 (define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
174 (fuel-mode--key ?e ?e 'fuel-eval-extended-region)
175
176 (define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
177
178 (fuel-mode--key ?d ?a 'fuel-autodoc-mode)
179 (fuel-mode--key ?d ?d 'fuel-help)
180 (fuel-mode--key ?d ?s 'fuel-help-short)
181
182 \f
183 (provide 'fuel-mode)
184 ;;; fuel-mode.el ends here