factor/libs/factor.el

171 lines
4.9 KiB
EmacsLisp

;; Eduardo Cavazos - wayo.cavazos@gmail.com
;; Add these lines to your .emacs file:
;; (load-file "/scratch/repos/Factor/contrib/factor.el")
;; (setq factor-binary "/scratch/repos/Factor/f")
;; (setq factor-image "/scratch/repos/Factor/factor.image")
;; Of course, you'll have to edit the directory paths for your system
;; accordingly.
;; That's all you have to do to "install" factor.el on your
;; system. Whenever you edit a factor file, Emacs will know to switch
;; to Factor mode.
;; M-x factor-listener === Start a new factor listener inside Emacs
;; M-x factor-listener-restart === Restart a factor listener whose
;; session has ended.
;; BUG: A double quote character on a commented line will break the
;; syntax highlighting for that line.
(defgroup factor nil
"Factor mode"
:group 'languages)
(defvar factor-mode-syntax-table nil
"Syntax table used while in Factor mode.")
(if factor-mode-syntax-table
()
(let ((i 0))
(setq factor-mode-syntax-table (make-syntax-table))
;; Default is atom-constituent
(while (< i 256)
(modify-syntax-entry i "_ ")
(setq i (1+ i)))
;; Word components.
(setq i ?0)
(while (<= i ?9)
(modify-syntax-entry i "w ")
(setq i (1+ i)))
(setq i ?A)
(while (<= i ?Z)
(modify-syntax-entry i "w ")
(setq i (1+ i)))
(setq i ?a)
(while (<= i ?z)
(modify-syntax-entry i "w ")
(setq i (1+ i)))
;; Whitespace
(modify-syntax-entry ?\t " ")
(modify-syntax-entry ?\n ">")
(modify-syntax-entry ?\f " ")
(modify-syntax-entry ?\r " ")
(modify-syntax-entry ? " ")
(modify-syntax-entry ?\[ "(] ")
(modify-syntax-entry ?\] ")[ ")
(modify-syntax-entry ?{ "(} ")
(modify-syntax-entry ?} "){ ")
(modify-syntax-entry ?\( "()")
(modify-syntax-entry ?\) ")(")
(modify-syntax-entry ?\" "\" ")))
(defcustom factor-mode-hook nil
"Hook run when entering Factor mode."
:type 'hook
:group 'factor)
(defconst factor-font-lock-keywords
'(("#!.*$" . font-lock-comment-face)
("!.*$" . font-lock-comment-face)
("( .* )" . font-lock-comment-face)
"IN:" "USING:" "TUPLE:" "^C:" "^M:" "USE:" "REQUIRE:" "PROVIDE:"
"REQUIRES:"
"GENERIC:" "SYMBOL:" "PREDICATE:" "VAR:"))
(defun factor-mode ()
"A mode for editing programs written in the Factor programming language."
(interactive)
(kill-all-local-variables)
(setq major-mode 'factor-mode)
(setq mode-name "Factor")
(make-local-variable 'comment-start)
(setq comment-start "! ")
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults
'(factor-font-lock-keywords nil nil nil nil))
(set-syntax-table factor-mode-syntax-table)
(run-hooks 'factor-mode-hooks))
(add-to-list 'auto-mode-alist '("\\.factor\\'" . factor-mode))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'comint)
(define-derived-mode factor-listener-mode comint-mode "Factor listener"
(setq comint-prompt-regexp "ok "))
(defvar factor-binary "/scratch/factor-darcs/repos/Factor/f")
(defvar factor-image "/scratch/factor-darcs/repos/Factor/factor.image")
(defun factor-server ()
(interactive)
(make-comint "factor-server" factor-binary nil factor-image "-shell=tty")
(comint-send-string "*factor-server*" "USE: shells telnet\n"))
;; (defun factor-listener ()
;; (interactive)
;; (factor-server)
;; (sleep-for 0 500)
;; (switch-to-buffer (make-comint "factor-listener" '("localhost" . 9999)))
;; (rename-uniquely)
;; (factor-listener-mode))
(defun factor-listener ()
(interactive)
(factor-server)
(sleep-for 0 1000)
(if (get-buffer "*factor-listener*")
(save-excursion
(set-buffer "*factor-listener*")
(rename-uniquely)))
(switch-to-buffer (make-comint "factor-listener" '("localhost" . 9999)))
(factor-listener-mode))
(defun factor-listener-restart ()
(interactive)
(factor-server)
(sleep-for 0 1000)
(make-comint-in-buffer
"factor-listener" (current-buffer) '("localhost" . 9999)))
(defun factor-run-file (file-name)
(interactive "fRun Factor file: ")
(comint-send-string nil (format "\"%s\" run-file\n" file-name)))
(defun factor-update-stack-buffer (&optional string)
(interactive)
(save-excursion
(set-buffer (get-buffer-create "*factor-stack*"))
(erase-buffer)
(comint-redirect-send-command-to-process
".s" "*factor-stack*" "*factor-listener*" nil)))
(defvar factor-update-stackp nil "*")
(defun factor-send-input ()
(interactive)
(comint-send-input)
(if factor-update-stackp
(progn (sleep-for 0 250) (factor-update-stack-buffer))))
(defun factor-synopsis ()
(interactive)
(message
(first
(comint-redirect-results-list-from-process
(get-buffer-process "*factor-listener*")
(format "\\ %s summary print" (thing-at-point 'symbol))
;; "[ ]*\\(.*\\)\n"
"\\(.*\\)\n"
1))))
(fset 'factor-comment-line "\C-a! ")