]> gitweb.factorcode.org Git - factor.git/blobdiff - misc/fuel/fuel-listener.el
fuel: Incorporate refresh-and-test-all
[factor.git] / misc / fuel / fuel-listener.el
index 1d23571a0abda5173627a68cc977fefdba024e58..3058a0d6961de81e86df856594798c11ed3871e0 100644 (file)
@@ -1,6 +1,6 @@
-;;; fuel-listener.el --- starting the fuel listener
+;;; fuel-listener.el --- starting the fuel listener -*- lexical-binding: t -*-
 
-;; Copyright (C) 2008, 2009  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>
 
 (require 'fuel-stack)
 (require 'fuel-completion)
-(require 'fuel-xref)
 (require 'fuel-eval)
 (require 'fuel-connection)
-(require 'fuel-syntax)
+(require 'fuel-menu)
 (require 'fuel-base)
 
 (require 'comint)
 
-\f
 ;;; Customization:
 
+;;;###autoload
 (defgroup fuel-listener nil
   "Interacting with a Factor listener inside Emacs."
   :group 'fuel)
 
-(defcustom fuel-listener-factor-binary
-  (expand-file-name (cond ((eq system-type 'windows-nt)
-                           "factor.com")
-                          ((eq system-type 'darwin)
-                           "Factor.app/Contents/MacOS/factor")
-                          (t "factor"))
-                    fuel-factor-root-dir)
+(defcustom fuel-factor-root-dir nil
+  "Full path to the factor root directory when starting a listener."
+  :type 'directory
+  :group 'fuel-listener)
+
+;;; Is factor.com still valid on Windows...?
+(defcustom fuel-listener-factor-binary nil
   "Full path to the factor executable to use when starting a listener."
   :type '(file :must-match t)
   :group 'fuel-listener)
 
-(defcustom fuel-listener-factor-image
-  (expand-file-name "factor.image" fuel-factor-root-dir)
+(defcustom fuel-listener-factor-image nil
   "Full path to the factor image to use when starting a listener."
   :type '(file :must-match t)
   :group 'fuel-listener)
@@ -53,14 +51,10 @@ the factor-listener buffer."
   :type 'boolean
   :group 'fuel-listener)
 
-(defcustom fuel-listener-window-allow-split t
-  "Allow window splitting when switching to the fuel listener
-buffer."
-  :type 'boolean
-  :group 'fuel-listener)
-
-(defcustom fuel-listener-history-filename (expand-file-name "~/.fuel_history")
-  "File where listener input history is saved, so that it persists between sessions."
+(defcustom fuel-listener-history-filename
+  (expand-file-name "~/.fuel_history.eld")
+  "File where listener input history is saved, so that it persists between
+sessions."
   :type 'filename
   :group 'fuel-listener)
 
@@ -69,6 +63,29 @@ buffer."
   :type 'integer
   :group 'fuel-listener)
 
+(defcustom fuel-listener-prompt-read-only-p t
+  "Whether listener's prompt should be read-only."
+  :type 'boolean
+  :group 'fuel-listener)
+
+\f
+;;; Factor paths:
+
+(defun fuel-listener-factor-binary ()
+  "Full path to the factor executable to use when starting a listener."
+  (or fuel-listener-factor-binary
+      (expand-file-name (cond ((eq system-type 'windows-nt)
+                               "factor.com")
+                              ((eq system-type 'darwin)
+                               "Factor.app/Contents/MacOS/factor")
+                              (t "factor"))
+                        fuel-factor-root-dir)))
+
+(defun fuel-listener-factor-image ()
+  "Full path to the factor image to use when starting a listener."
+  (or fuel-listener-factor-image
+      (expand-file-name "factor.image" fuel-factor-root-dir)))
+
 \f
 ;;; Listener history:
 
@@ -79,14 +96,15 @@ buffer."
         (comint-write-input-ring)
         (when (buffer-name (current-buffer))
           (insert "\nBye bye. It's been nice listening to you!\n")
-          (insert "Press C-cz to bring me back.\n" ))))))
+          (insert "Press C-c C-z to bring me back.\n" ))))))
 
 (defun fuel-listener--history-setup ()
-  (set (make-local-variable 'comint-input-ring-file-name) fuel-listener-history-filename)
-  (set (make-local-variable 'comint-input-ring-size) fuel-listener-history-size)
+  (setq-local comint-input-ring-file-name fuel-listener-history-filename)
+  (setq-local comint-input-ring-size fuel-listener-history-size)
   (add-hook 'kill-buffer-hook 'comint-write-input-ring nil t)
   (comint-read-input-ring t)
-  (set-process-sentinel (get-buffer-process (current-buffer)) 'fuel-listener--sentinel))
+  (set-process-sentinel (get-buffer-process (current-buffer))
+                        'fuel-listener--sentinel))
 
 \f
 ;;; Fuel listener buffer/process:
@@ -102,8 +120,8 @@ buffer."
       (setq fuel-listener--buffer (current-buffer)))))
 
 (defun fuel-listener--start-process ()
-  (let ((factor (expand-file-name fuel-listener-factor-binary))
-        (image (expand-file-name fuel-listener-factor-image))
+  (let ((factor (expand-file-name (fuel-listener-factor-binary)))
+        (image (expand-file-name (fuel-listener-factor-image)))
         (comint-redirect-perform-sanity-check nil))
     (unless (file-executable-p factor)
       (error "Could not run factor: %s is not executable" factor))
@@ -112,11 +130,12 @@ buffer."
     (message "Starting FUEL listener (this may take a while) ...")
     (pop-to-buffer (fuel-listener--buffer))
     (make-comint-in-buffer "fuel listener" (current-buffer) factor nil
-                           "-run=listener" (format "-i=%s" image))
+                           "-run=fuel.listener" (format "-i=%s" image))
     (fuel-listener--wait-for-prompt 60000)
     (fuel-listener--history-setup)
     (fuel-con--setup-connection (current-buffer))))
 
+;;; TODO Add the ability to debug to non-localhost
 (defun fuel-listener--connect-process (port)
   (message "Connecting to remote listener ...")
   (pop-to-buffer (fuel-listener--buffer))
@@ -148,22 +167,20 @@ buffer."
     (goto-char (point-max))
     (unless seen (error "No prompt found!"))))
 
-
 \f
 ;;; Interface: starting and interacting with fuel listener:
 
-(defalias 'switch-to-factor 'run-factor)
-(defalias 'switch-to-fuel-listener 'run-factor)
 ;;;###autoload
 (defun run-factor (&optional arg)
   "Show the fuel-listener buffer, starting the process if needed."
   (interactive)
-  (let ((buf (process-buffer (fuel-listener--process t)))
-        (pop-up-windows fuel-listener-window-allow-split))
+  (let ((buf (process-buffer (fuel-listener--process t))))
     (if fuel-listener-use-other-window
         (pop-to-buffer buf)
-      (switch-to-buffer buf))))
+      (switch-to-buffer buf))
+    (add-hook 'factor-mode-hook 'fuel-mode)))
 
+;;;###autoload
 (defun connect-to-factor (&optional arg)
   "Connects to a remote listener running in the same host.
 Without prefix argument, the default port, 9000, is used.
@@ -173,7 +190,8 @@ remote listener you need to issue the words
 fuel-start-remote-listener', from the fuel vocabulary."
   (interactive "P")
   (let ((port (if (not arg) 9000 (read-number "Port: "))))
-    (fuel-listener--connect-process port)))
+    (fuel-listener--connect-process port)
+    (add-hook 'factor-mode-hook 'fuel-mode)))
 
 (defun fuel-listener-nuke ()
   "Try this command if the listener becomes unresponsive."
@@ -183,32 +201,54 @@ fuel-start-remote-listener', from the fuel vocabulary."
   (comint-redirect-cleanup)
   (fuel-con--setup-connection fuel-listener--buffer))
 
-(defun fuel-refresh-all ()
+(defun fuel-refresh-all (&optional arg)
   "Switch to the listener buffer and invokes Factor's refresh-all.
 With prefix, you're teletransported to the listener's buffer."
-  (interactive)
+  (interactive "P")
+  (let ((buf (process-buffer (fuel-listener--process))))
+    (with-current-buffer buf
+      (comint-send-string nil "\"Refreshing loaded vocabs...\" write nl flush")
+      (comint-send-string nil " refresh-all \"Done!\" write nl flush\n"))
+    (when arg (pop-to-buffer buf))))
+
+(defun fuel-refresh-and-test-all (&optional arg)
+  "Switch to the listener buffer and invokes Factor's refresh-and-test-all.
+With prefix, you're teletransporteded to the listener's buffer."
+  (interactive "P")
   (let ((buf (process-buffer (fuel-listener--process))))
-    (pop-to-buffer buf)
-    (comint-send-string nil "\"Refreshing loaded vocabs...\" write nl flush")
-    (comint-send-string nil " refresh-all \"Done!\" write nl flush\n")))
+    (with-current-buffer buf
+      (comint-send-string nil "\"Refreshing loaded vocabs and running tests...\" write nl flush")
+      (comint-send-string nil " refresh-and-test-all \"Done!\" write nl flush\n"))
+    (when arg (pop-to-buffer buf))))
+
+(defun fuel-test-vocab (&optional arg)
+  "Run the unit tests for the current vocabulary. With prefix argument, ask for
+the vocabulary name."
+  (interactive "P")
+  (let* ((vocab (or (and (not arg) (factor-current-vocab))
+                    (fuel-completion--read-vocab nil))))
+    (comint-send-string (fuel-listener--process)
+                        (concat "\"" vocab "\" reload nl flush\n"
+                                "\"" vocab "\" test nl flush\n"))))
 
 \f
-;;; Completion support
+;;; Completion support:
 
 (defsubst fuel-listener--current-vocab () nil)
 (defsubst fuel-listener--usings () nil)
 
 (defun fuel-listener--setup-completion ()
-  (setq fuel-syntax--current-vocab-function 'fuel-listener--current-vocab)
-  (setq fuel-syntax--usings-function 'fuel-listener--usings))
+  (setq factor-current-vocab-function 'fuel-listener--current-vocab)
+  (setq factor-usings-function 'fuel-listener--usings))
 
 \f
-;;; Stack mode support
+;;; Stack mode support:
 
 (defun fuel-listener--stack-region ()
-  (fuel--region-to-string (if (zerop (fuel-syntax--brackets-depth))
-                              (comint-line-beginning-position)
-                            (1+ (fuel-syntax--brackets-start)))))
+  (fuel-region-to-string
+   (if (zerop (factor-brackets-depth))
+       (comint-line-beginning-position)
+     (1+ (factor-brackets-start)))))
 
 (defun fuel-listener--setup-stack-mode ()
   (setq fuel-stack--region-function 'fuel-listener--stack-region))
@@ -221,29 +261,42 @@ With prefix, you're teletransported to the listener's buffer."
   (when (= (point) (comint-bol)) (beginning-of-line)))
 
 ;;;###autoload
-(define-derived-mode fuel-listener-mode comint-mode "Fuel Listener"
+(define-derived-mode fuel-listener-mode comint-mode "FUEL Listener"
   "Major mode for interacting with an inferior Factor listener process.
 \\{fuel-listener-mode-map}"
-  (set (make-local-variable 'comint-prompt-regexp) fuel-con--prompt-regex)
-  (set (make-local-variable 'comint-use-prompt-regexp) t)
-  (set (make-local-variable 'comint-prompt-read-only) t)
+  (setq-local comint-prompt-regexp fuel-con--prompt-regex)
+  (setq-local comint-use-prompt-regexp nil)
+  (setq-local comint-prompt-read-only fuel-listener-prompt-read-only-p)
   (fuel-listener--setup-completion)
-  (fuel-listener--setup-stack-mode))
+  (fuel-listener--setup-stack-mode)
+  (set-syntax-table (fuel-syntax-table)))
 
-(define-key fuel-listener-mode-map "\C-cz" 'run-factor)
-(define-key fuel-listener-mode-map "\C-c\C-z" 'run-factor)
 (define-key fuel-listener-mode-map "\C-a" 'fuel-listener--bol)
-(define-key fuel-listener-mode-map "\C-ca" 'fuel-autodoc-mode)
-(define-key fuel-listener-mode-map "\C-ch" 'fuel-help)
-(define-key fuel-listener-mode-map "\C-cr" 'fuel-refresh-all)
-(define-key fuel-listener-mode-map "\C-cs" 'fuel-stack-mode)
-(define-key fuel-listener-mode-map "\C-cp" 'fuel-apropos)
-(define-key fuel-listener-mode-map "\M-." 'fuel-edit-word-at-point)
-(define-key fuel-listener-mode-map "\C-cv" 'fuel-edit-vocabulary)
-(define-key fuel-listener-mode-map "\C-c\C-v" 'fuel-edit-vocabulary)
-(define-key fuel-listener-mode-map "\C-ck" 'fuel-run-file)
-(define-key fuel-listener-mode-map (kbd "TAB") 'fuel-completion--complete-symbol)
+
+(fuel-menu--defmenu listener fuel-listener-mode-map
+  ("Complete symbol" ((kbd "TAB") (kbd "M-TAB"))
+   fuel-completion--complete-symbol :enable (symbol-at-point))
+  --
+  ("Edit word or vocab at point" "\M-." fuel-edit-word-at-point)
+  ("Edit vocabulary" "\C-c\C-v" fuel-edit-vocabulary)
+  --
+  ("Help on word" "\C-c\C-w" fuel-help)
+  ("Apropos..." "\C-c\C-p" fuel-apropos)
+  (mode "Show stack mode" "\C-c\C-s" fuel-stack-mode)
+  --
+  (menu "Crossref"
+        ("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-a" fuel-autodoc-mode))
+  ("Run file" "\C-c\C-k" fuel-run-file)
+  ("Refresh vocabs" "\C-c\C-r" fuel-refresh-all)
+  ("Refresh vocabs and test" "\C-c\M-r" fuel-refresh-and-test-all))
+
+(define-key fuel-listener-mode-map [menu-bar completion] 'undefined)
 
 \f
 (provide 'fuel-listener)
+
 ;;; fuel-listener.el ends here