Monday, August 10, 2009

Emacs: run-forth.el


;Article: 50575 of comp.lang.forth
;Path: news.tuwien.ac.at!aconews.univie.ac.at!news-fra1.dfn.de!news0.de.colt.net!colt.net!newsfeed.icl.net!skynet.be!News.Amsterdam.UnisourceCS!news.pt.lu!iceberg.ltnb.lu
;From: bob@prophecy.lu (Bob Pepin)
;Newsgroups: comp.lang.forth
;Subject: Re: Basicly a basic BASIC
;Date: 06 Dec 1999 03:50:35 +0100
;Organization: Entreprise des P&T
;Lines: 193
;Message-ID: <86ogc46av8.fsf@homer.localnet>
;References: <81rct3$g4k@web.nmti.com> <81u1h0$207f$2@news.hal-pc.org> <3843FD27.57939753@gecm.com> <38441CF6.A093E03@cs.ucsd.edu> <3844B2D5.C06B4C28@cs.ucsd.edu> <384558b0$0$96893@news.tdi.net> <827d20$6j7$1@nntp3.atl.mindspring.net> <82dhap$gp$1@news.tuwien.ac.at>
;NNTP-Posting-Host: iceberg.ltnb.lu
;X-Trace: calais.pt.lu 944448945 13997 158.64.28.45 (6 Dec 1999 02:55:45 GMT)
;X-Complaints-To: usenet@news.pt.lu
;NNTP-Posting-Date: 6 Dec 1999 02:55:45 GMT
;X-Newsreader: Gnus v5.7/Emacs 20.4
;Xref: news.tuwien.ac.at comp.lang.forth:50575

;anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:

;> In article <827d20$6j7$1@nntp3.atl.mindspring.net>,
;> Wil Baden writes:
;> Goran Rydquist's forth.el (and, by inheritance, gforth.el) also has a
;> feature that supports running a Forth system interactively in an emacs
;> window and copying lines or regions with a few keystrokes from an
;> edited file to the Forth window, passing the text to the Forth system,
;> and displaying the output in the Forth window. No bouncing either.
;> However, I don't use or maintain this stuff, and IIRC it does not work
;> well with current versions of emacs and Gforth.

;I've attached a small .el that interfaces to forth via comint, works fine
;with the new emacsen, hope someone finds it useful..

;;;; run-forth.el
;;;; mostly stolen from cmuscheme.el

(provide 'run-forth)
;(require 'gforth)
(require 'comint)
;(require 'string)

(defvar inferior-forth-mode-hook nil
"*Hook for customising inferior-forth mode.")
(defvar inferior-forth-mode-map nil)

(cond ((not inferior-forth-mode-map)
(setq inferior-forth-mode-map
(copy-keymap comint-mode-map))
(define-key inferior-forth-mode-map "\M-\C-x" ;gnu convention
'forth-send-definition)
(define-key inferior-forth-mode-map "\C-x\C-e" 'forth-send-line)))

;; Install the process communication commands in the forth-mode keymap.
(define-key forth-mode-map "\M-\C-x" 'forth-send-definition);gnu convention
(define-key forth-mode-map "\C-x\C-e" 'forth-send-line);gnu convention
(define-key forth-mode-map "\C-ce" 'forth-send-definition)
(define-key forth-mode-map "\C-c\C-e" 'forth-send-definition-and-go)
(define-key forth-mode-map "\C-cr" 'forth-send-region)
(define-key forth-mode-map "\C-c\C-r" 'forth-send-region-and-go)
(define-key forth-mode-map "\C-cb" 'forth-send-buffer)
(define-key forth-mode-map "\C-c\C-b" 'forth-send-buffer-and-go)
(define-key forth-mode-map "\C-cz" 'switch-to-forth)

(defun inferior-forth-mode ()
"Major mode for interacting with an inferior Forth process.

The following commands are available:
\\{inferior-forth-mode-map}

A Forth process can be fired up with M-x run-forth.

Customisation: Entry to this mode runs the hooks on comint-mode-hook and
inferior-forth-mode-hook (in that order).

You can send text to the inferior Forth process from other buffers containing
Forth source.
switch-to-forth switches the current buffer to the Forth process buffer.
forth-send-definition sends the current definition to the Forth process.
forth-compile-definition compiles the current definition.
forth-send-region sends the current region to the Forth process.
forth-compile-region compiles the current region.

forth-send-definition-and-go, forth-compile-definition-and-go,
forth-send-region-and-go, and forth-compile-region-and-go
switch to the Forth process buffer after sending their text.
For information on running multiple processes in multiple buffers, see
documentation for variable forth-buffer."
(interactive)
(comint-mode)
;; Customise in inferior-forth-mode-hook
(setq comint-prompt-regexp "")
; (forth-mode-variables)
(setq major-mode 'inferior-forth-mode)
(setq mode-name "Inferior Forth")
(setq mode-line-process '(": %s"))
(use-local-map inferior-forth-mode-map)
(run-hooks 'inferior-forth-mode-hook))

(defvar forth-program-name "forth"
"*Program invoked be the run-forth command")

(defun run-forth (cmd)
"Run an inferior Forth process, input and output via buffer *forth*.
If there is a process already running in *forth*, just switch to that buffer.
With argument, allows you to edit the command line (default is value
of forth-program-name). Runs the hooks from inferior-forth-mode-hook
\(after the comint-mode-hook is run).
\(Type \\[describe-mode] in the process buffer for a list of commands.)"

(interactive (list (if current-prefix-arg
(read-string "Run Forth: " forth-program-name)
forth-program-name)))
(if (not (comint-check-proc "*forth*"))
(let ((cmdlist (split-string cmd "[\t ]")))
(set-buffer (apply 'make-comint "forth" (car cmdlist)
nil (cdr cmdlist)))
(inferior-forth-mode)))
(setq forth-buffer "*forth*")
(switch-to-buffer "*forth*"))

(defun forth-send-region (start end)
"Send the current region to the inferior Forth process."
(interactive "r")
(comint-send-region (forth-proc) start end)
(comint-send-string (forth-proc) "\n"))

(defun forth-send-definition ()
"Send the current definition to the inferior Forth process."
(interactive)
(save-excursion
(end-of-definition)
(let ((end (point)))
(beginning-of-definition)
(forth-send-region (point) end))))

(defun forth-send-line ()
"Send the current line to the inferior Forth process."
(interactive)
(save-excursion
(end-of-line)
(let ((end (point)))
(beginning-of-line)
(forth-send-region (point) end))))

(defun forth-send-buffer ()
"Send the current buffer to the inferior Forth process."
(interactive)
(forth-send-region (point-min) (point-max)))

(defun forth-send-region-and-go (start end)
"Send the current region to the inferior Forth process,
and switch to the process buffer."
(interactive "r")
(forth-send-region start end)
(switch-to-forth t))

(defun forth-send-definition-and-go ()
"Send the current definition to the inferior Forth,
and switch to the process buffer."
(interactive)
(forth-send-definition)
(switch-to-forth t))

(defun forth-send-line-and-go ()
"Send the current line to the inferior Forth,
and switch to the process buffer."
(interactive)
(forth-send-line)
(switch-to-forth t))

(defun forth-send-buffer-and-go ()
"Send the current buffer to the inferior Forth,
and switch to the process buffer."
(interactive)
(forth-send-buffer)
(switch-to-forth t))

(defun beginning-of-definition ()
(search-backward-regexp "\\<:\\>"))

(defun end-of-definition ()
(search-forward-regexp "\\<;\\>"))

(defun switch-to-forth (eob-p)
"Switch to the forth process buffer.
With argument, positions cursor at end of buffer."
(interactive "P")
(if (get-buffer forth-buffer)
(pop-to-buffer forth-buffer)
(error "No current process buffer. See variable forth-buffer."))
(cond (eob-p
(push-mark)
(goto-char (point-max)))))

(defvar forth-buffer nil "*The current forth process buffer.")

(defun forth-proc ()
"Returns the current forth process. See variable forth-buffer."
(let ((proc (get-buffer-process (if (eq major-mode 'inferior-forth-mode)
(current-buffer)
forth-buffer))))
(or proc
(error "No current process. See variable forth-buffer"))))

(run-hooks 'run-forth-load-hook)



;--
; sell me shitty software once, shame on you.
; sell me shitty software twice, shame on me.


No comments: