--- gforth/gforth.el 1994/05/07 14:55:53 1.1 +++ gforth/gforth.el 1994/08/25 15:25:26 1.8 @@ -1,5 +1,9 @@ ;; This file is part of GNU Emacs. ;; Changes by anton +;; This is a variant of forth.el that came with TILE. +;; I left most of this stuff untouched and made just a few changes for +;; the things I use (mainly indentation and syntax tables). +;; So there is still a lot of work to do to adapt this to gforth. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor @@ -16,7 +20,7 @@ ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. -;;; $Header: /nfs/unsafe/cvs-repository/src-master/gforth/gforth.el,v 1.1 1994/05/07 14:55:53 anton Exp $ +;;; $Header: /nfs/unsafe/cvs-repository/src-master/gforth/gforth.el,v 1.8 1994/08/25 15:25:26 anton Exp $ ;;------------------------------------------------------------------- ;; A Forth indentation, documentation search and interaction library @@ -33,21 +37,25 @@ (defvar forth-positives - " : begin do ?do while if ?dup-if ?dup-not-if else case create does> exception> " + " : :noname begin do ?do while if ?dup-if ?dup-not-if else case create does> exception> struct [if] [else] " "Contains all words which will cause the indent-level to be incremented on the next line. OBS! All words in forth-positives must be surrounded by spaces.") (defvar forth-negatives - " ; until repeat while +loop loop else then endif again endcase does> " + " ; until repeat while +loop loop s+loop else then endif again endcase does> end-struct [then] [else] " "Contains all words which will cause the indent-level to be decremented on the current line. OBS! All words in forth-negatives must be surrounded by spaces.") (defvar forth-zeroes - " : " + " : :noname " "Contains all words which causes the indent to go to zero") +(defvar forth-prefixes + " postpone [compile] ['] [char] " + "words that prefix and escape other words") + (defvar forth-mode-abbrev-table nil "Abbrev table in use in Forth-mode buffers.") @@ -63,12 +71,17 @@ OBS! All words in forth-negatives must b (global-set-key "\C-x\C-m" 'forth-split) (global-set-key "\e " 'forth-reload) +(define-key forth-mode-map "\M-\C-x" 'compile) +(define-key forth-mode-map "\C-x\\" 'comment-region) +(define-key forth-mode-map "\C-x|" 'uncomment-region) +(define-key forth-mode-map "\C-x~" 'forth-remove-tracers) (define-key forth-mode-map "\e\C-m" 'forth-send-paragraph) (define-key forth-mode-map "\eo" 'forth-send-buffer) (define-key forth-mode-map "\C-x\C-m" 'forth-split) (define-key forth-mode-map "\e " 'forth-reload) (define-key forth-mode-map "\t" 'forth-indent-command) (define-key forth-mode-map "\C-m" 'reindent-then-newline-and-indent) +(define-key forth-mode-map "\M-q" 'forth-fill-paragraph) (defvar forth-mode-syntax-table nil "Syntax table in use in Forth-mode buffers.") @@ -76,23 +89,28 @@ OBS! All words in forth-negatives must b (if (not forth-mode-syntax-table) (progn (setq forth-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?\\ "\\" forth-mode-syntax-table) - (modify-syntax-entry ?/ ". 14" forth-mode-syntax-table) - (modify-syntax-entry ?* ". 23" forth-mode-syntax-table) - (modify-syntax-entry ?+ "." forth-mode-syntax-table) - (modify-syntax-entry ?- "." forth-mode-syntax-table) - (modify-syntax-entry ?= "." forth-mode-syntax-table) - (modify-syntax-entry ?% "." forth-mode-syntax-table) - (modify-syntax-entry ?< "." forth-mode-syntax-table) - (modify-syntax-entry ?> "." forth-mode-syntax-table) - (modify-syntax-entry ?& "." forth-mode-syntax-table) - (modify-syntax-entry ?| "." forth-mode-syntax-table) - (modify-syntax-entry ?\' "\"" forth-mode-syntax-table) - (modify-syntax-entry ?\t " " forth-mode-syntax-table) - (modify-syntax-entry ?) "> " forth-mode-syntax-table) - (modify-syntax-entry ?( "< " forth-mode-syntax-table) - (modify-syntax-entry ?\( "() " forth-mode-syntax-table) - (modify-syntax-entry ?\) ")( " forth-mode-syntax-table))) + (let ((char 0)) + (while (< char ?!) + (modify-syntax-entry char " " forth-mode-syntax-table) + (setq char (1+ char))) + (while (< char 256) + (modify-syntax-entry char "w" forth-mode-syntax-table) + (setq char (1+ char)))) + (modify-syntax-entry ?\" "\"" forth-mode-syntax-table) + (modify-syntax-entry ?\\ "<" forth-mode-syntax-table) + (modify-syntax-entry ?\n ">" forth-mode-syntax-table) + )) +;I do not define '(' and ')' as comment delimiters, because emacs +;only supports one comment syntax (and a hack to accomodate C++); I +;use '\' for natural language comments and '(' for formal comments +;like stack comments, so for me it's better to have emacs treat '\' +;comments as comments. I you want it different, make the appropriate +;changes (best in your .emacs file). +; +;Hmm, the C++ hack could be used to support both comment syntaxes: we +;can have different comment styles, if both comments start with the +;same character. we could use ' ' as first and '(' and '\' as second +;character. However this would fail for G\ comments. (defconst forth-indent-level 4 "Indentation of Forth statements.") @@ -106,21 +124,22 @@ OBS! All words in forth-negatives must b (setq paragraph-separate paragraph-start) (make-local-variable 'indent-line-function) (setq indent-line-function 'forth-indent-line) - (make-local-variable 'require-final-newline) - (setq require-final-newline t) +; (make-local-variable 'require-final-newline) +; (setq require-final-newline t) (make-local-variable 'comment-start) - (setq comment-start "( ") - (make-local-variable 'comment-end) - (setq comment-end " )") + (setq comment-start "\\ ") + ;(make-local-variable 'comment-end) + ;(setq comment-end " )") (make-local-variable 'comment-column) (setq comment-column 40) (make-local-variable 'comment-start-skip) - (setq comment-start-skip "( ") + (setq comment-start-skip "\\ ") (make-local-variable 'comment-indent-hook) (setq comment-indent-hook 'forth-comment-indent) (make-local-variable 'parse-sexp-ignore-comments) (setq parse-sexp-ignore-comments t)) +;;;###autoload (defun forth-mode () " Major mode for editing Forth code. Tab indents for Forth code. Comments @@ -196,6 +215,22 @@ Variables controling documentation searc ; (run-forth forth-program-name)) (run-hooks 'forth-mode-hook)) +(setq forth-mode-hook + '(lambda () (setq compile-command "gforth "))) + +(defun forth-fill-paragraph () + "Fill comments (starting with '\'; do not fill code (block style +programmers who tend to fill code won't use emacs anyway:-)." + ; currently only comments at the start of the line are + ; filled. something like lisp-fill-paragraph may be better + (interactive) + (save-excursion + (beginning-of-line) + (if (looking-at "[ \t]*\\\\[ \t]+") + (progn (goto-char (match-end 0)) + (set-fill-prefix) + (fill-paragraph nil))))) + (defun forth-comment-indent () (save-excursion (beginning-of-line) @@ -280,8 +315,6 @@ Variables controling documentation searc forth-positives)) (setq t2 (string-match (regexp-quote (concat " " w " ")) forth-negatives)) - (if (and t1 t2) - (setq sum (+ sum forth-indent-level))) (if t1 (setq sum (+ sum forth-indent-level))) (if (and t2 (not first)) @@ -292,7 +325,10 @@ Variables controling documentation searc (defun forth-next-word () - "Return the next forth-word. Skip anything enclosed in double quotes or ()." + "Return the next forth-word. Skip anything that the forth-word takes from +the input stream (comments, arguments, etc.)" +;actually, it would be better to use commands based on the +;syntax-table or comment-start etc. (let ((w1 nil)) (while (not w1) (skip-chars-forward " \t\n") @@ -301,19 +337,31 @@ Variables controling documentation searc (setq w1 (buffer-substring p (point)))) (cond ((string-match "\"" w1) (progn - (skip-chars-forward "^\"") - (setq w1 nil))) - ((string-match "\(" w1) + (skip-chars-forward "^\"\n") + (forward-char))) + ((string-match "\\\\" w1) + (progn + (end-of-line) + )) + ((or (equal "(" w1) (equal ".(" w1)) (progn - (skip-chars-forward "^\)") - (setq w1 nil))) + (skip-chars-forward "^)\n") + (forward-char))) + ((string-match (regexp-quote (concat " " w1 " ")) forth-prefixes) + (progn (skip-chars-forward " \t\n") + (skip-chars-forward "^ \t\n"))) (t nil))) w1)) ;; Forth commands -(defvar forth-program-name "forth" +(defun forth-remove-tracers () + "Remove tracers of the form `~~ '. Queries the user for each occurrence." + (interactive) + (query-replace "~~ " "")) + +(defvar forth-program-name "gforth" "*Program invoked by the `run-forth' command.") (defvar forth-band-name nil @@ -616,7 +664,7 @@ The region is sent terminated by a newli ;; Misc (setq auto-mode-alist (append auto-mode-alist - '(("\\.f83$" . forth-mode)))) + '(("\\.fs$" . forth-mode)))) (defun forth-split () (interactive) @@ -688,7 +736,7 @@ The region is sent terminated by a newli (error "forth-help-load-path not specified"))) -(define-key forth-mode-map "\C-hf" 'forth-documentation) +;(define-key forth-mode-map "\C-hf" 'forth-documentation) (defun forth-documentation (function) "Display the full documentation of FORTH word." @@ -796,7 +844,7 @@ The region is sent terminated by a newli (define-key forth-mode-map "\C-x\C-n" 'next-error) (require 'compile "compile") -(defvar forth-compile-command "forth ") +(defvar forth-compile-command "gforth ") (defvar forth-compilation-window-percent-height 30) (defun forth-compile (command)