1 ;;; fuel-mode.el -- Minor mode enabling FUEL niceties
3 ;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
4 ;; See http://factorcode.org/license.txt for BSD license.
6 ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
7 ;; Keywords: languages, fuel, factor
8 ;; Start date: Sat Dec 06, 2008 00:52
12 ;; Enhancements to vanilla factor-mode (notably, listener interaction)
13 ;; enabled by means of a minor mode.
17 (require 'factor-mode)
19 (require 'fuel-syntax)
20 (require 'fuel-font-lock)
24 (require 'fuel-listener)
29 (defgroup fuel-mode nil
30 "Mode enabling FUEL's ultimate abilities."
33 (defcustom fuel-mode-autodoc-p t
34 "Whether `fuel-autodoc-mode' gets enable by default in fuel buffers."
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."
45 (let* ((file (or (and arg (read-file-name "File: " nil (buffer-file-name) t))
47 (file (expand-file-name file))
48 (buffer (find-file-noselect file)))
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)))))))
55 (defun fuel--run-file-cont (ret file)
56 (if (fuel-debug--display-retort ret
57 (format "%s successfully compiled" file)
60 (message "Compiling %s ... OK!" file)
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."
68 (fuel-debug--display-retort
69 (fuel-eval--send/wait (fuel-eval--cmd/region begin end) 10000)
71 (if fuel-syntax--current-vocab
72 (format "IN: %s " fuel-syntax--current-vocab)
74 (fuel--shorten-region begin end 70))
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."
84 (fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
85 (save-excursion (goto-char end) (mark-defun) (mark))
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."
95 (let* ((begin (point))
97 (unless (< begin end) (error "No evaluable definition around point"))
98 (fuel-eval-region begin end arg))))
100 (defun fuel--try-edit (ret)
101 (let* ((err (fuel-eval--retort-error ret))
102 (loc (fuel-eval--retort-result ret)))
103 (when (or err (not loc) (not (listp loc)) (not (stringp (car loc))))
104 (error "Couldn't find edit location for '%s'" word))
105 (unless (file-readable-p (car loc))
106 (error "Couldn't open '%s' for read" (car loc)))
107 (find-file-other-window (car loc))
108 (goto-line (if (numberp (cadr loc)) (cadr loc) 1))))
110 (defun fuel-edit-word-at-point (&optional arg)
111 "Opens a new window visiting the definition of the word at point.
112 With prefix, asks for the word to edit."
114 (let* ((word (fuel-syntax-symbol-at-point))
115 (ask (or arg (not word)))
118 (format "Edit word%s: "
119 (if word (format " (%s)" word) ""))
122 (let ((str (fuel-eval--cmd/string
123 (format "\\ %s fuel-get-edit-location" word))))
125 (fuel--try-edit (fuel-eval--send/wait str))
126 (error (fuel-edit-vocabulary word))))))
128 (defvar fuel--vocabs-prompt-history nil)
130 (defun fuel--read-vocabulary-name ()
131 (let* ((str (fuel-eval--cmd/string "fuel-get-vocabs" t "fuel" t))
132 (vocabs (fuel-eval--retort-result (fuel-eval--send/wait str)))
133 (prompt "Vocabulary name: "))
135 (completing-read prompt vocabs nil t nil fuel--vocabs-prompt-history)
136 (read-string prompt nil fuel--vocabs-prompt-history))))
138 (defun fuel-edit-vocabulary (vocab)
139 "Visits vocabulary file in Emacs.
140 When called interactively, asks for vocabulary with completion."
141 (interactive (list (fuel--read-vocabulary-name)))
142 (let* ((str (fuel-eval--cmd/string
143 (format "%S fuel-get-vocab-location" vocab) t "fuel" t)))
144 (fuel--try-edit (fuel-eval--send/wait str))))
147 ;;; Minor mode definition:
149 (make-variable-buffer-local
150 (defvar fuel-mode-string " F"
151 "Modeline indicator for fuel-mode"))
153 (defvar fuel-mode-map (make-sparse-keymap)
154 "Key map for fuel-mode")
156 (define-minor-mode fuel-mode
158 With no argument, this command toggles the mode.
159 Non-null prefix argument turns on the mode.
160 Null prefix argument turns off the mode.
162 When Fuel mode is enabled, a host of nice utilities for
163 interacting with a factor listener is at your disposal.
166 :lighter fuel-mode-string
168 :keymap fuel-mode-map
170 (setq fuel-autodoc-mode-string "/A")
171 (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode)))
176 (defun fuel-mode--key-1 (k c)
177 (define-key fuel-mode-map (vector '(control ?c) k) c)
178 (define-key fuel-mode-map (vector '(control ?c) `(control ,k)) c))
180 (defun fuel-mode--key (p k c)
181 (define-key fuel-mode-map (vector '(control ?c) `(control ,p) k) c)
182 (define-key fuel-mode-map (vector '(control ?c) `(control ,p) `(control ,k)) c))
184 (fuel-mode--key-1 ?z 'run-factor)
186 (fuel-mode--key-1 ?k 'fuel-run-file)
187 (fuel-mode--key ?e ?k 'fuel-run-file)
189 (define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
190 (fuel-mode--key ?e ?x 'fuel-eval-definition)
192 (fuel-mode--key-1 ?r 'fuel-eval-region)
193 (fuel-mode--key ?e ?r 'fuel-eval-region)
195 (define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
196 (fuel-mode--key ?e ?e 'fuel-eval-extended-region)
198 (fuel-mode--key ?e ?v 'fuel-edit-vocabulary)
200 (define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
202 (fuel-mode--key ?d ?a 'fuel-autodoc-mode)
203 (fuel-mode--key ?d ?d 'fuel-help)
204 (fuel-mode--key ?d ?s 'fuel-help-short)
208 ;;; fuel-mode.el ends here