2008-12-05 22:34:25 -05:00
|
|
|
|
;;; fuel-mode.el -- Minor mode enabling FUEL niceties
|
|
|
|
|
|
|
|
|
|
;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
|
|
|
|
|
;; See http://factorcode.org/license.txt for BSD license.
|
|
|
|
|
|
|
|
|
|
;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org>
|
|
|
|
|
;; Keywords: languages, fuel, factor
|
|
|
|
|
;; Start date: Sat Dec 06, 2008 00:52
|
|
|
|
|
|
|
|
|
|
;;; Comentary:
|
|
|
|
|
|
|
|
|
|
;; Enhancements to vanilla factor-mode (notably, listener interaction)
|
|
|
|
|
;; enabled by means of a minor mode.
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
|
|
(require 'fuel-listener)
|
2008-12-18 18:20:56 -05:00
|
|
|
|
(require 'fuel-completion)
|
2008-12-20 10:51:05 -05:00
|
|
|
|
(require 'fuel-debug)
|
2008-12-18 18:20:56 -05:00
|
|
|
|
(require 'fuel-eval)
|
|
|
|
|
(require 'fuel-help)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(require 'fuel-xref)
|
2008-12-20 10:51:05 -05:00
|
|
|
|
(require 'fuel-stack)
|
|
|
|
|
(require 'fuel-autodoc)
|
2008-12-18 18:20:56 -05:00
|
|
|
|
(require 'fuel-font-lock)
|
|
|
|
|
(require 'fuel-syntax)
|
|
|
|
|
(require 'fuel-base)
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Customization:
|
|
|
|
|
|
|
|
|
|
(defgroup fuel-mode nil
|
|
|
|
|
"Mode enabling FUEL's ultimate abilities."
|
|
|
|
|
:group 'fuel)
|
|
|
|
|
|
|
|
|
|
(defcustom fuel-mode-autodoc-p t
|
2008-12-20 10:51:05 -05:00
|
|
|
|
"Whether `fuel-autodoc-mode' gets enabled by default in factor buffers."
|
|
|
|
|
:group 'fuel-mode
|
2008-12-20 19:43:28 -05:00
|
|
|
|
:group 'fuel-autodoc
|
2008-12-20 10:51:05 -05:00
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
(defcustom fuel-mode-stack-p nil
|
|
|
|
|
"Whether `fuel-stack-mode' gets enabled by default in factor buffers."
|
2008-12-05 22:34:25 -05:00
|
|
|
|
:group 'fuel-mode
|
2008-12-20 19:43:28 -05:00
|
|
|
|
:group 'fuel-stack
|
2008-12-05 22:34:25 -05:00
|
|
|
|
:type 'boolean)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; User commands
|
|
|
|
|
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(defun fuel-mode--read-file (arg)
|
2008-12-08 20:36:55 -05:00
|
|
|
|
(let* ((file (or (and arg (read-file-name "File: " nil (buffer-file-name) t))
|
|
|
|
|
(buffer-file-name)))
|
|
|
|
|
(file (expand-file-name file))
|
2008-12-12 19:54:18 -05:00
|
|
|
|
(buffer (find-file-noselect file)))
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(when (and buffer
|
|
|
|
|
(buffer-modified-p buffer)
|
|
|
|
|
(y-or-n-p "Save file? "))
|
|
|
|
|
(save-buffer buffer))
|
|
|
|
|
(cons file buffer)))
|
|
|
|
|
|
|
|
|
|
(defun fuel-run-file (&optional arg)
|
|
|
|
|
"Sends the current file to Factor for compilation.
|
|
|
|
|
With prefix argument, ask for the file to run."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let* ((f/b (fuel-mode--read-file arg))
|
|
|
|
|
(file (car f/b))
|
|
|
|
|
(buffer (cdr f/b)))
|
2008-12-08 20:36:55 -05:00
|
|
|
|
(when buffer
|
|
|
|
|
(with-current-buffer buffer
|
2008-12-22 18:34:43 -05:00
|
|
|
|
(let ((msg (format "Compiling %s ..." file)))
|
|
|
|
|
(fuel-debug--prepare-compilation file msg)
|
|
|
|
|
(message msg)
|
|
|
|
|
(fuel-eval--send `(:fuel (,file fuel-run-file))
|
|
|
|
|
`(lambda (r) (fuel--run-file-cont r ,file))))))))
|
2008-12-12 19:54:18 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel--run-file-cont (ret file)
|
2008-12-22 18:34:43 -05:00
|
|
|
|
(if (fuel-debug--display-retort ret (format "%s successfully compiled" file))
|
2008-12-12 19:54:18 -05:00
|
|
|
|
(message "Compiling %s ... OK!" file)
|
|
|
|
|
(message "")))
|
2008-12-08 20:36:55 -05:00
|
|
|
|
|
2008-12-17 17:50:48 -05:00
|
|
|
|
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(defun fuel-eval-region (begin end &optional arg)
|
|
|
|
|
"Sends region to Fuel's listener for evaluation.
|
2008-12-20 10:51:05 -05:00
|
|
|
|
Unless called with a prefix, switches to the compilation results
|
2008-12-08 20:36:55 -05:00
|
|
|
|
buffer in case of errors."
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(interactive "r\nP")
|
2008-12-22 18:34:43 -05:00
|
|
|
|
(let* ((rstr (buffer-substring begin end))
|
|
|
|
|
(lines (split-string (substring-no-properties rstr)
|
|
|
|
|
"[\f\n\r\v]+"
|
|
|
|
|
t))
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(cmd `(:fuel (,(mapcar (lambda (l) `(:factor ,l)) lines))))
|
|
|
|
|
(cv (fuel-syntax--current-vocab)))
|
2008-12-22 18:34:43 -05:00
|
|
|
|
(fuel-debug--prepare-compilation (buffer-file-name)
|
|
|
|
|
(format "Evaluating:\n\n%s" rstr))
|
2008-12-14 10:50:34 -05:00
|
|
|
|
(fuel-debug--display-retort
|
|
|
|
|
(fuel-eval--send/wait cmd 10000)
|
|
|
|
|
(format "%s%s"
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(if cv (format "IN: %s " cv) "")
|
2008-12-14 10:50:34 -05:00
|
|
|
|
(fuel--shorten-region begin end 70))
|
2008-12-22 18:34:43 -05:00
|
|
|
|
arg)))
|
2008-12-06 01:01:12 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-eval-extended-region (begin end &optional arg)
|
2008-12-20 10:51:05 -05:00
|
|
|
|
"Sends region, extended outwards to nearest definition,
|
2008-12-08 20:36:55 -05:00
|
|
|
|
to Fuel's listener for evaluation.
|
2008-12-20 10:51:05 -05:00
|
|
|
|
Unless called with a prefix, switches to the compilation results
|
2008-12-08 20:36:55 -05:00
|
|
|
|
buffer in case of errors."
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(interactive "r\nP")
|
|
|
|
|
(fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
|
2008-12-08 20:36:55 -05:00
|
|
|
|
(save-excursion (goto-char end) (mark-defun) (mark))
|
|
|
|
|
arg))
|
2008-12-06 01:01:12 -05:00
|
|
|
|
|
2008-12-05 22:34:25 -05:00
|
|
|
|
(defun fuel-eval-definition (&optional arg)
|
|
|
|
|
"Sends definition around point to Fuel's listener for evaluation.
|
2008-12-20 10:51:05 -05:00
|
|
|
|
Unless called with a prefix, switches to the compilation results
|
2008-12-08 20:36:55 -05:00
|
|
|
|
buffer in case of errors."
|
2008-12-05 22:34:25 -05:00
|
|
|
|
(interactive "P")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(mark-defun)
|
|
|
|
|
(let* ((begin (point))
|
|
|
|
|
(end (mark)))
|
|
|
|
|
(unless (< begin end) (error "No evaluable definition around point"))
|
2008-12-08 20:36:55 -05:00
|
|
|
|
(fuel-eval-region begin end arg))))
|
2008-12-06 01:01:12 -05:00
|
|
|
|
|
2008-12-13 18:41:35 -05:00
|
|
|
|
(defun fuel--try-edit (ret)
|
|
|
|
|
(let* ((err (fuel-eval--retort-error ret))
|
|
|
|
|
(loc (fuel-eval--retort-result ret)))
|
|
|
|
|
(when (or err (not loc) (not (listp loc)) (not (stringp (car loc))))
|
|
|
|
|
(error "Couldn't find edit location for '%s'" word))
|
|
|
|
|
(unless (file-readable-p (car loc))
|
|
|
|
|
(error "Couldn't open '%s' for read" (car loc)))
|
|
|
|
|
(find-file-other-window (car loc))
|
|
|
|
|
(goto-line (if (numberp (cadr loc)) (cadr loc) 1))))
|
|
|
|
|
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(defun fuel-edit-word-at-point (&optional arg)
|
|
|
|
|
"Opens a new window visiting the definition of the word at point.
|
|
|
|
|
With prefix, asks for the word to edit."
|
|
|
|
|
(interactive "P")
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(let* ((word (or (and (not arg) (fuel-syntax-symbol-at-point))
|
2008-12-21 21:07:45 -05:00
|
|
|
|
(fuel-completion--read-word "Edit word: ")))
|
|
|
|
|
(cmd `(:fuel* ((:quote ,word) fuel-get-edit-location))))
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(condition-case nil
|
|
|
|
|
(fuel--try-edit (fuel-eval--send/wait cmd))
|
|
|
|
|
(error (fuel-edit-vocabulary nil word)))))
|
|
|
|
|
|
2008-12-21 21:07:45 -05:00
|
|
|
|
(defun fuel-edit-word-doc-at-point (&optional arg)
|
|
|
|
|
"Opens a new window visiting the documentation file for the word at point.
|
|
|
|
|
With prefix, asks for the word to edit."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let* ((word (or (and (not arg) (fuel-syntax-symbol-at-point))
|
|
|
|
|
(fuel-completion--read-word "Edit word: ")))
|
|
|
|
|
(cmd `(:fuel* ((:quote ,word) fuel-get-doc-location))))
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(fuel--try-edit (fuel-eval--send/wait cmd))
|
|
|
|
|
(error (when (y-or-n-p (concat "No documentation found. "
|
|
|
|
|
"Do you want to open the vocab's "
|
|
|
|
|
"doc file? "))
|
|
|
|
|
(find-file-other-window
|
|
|
|
|
(format "%s-docs.factor"
|
|
|
|
|
(file-name-sans-extension (buffer-file-name)))))))))
|
|
|
|
|
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(defvar fuel-mode--word-history nil)
|
|
|
|
|
|
|
|
|
|
(defun fuel-edit-word (&optional arg)
|
|
|
|
|
"Asks for a word to edit, with completion.
|
|
|
|
|
With prefix, only words visible in the current vocabulary are
|
|
|
|
|
offered."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let* ((word (fuel-completion--read-word "Edit word: "
|
|
|
|
|
nil
|
|
|
|
|
fuel-mode--word-history
|
|
|
|
|
arg))
|
2008-12-21 21:07:45 -05:00
|
|
|
|
(cmd `(:fuel* ((:quote ,word) fuel-get-edit-location))))
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(fuel--try-edit (fuel-eval--send/wait cmd))))
|
2008-12-13 18:41:35 -05:00
|
|
|
|
|
|
|
|
|
(defvar fuel--vocabs-prompt-history nil)
|
|
|
|
|
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(defun fuel--read-vocabulary-name (refresh)
|
|
|
|
|
(let* ((vocabs (fuel-completion--vocabs refresh))
|
2008-12-13 18:41:35 -05:00
|
|
|
|
(prompt "Vocabulary name: "))
|
|
|
|
|
(if vocabs
|
|
|
|
|
(completing-read prompt vocabs nil t nil fuel--vocabs-prompt-history)
|
|
|
|
|
(read-string prompt nil fuel--vocabs-prompt-history))))
|
|
|
|
|
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(defun fuel-edit-vocabulary (&optional refresh vocab)
|
2008-12-13 18:41:35 -05:00
|
|
|
|
"Visits vocabulary file in Emacs.
|
2008-12-15 17:44:13 -05:00
|
|
|
|
When called interactively, asks for vocabulary with completion.
|
|
|
|
|
With prefix argument, refreshes cached vocabulary list."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let* ((vocab (or vocab (fuel--read-vocabulary-name refresh)))
|
|
|
|
|
(cmd `(:fuel* (,vocab fuel-get-vocab-location) "fuel" t)))
|
2008-12-14 10:50:34 -05:00
|
|
|
|
(fuel--try-edit (fuel-eval--send/wait cmd))))
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(defun fuel-show-callers (&optional arg)
|
|
|
|
|
"Show a list of callers of word at point.
|
|
|
|
|
With prefix argument, ask for word."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((word (if arg (fuel-completion--read-word "Find callers for: "
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-mode--word-history)
|
|
|
|
|
(fuel-syntax-symbol-at-point))))
|
|
|
|
|
(when word
|
|
|
|
|
(message "Looking up %s's callers ..." word)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(fuel-xref--show-callers word))))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
|
|
|
|
(defun fuel-show-callees (&optional arg)
|
|
|
|
|
"Show a list of callers of word at point.
|
|
|
|
|
With prefix argument, ask for word."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(let ((word (if arg (fuel-completion--read-word "Find callees for: "
|
|
|
|
|
(fuel-syntax-symbol-at-point)
|
|
|
|
|
fuel-mode--word-history)
|
|
|
|
|
(fuel-syntax-symbol-at-point))))
|
|
|
|
|
(when word
|
|
|
|
|
(message "Looking up %s's callees ..." word)
|
2008-12-21 12:39:59 -05:00
|
|
|
|
(fuel-xref--show-callees word))))
|
2008-12-20 19:43:28 -05:00
|
|
|
|
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
|
|
|
|
;;; Minor mode definition:
|
|
|
|
|
|
|
|
|
|
(make-variable-buffer-local
|
|
|
|
|
(defvar fuel-mode-string " F"
|
|
|
|
|
"Modeline indicator for fuel-mode"))
|
|
|
|
|
|
|
|
|
|
(defvar fuel-mode-map (make-sparse-keymap)
|
|
|
|
|
"Key map for fuel-mode")
|
|
|
|
|
|
|
|
|
|
(define-minor-mode fuel-mode
|
|
|
|
|
"Toggle Fuel's mode.
|
|
|
|
|
With no argument, this command toggles the mode.
|
|
|
|
|
Non-null prefix argument turns on the mode.
|
|
|
|
|
Null prefix argument turns off the mode.
|
|
|
|
|
|
|
|
|
|
When Fuel mode is enabled, a host of nice utilities for
|
|
|
|
|
interacting with a factor listener is at your disposal.
|
|
|
|
|
\\{fuel-mode-map}"
|
|
|
|
|
:init-value nil
|
|
|
|
|
:lighter fuel-mode-string
|
|
|
|
|
:group 'fuel
|
|
|
|
|
:keymap fuel-mode-map
|
|
|
|
|
|
|
|
|
|
(setq fuel-autodoc-mode-string "/A")
|
2008-12-20 10:51:05 -05:00
|
|
|
|
(when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode))
|
|
|
|
|
|
|
|
|
|
(setq fuel-stack-mode-string "/S")
|
|
|
|
|
(when fuel-mode-stack-p (fuel-stack-mode fuel-mode)))
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;; Keys:
|
|
|
|
|
|
|
|
|
|
(defun fuel-mode--key-1 (k c)
|
|
|
|
|
(define-key fuel-mode-map (vector '(control ?c) k) c)
|
|
|
|
|
(define-key fuel-mode-map (vector '(control ?c) `(control ,k)) c))
|
|
|
|
|
|
|
|
|
|
(defun fuel-mode--key (p k c)
|
|
|
|
|
(define-key fuel-mode-map (vector '(control ?c) `(control ,p) k) c)
|
|
|
|
|
(define-key fuel-mode-map (vector '(control ?c) `(control ,p) `(control ,k)) c))
|
|
|
|
|
|
2008-12-08 20:36:55 -05:00
|
|
|
|
(fuel-mode--key-1 ?k 'fuel-run-file)
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(fuel-mode--key-1 ?l 'fuel-run-file)
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(fuel-mode--key-1 ?r 'fuel-eval-region)
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(fuel-mode--key-1 ?z 'run-factor)
|
2008-12-06 01:01:12 -05:00
|
|
|
|
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
|
2008-12-06 01:01:12 -05:00
|
|
|
|
(define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(define-key fuel-mode-map "\C-c\M-<" 'fuel-show-callers)
|
|
|
|
|
(define-key fuel-mode-map "\C-c\M->" 'fuel-show-callees)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(define-key fuel-mode-map (kbd "M-TAB") 'fuel-completion--complete-symbol)
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
2008-12-21 21:07:45 -05:00
|
|
|
|
(fuel-mode--key ?e ?d 'fuel-edit-word-doc-at-point)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(fuel-mode--key ?e ?e 'fuel-eval-extended-region)
|
2008-12-17 17:50:48 -05:00
|
|
|
|
(fuel-mode--key ?e ?l 'fuel-run-file)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(fuel-mode--key ?e ?r 'fuel-eval-region)
|
2008-12-13 18:41:35 -05:00
|
|
|
|
(fuel-mode--key ?e ?v 'fuel-edit-vocabulary)
|
2008-12-16 19:12:15 -05:00
|
|
|
|
(fuel-mode--key ?e ?w 'fuel-edit-word)
|
2008-12-15 17:44:13 -05:00
|
|
|
|
(fuel-mode--key ?e ?x 'fuel-eval-definition)
|
2008-12-05 22:34:25 -05:00
|
|
|
|
|
2008-12-20 19:43:28 -05:00
|
|
|
|
(fuel-mode--key ?d ?> 'fuel-show-callees)
|
|
|
|
|
(fuel-mode--key ?d ?< 'fuel-show-callers)
|
2008-12-05 22:34:25 -05:00
|
|
|
|
(fuel-mode--key ?d ?a 'fuel-autodoc-mode)
|
|
|
|
|
(fuel-mode--key ?d ?d 'fuel-help)
|
2008-12-20 10:51:05 -05:00
|
|
|
|
(fuel-mode--key ?d ?e 'fuel-stack-effect-sexp)
|
2008-12-05 22:34:25 -05:00
|
|
|
|
(fuel-mode--key ?d ?s 'fuel-help-short)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(provide 'fuel-mode)
|
|
|
|
|
;;; fuel-mode.el ends here
|