factor/misc/fuel/fuel-mode.el

243 lines
8.4 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

;;; fuel-mode.el --- Major mode for editing Factor programs.
;; 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
;;; Commentary:
;; A major mode (factor-mode) for editing Factor programs and a minor mode
;; (fuel-mode) for interacting with a running Factor image.
;;; Code:
(require 'fuel-base)
(require 'fuel-listener)
(require 'fuel-completion)
(require 'fuel-debug)
(require 'fuel-debug-uses)
(require 'fuel-eval)
(require 'fuel-help)
(require 'fuel-xref)
(require 'fuel-refactor)
(require 'fuel-stack)
(require 'fuel-autodoc)
(require 'fuel-autohelp)
(require 'fuel-edit)
(require 'fuel-menu)
;;; 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 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)
;;; User commands
(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)))
(when buffer
(with-current-buffer buffer
(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))
(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, switches to the compilation results
buffer in case of errors."
(interactive "r\nP")
(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 definition,
to Fuel's listener for evaluation.
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))
(save-excursion (goto-char end) (mark-defun) (mark))
arg))
(defun fuel-eval-definition (&optional arg)
"Sends definition around point to Fuel's listener for evaluation.
Unless called with a prefix, switches to the compilation results
buffer in case of errors."
(interactive "P")
(save-excursion
(mark-defun)
(let* ((begin (point))
(end (mark)))
(unless (< begin end) (error "No evaluable definition around point"))
(fuel-eval-region begin end arg))))
(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"))))
;;; Minor mode definition:
(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.
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")
(when fuel-mode-autodoc-p (fuel-autodoc-mode fuel-mode))
(setq fuel-autohelp-mode-string "/H")
(when fuel-mode-autohelp-p (fuel-autohelp-mode fuel-mode))
(setq fuel-stack-mode-string "/S")
(when fuel-mode-stack-p (fuel-stack-mode fuel-mode))
(let ((file-name (buffer-file-name)))
(when (and fuel-mode
file-name
(not (file-exists-p file-name)))
(fuel-scaffold--maybe-insert))))
;;; 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)
--
(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)))
(provide 'fuel-mode)
;;; fuel-mode.el ends here