]> gitweb.factorcode.org Git - factor.git/blobdiff - misc/fuel/fuel-mode.el
fuel: Incorporate refresh-and-test-all
[factor.git] / misc / fuel / fuel-mode.el
index feaea1548e2f44463694c6d3fb321c52bde13944..86c454bbe0699cc2c407bb5db1240636af8a6c91 100644 (file)
@@ -1,38 +1,58 @@
-;;; fuel-mode.el -- Minor mode enabling FUEL niceties
+;;; fuel-mode.el --- Major mode for editing Factor programs. -*- lexical-binding: t -*-
 
-;; Copyright (C) 2008 Jose Antonio Ortega Ruiz
+;; Copyright (C) 2008, 2009, 2010 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:
+;;; Commentary:
 
-;; Enhancements to vanilla factor-mode (notably, listener interaction)
-;; enabled by means of a minor mode.
+;; A major mode (factor-mode) for editing Factor programs and a minor mode
+;; (fuel-mode) for interacting with a running Factor image.
 
 ;;; Code:
 
-(require 'factor-mode)
 (require 'fuel-base)
-(require 'fuel-syntax)
-(require 'fuel-font-lock)
+(require 'fuel-listener)
+(require 'fuel-completion)
 (require 'fuel-debug)
-(require 'fuel-help)
+(require 'fuel-debug-uses)
 (require 'fuel-eval)
-(require 'fuel-listener)
+(require 'fuel-help)
+(require 'fuel-xref)
+(require 'fuel-refactor)
+(require 'fuel-stack)
+(require 'fuel-autodoc)
+(require 'fuel-autohelp)
+(require 'fuel-edit)
+(require 'fuel-menu)
 
 \f
 ;;; Customization:
 
+;;;###autoload
 (defgroup fuel-mode nil
   "Mode enabling FUEL's ultimate abilities."
   :group 'fuel)
 
 (defcustom fuel-mode-autodoc-p t
-  "Whether `fuel-autodoc-mode' gets enable by default in fuel buffers."
+  "Whether `fuel-autodoc-mode' gets enabled by default in factor buffers."
+  :group 'fuel-mode
+  :group 'fuel-autodoc
+  :type 'boolean)
+
+(defcustom fuel-mode-autohelp-p nil
+  "Whether `fuel-autohelp-mode' gets enabled by default in factor buffers."
+  :group 'fuel-mode
+  :group 'fuel-autohelp
+  :type 'boolean)
+
+(defcustom fuel-mode-stack-p nil
+  "Whether `fuel-stack-mode' gets enabled by default in factor buffers."
   :group 'fuel-mode
+  :group 'fuel-stack
   :type 'boolean)
 
 \f
   "Sends the current file to Factor for compilation.
 With prefix argument, ask for the file to run."
   (interactive "P")
-  (let* ((file (or (and arg (read-file-name "File: " nil (buffer-file-name) t))
-                   (buffer-file-name)))
-         (file (expand-file-name file))
-         (buffer (find-file-noselect file)))
+  (let* ((f/b (fuel-mode--read-file arg))
+         (file (car f/b))
+         (buffer (cdr f/b)))
     (when buffer
       (with-current-buffer buffer
-        (message "Compiling %s ..." file)
-        (fuel-eval--send (fuel-eval--cmd/string (format "%S fuel-run-file" file))
-                         `(lambda (r) (fuel--run-file-cont r ,file)))))))
+        (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))))))))
 
 (defun fuel--run-file-cont (ret file)
-  (if (fuel-debug--display-retort ret
-                                  (format "%s successfully compiled" file)
-                                  nil
-                                  file)
+  (if (fuel-debug--display-retort ret (format "%s successfully compiled" file))
       (message "Compiling %s ... OK!" file)
     (message "")))
 
 (defun fuel-eval-region (begin end &optional arg)
   "Sends region to Fuel's listener for evaluation.
-Unless called with a prefix, switchs to the compilation results
+Unless called with a prefix, switches to the compilation results
 buffer in case of errors."
   (interactive "r\nP")
-  (fuel-debug--display-retort
-   (fuel-eval--send/wait (fuel-eval--cmd/region begin end) 10000)
-   (format "%s%s"
-           (if fuel-syntax--current-vocab
-               (format "IN: %s " fuel-syntax--current-vocab)
-             "")
-           (fuel--shorten-region begin end 70))
-   arg
-   (buffer-file-name)))
+  (let* ((rstr (buffer-substring begin end))
+         (lines (split-string (substring-no-properties rstr)
+                              "[\f\n\r\v]+"
+                              t))
+         (cmd `(:fuel (,(mapcar (lambda (l) `(:factor ,l)) lines))))
+         (cv (factor-current-vocab)))
+    (fuel-debug--prepare-compilation (buffer-file-name)
+                                     (format "Evaluating:\n\n%s" rstr))
+    (fuel-debug--display-retort
+     (fuel-eval--send/wait cmd 10000)
+     (format "%s%s"
+             (if cv (format "IN: %s " cv) "")
+             (fuel-shorten-region begin end 70))
+     arg)))
 
 (defun fuel-eval-extended-region (begin end &optional arg)
-  "Sends region extended outwards to nearest definitions,
+  "Sends region, extended outwards to nearest definition,
 to Fuel's listener for evaluation.
-Unless called with a prefix, switchs to the compilation results
+Unless called with a prefix, switches to the compilation results
 buffer in case of errors."
   (interactive "r\nP")
   (fuel-eval-region (save-excursion (goto-char begin) (mark-defun) (point))
@@ -87,7 +110,7 @@ buffer in case of errors."
 
 (defun fuel-eval-definition (&optional arg)
   "Sends definition around point to Fuel's listener for evaluation.
-Unless called with a prefix, switchs to the compilation results
+Unless called with a prefix, switches to the compilation results
 buffer in case of errors."
   (interactive "P")
   (save-excursion
@@ -97,40 +120,27 @@ buffer in case of errors."
       (unless (< begin end) (error "No evaluable definition around point"))
       (fuel-eval-region begin end arg))))
 
-(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")
-  (let* ((word (fuel-syntax-symbol-at-point))
-         (ask (or arg (not word)))
-         (word (if ask
-                   (read-string nil
-                                (format "Edit word%s: "
-                                        (if word (format " (%s)" word) ""))
-                                word)
-                 word)))
-    (let* ((str (fuel-eval--cmd/string
-                 (format "\\ %s fuel-get-edit-location" word)))
-           (ret (fuel-eval--send/wait str))
-           (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)))))
+(defun fuel-load-usings ()
+  "Loads all vocabularies in the current buffer's USING: from.
+Useful to activate autodoc help messages in a vocabulary not yet
+loaded."
+  (interactive)
+  (message "Loading all vocabularies in USING: form ...")
+  (let ((err (fuel-eval--retort-error
+              (fuel-eval--send/wait '(:fuel* (t .) t :usings) 120000))))
+    (message (if err "Warning: some vocabularies failed to load"
+               "All vocabularies loaded"))))
 
 \f
 ;;; Minor mode definition:
 
-(make-variable-buffer-local
- (defvar fuel-mode-string " F"
-   "Modeline indicator for fuel-mode"))
+(defvar-local fuel-mode-string " F"
+  "Modeline indicator for fuel-mode")
 
 (defvar fuel-mode-map (make-sparse-keymap)
   "Key map for fuel-mode")
 
+;;;###autoload
 (define-minor-mode fuel-mode
   "Toggle Fuel's mode.
 With no argument, this command toggles the mode.
@@ -146,39 +156,88 @@ interacting with a factor listener is at your disposal.
   :keymap fuel-mode-map
 
   (setq fuel-autodoc-mode-string "/A")
-  (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode)))
-
-\f
-;;; 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))
+  (when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode))
 
-(fuel-mode--key-1 ?z 'run-factor)
+  (setq fuel-autohelp-mode-string "/H")
+  (when fuel-mode-autohelp-p (fuel-autohelp-mode fuel-mode))
 
-(fuel-mode--key-1 ?k 'fuel-run-file)
-(fuel-mode--key ?e ?k 'fuel-run-file)
+  (setq fuel-stack-mode-string "/S")
+  (when fuel-mode-stack-p (fuel-stack-mode fuel-mode))
 
-(define-key fuel-mode-map "\C-\M-x" 'fuel-eval-definition)
-(fuel-mode--key ?e ?x 'fuel-eval-definition)
+  (let ((file-name (buffer-file-name)))
+    (when (and fuel-mode
+               file-name
+               (not (file-exists-p file-name)))
+      (fuel-scaffold--maybe-insert))))
 
-(fuel-mode--key-1 ?r 'fuel-eval-region)
-(fuel-mode--key ?e ?r 'fuel-eval-region)
-
-(define-key fuel-mode-map "\C-\M-r" 'fuel-eval-extended-region)
-(fuel-mode--key ?e ?e 'fuel-eval-extended-region)
-
-(define-key fuel-mode-map "\M-." 'fuel-edit-word-at-point)
-
-(fuel-mode--key ?d ?a 'fuel-autodoc-mode)
-(fuel-mode--key ?d ?d 'fuel-help)
-(fuel-mode--key ?d ?s 'fuel-help-short)
+\f
+;;; Keys and menu:
+
+(fuel-menu--defmenu fuel fuel-mode-map
+  ("Complete symbol" ((kbd "M-TAB"))
+   fuel-completion--complete-symbol :enable (symbol-at-point))
+  ("Update USING:" ("\C-c\C-e\C-u" "\C-c\C-eu") fuel-update-usings)
+  --
+  ("Eval definition" ("\C-\M-x" "\C-c\C-e\C-x" "\C-c\C-ex")
+   fuel-eval-definition)
+  ("Eval extended region" ("\C-\M-r" "\C-c\C-e\C-e" "\C-c\C-ee")
+   fuel-eval-extended-region :enable mark-active)
+  ("Eval region" ("\C-c\C-e\C-r" "\C-c\C-er")
+   fuel-eval-region :enable mark-active)
+  --
+  ("Edit word or vocab at point..." ("\M-." "\C-c\C-e\C-d" "\C-c\C-ed")
+   fuel-edit-word-at-point)
+  ("Edit vocab..." ("\C-c\C-e\C-v" "\C-c\C-ev") fuel-edit-vocabulary)
+  ("Jump back" "\M-," fuel-edit-pop-edit-word-stack)
+  --
+  ("Help on word" ("\C-c\C-d\C-d" "\C-c\C-dd") fuel-help)
+  ("Apropos..." ("\C-c\C-d\C-p" "\C-c\C-dp") fuel-apropos)
+  ("Show stack effect" ("\C-c\C-d\C-e" "\C-c\C-de") fuel-stack-effect-sexp)
+  --
+  (menu "Crossref"
+        ("Show all words" ("\C-c\C-d\C-v" "\C-c\C-dv") fuel-show-file-words)
+        ("Word callers" "\C-c\M-<" fuel-show-callers :enable (symbol-at-point))
+        ("Word callees" "\C-c\M->" fuel-show-callees :enable (symbol-at-point))
+        (mode "Autodoc mode" ("\C-c\C-d\C-a" "\C-c\C-da") fuel-autodoc-mode))
+  (menu "Refactor"
+        ("Rename word" ("\C-c\C-x\C-w" "\C-c\C-xw") fuel-refactor-rename-word)
+        ("Inline word" ("\C-c\C-x\C-i" "\C-c\C-xi") fuel-refactor-inline-word)
+        ("Extract region" ("\C-c\C-x\C-r" "\C-c\C-xr")
+         fuel-refactor-extract-region :enable mark-active)
+        ("Extract subregion" ("\C-c\C-x\C-s" "\C-c\C-xs")
+         fuel-refactor-extract-sexp)
+        ("Extract vocab" ("\C-c\C-x\C-v" "\C-c\C-xv")
+         fuel-refactor-extract-vocab)
+        ("Make generic" ("\C-c\C-x\C-g" "\C-c\C-xg")
+         fuel-refactor-make-generic)
+        --
+        ("Extract article" ("\C-c\C-x\C-a" "\C-c\C-xa")
+         fuel-refactor-extract-article))
+  (menu "Scaffold"
+        ("New vocab" ("\C-c\C-c\C-v") fuel-scaffold-vocab)
+        ("Tests for vocab" ("\C-c\C-c\C-t") fuel-scaffold-tests)
+        ("Help for vocab" ("\C-c\C-c\C-h") fuel-scaffold-help)
+        ("Tags for vocab" ("\C-c\C-c\C-g") fuel-scaffold-tags)
+        ("Summary for vocab" ("\C-c\C-c\C-s") fuel-scaffold-summary)
+        ("Authors for vocab" ("\C-c\C-c\C-a") fuel-scaffold-authors)
+        ("Platforms for vocab" ("\C-c\C-c\C-p") fuel-scaffold-platforms))
+  --
+  ("Load used vocabs" ("\C-c\C-e\C-l" "\C-c\C-el") fuel-load-usings)
+  ("Run file" ("\C-c\C-k" "\C-c\C-l" "\C-c\C-e\C-k") fuel-run-file)
+  ("Run unit tests" "\C-c\C-t" fuel-test-vocab)
+  ("Refresh vocabs" "\C-c\C-r" fuel-refresh-all)
+  ("Refresh vocabs and test" "\C-c\M-r" fuel-refresh-and-test-all)
+  --
+  (menu "Switch to"
+        ("Listener" "\C-c\C-z" run-factor)
+        ("Related Factor file" "\C-c\C-o" factor-visit-other-file)
+        ("Other Factor buffer" "\C-c\C-s" fuel-switch-to-buffer)
+        ("Other Factor buffer other window" "\C-x4s"
+         fuel-switch-to-buffer-other-window)
+        ("Other Factor buffer other frame" "\C-x5s"
+         fuel-switch-to-buffer-other-frame)))
 
 \f
 (provide 'fuel-mode)
+
 ;;; fuel-mode.el ends here