summaryrefslogtreecommitdiff
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorDaniel LaLiberte <liberte@gnu.org>1994-04-09 21:49:52 +0000
committerDaniel LaLiberte <liberte@gnu.org>1994-04-09 21:49:52 +0000
commit03cc57507bf8c3b21b12bdde2facbb63c2a5f13d (patch)
tree0c332edc81df1228e1bdc90dd2b05865af3a2bee /lisp/progmodes
parentc4c197197897f6a1da4c64c4fc237f1fe3c239e5 (diff)
downloademacs-03cc57507bf8c3b21b12bdde2facbb63c2a5f13d.tar.gz
BrachnCreate branch for FSF mods of edebug.el.
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/asm-mode.el219
-rw-r--r--lisp/progmodes/awk-mode.el95
-rw-r--r--lisp/progmodes/c-mode.el1485
-rw-r--r--lisp/progmodes/cmacexp.el443
-rw-r--r--lisp/progmodes/compile.el1307
-rw-r--r--lisp/progmodes/cplus-md.el917
-rw-r--r--lisp/progmodes/etags.el1447
-rw-r--r--lisp/progmodes/fortran.el1292
-rw-r--r--lisp/progmodes/hideif.el1041
-rw-r--r--lisp/progmodes/icon.el559
-rw-r--r--lisp/progmodes/inf-lisp.el634
-rw-r--r--lisp/progmodes/make-mode.el1073
-rw-r--r--lisp/progmodes/modula2.el454
-rw-r--r--lisp/progmodes/pascal.el1404
-rw-r--r--lisp/progmodes/perl-mode.el641
-rw-r--r--lisp/progmodes/prolog.el271
-rw-r--r--lisp/progmodes/scheme.el507
-rw-r--r--lisp/progmodes/sh-script.el895
-rw-r--r--lisp/progmodes/simula.el1291
-rw-r--r--lisp/progmodes/tcl.el1816
20 files changed, 0 insertions, 17791 deletions
diff --git a/lisp/progmodes/asm-mode.el b/lisp/progmodes/asm-mode.el
deleted file mode 100644
index cd91a957bcf..00000000000
--- a/lisp/progmodes/asm-mode.el
+++ /dev/null
@@ -1,219 +0,0 @@
-;;; asm-mode.el --- mode for editing assembler code
-
-;; Copyright (C) 1991 Free Software Foundation, Inc.
-
-;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
-;; Last-Modified: 14 Jul 1992
-;; Keywords: tools, languages
-
-;; @(#)asm-mode.el 1.7
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; This mode was written by Eric S. Raymond <esr@snark.thyrsus.com>,
-;; inspired by an earlier asm-mode by Martin Neitzel.
-
-;; This minor mode is based on text mode. It defines a private abbrev table
-;; that can be used to save abbrevs for assembler mnemonics. It binds just
-;; five keys:
-;;
-;; TAB tab to next tab stop
-;; : outdent preceding label, tab to tab stop
-;; ; place or move comment
-;; C-j, C-m newline and tab to tab stop
-;;
-;; Code is indented to the first tab stop level.
-;; The ; key inserts copies of the value of asm-comment-char at an
-;; appropriate spot.
-
-;; This mode runs two hooks:
-;; 1) An asm-set-comment-hook before the part of the initialization
-;; depending on asm-comment-char, and
-;; 2) an asm-mode-hook at the end of initialization.
-
-;;; Code:
-
-(defvar asm-comment-char ?;
- "*The comment-start character assumed by Asm mode.")
-
-(defvar asm-mode-syntax-table nil
- "Syntax table used while in Asm mode.")
-
-(defvar asm-mode-abbrev-table nil
- "Abbrev table used while in Asm mode.")
-(define-abbrev-table 'asm-mode-abbrev-table ())
-
-(defvar asm-mode-map nil
- "Keymap for Asm mode.")
-
-(if asm-mode-map
- nil
- (setq asm-mode-map (make-sparse-keymap))
- (define-key asm-mode-map ";" 'asm-comment)
- (define-key asm-mode-map ":" 'asm-colon)
- (define-key asm-mode-map "\C-i" 'tab-to-tab-stop)
- (define-key asm-mode-map "\C-j" 'asm-newline)
- (define-key asm-mode-map "\C-m" 'asm-newline)
- )
-
-(defvar asm-code-level-empty-comment-pattern nil)
-(defvar asm-flush-left-empty-comment-pattern nil)
-(defvar asm-inline-empty-comment-pattern nil)
-
-;;;###autoload
-(defun asm-mode ()
- "Major mode for editing typical assembler code.
-Features a private abbrev table and the following bindings:
-
-\\[asm-colon]\toutdent a preceding label, tab to next tab stop.
-\\[tab-to-tab-stop]\ttab to next tab stop.
-\\[asm-newline]\tnewline, then tab to next tab stop.
-\\[asm-comment]\tsmart placement of assembler comments.
-
-The character used for making comments is set by the variable
-`asm-comment-char' (which defaults to `?;').
-
-Alternatively, you may set this variable in `asm-set-comment-hook', which is
-called near the beginning of mode initialization.
-
-Turning on Asm mode runs the hook `asm-mode-hook' at the end of initialization.
-
-Special commands:
-\\{asm-mode-map}
-"
- (interactive)
- (kill-all-local-variables)
- (use-local-map asm-mode-map)
- (setq mode-name "Assembler")
- (setq major-mode 'asm-mode)
- (setq local-abbrev-table asm-mode-abbrev-table)
- (make-local-variable 'asm-mode-syntax-table)
- (setq asm-mode-syntax-table (make-syntax-table))
- (set-syntax-table asm-mode-syntax-table)
- (run-hooks 'asm-mode-set-comment-hook)
- (modify-syntax-entry asm-comment-char
- "<" asm-mode-syntax-table)
- (modify-syntax-entry ?\n
- ">" asm-mode-syntax-table)
- (let ((cs (regexp-quote (char-to-string asm-comment-char))))
- (make-local-variable 'comment-start)
- (setq comment-start (concat cs " "))
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip (concat cs "+[ \t]*"))
- (setq asm-inline-empty-comment-pattern (concat "^.+" cs "+ *$"))
- (setq asm-code-level-empty-comment-pattern (concat "^[\t ]+" cs cs " *$"))
- (setq asm-flush-left-empty-comment-pattern (concat "^" cs cs cs " *$"))
- )
- (make-local-variable 'comment-end)
- (setq comment-end "")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (setq fill-prefix "\t")
- (run-hooks 'asm-mode-hook)
- )
-
-
-(defun asm-colon ()
- "Insert a colon; if it follows a label, delete the label's indentation."
- (interactive)
- (save-excursion
- (beginning-of-line)
- (if (looking-at "[ \t]+\\(\\sw\\|\\s_\\)+$")
- (delete-horizontal-space)))
- (insert ":")
- (tab-to-tab-stop)
- )
-
-(defun asm-newline ()
- "Insert LFD + fill-prefix, to bring us back to code-indent level."
- (interactive)
- (if (eolp) (delete-horizontal-space))
- (insert "\n")
- (tab-to-tab-stop)
- )
-
-(defun asm-line-matches (pattern &optional withcomment)
- (save-excursion
- (beginning-of-line)
- (looking-at pattern)))
-
-(defun asm-pop-comment-level ()
- ;; Delete an empty comment ending current line. Then set up for a new one,
- ;; on the current line if it was all comment, otherwise above it
- (end-of-line)
- (delete-horizontal-space)
- (while (= (preceding-char) asm-comment-char)
- (delete-backward-char 1))
- (delete-horizontal-space)
- (if (bolp)
- nil
- (beginning-of-line)
- (open-line 1))
- )
-
-
-(defun asm-comment ()
- "Convert an empty comment to a `larger' kind, or start a new one.
-These are the known comment classes:
-
- 1 -- comment to the right of the code (at the comment-column)
- 2 -- comment on its own line, indented like code
- 3 -- comment on its own line, beginning at the left-most column.
-
-Suggested usage: while writing your code, trigger asm-comment
-repeatedly until you are satisfied with the kind of comment."
- (interactive)
- (cond
-
- ;; Blank line? Then start comment at code indent level.
- ((asm-line-matches "^[ \t]*$")
- (delete-horizontal-space)
- (tab-to-tab-stop)
- (insert asm-comment-char comment-start))
-
- ;; Nonblank line with no comment chars in it?
- ;; Then start a comment at the current comment column
- ((asm-line-matches (format "^[^%c]+$" asm-comment-char))
- (indent-for-comment))
-
- ;; Flush-left comment present? Just insert character.
- ((asm-line-matches asm-flush-left-empty-comment-pattern)
- (insert asm-comment-char))
-
- ;; Empty code-level comment already present?
- ;; Then start flush-left comment, on line above if this one is nonempty.
- ((asm-line-matches asm-code-level-empty-comment-pattern)
- (asm-pop-comment-level)
- (insert asm-comment-char asm-comment-char comment-start))
-
- ;; Empty comment ends line?
- ;; Then make code-level comment, on line above if this one is nonempty.
- ((asm-line-matches asm-inline-empty-comment-pattern)
- (asm-pop-comment-level)
- (tab-to-tab-stop)
- (insert asm-comment-char comment-start))
-
- ;; If all else fails, insert character
- (t
- (insert asm-comment-char))
-
- )
- (end-of-line))
-
-;;; asm-mode.el ends here
diff --git a/lisp/progmodes/awk-mode.el b/lisp/progmodes/awk-mode.el
deleted file mode 100644
index ba3249ac357..00000000000
--- a/lisp/progmodes/awk-mode.el
+++ /dev/null
@@ -1,95 +0,0 @@
-;;; awk-mode.el --- AWK code editing commands for Emacs
-
-;; Copyright (C) 1988 Free Software Foundation, Inc.
-
-;; Maintainer: FSF
-;; Keywords: unix, languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; Sets up C-mode with support for awk-style #-comments and a lightly
-;; hacked syntax table.
-
-;;; Code:
-
-(defvar awk-mode-syntax-table nil
- "Syntax table in use in Awk-mode buffers.")
-
-(if awk-mode-syntax-table
- ()
- (setq awk-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\\ "\\" awk-mode-syntax-table)
- (modify-syntax-entry ?\n "> " awk-mode-syntax-table)
- (modify-syntax-entry ?\f "> " awk-mode-syntax-table)
- (modify-syntax-entry ?\# "< " awk-mode-syntax-table)
- (modify-syntax-entry ?/ "." awk-mode-syntax-table)
- (modify-syntax-entry ?* "." awk-mode-syntax-table)
- (modify-syntax-entry ?+ "." awk-mode-syntax-table)
- (modify-syntax-entry ?- "." awk-mode-syntax-table)
- (modify-syntax-entry ?= "." awk-mode-syntax-table)
- (modify-syntax-entry ?% "." awk-mode-syntax-table)
- (modify-syntax-entry ?< "." awk-mode-syntax-table)
- (modify-syntax-entry ?> "." awk-mode-syntax-table)
- (modify-syntax-entry ?& "." awk-mode-syntax-table)
- (modify-syntax-entry ?| "." awk-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" awk-mode-syntax-table))
-
-(defvar awk-mode-abbrev-table nil
- "Abbrev table in use in Awk-mode buffers.")
-(define-abbrev-table 'awk-mode-abbrev-table ())
-
-;;;###autoload
-(defun awk-mode ()
- "Major mode for editing AWK code.
-This is much like C mode except for the syntax of comments. It uses
-the same keymap as C mode and has the same variables for customizing
-indentation. It has its own abbrev table and its own syntax table.
-
-Turning on AWK mode calls the value of the variable `awk-mode-hook'
-with no args, if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map c-mode-map)
- (setq major-mode 'awk-mode)
- (setq mode-name "AWK")
- (setq local-abbrev-table awk-mode-abbrev-table)
- (set-syntax-table awk-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'c-indent-line)
- (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 "")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "#+ *")
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'c-comment-indent)
- (run-hooks 'awk-mode-hook))
-
-;;; awk-mode.el ends here
diff --git a/lisp/progmodes/c-mode.el b/lisp/progmodes/c-mode.el
deleted file mode 100644
index 91016c99b9b..00000000000
--- a/lisp/progmodes/c-mode.el
+++ /dev/null
@@ -1,1485 +0,0 @@
-;;; c-mode.el --- C code editing commands for Emacs
-;; Copyright (C) 1985, 1986, 1987, 1992, 1994 Free Software Foundation, Inc.
-
-;; Maintainer: FSF
-;; Keywords: c
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; A smart editing mode for C code. It knows a lot about C syntax and tries
-;; to position the curser according to C layout conventions. You can
-;; change the details of the layout style with option variables. Load it
-;; and do M-x describe-mode for details.
-
-;;; Code:
-
-(defvar c-mode-abbrev-table nil
- "Abbrev table in use in C mode.")
-(define-abbrev-table 'c-mode-abbrev-table ())
-
-(defvar c-mode-map (make-sparse-keymap)
- "Keymap used in C mode.")
-
-(define-key c-mode-map "{" 'electric-c-brace)
-(define-key c-mode-map "}" 'electric-c-brace)
-(define-key c-mode-map ";" 'electric-c-semi)
-(define-key c-mode-map "#" 'electric-c-sharp-sign)
-(define-key c-mode-map ":" 'electric-c-terminator)
-(define-key c-mode-map "\e\C-h" 'mark-c-function)
-(define-key c-mode-map "\e\C-q" 'indent-c-exp)
-(define-key c-mode-map "\ea" 'c-beginning-of-statement)
-(define-key c-mode-map "\ee" 'c-end-of-statement)
-(define-key c-mode-map "\eq" 'c-fill-paragraph)
-(define-key c-mode-map "\C-c\C-n" 'c-forward-conditional)
-(define-key c-mode-map "\C-c\C-p" 'c-backward-conditional)
-(define-key c-mode-map "\C-c\C-u" 'c-up-conditional)
-(define-key c-mode-map "\177" 'backward-delete-char-untabify)
-(define-key c-mode-map "\t" 'c-indent-command)
-
-(define-key c-mode-map [menu-bar] (make-sparse-keymap))
-
-(define-key c-mode-map [menu-bar c]
- (cons "C" (make-sparse-keymap "C")))
-
-(define-key c-mode-map [menu-bar c comment-region]
- '("Comment Out Region" . comment-region))
-(define-key c-mode-map [menu-bar c c-macro-expand]
- '("Macro Expand Region" . c-macro-expand))
-(define-key c-mode-map [menu-bar c c-backslash-region]
- '("Backslashify" . c-backslash-region))
-(define-key c-mode-map [menu-bar c indent-exp]
- '("Indent Expression" . indent-c-exp))
-(define-key c-mode-map [menu-bar c indent-line]
- '("Indent Line" . c-indent-command))
-(define-key c-mode-map [menu-bar c fill]
- '("Fill Comment Paragraph" . c-fill-paragraph))
-(define-key c-mode-map [menu-bar c up]
- '("Up Conditional" . c-up-conditional))
-(define-key c-mode-map [menu-bar c backward]
- '("Backward Conditional" . c-backward-conditional))
-(define-key c-mode-map [menu-bar c forward]
- '("Forward Conditional" . c-forward-conditional))
-(define-key c-mode-map [menu-bar c backward-stmt]
- '("Backward Statement" . c-beginning-of-statement))
-(define-key c-mode-map [menu-bar c forward-stmt]
- '("Forward Statement" . c-end-of-statement))
-
-(autoload 'c-macro-expand "cmacexp"
- "Display the result of expanding all C macros occurring in the region.
-The expansion is entirely correct because it uses the C preprocessor."
- t)
-
-(defvar c-mode-syntax-table nil
- "Syntax table in use in C-mode buffers.")
-
-(if c-mode-syntax-table
- ()
- (setq c-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\\ "\\" c-mode-syntax-table)
- (modify-syntax-entry ?/ ". 14" c-mode-syntax-table)
- (modify-syntax-entry ?* ". 23" c-mode-syntax-table)
- (modify-syntax-entry ?+ "." c-mode-syntax-table)
- (modify-syntax-entry ?- "." c-mode-syntax-table)
- (modify-syntax-entry ?= "." c-mode-syntax-table)
- (modify-syntax-entry ?% "." c-mode-syntax-table)
- (modify-syntax-entry ?< "." c-mode-syntax-table)
- (modify-syntax-entry ?> "." c-mode-syntax-table)
- (modify-syntax-entry ?& "." c-mode-syntax-table)
- (modify-syntax-entry ?| "." c-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" c-mode-syntax-table))
-
-(defconst c-indent-level 2
- "*Indentation of C statements with respect to containing block.")
-(defconst c-brace-imaginary-offset 0
- "*Imagined indentation of a C open brace that actually follows a statement.")
-(defconst c-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context.")
-(defconst c-argdecl-indent 5
- "*Indentation level of declarations of C function arguments.")
-(defconst c-label-offset -2
- "*Offset of C label lines and case statements relative to usual indentation.")
-(defconst c-continued-statement-offset 2
- "*Extra indent for lines not starting new statements.")
-(defconst c-continued-brace-offset 0
- "*Extra indent for substatements that start with open-braces.
-This is in addition to c-continued-statement-offset.")
-(defconst c-style-alist
- '(("GNU"
- (c-indent-level . 2)
- (c-argdecl-indent . 5)
- (c-brace-offset . 0)
- (c-label-offset . -2)
- (c-continued-statement-offset . 2))
- ("K&R"
- (c-indent-level . 5)
- (c-argdecl-indent . 0)
- (c-brace-offset . -5)
- (c-label-offset . -5)
- (c-continued-statement-offset . 5))
- ("BSD"
- (c-indent-level . 4)
- (c-argdecl-indent . 4)
- (c-brace-offset . -4)
- (c-label-offset . -4)
- (c-continued-statement-offset . 4))
- ("C++"
- (c-indent-level . 4)
- (c-continued-statement-offset . 4)
- (c-brace-offset . -4)
- (c-argdecl-indent . 0)
- (c-label-offset . -4)
- (c-auto-newline . t))
- ("Whitesmith"
- (c-indent-level . 4)
- (c-argdecl-indent . 4)
- (c-brace-offset . 0)
- (c-label-offset . -4)
- (c-continued-statement-offset . 4))))
-
-(defconst c-auto-newline nil
- "*Non-nil means automatically newline before and after braces,
-and after colons and semicolons, inserted in C code.
-If you do not want a leading newline before braces then use:
- (define-key c-mode-map \"{\" 'electric-c-semi)")
-
-(defconst c-tab-always-indent t
- "*Non-nil means TAB in C mode should always reindent the current line,
-regardless of where in the line point is when the TAB command is used.")
-
-;;; Regular expression used internally to recognize labels in switch
-;;; statements.
-(defconst c-switch-label-regexp "case[ \t'/(]\\|default\\(\\S_\\|'\\)")
-
-
-(defun c-mode ()
- "Major mode for editing C code.
-Expression and list commands understand all C brackets.
-Tab indents for C code.
-Comments are delimited with /* ... */.
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-\\{c-mode-map}
-Variables controlling indentation style:
- c-tab-always-indent
- Non-nil means TAB in C mode should always reindent the current line,
- regardless of where in the line point is when the TAB command is used.
- c-auto-newline
- Non-nil means automatically newline before and after braces,
- and after colons and semicolons, inserted in C code.
- c-indent-level
- Indentation of C statements within surrounding block.
- The surrounding block's indentation is the indentation
- of the line on which the open-brace appears.
- c-continued-statement-offset
- Extra indentation given to a substatement, such as the
- then-clause of an if or body of a while.
- c-continued-brace-offset
- Extra indentation given to a brace that starts a substatement.
- This is in addition to c-continued-statement-offset.
- c-brace-offset
- Extra indentation for line if it starts with an open brace.
- c-brace-imaginary-offset
- An open brace following other text is treated as if it were
- this far to the right of the start of its line.
- c-argdecl-indent
- Indentation level of declarations of C function arguments.
- c-label-offset
- Extra indentation for line that is a label, or case or default.
-
-Settings for K&R and BSD indentation styles are
- c-indent-level 5 8
- c-continued-statement-offset 5 8
- c-brace-offset -5 -8
- c-argdecl-indent 0 8
- c-label-offset -5 -8
-
-Turning on C mode calls the value of the variable c-mode-hook with no args,
-if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map c-mode-map)
- (setq major-mode 'c-mode)
- (setq mode-name "C")
- (setq local-abbrev-table c-mode-abbrev-table)
- (set-syntax-table c-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'c-indent-line)
- (make-local-variable 'indent-region-function)
- (setq indent-region-function 'c-indent-region)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'outline-regexp)
- (setq outline-regexp "[^#\n\^M]")
- (make-local-variable 'outline-level)
- (setq outline-level 'c-outline-level)
- (make-local-variable 'comment-start)
- (setq comment-start "/* ")
- (make-local-variable 'comment-end)
- (setq comment-end " */")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "/\\*+ *")
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'c-comment-indent)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (run-hooks 'c-mode-hook))
-
-(defun c-outline-level ()
- (save-excursion
- (skip-chars-forward "\t ")
- (current-column)))
-
-;; This is used by indent-for-comment
-;; to decide how much to indent a comment in C code
-;; based on its context.
-(defun c-comment-indent ()
- (if (looking-at "^/\\*")
- 0 ;Existing comment at bol stays there.
- (let ((opoint (point)))
- (save-excursion
- (beginning-of-line)
- (cond ((looking-at "[ \t]*}[ \t]*\\($\\|/\\*\\)")
- ;; A comment following a solitary close-brace
- ;; should have only one space.
- (search-forward "}")
- (1+ (current-column)))
- ((or (looking-at "^#[ \t]*endif[ \t]*")
- (looking-at "^#[ \t]*else[ \t]*"))
- 7) ;2 spaces after #endif
- ((progn
- (goto-char opoint)
- (skip-chars-backward " \t")
- (and (= comment-column 0) (bolp)))
- ;; If comment-column is 0, and nothing but space
- ;; before the comment, align it at 0 rather than 1.
- 0)
- (t
- (max (1+ (current-column)) ;Else indent at comment column
- comment-column))))))) ; except leave at least one space.
-
-(defun c-fill-paragraph (&optional arg)
- "Like \\[fill-paragraph] but handle C comments.
-If any of the current line is a comment or within a comment,
-fill the comment or the paragraph of it that point is in,
-preserving the comment indentation or line-starting decorations."
- (interactive "P")
- (let* (comment-start-place
- (first-line
- ;; Check for obvious entry to comment.
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t\n")
- (and (looking-at comment-start-skip)
- (setq comment-start-place (point))))))
- (if (and (eq major-mode 'c++-mode)
- (save-excursion
- (beginning-of-line)
- (looking-at ".*//")))
- (let (fill-prefix
- (paragraph-start
- ;; Lines containing just a comment start or just an end
- ;; should not be filled into paragraphs they are next to.
- (concat
- paragraph-start
- "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
- (paragraph-separate
- (concat
- paragraph-separate
- "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$")))
- (save-excursion
- (beginning-of-line)
- ;; Move up to first line of this comment.
- (while (and (not (bobp)) (looking-at "[ \t]*//"))
- (forward-line -1))
- (if (not (looking-at ".*//"))
- (forward-line 1))
- ;; Find the comment start in this line.
- (re-search-forward "[ \t]*//[ \t]*")
- ;; Set the fill-prefix to be what all lines except the first
- ;; should start with.
- (let ((endcol (current-column)))
- (skip-chars-backward " \t")
- (setq fill-prefix
- (concat (make-string (- (current-column) 2) ?\ )
- "//"
- (make-string (- endcol (current-column)) ?\ ))))
- (save-restriction
- ;; Narrow down to just the lines of this comment.
- (narrow-to-region (point)
- (save-excursion
- (forward-line 1)
- (while (looking-at "[ \t]*//")
- (forward-line 1))
- (point)))
- (insert fill-prefix)
- (fill-paragraph arg)
- (delete-region (point-min)
- (+ (point-min) (length fill-prefix))))))
- (if (or first-line
- ;; t if we enter a comment between start of function and this line.
- (eq (calculate-c-indent) t)
- ;; t if this line contains a comment starter.
- (setq first-line
- (save-excursion
- (beginning-of-line)
- (prog1
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line)
- (point))
- t)
- (setq comment-start-place (point))))))
- ;; Inside a comment: fill one comment paragraph.
- (let ((fill-prefix
- ;; The prefix for each line of this paragraph
- ;; is the appropriate part of the start of this line,
- ;; up to the column at which text should be indented.
- (save-excursion
- (beginning-of-line)
- (if (looking-at "[ \t]*/\\*.*\\*/")
- (progn (re-search-forward comment-start-skip)
- (make-string (current-column) ?\ ))
- (if first-line (forward-line 1))
-
- (let ((line-width (progn (end-of-line) (current-column))))
- (beginning-of-line)
- (prog1
- (buffer-substring
- (point)
-
- ;; How shall we decide where the end of the
- ;; fill-prefix is?
- ;; calculate-c-indent-within-comment bases its value
- ;; on the indentation of previous lines; if they're
- ;; indented specially, it could return a column
- ;; that's well into the current line's text. So
- ;; we'll take at most that many space, tab, or *
- ;; characters, and use that as our fill prefix.
- (let ((max-prefix-end
- (progn
- (move-to-column
- (calculate-c-indent-within-comment t)
- t)
- (point))))
- (beginning-of-line)
- (skip-chars-forward " \t*" max-prefix-end)
- (point)))
-
- ;; If the comment is only one line followed by a blank
- ;; line, calling move-to-column above may have added
- ;; some spaces and tabs to the end of the line; the
- ;; fill-paragraph function will then delete it and the
- ;; newline following it, so we'll lose a blank line
- ;; when we shouldn't. So delete anything
- ;; move-to-column added to the end of the line. We
- ;; record the line width instead of the position of the
- ;; old line end because move-to-column might break a
- ;; tab into spaces, and the new characters introduced
- ;; there shouldn't be deleted.
-
- ;; If you can see a better way to do this, please make
- ;; the change. This seems very messy to me.
- (delete-region (progn (move-to-column line-width)
- (point))
- (progn (end-of-line) (point))))))))
-
- (paragraph-start
- ;; Lines containing just a comment start or just an end
- ;; should not be filled into paragraphs they are next to.
- (concat
- paragraph-start
- "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
- (paragraph-separate
- (concat
- paragraph-separate
- "\\|^[ \t]*/\\*[ \t]*$\\|^[ \t]*\\*/[ \t]*$\\|^[ \t/*]*$"))
- (chars-to-delete 0))
- (save-restriction
- ;; Don't fill the comment together with the code following it.
- ;; So temporarily exclude everything before the comment start,
- ;; and everything after the line where the comment ends.
- ;; If comment-start-place is non-nil, the comment starter is there.
- ;; Otherwise, point is inside the comment.
- (narrow-to-region (save-excursion
- (if comment-start-place
- (goto-char comment-start-place)
- (search-backward "/*"))
- ;; Protect text before the comment start
- ;; by excluding it. Add spaces to bring back
- ;; proper indentation of that point.
- (let ((column (current-column)))
- (prog1 (point)
- (setq chars-to-delete column)
- (insert-char ?\ column))))
- (save-excursion
- (if comment-start-place
- (goto-char (+ comment-start-place 2)))
- (search-forward "*/" nil 'move)
- (forward-line 1)
- (point)))
- (fill-paragraph arg)
- (save-excursion
- ;; Delete the chars we inserted to avoid clobbering
- ;; the stuff before the comment start.
- (goto-char (point-min))
- (if (> chars-to-delete 0)
- (delete-region (point) (+ (point) chars-to-delete)))
- ;; Find the comment ender (should be on last line of buffer,
- ;; given the narrowing) and don't leave it on its own line.
- ;; Do this with a fill command, so as to preserve sentence
- ;; boundaries.
- (goto-char (point-max))
- (forward-line -1)
- (search-forward "*/" nil 'move)
- (beginning-of-line)
- (if (looking-at "[ \t]*\\*/")
- (let ((fill-column (+ fill-column 9999)))
- (forward-line -1)
- (fill-region-as-paragraph (point) (point-max)))))))
- ;; Outside of comments: do ordinary filling.
- (fill-paragraph arg)))))
-
-(defun electric-c-brace (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (let (insertpos)
- (if (and (not arg)
- (eolp)
- (or (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (if c-auto-newline (progn (c-indent-line) (newline) t) nil)))
- (progn
- (insert last-command-char)
- (c-indent-line)
- (if c-auto-newline
- (progn
- (newline)
- ;; (newline) may have done auto-fill
- (setq insertpos (- (point) 2))
- (c-indent-line)))
- (save-excursion
- (if insertpos (goto-char (1+ insertpos)))
- (delete-char -1))))
- (if insertpos
- (save-excursion
- (goto-char insertpos)
- (self-insert-command (prefix-numeric-value arg)))
- (self-insert-command (prefix-numeric-value arg)))))
-
-(defun electric-c-sharp-sign (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (if (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (let ((c-auto-newline nil))
- (electric-c-terminator arg))
- (self-insert-command (prefix-numeric-value arg))))
-
-(defun electric-c-semi (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (if c-auto-newline
- (electric-c-terminator arg)
- (self-insert-command (prefix-numeric-value arg))))
-
-(defun electric-c-terminator (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (let (insertpos (end (point)))
- (if (and (not arg) (eolp)
- (not (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (or (= (following-char) ?#)
- ;; Colon is special only after a label, or case ....
- ;; So quickly rule out most other uses of colon
- ;; and do no indentation for them.
- (and (eq last-command-char ?:)
- (not (looking-at c-switch-label-regexp))
- (save-excursion
- (skip-chars-forward "a-zA-Z0-9_$")
- (skip-chars-forward " \t")
- (< (point) end)))
- (progn
- (beginning-of-defun)
- (let ((pps (parse-partial-sexp (point) end)))
- (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
- (progn
- (insert last-command-char)
- (c-indent-line)
- (and c-auto-newline
- (not (c-inside-parens-p))
- (progn
- (newline)
- ;; (newline) may have done auto-fill
- (setq insertpos (- (point) 2))
- (c-indent-line)))
- (save-excursion
- (if insertpos (goto-char (1+ insertpos)))
- (delete-char -1))))
- (if insertpos
- (save-excursion
- (goto-char insertpos)
- (self-insert-command (prefix-numeric-value arg)))
- (self-insert-command (prefix-numeric-value arg)))))
-
-(defun c-inside-parens-p ()
- (condition-case ()
- (save-excursion
- (save-restriction
- (narrow-to-region (point)
- (progn (beginning-of-defun) (point)))
- (goto-char (point-max))
- (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
- (error nil)))
-
-(defun c-indent-command (&optional whole-exp)
- "Indent current line as C code, or in some cases insert a tab character.
-If `c-tab-always-indent' is non-nil (the default), always indent current line.
-Otherwise, indent the current line only if point is at the left margin or
-in the line's indentation; otherwise insert a tab.
-
-A numeric argument, regardless of its value, means indent rigidly all the
-lines of the expression starting after point so that this line becomes
-properly indented. The relative indentation among the lines of the
-expression are preserved."
- (interactive "P")
- (if whole-exp
- ;; If arg, always indent this line as C
- ;; and shift remaining lines of expression the same amount.
- (let ((shift-amt (c-indent-line))
- beg end)
- (save-excursion
- (if c-tab-always-indent
- (beginning-of-line))
- ;; Find beginning of following line.
- (save-excursion
- (forward-line 1) (setq beg (point)))
- ;; Find first beginning-of-sexp for sexp extending past this line.
- (while (< (point) beg)
- (forward-sexp 1)
- (setq end (point))
- (skip-chars-forward " \t\n")))
- (if (> end beg)
- (indent-code-rigidly beg end shift-amt "#")))
- (if (and (not c-tab-always-indent)
- (save-excursion
- (skip-chars-backward " \t")
- (not (bolp))))
- (insert-tab)
- (c-indent-line))))
-
-(defun c-indent-line ()
- "Indent current line as C code.
-Return the amount the indentation changed by."
- (let ((indent (calculate-c-indent nil))
- beg shift-amt
- (case-fold-search nil)
- (pos (- (point-max) (point))))
- (beginning-of-line)
- (setq beg (point))
- (cond ((eq indent nil)
- (setq indent (current-indentation)))
- ((eq indent t)
- (setq indent (calculate-c-indent-within-comment)))
- ((looking-at "[ \t]*#")
- (setq indent 0))
- (t
- (skip-chars-forward " \t")
- (if (listp indent) (setq indent (car indent)))
- (cond ((or (looking-at c-switch-label-regexp)
- (and (looking-at "[A-Za-z]")
- (save-excursion
- (forward-sexp 1)
- (looking-at ":"))))
- (setq indent (max 1 (+ indent c-label-offset))))
- ((and (looking-at "else\\b")
- (not (looking-at "else\\s_")))
- (setq indent (save-excursion
- (c-backward-to-start-of-if)
- (current-indentation))))
- ((looking-at "}[ \t]*else")
- (setq indent (save-excursion
- (forward-char)
- (backward-sexp)
- (c-backward-to-start-of-if)
- (current-indentation))))
- ((and (looking-at "while\\b")
- (save-excursion
- (c-backward-to-start-of-do)))
- ;; This is a `while' that ends a do-while.
- (setq indent (save-excursion
- (c-backward-to-start-of-do)
- (current-indentation))))
- ((= (following-char) ?})
- (setq indent (- indent c-indent-level)))
- ((= (following-char) ?{)
- (setq indent (+ indent c-brace-offset))))))
- (skip-chars-forward " \t")
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- (delete-region beg (point))
- (indent-to indent)
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos))))
- shift-amt))
-
-(defun calculate-c-indent (&optional parse-start)
- "Return appropriate indentation for current line as C code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment."
- (save-excursion
- (beginning-of-line)
- (let ((indent-point (point))
- (case-fold-search nil)
- state
- containing-sexp)
- (if parse-start
- (goto-char parse-start)
- (beginning-of-defun))
- (while (< (point) indent-point)
- (setq parse-start (point))
- (setq state (parse-partial-sexp (point) indent-point 0))
- (setq containing-sexp (car (cdr state))))
- (cond ((or (nth 3 state) (nth 4 state))
- ;; return nil or t if should not change this line
- (nth 4 state))
- ((null containing-sexp)
- ;; Line is at top level. May be data or function definition,
- ;; or may be function argument declaration.
- ;; Indent like the previous top level line
- ;; unless that ends in a closeparen without semicolon,
- ;; in which case this line is the first argument decl.
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (if (= (following-char) ?{)
- 0 ; Unless it starts a function body
- (c-backward-to-noncomment (or parse-start (point-min)))
- ;; Look at previous line that's at column 0
- ;; to determine whether we are in top-level decls
- ;; or function's arg decls. Set basic-indent accordingly.
- (let ((basic-indent
- (save-excursion
- (re-search-backward "^[^ \^L\t\n#]" nil 'move)
- (let (comment lim)
- ;; Recognize the DEFUN macro in Emacs.
- (if (save-excursion
- ;; Move down to the (putative) argnames line.
- (while (and (not (eobp))
- (not (looking-at " *[({}#/]")))
- (forward-line 1))
- ;; Go back to the DEFUN, if it is one.
- (condition-case nil
- (backward-sexp 1)
- (error))
- (beginning-of-line)
- (looking-at "DEFUN\\b"))
- c-argdecl-indent
- (if (and (looking-at "\\sw\\|\\s_")
- ;; This is careful to stop at the first
- ;; paren if we have
- ;; int foo Proto ((int, int));
- (looking-at "[^\"\n=(]*(")
- (progn
- (goto-char (1- (match-end 0)))
- (setq lim (point))
- (condition-case nil
- (forward-sexp 1)
- (error))
- (skip-chars-forward " \t\f")
- (and (< (point) indent-point)
- (not (memq (following-char)
- '(?\, ?\;)))))
- ;; Make sure the "function decl" we found
- ;; is not inside a comment.
- (progn
- ;; Move back to the `(' starting arglist
- (goto-char lim)
- (beginning-of-line)
- (while (and (not comment)
- (search-forward "/*" lim t))
- (setq comment
- (not (search-forward "*/" lim t))))
- (not comment)))
- c-argdecl-indent 0))))))
- basic-indent)))
-
-;; ;; Now add a little if this is a continuation line.
-;; (+ basic-indent (if (or (bobp)
-;; (memq (preceding-char) '(?\) ?\; ?\}))
-;; ;; Line with zero indentation
-;; ;; is probably the return-type
-;; ;; of a function definition,
-;; ;; so following line is function name.
-;; (= (current-indentation) 0))
-;; 0 c-continued-statement-offset))
-
- ((/= (char-after containing-sexp) ?{)
- ;; line is expression, not statement:
- ;; indent to just after the surrounding open.
- (goto-char (1+ containing-sexp))
- (current-column))
- (t
- ;; Statement level. Is it a continuation or a new statement?
- ;; Find previous non-comment character.
- (goto-char indent-point)
- (c-backward-to-noncomment containing-sexp)
- ;; Back up over label lines, since they don't
- ;; affect whether our line is a continuation.
- (while (or (eq (preceding-char) ?\,)
- (and (eq (preceding-char) ?:)
- (or (eq (char-after (- (point) 2)) ?\')
- (memq (char-syntax (char-after (- (point) 2)))
- '(?w ?_)))))
- (if (eq (preceding-char) ?\,)
- (progn (forward-char -1)
- (c-backward-to-start-of-continued-exp containing-sexp)))
- (beginning-of-line)
- (c-backward-to-noncomment containing-sexp))
- ;; Check for a preprocessor statement or its continuation lines.
- ;; Move back to end of previous non-preprocessor line,
- ;; or possibly beginning of buffer.
- (let ((found (point)) stop)
- (while (not stop)
- (beginning-of-line)
- (cond ((bobp)
- (setq found (point)
- stop t))
- ((save-excursion (forward-char -1)
- (= (preceding-char) ?\\))
- (forward-char -1))
- ;; This line is not preceded by a backslash.
- ;; So either it starts a preprocessor command
- ;; or any following continuation lines
- ;; should not be skipped.
- ((= (following-char) ?#)
- (forward-char -1)
- (setq found (point)))
- (t (setq stop t))))
- (goto-char found))
- ;; Now we get the answer.
- (if (and (not (memq (preceding-char) '(0 ?\, ?\; ?\} ?\{)))
- ;; But don't treat a line with a close-brace
- ;; as a continuation. It is probably the
- ;; end of an enum type declaration.
- (save-excursion
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (not (= (following-char) ?}))))
- ;; This line is continuation of preceding line's statement;
- ;; indent c-continued-statement-offset more than the
- ;; previous line of the statement.
- (progn
- (c-backward-to-start-of-continued-exp containing-sexp)
- (+ c-continued-statement-offset (current-column)
- (if (save-excursion (goto-char indent-point)
- (skip-chars-forward " \t")
- (eq (following-char) ?{))
- c-continued-brace-offset 0)))
- ;; This line starts a new statement.
- ;; Position following last unclosed open.
- (goto-char containing-sexp)
- ;; Is line first statement after an open-brace?
- (or
- ;; If no, find that first statement and indent like it.
- (save-excursion
- (forward-char 1)
- (let ((colon-line-end 0))
- (while (progn (skip-chars-forward " \t\n")
- (looking-at "#\\|/\\*\\|case[ \t\n'/(].*:\\|[a-zA-Z0-9_$]*:"))
- ;; Skip over comments and labels following openbrace.
- (cond ((= (following-char) ?\#)
- (forward-line 1))
- ((= (following-char) ?\/)
- (forward-char 2)
- (search-forward "*/" nil 'move))
- ;; case or label:
- (t
- (save-excursion (end-of-line)
- (setq colon-line-end (point)))
- (search-forward ":"))))
- ;; The first following code counts
- ;; if it is before the line we want to indent.
- (and (< (point) indent-point)
- (-
- (if (> colon-line-end (point))
- (- (current-indentation) c-label-offset)
- (current-column))
- ;; If prev stmt starts with open-brace, that
- ;; open brace was offset by c-brace-offset.
- ;; Compensate to get the column where
- ;; an ordinary statement would start.
- (if (= (following-char) ?\{) c-brace-offset 0)))))
- ;; If no previous statement,
- ;; indent it relative to line brace is on.
- ;; For open brace in column zero, don't let statement
- ;; start there too. If c-indent-level is zero,
- ;; use c-brace-offset + c-continued-statement-offset instead.
- ;; For open-braces not the first thing in a line,
- ;; add in c-brace-imaginary-offset.
- (+ (if (and (bolp) (zerop c-indent-level))
- (+ c-brace-offset c-continued-statement-offset)
- c-indent-level)
- ;; Move back over whitespace before the openbrace.
- ;; If openbrace is not first nonwhite thing on the line,
- ;; add the c-brace-imaginary-offset.
- (progn (skip-chars-backward " \t")
- (if (bolp) 0 c-brace-imaginary-offset))
- ;; If the openbrace is preceded by a parenthesized exp,
- ;; move to the beginning of that;
- ;; possibly a different line
- (progn
- (if (eq (preceding-char) ?\))
- (forward-sexp -1))
- ;; Get initial indentation of the line we are on.
- (current-indentation))))))))))
-
-(defun calculate-c-indent-within-comment (&optional after-star)
- "Return the indentation amount for line inside a block comment.
-Optional arg AFTER-STAR means, if lines in the comment have a leading star,
-return the indentation of the text that would follow this star."
- (let (end star-start)
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (setq star-start (= (following-char) ?\*))
- (skip-chars-backward " \t\n")
- (setq end (point))
- (beginning-of-line)
- (skip-chars-forward " \t")
- (if after-star
- (and (looking-at "\\*")
- (re-search-forward "\\*[ \t]*")))
- (and (re-search-forward "/\\*[ \t]*" end t)
- star-start
- (not after-star)
- (goto-char (1+ (match-beginning 0))))
- (if (and (looking-at "[ \t]*$") (= (preceding-char) ?\*))
- (1+ (current-column))
- (current-column)))))
-
-
-(defun c-backward-to-noncomment (lim)
- (let (opoint stop)
- (while (not stop)
- (skip-chars-backward " \t\n\f" lim)
- (setq opoint (point))
- (if (and (>= (point) (+ 2 lim))
- (save-excursion
- (forward-char -2)
- (looking-at "\\*/")))
- (search-backward "/*" lim 'move)
- (setq stop (or (<= (point) lim)
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (not (looking-at "#")))))
- (or stop (beginning-of-line))))))
-
-(defun c-backward-to-start-of-continued-exp (lim)
- (if (memq (preceding-char) '(?\) ?\"))
- (forward-sexp -1))
- (beginning-of-line)
- (if (<= (point) lim)
- (goto-char (1+ lim)))
- (skip-chars-forward " \t"))
-
-(defun c-backward-to-start-of-if (&optional limit)
- "Move to the start of the last \"unbalanced\" `if'."
- (or limit (setq limit (save-excursion (beginning-of-defun) (point))))
- (let ((if-level 1)
- (case-fold-search nil))
- (while (and (not (bobp)) (not (zerop if-level)))
- (backward-sexp 1)
- (cond ((looking-at "else\\b")
- (setq if-level (1+ if-level)))
- ((looking-at "if\\b")
- (setq if-level (1- if-level)))
- ((< (point) limit)
- (setq if-level 0)
- (goto-char limit))))))
-
-(defun c-backward-to-start-of-do (&optional limit)
- "If point follows a `do' statement, move to beginning of it and return t.
-Otherwise return nil and don't move point."
- (or limit (setq limit (save-excursion (beginning-of-defun) (point))))
- (let ((first t)
- (startpos (point))
- (done nil))
- (while (not done)
- (let ((next-start (point)))
- (condition-case nil
- ;; Move back one token or one brace or paren group.
- (backward-sexp 1)
- ;; If we find an open-brace, we lose.
- (error (setq done 'fail)))
- (if done
- nil
- ;; If we reached a `do', we win.
- (if (looking-at "do\\b")
- (setq done 'succeed)
- ;; Otherwise, if we skipped a semicolon, we lose.
- ;; (Exception: we can skip one semicolon before getting
- ;; to a the last token of the statement, unless that token
- ;; is a close brace.)
- (if (save-excursion
- (forward-sexp 1)
- (or (and (not first) (= (preceding-char) ?}))
- (search-forward ";" next-start t
- (if (and first
- (/= (preceding-char) ?}))
- 2 1))))
- (setq done 'fail)
- (setq first nil)
- ;; If we go too far back in the buffer, we lose.
- (if (< (point) limit)
- (setq done 'fail)))))))
- (if (eq done 'succeed)
- t
- (goto-char startpos)
- nil)))
-
-(defun c-beginning-of-statement (count)
- "Go to the beginning of the innermost C statement.
-With prefix arg, go back N - 1 statements. If already at the beginning of a
-statement then go to the beginning of the preceding one.
-If within a string or comment, or next to a comment (only whitespace between),
-move by sentences instead of statements."
- (interactive "p")
- (let ((here (point)) state)
- (save-excursion
- (beginning-of-defun)
- (setq state (parse-partial-sexp (point) here nil nil)))
- (if (or (nth 3 state) (nth 4 state)
- (looking-at (concat "[ \t]*" comment-start-skip))
- (save-excursion (skip-chars-backward " \t")
- (goto-char (- (point) 2))
- (looking-at "\\*/")))
- (forward-sentence (- count))
- (while (> count 0)
- (c-beginning-of-statement-1)
- (setq count (1- count)))
- (while (< count 0)
- (c-end-of-statement-1)
- (setq count (1+ count))))))
-
-(defun c-end-of-statement (count)
- "Go to the end of the innermost C statement.
-With prefix arg, go forward N - 1 statements.
-Move forward to end of the next statement if already at end.
-If within a string or comment, move by sentences instead of statements."
- (interactive "p")
- (c-beginning-of-statement (- count)))
-
-(defun c-beginning-of-statement-1 ()
- (let ((last-begin (point))
- (first t))
- (condition-case ()
- (progn
- (while (and (not (bobp))
- (progn
- (backward-sexp 1)
- (or first
- (not (re-search-forward "[;{}]" last-begin t)))))
- (setq last-begin (point) first nil))
- (goto-char last-begin))
- (error (if first (backward-up-list 1) (goto-char last-begin))))))
-
-(defun c-end-of-statement-1 ()
- (condition-case ()
- (progn
- (while (and (not (eobp))
- (let ((beg (point)))
- (forward-sexp 1)
- (let ((end (point)))
- (save-excursion
- (goto-char beg)
- (not (re-search-forward "[;{}]" end t)))))))
- (re-search-backward "[;}]")
- (forward-char 1))
- (error
- (let ((beg (point)))
- (backward-up-list -1)
- (let ((end (point)))
- (goto-char beg)
- (search-forward ";" end 'move))))))
-
-(defun mark-c-function ()
- "Put mark at end of C function, point at beginning."
- (interactive)
- (push-mark (point))
- (end-of-defun)
- (push-mark (point) nil t)
- (beginning-of-defun)
- (backward-paragraph))
-
-;; Idea of ENDPOS is, indent each line, stopping when
-;; ENDPOS is encountered. But it's too much of a pain to make that work.
-(defun indent-c-exp (&optional endpos)
- "Indent each line of the C grouping following point."
- (interactive)
- (let* ((indent-stack (list nil))
- (opoint (point)) ;; May be altered below.
- (contain-stack
- (list (if endpos
- (let (funbeg)
- ;; Find previous fcn-start.
- (save-excursion (forward-char 1)
- (beginning-of-defun)
- (setq funbeg (point)))
- (setq opoint funbeg)
- ;; Try to find containing open,
- ;; but don't scan past that fcn-start.
- (save-restriction
- (narrow-to-region funbeg (point))
- (condition-case nil
- (save-excursion
- (backward-up-list 1)
- (point))
- ;; We gave up: must be between fcns.
- ;; Set opoint to beg of prev fcn
- ;; since otherwise calculate-c-indent
- ;; will get wrong answers.
- (error (setq opoint funbeg)
- (point)))))
- (point))))
- (case-fold-search nil)
- restart outer-loop-done inner-loop-done state ostate
- this-indent last-sexp
- at-else at-brace at-while
- last-depth this-point
- (next-depth 0))
- ;; If the braces don't match, get an error right away.
- (save-excursion
- (forward-sexp 1))
- ;; Realign the comment on the first line, even though we don't reindent it.
- (save-excursion
- (let ((beg (point)))
- (and (re-search-forward
- comment-start-skip
- (save-excursion (end-of-line) (point)) t)
- ;; Make sure this isn't a comment alone on a line
- ;; (which should be indented like code instead).
- (save-excursion
- (goto-char (match-beginning 0))
- (skip-chars-backward " \t")
- (not (bolp)))
- ;; Make sure the comment starter we found
- ;; is not actually in a string or quoted.
- (let ((new-state
- (parse-partial-sexp beg (point)
- nil nil state)))
- (and (not (nth 3 new-state)) (not (nth 5 new-state))))
- (progn (indent-for-comment) (beginning-of-line)))))
- (save-excursion
- (setq outer-loop-done nil)
- (while (and (not (eobp))
- (if endpos (< (point) endpos)
- (not outer-loop-done)))
- (setq last-depth next-depth)
- ;; Compute how depth changes over this line
- ;; plus enough other lines to get to one that
- ;; does not end inside a comment or string.
- ;; Meanwhile, do appropriate indentation on comment lines.
- (setq inner-loop-done nil)
- (while (and (not inner-loop-done)
- (not (and (eobp) (setq outer-loop-done t))))
- (setq ostate state)
- (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
- nil nil state))
- (setq next-depth (car state))
- (if (and (car (cdr (cdr state)))
- (>= (car (cdr (cdr state))) 0))
- (setq last-sexp (car (cdr (cdr state)))))
- ;; If this line started within a comment, indent it as such.
- (if (or (nth 4 ostate) (nth 7 ostate))
- (c-indent-line))
- ;; If it ends outside of comments or strings, exit the inner loop.
- ;; Otherwise move on to next line.
- (if (or (nth 3 state) (nth 4 state) (nth 7 state))
- (forward-line 1)
- (setq inner-loop-done t)))
- (and endpos
- (while (< next-depth 0)
- (setq indent-stack (append indent-stack (list nil)))
- (setq contain-stack (append contain-stack (list nil)))
- (setq next-depth (1+ next-depth))
- (setq last-depth (1+ last-depth))
- (setcar (nthcdr 6 state) (1+ (nth 6 state)))))
- (setq outer-loop-done (and (not endpos) (<= next-depth 0)))
- (if outer-loop-done
- nil
- ;; If this line had ..))) (((.. in it, pop out of the levels
- ;; that ended anywhere in this line, even if the final depth
- ;; doesn't indicate that they ended.
- (while (> last-depth (nth 6 state))
- (setq indent-stack (cdr indent-stack)
- contain-stack (cdr contain-stack)
- last-depth (1- last-depth)))
- (if (/= last-depth next-depth)
- (setq last-sexp nil))
- ;; Add levels for any parens that were started in this line.
- (while (< last-depth next-depth)
- (setq indent-stack (cons nil indent-stack)
- contain-stack (cons nil contain-stack)
- last-depth (1+ last-depth)))
- (if (null (car contain-stack))
- (setcar contain-stack (or (car (cdr state))
- (save-excursion (forward-sexp -1)
- (point)))))
- (forward-line 1)
- (skip-chars-forward " \t")
- ;; Don't really reindent if the line is just whitespace,
- ;; or if it is past the endpos.
- ;; (The exit test in the outer while
- ;; does not exit until we have passed the first line
- ;; past the region.)
- (if (or (eolp) (and endpos (>= (point) endpos)))
- nil
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- ;; Line is on an existing nesting level.
- ;; Lines inside parens are handled specially.
- (if (/= (char-after (car contain-stack)) ?{)
- (setq this-indent (car indent-stack))
- ;; Line is at statement level.
- ;; Is it a new statement? Is it an else?
- ;; Find last non-comment character before this line
- (save-excursion
- (setq this-point (point))
- (setq at-else (looking-at "else\\W"))
- (setq at-brace (= (following-char) ?{))
- (setq at-while (looking-at "while\\b"))
- (if (= (following-char) ?})
- (setq this-indent (car indent-stack))
- (c-backward-to-noncomment opoint)
- (if (not (memq (preceding-char) '(0 ?\, ?\; ?} ?: ?{)))
- ;; Preceding line did not end in comma or semi;
- ;; indent this line c-continued-statement-offset
- ;; more than previous.
- (progn
- (c-backward-to-start-of-continued-exp (car contain-stack))
- (setq this-indent
- (+ c-continued-statement-offset (current-column)
- (if at-brace c-continued-brace-offset 0))))
- ;; Preceding line ended in comma or semi;
- ;; use the standard indent for this level.
- (cond (at-else (progn (c-backward-to-start-of-if opoint)
- (setq this-indent
- (current-indentation))))
- ((and at-while (c-backward-to-start-of-do opoint))
- (setq this-indent (current-indentation)))
- ((eq (preceding-char) ?\,)
- (goto-char this-point)
- (setq this-indent (calculate-c-indent)))
- (t (setq this-indent (car indent-stack))))))))
- ;; Just started a new nesting level.
- ;; Compute the standard indent for this level.
- (let ((val (calculate-c-indent
- (if (car indent-stack)
- (- (car indent-stack))
- opoint))))
- ;; t means we are in a block comment and should
- ;; calculate accordingly.
- (if (eq val t)
- (setq val (calculate-c-indent-within-comment)))
- (setcar indent-stack
- (setq this-indent val))))
- ;; Adjust line indentation according to its contents
- (if (or (looking-at c-switch-label-regexp)
- (and (looking-at "[A-Za-z]")
- (save-excursion
- (forward-sexp 1)
- (looking-at ":"))))
- (setq this-indent (max 1 (+ this-indent c-label-offset))))
- (if (= (following-char) ?})
- (setq this-indent (- this-indent c-indent-level)))
- (if (= (following-char) ?{)
- ;; Don't move an open-brace in column 0.
- ;; This is good when constructs such as
- ;; `extern "C" {' surround a function definition
- ;; that should be indented as usual.
- ;; It is also good for nested functions.
- ;; It is bad when an open-brace is indented at column 0
- ;; and you want to fix that, but we can't win 'em all.
- (if (zerop (current-column))
- (setq this-indent 0)
- (setq this-indent (+ this-indent c-brace-offset))))
- ;; Don't leave indentation in empty lines.
- (if (eolp) (setq this-indent 0))
- ;; Put chosen indentation into effect.
- (or (= (current-column) this-indent)
- (= (following-char) ?\#)
- (progn
- (delete-region (point) (progn (beginning-of-line) (point)))
- (indent-to this-indent)))
- ;; Indent any comment following the text.
- (or (looking-at comment-start-skip)
- (let ((beg (point)))
- (and (re-search-forward
- comment-start-skip
- (save-excursion (end-of-line) (point)) t)
- ;; Make sure the comment starter we found
- ;; is not actually in a string or quoted.
- (let ((new-state
- (parse-partial-sexp beg (point)
- nil nil state)))
- (and (not (nth 3 new-state)) (not (nth 5 new-state))))
- (progn (indent-for-comment) (beginning-of-line)))))))))))
-
-;; Look at all comment-start strings in the current line after point.
-;; Return t if one of them starts a real comment.
-;; This is not used yet, because indent-for-comment
-;; isn't smart enough to handle the cases this can find.
-(defun indent-c-find-real-comment ()
- (let (win)
- (while (and (not win)
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line) (point))
- t))
- ;; Make sure the comment start is not quoted.
- (let ((state-1
- (parse-partial-sexp
- (save-excursion (beginning-of-line) (point))
- (point) nil nil state)))
- (setq win (and (null (nth 3 state-1)) (null (nth 5 state-1))))))
- win))
-
-;; Indent every line whose first char is between START and END inclusive.
-(defun c-indent-region (start end)
- (save-excursion
- (goto-char start)
- ;; Advance to first nonblank line.
- (skip-chars-forward " \t\n")
- (beginning-of-line)
- (let ((endmark (copy-marker end))
- (c-tab-always-indent t))
- (while (and (bolp) (not (eobp)) (< (point) endmark))
- ;; Indent one line as with TAB.
- (let ((shift-amt (c-indent-line))
- nextline sexpbeg sexpend)
- (if (save-excursion (beginning-of-line) (looking-at "[ \t]*#"))
- (forward-line 1)
- (save-excursion
- ;; Find beginning of following line.
- (save-excursion
- (forward-line 1) (setq nextline (point)))
- ;; Find first beginning-of-sexp for sexp extending past this line.
- (beginning-of-line)
- (while (< (point) nextline)
- (condition-case nil
- (progn
- (forward-sexp 1)
- (setq sexpend (point-marker)))
- (error (setq sexpend nil)
- (goto-char nextline)))
- (skip-chars-forward " \t\n"))
- (if sexpend
- (progn
- ;; Make sure the sexp we found really starts on the
- ;; current line and extends past it.
- (goto-char sexpend)
- (backward-sexp 1)
- (setq sexpbeg (point)))))
- ;; If that sexp ends within the region,
- ;; indent it all at once, fast.
- (if (and sexpend (> sexpend nextline) (<= sexpend endmark)
- (< sexpbeg nextline))
- (progn
- (indent-c-exp)
- (goto-char sexpend)))
- ;; Move to following line and try again.
- (and sexpend (set-marker sexpend nil))
- (forward-line 1))))
- (set-marker endmark nil))))
-
-(defun set-c-style (style &optional global)
- "Set C-mode variables to use one of several different indentation styles.
-The arguments are a string representing the desired style
-and a flag which, if non-nil, means to set the style globally.
-\(Interactively, the flag comes from the prefix argument.)
-Available styles are GNU, K&R, BSD and Whitesmith."
- (interactive (list (completing-read "Use which C indentation style? "
- c-style-alist nil t)
- current-prefix-arg))
- (let ((vars (cdr (assoc style c-style-alist))))
- (or vars
- (error "Invalid C indentation style `%s'" style))
- (while vars
- (or global
- (make-local-variable (car (car vars))))
- (set (car (car vars)) (cdr (car vars)))
- (setq vars (cdr vars)))))
-
-;;; This page handles insertion and removal of backslashes for C macros.
-
-(defvar c-backslash-column 48
- "*Minimum column for end-of-line backslashes of macro definitions.")
-
-(defun c-backslash-region (from to delete-flag)
- "Insert, align, or delete end-of-line backslashes on the lines in the region.
-With no argument, inserts backslashes and aligns existing backslashes.
-With an argument, deletes the backslashes.
-
-This function does not modify the last line of the region if the region ends
-right at the start of the following line; it does not modify blank lines
-at the start of the region. So you can put the region around an entire macro
-definition and conveniently use this command."
- (interactive "r\nP")
- (save-excursion
- (goto-char from)
- (let ((column c-backslash-column)
- (endmark (make-marker)))
- (move-marker endmark to)
- ;; Compute the smallest column number past the ends of all the lines.
- (if (not delete-flag)
- (while (< (point) to)
- (end-of-line)
- (if (= (preceding-char) ?\\)
- (progn (forward-char -1)
- (skip-chars-backward " \t")))
- (setq column (max column (1+ (current-column))))
- (forward-line 1)))
- ;; Adjust upward to a tab column, if that doesn't push past the margin.
- (if (> (% column tab-width) 0)
- (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
- (if (< adjusted (window-width))
- (setq column adjusted))))
- ;; Don't modify blank lines at start of region.
- (goto-char from)
- (while (and (< (point) endmark) (eolp))
- (forward-line 1))
- ;; Add or remove backslashes on all the lines.
- (while (and (< (point) endmark)
- ;; Don't backslashify the last line
- ;; if the region ends right at the start of the next line.
- (save-excursion
- (forward-line 1)
- (< (point) endmark)))
- (if (not delete-flag)
- (c-append-backslash column)
- (c-delete-backslash))
- (forward-line 1))
- (move-marker endmark nil))))
-
-(defun c-append-backslash (column)
- (end-of-line)
- ;; Note that "\\\\" is needed to get one backslash.
- (if (= (preceding-char) ?\\)
- (progn (forward-char -1)
- (delete-horizontal-space)
- (indent-to column))
- (indent-to column)
- (insert "\\")))
-
-(defun c-delete-backslash ()
- (end-of-line)
- (or (bolp)
- (progn
- (forward-char -1)
- (if (looking-at "\\\\")
- (delete-region (1+ (point))
- (progn (skip-chars-backward " \t") (point)))))))
-
-(defun c-up-conditional (count)
- "Move back to the containing preprocessor conditional, leaving mark behind.
-A prefix argument acts as a repeat count. With a negative argument,
-move forward to the end of the containing preprocessor conditional.
-When going backwards, `#elif' is treated like `#else' followed by `#if'.
-When going forwards, `#elif' is ignored."
- (interactive "p")
- (c-forward-conditional (- count) t))
-
-(defun c-backward-conditional (count &optional up-flag)
- "Move back across a preprocessor conditional, leaving mark behind.
-A prefix argument acts as a repeat count. With a negative argument,
-move forward across a preprocessor conditional."
- (interactive "p")
- (c-forward-conditional (- count) up-flag))
-
-(defun c-forward-conditional (count &optional up-flag)
- "Move forward across a preprocessor conditional, leaving mark behind.
-A prefix argument acts as a repeat count. With a negative argument,
-move backward across a preprocessor conditional."
- (interactive "p")
- (let* ((forward (> count 0))
- (increment (if forward -1 1))
- (search-function (if forward 're-search-forward 're-search-backward))
- (opoint (point))
- (new))
- (save-excursion
- (while (/= count 0)
- (let ((depth (if up-flag 0 -1)) found)
- (save-excursion
- ;; Find the "next" significant line in the proper direction.
- (while (and (not found)
- ;; Rather than searching for a # sign that comes
- ;; at the beginning of a line aside from whitespace,
- ;; search first for a string starting with # sign.
- ;; Then verify what precedes it.
- ;; This is faster on account of the fastmap feature of
- ;; the regexp matcher.
- (funcall search-function
- "#[ \t]*\\(if\\|elif\\|endif\\)"
- nil t))
- (beginning-of-line)
- ;; Now verify it is really a preproc line.
- (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
- (let ((prev depth))
- ;; Update depth according to what we found.
- (beginning-of-line)
- (cond ((looking-at "[ \t]*#[ \t]*endif")
- (setq depth (+ depth increment)))
- ((looking-at "[ \t]*#[ \t]*elif")
- (if (and forward (= depth 0))
- (setq found (point))))
- (t (setq depth (- depth increment))))
- ;; If we are trying to move across, and we find
- ;; an end before we find a beginning, get an error.
- (if (and (< prev 0) (< depth prev))
- (error (if forward
- "No following conditional at this level"
- "No previous conditional at this level")))
- ;; When searching forward, start from next line
- ;; so that we don't find the same line again.
- (if forward (forward-line 1))
- ;; If this line exits a level of conditional, exit inner loop.
- (if (< depth 0)
- (setq found (point)))))))
- (or found
- (error "No containing preprocessor conditional"))
- (goto-char (setq new found)))
- (setq count (+ count increment))))
- (push-mark)
- (goto-char new)))
-
-;;; c-mode.el ends here
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
deleted file mode 100644
index e82940d2d44..00000000000
--- a/lisp/progmodes/cmacexp.el
+++ /dev/null
@@ -1,443 +0,0 @@
-;;; cmacexp.el --- expand C macros in a region
-
-;; Copyright (C) 1992 Free Software Foundation, Inc.
-
-;; Author: Francesco Potorti` <pot@cnuce.cnr.it>
-;; Version: $Id: cmacexp.el,v 1.9 1994/02/07 05:40:46 rms Exp rms $
-;; Adapted-By: ESR
-;; Keywords: c
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; In C mode C-M-x is bound to c-macro-expand. The result of the
-;; expansion is put in a separate buffer. A user option
-;; allows the window displaying the buffer to be optimally sized.
-;;
-;; When called with a C-u prefix, c-macro-expand replaces the selected
-;; region with the expansion. With two C-u's the user is offered to
-;; change the flags to the preprocessor (while the results of the
-;; expansion go to a separate buffer). Preprocessor arguments default
-;; to the last ones entered. Both the preprocessor name and the
-;; initial flag defaults can be set by the user. Setting
-;; c-macro-always-prompt to a non-nil value allows one to be always
-;; prompted for the flags, regardless of the prefix used.
-
-;; A c-macro-expansion function is provided for non-interactive use.
-;; A still experimental function c-macro-eval is provided. It aims at
-;; evaluating the contents of a region by using calc (by Dave
-;; Gillespie). Select a region and type C-x C-e (if you followed the
-;; suggestions in the INSTALLATION section) or type M-x c-ma RET v
-;; RET. If you have calc installed, the computed value of the
-;; expression will appear in the message area. If you give an
-;; interactive C-u prefix the computed value will be shown in signed,
-;; unsigned, hex and boolean representations. Two C-u's allow to
-;; change the preprocessor flags via prompt. c-macro-eval works well
-;; for constant expressions, but see the BUG section.
-
-;; A patch to calc 2.02 has been written by Dave Gillespie. It can
-;; be downloaded via anonymous ftp at fly.cnuce.cnr.it:pub/calc.diff.
-
-;; INSTALLATION ======================================================
-
-;; Put this file on your load-path, byte compile it for increased
-;; speed and put part or all of the following in your ~/.emacs file.
-
-;; To make a directory ~/emacs be in front of your load-path:
-;;(setq load-path (cons (expand-file-name "~/emacs") load-path))
-;;
-;; Suggested keybindings (work only in c-mode):
-;;(define-key c-mode-map "\C-\M-x" 'c-macro-expand)
-;;(define-key c-mode-map "\C-x\C-e" 'c-macro-eval)
-;;
-;; If you want the *Macroexpansion* window to be not higher than
-;; necessary:
-;;(setq c-macro-shrink-window-p t)
-;;
-;; If you use a preprocessor other than /lib/cpp (be careful to set a
-;; -C option or equivalent in order to make the preprocessor not to
-;; strip the comments):
-;;(setq c-macro-preprocessor "gpp -C")
-;;
-;; If you often use a particular set of flags, and want them to be
-;; the default:
-;;(setq c-macro-default-cppflags "-I /usr/include/local -DDEBUG"
-;;
-;; If you always want the "Preprocessor arguments: " prompt,
-;; regardless of the arguments provided:
-;;(setq c-macro-always-prompt-p t)
-;;
-;; If you want to experiment with the C constant expressions
-;; evaluation feature:
-;;(autoload 'c-macro-eval "cmacexp"
-;; "C constant expressions evaluation. Requires calc. Experimental." t)
-
-;; BUG REPORTS =======================================================
-
-;; Please report bugs, suggestions, complaints and so on to
-;; pot@cnuce.cnr.it (Francesco Potorti`).
-
-;; IMPROVEMENTS OVER emacs 18.xx cmacexp.el ==========================
-
-;; - A lot of user visible changes. See above.
-;; - #line directives are inserted, so __LINE__ and __FILE__ are
-;; correctly expanded. Works even with START inside a string, a
-;; comment or a region #ifdef'd away by cpp. cpp is invoked with -C,
-;; making comments visible in the expansion.
-;; - All work is done in core memory, no need for temporary files.
-;; - The /lib/cpp process is run synchronously. This fixes an
-;; infinite loop bug on Motorola Delta (cpp waiting forever for
-;; end-of-file, don't know why). Fixes a similar intermittent
-;; problem on SunOS 4.1.
-
-;; ACKNOWLEDGEMENTS ==================================================
-
-;; A lot of thanks to Don Maszle who did a great work of testing, bug
-;; reporting and suggestion of new features and to Dave Gillespie for
-;; his suggestions about calc. This work has been partially inspired by
-;; Don Maszle and Jonathan Segal's.
-
-;; BUGS ==============================================================
-
-;; calc 2.02 does not handle the C operators "->", ".", "*" (as a
-;; prefix), the composite assignement operators "+=" etc. It cannot
-;; handle the "," operator and will be confused by ";". Almost all
-;; these can be defined as no-ops using the Calc's Syntax Tables
-;; feature. The built-in calc functions will cause problems in
-;; certain circumstances. c-macro-eval behaves correctly only on
-;; expressions not containing such operators. Does not distinguish
-;; among integer and real division.
-
-;; If the start point of the region is inside a macro definition the
-;; macro expansion is often inaccurate.
-
-;;; Code:
-
-(defvar c-macro-shrink-window-p nil
- "*Non-nil means shrink the *Macroexpansion* window to fit its contents.")
-
-(defvar c-macro-always-prompt-p nil
- "*Non-nil means always prompt for preprocessor arguments.")
-
-(defvar c-macro-preprocessor "/lib/cpp -C" "\
-The preprocessor used by the cmacexp package.
-
-If you change this, be sure to preserve the -C (don't strip comments)
-option, or to set an equivalent one.")
-
-(defvar c-macro-default-cppflags ""
- "Default cpp flags used by c-macro-expand.")
-
-(defconst c-macro-buffer-name "*Macroexpansion*")
-
-(defun c-macro-expand (start end &optional flag) "\
-Expand all C macros occurring in the region using c-macro-preprocessor.
-Normally display output in temp buffer.
-Prefix arg means replace the region with it.
-Prompt for a string of arguments to the preprocessor, (e.g.
--DDEBUG -I ./include) when prefixed with two C-u's.
-
-It is intended for interactive use only.
-For non interactive use, see the c-macro-expansion function."
-
- (interactive "r\nP")
- (let* ((subst (and flag (not (equal flag '(16)))))
- (inbuf (current-buffer))
- (displaybuf (if subst
- (get-buffer c-macro-buffer-name)
- (get-buffer-create c-macro-buffer-name)))
- (expansion ""))
- ;; Build the command string.
- (if (or c-macro-always-prompt-p (equal flag '(16)))
- (setq c-macro-default-cppflags
- (read-string "Preprocessor arguments: "
- c-macro-default-cppflags)))
- ;; Decide where to display output.
- (if (and subst
- (and buffer-read-only (not inhibit-read-only))
- (not (eq inbuf displaybuf)))
- (progn
- (message
- "Buffer is read only: displaying expansion in alternate window")
- (sit-for 2)
- (setq subst nil)
- (or displaybuf
- (setq displaybuf (get-buffer-create c-macro-buffer-name)))))
- ;; Expand the macro and output it.
- (if (interactive-p) (message (c-macro-default-message)))
- (setq expansion
- (c-macro-expansion start end
- (concat c-macro-preprocessor " "
- c-macro-default-cppflags)))
- (message (concat (c-macro-default-message) "done"))
- (if subst
- (let ((exchange (= (point) start)))
- (delete-region start end)
- (insert expansion)
- (if exchange
- (exchange-point-and-mark)))
- (set-buffer displaybuf)
- (setq buffer-read-only nil)
- (buffer-flush-undo displaybuf)
- (erase-buffer)
- (insert expansion)
- (set-buffer-modified-p nil)
- (if (string= "" expansion)
- (message "Null expansion")
- (c-macro-display-buffer inbuf))
- (setq buffer-read-only t)
- (bury-buffer displaybuf))))
-
-
-;; Display the current buffer in a window which is either just large
-;; enough to contain the entire buffer, or half the size of the
-;; screen, whichever is smaller. Put the current buffer in view-mode
-;; if the Inge Frick's view-mode is installed, with buffer to return
-;; to set to RETBUF (if sensible). Do not select the new window.
-;;
-;; Several factors influence window resizing so that the window is
-;; sized optimally if it is created anew, and so that it is messed
-;; with minimally if it has been created by the user. If the window
-;; chosen for display exists already but contains something else, the
-;; window is not re-sized. If the window already contains the current
-;; buffer, it is never shrunk, but possibly expanded. Finally, if the
-;; variable c-macro-shrink-window-p is nil the window size is *never*
-;; changed.
-(defun c-macro-display-buffer (retbuf)
-
- (goto-char (point-min))
- (c-mode)
- (let ((oldwinheight (window-height))
- (alreadythere ;the window was already there
- (get-buffer-window (current-buffer)))
- (popped nil)) ;the window popped changing the layout
- (or alreadythere
- (progn
- (display-buffer (current-buffer) t)
- (setq popped (/= oldwinheight (window-height)))))
- (if (and c-macro-shrink-window-p ;user wants fancy shrinking :\)
- (or alreadythere popped))
- ;; Enlarge up to half screen, or shrink properly.
- (let ((oldwin (selected-window))
- (minheight 0)
- (maxheight 0))
- (save-excursion
- (select-window (get-buffer-window (current-buffer)))
- (setq minheight (if alreadythere
- (window-height)
- window-min-height))
- (setq maxheight (/ (screen-height) 2))
- (enlarge-window (- (min maxheight
- (max minheight
- (+ 2 (vertical-motion 1000000))))
- (window-height)))
- (goto-char (point-min))
- (select-window oldwin))))))
-
-
-(defun c-macro-expansion (start end cppcommand) "\
-Expands the region between START and END in the current buffer using
-the shell command CPPCOMMAND (e.g. \"/lib/cpp -C -DDEBUG\"). Be sure
-to use a -C (don't strip comments) or equivalent option.
-Returns the output as a string."
-
-;; Copy the current buffer's contents to a temporary hidden buffer.
-;; Delete from END to end of buffer. Insert a preprocessor #line
-;; directive at START and after each #endif following START that are
-;; not inside a comment or a string. Put all the strings thus
-;; inserted (without the "line" substring) in a list named linelist.
-;; If START is inside a comment, prepend "*/" and append "/*" to the
-;; #line directive. If inside a string, prepend and append "\"".
-;; Preprocess the buffer contents, then look for all the lines stored
-;; in linelist starting from end of buffer. The last line so found is
-;; where START was, so return the substring from point to end of
-;; buffer.
- (let ((inbuf (current-buffer))
- (outbuf (get-buffer-create " *C Macro Expansion*"))
- (filename (if (and buffer-file-name
- (string-match (regexp-quote default-directory)
- buffer-file-name))
- (substring buffer-file-name (match-end 0))
- (buffer-name)))
- (start-state)
- (linenum 0)
- (linelist ()))
- (unwind-protect
- (save-excursion
- (save-restriction
- (widen)
- (set-buffer outbuf)
- (setq buffer-read-only nil)
- (erase-buffer)
- (set-syntax-table c-mode-syntax-table)
- (insert-buffer-substring inbuf 1 end))
-
- ;; We have copied inbuf to outbuf. Point is at end of
- ;; outbuf. Insert a space at the end, so cpp can correctly
- ;; parse a token ending at END.
-
- (insert " ")
-
- (save-excursion
- (goto-char start)
- (setq start-state (parse-partial-sexp 1 (point))))
- ;; Now we insert the #line directives after all #endif or
- ;; #else following START.
- ;(switch-to-buffer outbuf) (debug) ;debugging instructions
- (while (re-search-backward "\n#\\(endif\\|else\\)\\>" start 'move)
- (if (equal (nthcdr 3 (parse-partial-sexp start (point) start-state))
- '(nil nil nil 0)) ;neither in string nor in
- ;comment nor after quote
- (progn
- (goto-char (match-end 0))
-;; (setq linenum (count-lines 1 (point)))
- (setq linelist
- ;; This used to be a #line command
- ;; but it's not guaranteed that the output
- ;; will have properly matching commands.
- ;; Only the *line numbers* have to agree!
- (cons (format "\n???!!!???!!!!\n")
- linelist))
- (insert (car linelist))
- (skip-chars-backward "^#")
- (insert "line")
- (goto-char (match-beginning 0)))))
-
- ;; We are at START. Insert the first #line directive. This
- ;; must work even inside a string or comment, or after a
- ;; quote.
-;;; (setq linenum (+ (count-lines 1 (point))
-;;; (if (bolp) 1 0)))
- (setq linelist
- (cons
- (let* ((startstat (parse-partial-sexp 1 start))
- (startinstring (nth 3 startstat))
- (startincomment (nth 4 startstat))
- (startafterquote (nth 5 startstat)))
- (concat (if startafterquote " ")
- (cond (startinstring "\"") (startincomment "*/"))
- (format "\n???!!!???!!!!")
- (cond (startinstring "\"") (startincomment "/*"))
- (if startafterquote "\\")))
- linelist))
- (insert (car linelist))
- (skip-chars-backward "^#")
- (insert "line")
-
- ;; Call the preprocessor.
- (call-process-region 1 (point-max) "sh" t t nil "-c"
- (concat cppcommand " 2>/dev/null"))
-
- (while (search-backward "\n???!!!???!!!!" nil t)
- (replace-match ""))
-
- ;; Compute the return value, keeping in account the space
- ;; inserted at the end of the buffer.
- (buffer-substring (point) (max (point) (- (point-max) 1))))
-
- ;; Cleanup.
- (kill-buffer outbuf))))
-
-
-;; Experimental. With an argument, print signed, unsigned, hex and
-;; boolean representations.
-(defun c-macro-eval (start end &optional flag) "\
-Expand region using cpp and evaluate it using calc.
-Interactively print value in minibuffer and push it on the kill ring.
-With a C-u argument shows the evaluation in a variety of formats.
-With two C-u's prompts the user for a string of flags to the preprocessor.
-
-Non interactively returns value of region between START and END
-as a string. Several formats are used if optional FLAG is non-nil."
-
- (interactive "r\nP")
- (or (fboundp 'calc-eval)
- (require 'calc))
- (if (or c-macro-always-prompt-p (equal flag '(16)))
- (setq c-macro-default-cppflags
- (read-string "Preprocessor arguments: "
- c-macro-default-cppflags)))
-
- ;; Expand the region.
- (if (interactive-p) (message (c-macro-default-message)))
- (let ((evaluation
- (c-macro-expansion start end
- (concat c-macro-preprocessor " "
- c-macro-default-cppflags)))
- (evalbuf (get-buffer-create " *Macro Evaluation*")))
- (unwind-protect
- (save-excursion
- (set-buffer evalbuf)
- (setq buffer-read-only nil)
- (erase-buffer)
- (insert evaluation)
-
- ;; Evaluate expression(s).
- (if (interactive-p)
- (message "Invoking calc..."))
- (setq evaluation
- (let ((calc-eval-error t))
- (calc-eval (list (buffer-string) 'calc-language 'c))))
- (erase-buffer)
- (cond
- (flag
- (insert (calc-eval (list evaluation
- 'calc-language 'c
- 'calc-simplify-mode 'binary))
- "(u)" " == "
- (calc-eval (list evaluation
- 'calc-language 'c
- 'calc-word-size (- calc-word-size)
- 'calc-simplify-mode 'binary))
- "(d)" " == "
- (calc-eval (list evaluation
- 'calc-language 'c
- 'calc-number-radix 16
- 'calc-simplify-mode 'binary))
- "(x)")
- (save-excursion
- (insert " == " (calc-eval (list evaluation
- 'calc-language 'c
- 'calc-number-radix 16
- 'calc-simplify-mode 'binary))))
- (while (re-search-forward "0x\\([^,]+\\)\\(, \\|\\'\\)" nil t)
- (if (string= "0"
- (buffer-substring (match-beginning 1)
- (match-end 1)))
- (replace-match "FALSE\\2")
- (replace-match "TRUE\\2"))))
- (t
- (insert evaluation)))
-
- ;; Output the evaluation.
- (if (interactive-p)
- (progn
- (copy-region-as-kill 1 (point-max))
- (message (buffer-string)))
- (buffer-string)))
- (kill-buffer evalbuf))))
-
-(defun c-macro-default-message ()
- (format "Invoking %s%s%s on region..."
- c-macro-preprocessor
- (if (string= "" c-macro-default-cppflags) "" " ")
- c-macro-default-cppflags))
-
-(provide 'cmacexp)
-
-;;; cmacexp.el ends here.
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
deleted file mode 100644
index 813412942d1..00000000000
--- a/lisp/progmodes/compile.el
+++ /dev/null
@@ -1,1307 +0,0 @@
-;;; compile.el --- run compiler as inferior of Emacs, parse error messages.
-
-;; Copyright (C) 1985, 86, 87, 93, 94 Free Software Foundation, Inc.
-
-;; Author: Roland McGrath <roland@prep.ai.mit.edu>
-;; Maintainer: FSF
-;; Keywords: tools, processes
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; This package provides the compile and grep facilities documented in
-;; the Emacs user's manual.
-
-;;; Code:
-
-;;;###autoload
-(defvar compilation-mode-hook nil
- "*List of hook functions run by `compilation-mode' (see `run-hooks').")
-
-;;;###autoload
-(defconst compilation-window-height nil
- "*Number of lines in a compilation window. If nil, use Emacs default.")
-
-(defvar compilation-error-list nil
- "List of error message descriptors for visiting erring functions.
-Each error descriptor is a cons (or nil). Its car is a marker pointing to
-an error message. If its cdr is a marker, it points to the text of the
-line the message is about. If its cdr is a cons, it is a list
-\(\(DIRECTORY . FILE\) LINE [COLUMN]\). Or its cdr may be nil if that
-error is not interesting.
-
-The value may be t instead of a list; this means that the buffer of
-error messages should be reparsed the next time the list of errors is wanted.
-
-Some other commands (like `diff') use this list to control the error
-message tracking facilites; if you change its structure, you should make
-sure you also change those packages. Perhaps it is better not to change
-it at all.")
-
-(defvar compilation-old-error-list nil
- "Value of `compilation-error-list' after errors were parsed.")
-
-(defvar compilation-parse-errors-function 'compilation-parse-errors
- "Function to call to parse error messages from a compilation.
-It takes args LIMIT-SEARCH and FIND-AT-LEAST.
-If LIMIT-SEARCH is non-nil, don't bother parsing past that location.
-If FIND-AT-LEAST is non-nil, don't bother parsing after finding that
-many new errors.
-It should read in the source files which have errors and set
-`compilation-error-list' to a list with an element for each error message
-found. See that variable for more info.")
-
-;;;###autoload
-(defvar compilation-buffer-name-function nil
- "Function to compute the name of a compilation buffer.
-The function receives one argument, the name of the major mode of the
-compilation buffer. It should return a string.
-nil means compute the name with `(concat \"*\" (downcase major-mode) \"*\")'.")
-
-;;;###autoload
-(defvar compilation-finish-function nil
- "*Function to call when a compilation process finishes.
-It is called with two arguments: the compilation buffer, and a string
-describing how the process finished.")
-
-(defvar compilation-last-buffer nil
- "The most recent compilation buffer.
-A buffer becomes most recent when its compilation is started
-or when it is used with \\[next-error] or \\[compile-goto-error].")
-
-(defvar compilation-in-progress nil
- "List of compilation processes now running.")
-(or (assq 'compilation-in-progress minor-mode-alist)
- (setq minor-mode-alist (cons '(compilation-in-progress " Compiling")
- minor-mode-alist)))
-
-(defvar compilation-parsing-end nil
- "Position of end of buffer when last error messages were parsed.")
-
-(defvar compilation-error-message "No more errors"
- "Message to print when no more matches are found.")
-
-(defvar compilation-num-errors-found)
-
-(defvar compilation-error-regexp-alist
- '(
- ;; NOTE! This first one is repeated in grep-regexp-alist, below.
-
- ;; 4.3BSD grep, cc, lint pass 1:
- ;; /usr/src/foo/foo.c(8): warning: w may be used before set
- ;; or GNU utilities:
- ;; foo.c:8: error message
- ;; or HP-UX 7.0 fc:
- ;; foo.f :16 some horrible error message
- ;;
- ;; We'll insist that the number be followed by a colon or closing
- ;; paren, because otherwise this matches just about anything
- ;; containing a number with spaces around it.
- ("\n\\([^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)[:) \t]" 1 2)
-
- ;; 4.3BSD lint pass 2
- ;; strcmp: variable # of args. llib-lc(359) :: /usr/src/foo/foo.c(8)
- ("[ \t:]\\([^:( \t\n]+\\)[:(](+[ \t]*\\([0-9]+\\))[:) \t]*$" 1 2)
-
- ;; 4.3BSD lint pass 3
- ;; bloofle defined( /users/wolfgang/foo.c(4) ), but never used
- ;; This used to be
- ;; ("[ \t(]+\\([^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]+" 1 2)
- ;; which is regexp Impressionism - it matches almost anything!
- ("([ \t]*\\([^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\))" 1 2)
-
- ;; Ultrix 3.0 f77:
- ;; Error on line 3 of t.f: Execution error unclassifiable statement
- ;; Unknown who does this:
- ;; Line 45 of "foo.c": bloofel undefined
- ;; Absoft FORTRAN 77 Compiler 3.1.3
- ;; error on line 19 of fplot.f: spelling error?
- ;; warning on line 17 of fplot.f: data type is undefined for variable d
- ("\\(\n\\|on \\)[Ll]ine[ \t]+\\([0-9]+\\)[ \t]+\
-of[ \t]+\"?\\([^\":\n]+\\)\"?:" 3 2)
-
- ;; Apollo cc, 4.3BSD fc:
- ;; "foo.f", line 3: Error: syntax error near end of statement
- ;; IBM RS6000:
- ;; "vvouch.c", line 19.5: 1506-046 (S) Syntax error.
- ;; Unknown compiler:
- ;; File "foobar.ml", lines 5-8, characters 20-155: blah blah
- ;; Microtec mcc68k:
- ;; "foo.c", line 32 pos 1; (E) syntax error; unexpected symbol: "lossage"
- ("\"\\([^,\" \n\t]+\\)\", lines? \\([0-9]+\\)[:., -]" 1 2)
-
- ;; MIPS RISC CC - the one distributed with Ultrix:
- ;; ccom: Error: foo.c, line 2: syntax error
- ;; DEC AXP OSF/1 cc
- ;; /usr/lib/cmplrs/cc/cfe: Error: foo.c: 1: blah blah
- ("rror: \\([^,\" \n\t]+\\)[,:] \\(line \\)?\\([0-9]+\\):" 1 3)
-
- ;; IBM AIX PS/2 C version 1.1:
- ;; ****** Error number 140 in line 8 of file errors.c ******
- ("in line \\([0-9]+\\) of file \\([^ \n]+[^. \n]\\)\\.? " 2 1)
- ;; IBM AIX lint is too painful to do right this way. File name
- ;; prefixes entire sections rather than being on each line.
-
- ;; Lucid Compiler, lcc 3.x
- ;; E, file.cc(35,52) Illegal operation on pointers
- ("[A-Z], \\([^(]*\\)(\\([0-9]+\\),[ \t]*\\([0-9]+\\)" 1 2 3)
-
- )
- "Alist that specifies how to match errors in compiler output.
-Each element has the form (REGEXP FILE-IDX LINE-IDX [COLUMN-IDX]).
-If REGEXP matches, the FILE-IDX'th subexpression gives the file name, and
-the LINE-IDX'th subexpression gives the line number. If COLUMN-IDX is
-given, the COLUMN-IDX'th subexpression gives the column number on that line.")
-
-(defvar compilation-read-command t
- "If not nil, M-x compile reads the compilation command to use.
-Otherwise, M-x compile just uses the value of `compile-command'.")
-
-(defvar compilation-ask-about-save t
- "If not nil, M-x compile asks which buffers to save before compiling.
-Otherwise, it saves all modified buffers without asking.")
-
-(defvar grep-regexp-alist
- '(("^\\([^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2))
- "Regexp used to match grep hits. See `compilation-error-regexp-alist'.")
-
-(defvar grep-command "grep -n "
- "Last grep command used in \\{grep}; default for next grep.")
-
-;;;###autoload
-(defvar compilation-search-path '(nil)
- "*List of directories to search for source files named in error messages.
-Elements should be directory names, not file names of directories.
-nil as an element means to try the default directory.")
-
-(defvar compile-command "make -k "
- "Last shell command used to do a compilation; default for next compilation.
-
-Sometimes it is useful for files to supply local values for this variable.
-You might also use mode hooks to specify it in certain modes, like this:
-
- (setq c-mode-hook
- '(lambda () (or (file-exists-p \"makefile\") (file-exists-p \"Makefile\")
- (progn (make-local-variable 'compile-command)
- (setq compile-command
- (concat \"make -k \"
- buffer-file-name))))))")
-
-(defconst compilation-enter-directory-regexp
- ": Entering directory `\\(.*\\)'$"
- "Regular expression matching lines that indicate a new current directory.
-This must contain one \\(, \\) pair around the directory name.
-
-The default value matches lines printed by the `-w' option of GNU Make.")
-
-(defconst compilation-leave-directory-regexp
- ": Leaving directory `\\(.*\\)'$"
- "Regular expression matching lines that indicate restoring current directory.
-This may contain one \\(, \\) pair around the name of the directory
-being moved from. If it does not, the last directory entered \(by a
-line matching `compilation-enter-directory-regexp'\) is assumed.
-
-The default value matches lines printed by the `-w' option of GNU Make.")
-
-(defvar compilation-directory-stack nil
- "Stack of previous directories for `compilation-leave-directory-regexp'.
-The head element is the directory the compilation was started in.")
-
-;; History of compile commands.
-(defvar compile-history nil)
-;; History of grep commands.
-(defvar grep-history nil)
-
-;;;###autoload
-(defun compile (command)
- "Compile the program including the current buffer. Default: run `make'.
-Runs COMMAND, a shell command, in a separate process asynchronously
-with output going to the buffer `*compilation*'.
-
-You can then use the command \\[next-error] to find the next error message
-and move to the source code that caused it.
-
-To run more than one compilation at once, start one and rename the
-\`*compilation*' buffer to some other name with \\[rename-buffer].
-Then start the next one.
-
-The name used for the buffer is actually whatever is returned by
-the function in `compilation-buffer-name-function', so you can set that
-to a function that generates a unique name."
- (interactive
- (if compilation-read-command
- (list (read-from-minibuffer "Compile command: "
- compile-command nil nil
- '(compile-history . 1)))
- (list compile-command)))
- (setq compile-command command)
- (save-some-buffers (not compilation-ask-about-save) nil)
- (compile-internal compile-command "No more errors"))
-
-;;;###autoload
-(defun grep (command-args)
- "Run grep, with user-specified args, and collect output in a buffer.
-While grep runs asynchronously, you can use the \\[next-error] command
-to find the text that grep hits refer to.
-
-This command uses a special history list for its arguments, so you can
-easily repeat a grep command."
- (interactive
- (list (read-from-minibuffer "Run grep (like this): "
- grep-command nil nil 'grep-history)))
- (compile-internal (concat command-args " /dev/null")
- "No more grep hits" "grep"
- ;; Give it a simpler regexp to match.
- nil grep-regexp-alist))
-
-(defun compile-internal (command error-message
- &optional name-of-mode parser regexp-alist
- name-function)
- "Run compilation command COMMAND (low level interface).
-ERROR-MESSAGE is a string to print if the user asks to see another error
-and there are no more errors. Third argument NAME-OF-MODE is the name
-to display as the major mode in the compilation buffer.
-
-Fourth arg PARSER is the error parser function (nil means the default). Fifth
-arg REGEXP-ALIST is the error message regexp alist to use (nil means the
-default). Sixth arg NAME-FUNCTION is a function called to name the buffer (nil
-means the default). The defaults for these variables are the global values of
-\`compilation-parse-errors-function', `compilation-error-regexp-alist', and
-\`compilation-buffer-name-function', respectively.
-
-Returns the compilation buffer created."
- (let (outbuf)
- (save-excursion
- (or name-of-mode
- (setq name-of-mode "Compilation"))
- (setq outbuf
- (get-buffer-create
- (funcall (or name-function compilation-buffer-name-function
- (function (lambda (mode)
- (concat "*" (downcase mode) "*"))))
- name-of-mode)))
- (set-buffer outbuf)
- (let ((comp-proc (get-buffer-process (current-buffer))))
- (if comp-proc
- (if (or (not (eq (process-status comp-proc) 'run))
- (yes-or-no-p
- (format "A %s process is running; kill it? "
- name-of-mode)))
- (condition-case ()
- (progn
- (interrupt-process comp-proc)
- (sit-for 1)
- (delete-process comp-proc))
- (error nil))
- (error "Cannot have two processes in `%s' at once"
- (buffer-name))
- )))
- ;; In case the compilation buffer is current, make sure we get the global
- ;; values of compilation-error-regexp-alist, etc.
- (kill-all-local-variables))
- (let ((regexp-alist (or regexp-alist compilation-error-regexp-alist))
- (parser (or parser compilation-parse-errors-function))
- (thisdir default-directory)
- outwin)
- (save-excursion
- ;; Clear out the compilation buffer and make it writable.
- ;; Change its default-directory to the directory where the compilation
- ;; will happen, and insert a `cd' command to indicate this.
- (set-buffer outbuf)
- (setq buffer-read-only nil)
- (erase-buffer)
- (setq default-directory thisdir)
- (insert "cd " thisdir "\n" command "\n")
- (set-buffer-modified-p nil))
- ;; If we're already in the compilation buffer, go to the end
- ;; of the buffer, so point will track the compilation output.
- (if (eq outbuf (current-buffer))
- (goto-char (point-max)))
- ;; Pop up the compilation buffer.
- (setq outwin (display-buffer outbuf))
- (save-excursion
- (set-buffer outbuf)
- (compilation-mode)
- (buffer-disable-undo (current-buffer))
- ;; (setq buffer-read-only t) ;;; Non-ergonomic.
- (set (make-local-variable 'compilation-parse-errors-function) parser)
- (set (make-local-variable 'compilation-error-message) error-message)
- (set (make-local-variable 'compilation-error-regexp-alist) regexp-alist)
- (setq default-directory thisdir
- compilation-directory-stack (list default-directory))
- (set-window-start outwin (point-min))
- (setq mode-name name-of-mode)
- (or (eq outwin (selected-window))
- (set-window-point outwin (point-min)))
- (and compilation-window-height
- (= (window-width outwin) (frame-width))
- (let ((w (selected-window)))
- (unwind-protect
- (progn
- (select-window outwin)
- (enlarge-window (- compilation-window-height
- (window-height))))
- (select-window w))))
- ;; Start the compilation.
- (if (fboundp 'start-process)
- (let ((proc (start-process-shell-command (downcase mode-name)
- outbuf
- command)))
- (set-process-sentinel proc 'compilation-sentinel)
- (set-process-filter proc 'compilation-filter)
- (set-marker (process-mark proc) (point) outbuf)
- (setq compilation-in-progress
- (cons proc compilation-in-progress)))
- ;; No asynchronous processes available
- (message (format "Executing `%s'..." command))
- (let ((status (call-process shell-file-name nil outbuf nil "-c"
- command))))
- (message (format "Executing `%s'...done" command)))))
- ;; Make it so the next C-x ` will use this buffer.
- (setq compilation-last-buffer outbuf)))
-
-(defvar compilation-minor-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] 'compile-mouse-goto-error)
- (define-key map "\C-c\C-c" 'compile-goto-error)
- (define-key map "\C-c\C-k" 'kill-compilation)
- (define-key map "\M-n" 'compilation-next-error)
- (define-key map "\M-p" 'compilation-previous-error)
- (define-key map "\M-{" 'compilation-previous-file)
- (define-key map "\M-}" 'compilation-next-file)
- map)
- "Keymap for `compilation-minor-mode'.")
-
-(defvar compilation-mode-map
- (let ((map (cons 'keymap compilation-minor-mode-map)))
- (define-key map " " 'scroll-up)
- (define-key map "\^?" 'scroll-down)
- map)
- "Keymap for compilation log buffers.
-`compilation-minor-mode-map' is a cdr of this.")
-
-(defun compilation-mode ()
- "Major mode for compilation log buffers.
-\\<compilation-mode-map>To visit the source for a line-numbered error,
-move point to the error message line and type \\[compile-goto-error].
-To kill the compilation, type \\[kill-compilation].
-
-Runs `compilation-mode-hook' with `run-hooks' (which see)."
- (interactive)
- (fundamental-mode)
- (use-local-map compilation-mode-map)
- (setq major-mode 'compilation-mode
- mode-name "Compilation")
- (compilation-setup)
- (run-hooks 'compilation-mode-hook))
-
-;; Prepare the buffer for the compilation parsing commands to work.
-(defun compilation-setup ()
- ;; Make the buffer's mode line show process state.
- (setq mode-line-process '(": %s"))
- (set (make-local-variable 'compilation-error-list) nil)
- (set (make-local-variable 'compilation-old-error-list) nil)
- (set (make-local-variable 'compilation-parsing-end) 1)
- (set (make-local-variable 'compilation-directory-stack) nil)
- (setq compilation-last-buffer (current-buffer)))
-
-(defvar compilation-minor-mode nil
- "Non-nil when in compilation-minor-mode.
-In this minor mode, all the error-parsing commands of the
-Compilation major mode are available.")
-(make-variable-buffer-local 'compilation-minor-mode)
-
-(or (assq 'compilation-minor-mode minor-mode-alist)
- (setq minor-mode-alist (cons '(compilation-minor-mode " Compilation")
- minor-mode-alist)))
-(or (assq 'compilation-minor-mode minor-mode-map-alist)
- (setq minor-mode-map-alist (cons (cons 'compilation-minor-mode
- compilation-minor-mode-map)
- minor-mode-map-alist)))
-
-;;;###autoload
-(defun compilation-minor-mode (&optional arg)
- "Toggle compilation minor mode.
-With arg, turn compilation mode on if and only if arg is positive.
-See `compilation-mode'."
- (interactive "P")
- (if (setq compilation-minor-mode (if (null arg)
- (null compilation-minor-mode)
- (> (prefix-numeric-value arg) 0)))
- (compilation-setup)))
-
-;; Called when compilation process changes state.
-(defun compilation-sentinel (proc msg)
- "Sentinel for compilation buffers."
- (let ((buffer (process-buffer proc)))
- (if (memq (process-status proc) '(signal exit))
- (progn
- (if (null (buffer-name buffer))
- ;; buffer killed
- (set-process-buffer proc nil)
- (let ((obuf (current-buffer))
- omax opoint)
- ;; save-excursion isn't the right thing if
- ;; process-buffer is current-buffer
- (unwind-protect
- (progn
- ;; Write something in the compilation buffer
- ;; and hack its mode line.
- (set-buffer buffer)
- (let ((buffer-read-only nil))
- (setq omax (point-max)
- opoint (point))
- (goto-char omax)
- ;; Record where we put the message, so we can ignore it
- ;; later on.
- (insert ?\n mode-name " " msg)
- (forward-char -1)
- (insert " at " (substring (current-time-string) 0 19))
- (forward-char 1)
- (setq mode-line-process
- (concat ": "
- (symbol-name (process-status proc))))
- ;; Since the buffer and mode line will show that the
- ;; process is dead, we can delete it now. Otherwise it
- ;; will stay around until M-x list-processes.
- (delete-process proc)
- ;; Force mode line redisplay soon.
- (set-buffer-modified-p (buffer-modified-p)))
- (if (and opoint (< opoint omax))
- (goto-char opoint))
- (if compilation-finish-function
- (funcall compilation-finish-function buffer msg)))
- (set-buffer obuf))))
- (setq compilation-in-progress (delq proc compilation-in-progress))
- ))))
-
-(defun compilation-filter (proc string)
- "Process filter for compilation buffers.
-Just inserts the text, but uses `insert-before-markers'."
- (save-excursion
- (set-buffer (process-buffer proc))
- (let ((buffer-read-only nil))
- (save-excursion
- (goto-char (process-mark proc))
- (insert-before-markers string)
- (set-marker (process-mark proc) (point))))))
-
-;; Return the cdr of compilation-old-error-list for the error containing point.
-(defun compile-error-at-point ()
- (compile-reinitialize-errors nil (point))
- (let ((errors compilation-old-error-list))
- (while (and errors
- (> (point) (car (car errors))))
- (setq errors (cdr errors)))
- errors))
-
-(defsubst compilation-buffer-p (buffer)
- (assq 'compilation-error-list (buffer-local-variables buffer)))
-
-(defun compilation-next-error (n)
- "Move point to the next error in the compilation buffer.
-Does NOT find the source line like \\[next-error]."
- (interactive "p")
- (or (compilation-buffer-p (current-buffer))
- (error "Not in a compilation buffer."))
- (setq compilation-last-buffer (current-buffer))
-
- (let ((errors (compile-error-at-point)))
-
- ;; Move to the error after the one containing point.
- (goto-char (car (if (< n 0)
- (let ((i 0)
- (e compilation-old-error-list))
- ;; See how many cdrs away ERRORS is from the start.
- (while (not (eq e errors))
- (setq i (1+ i)
- e (cdr e)))
- (if (> (- n) i)
- (error "Moved back past first error")
- (nth (+ i n) compilation-old-error-list)))
- (let ((compilation-error-list (cdr errors)))
- (compile-reinitialize-errors nil nil n)
- (if compilation-error-list
- (nth (1- n) compilation-error-list)
- (error "Moved past last error"))))))))
-
-(defun compilation-previous-error (n)
- "Move point to the previous error in the compilation buffer.
-Does NOT find the source line like \\[next-error]."
- (interactive "p")
- (compilation-next-error (- n)))
-
-
-;; Given an elt of `compilation-error-list', return an object representing
-;; the referenced file which is equal to (but not necessarily eq to) what
-;; this function would return for another error in the same file.
-(defsubst compilation-error-filedata (data)
- (setq data (cdr data))
- (if (markerp data)
- (marker-buffer data)
- (car data)))
-
-;; Return a string describing a value from compilation-error-filedata.
-;; This value is not necessarily useful as a file name, but should be
-;; indicative to the user of what file's errors are being referred to.
-(defsubst compilation-error-filedata-file-name (filedata)
- (if (bufferp filedata)
- (buffer-file-name filedata)
- (car filedata)))
-
-(defun compilation-next-file (n)
- "Move point to the next error for a different file than the current one."
- (interactive "p")
- (or (compilation-buffer-p (current-buffer))
- (error "Not in a compilation buffer."))
- (setq compilation-last-buffer (current-buffer))
-
- (let ((reversed (< n 0))
- errors filedata)
-
- (if (not reversed)
- (setq errors (or (compile-error-at-point)
- (error "Moved past last error")))
-
- ;; Get a reversed list of the errors up through the one containing point.
- (compile-reinitialize-errors nil (point))
- (setq errors (reverse compilation-old-error-list)
- n (- n))
-
- ;; Ignore errors after point. (car ERRORS) will be the error
- ;; containing point, (cadr ERRORS) the one before it.
- (while (and errors
- (< (point) (car (car errors))))
- (setq errors (cdr errors))))
-
- (while (> n 0)
- (setq filedata (compilation-error-filedata (car errors)))
-
- ;; Skip past the following errors for this file.
- (while (equal filedata
- (compilation-error-filedata
- (car (or errors
- (if reversed
- (error "%s the first erring file"
- (compilation-error-filedata-file-name
- filedata))
- (let ((compilation-error-list nil))
- ;; Parse some more.
- (compile-reinitialize-errors nil nil 2)
- (setq errors compilation-error-list)))
- (error "%s is the last erring file"
- (compilation-error-filedata-file-name
- filedata))))))
- (setq errors (cdr errors)))
-
- (setq n (1- n)))
-
- ;; Move to the following error.
- (goto-char (car (car (or errors
- (if reversed
- (error "This is the first erring file")
- (let ((compilation-error-list nil))
- ;; Parse the last one.
- (compile-reinitialize-errors nil nil 1)
- compilation-error-list))))))))
-
-(defun compilation-previous-file (n)
- "Move point to the previous error for a different file than the current one."
- (interactive "p")
- (compilation-next-file (- n)))
-
-
-(defun kill-compilation ()
- "Kill the process made by the \\[compile] command."
- (interactive)
- (let ((buffer (compilation-find-buffer)))
- (if (get-buffer-process buffer)
- (interrupt-process (get-buffer-process buffer))
- (error "The compilation process is not running."))))
-
-
-;; Parse any new errors in the compilation buffer,
-;; or reparse from the beginning if the user has asked for that.
-(defun compile-reinitialize-errors (reparse
- &optional limit-search find-at-least)
- (save-excursion
- (set-buffer compilation-last-buffer)
- ;; If we are out of errors, or if user says "reparse",
- ;; discard the info we have, to force reparsing.
- (if (or (eq compilation-error-list t)
- reparse)
- (compilation-forget-errors))
- (if (and compilation-error-list
- (or (not limit-search)
- (> compilation-parsing-end limit-search))
- (or (not find-at-least)
- (>= (length compilation-error-list) find-at-least)))
- ;; Since compilation-error-list is non-nil, it points to a specific
- ;; error the user wanted. So don't move it around.
- nil
- ;; This was here for a long time (before my rewrite); why? --roland
- ;;(switch-to-buffer compilation-last-buffer)
- (set-buffer-modified-p nil)
- (if (< compilation-parsing-end (point-max))
- ;; compilation-error-list might be non-nil if we have a non-nil
- ;; LIMIT-SEARCH or FIND-AT-LEAST arg. In that case its value
- ;; records the current position in the error list, and we must
- ;; preserve that after reparsing.
- (let ((error-list-pos compilation-error-list))
- (funcall compilation-parse-errors-function
- limit-search
- (and find-at-least
- ;; We only need enough new parsed errors to reach
- ;; FIND-AT-LEAST errors past the current
- ;; position.
- (- find-at-least (length compilation-error-list))))
- ;; Remember the entire list for compilation-forget-errors. If
- ;; this is an incremental parse, append to previous list. If
- ;; we are parsing anew, compilation-forget-errors cleared
- ;; compilation-old-error-list above.
- (setq compilation-old-error-list
- (nconc compilation-old-error-list compilation-error-list))
- (if error-list-pos
- ;; We started in the middle of an existing list of parsed
- ;; errors before parsing more; restore that position.
- (setq compilation-error-list error-list-pos))
- )))))
-
-(defun compile-mouse-goto-error (event)
- (interactive "e")
- (save-excursion
- (set-buffer (window-buffer (posn-window (event-end event))))
- (goto-char (posn-point (event-end event)))
-
- (or (compilation-buffer-p (current-buffer))
- (error "Not in a compilation buffer."))
- (setq compilation-last-buffer (current-buffer))
- (compile-reinitialize-errors nil (point))
-
- ;; Move to bol; the marker for the error on this line will point there.
- (beginning-of-line)
-
- ;; Move compilation-error-list to the elt of compilation-old-error-list
- ;; we want.
- (setq compilation-error-list compilation-old-error-list)
- (while (and compilation-error-list
- (> (point) (car (car compilation-error-list))))
- (setq compilation-error-list (cdr compilation-error-list)))
- (or compilation-error-list
- (error "No error to go to")))
- (select-window (posn-window (event-end event)))
- ;; Move to another window, so that next-error's window changes
- ;; result in the desired setup.
- (or (one-window-p)
- (progn
- (other-window -1)
- ;; other-window changed the selected buffer,
- ;; but we didn't want to do that.
- (set-buffer compilation-last-buffer)))
-
- (push-mark)
- (next-error 1))
-
-(defun compile-goto-error (&optional argp)
- "Visit the source for the error message point is on.
-Use this command in a compilation log buffer. Sets the mark at point there.
-\\[universal-argument] as a prefix arg means to reparse the buffer's error messages first;
-other kinds of prefix arguments are ignored."
- (interactive "P")
- (or (compilation-buffer-p (current-buffer))
- (error "Not in a compilation buffer."))
- (setq compilation-last-buffer (current-buffer))
- (compile-reinitialize-errors (consp argp) (point))
-
- ;; Move to bol; the marker for the error on this line will point there.
- (beginning-of-line)
-
- ;; Move compilation-error-list to the elt of compilation-old-error-list
- ;; we want.
- (setq compilation-error-list compilation-old-error-list)
- (while (and compilation-error-list
- (> (point) (car (car compilation-error-list))))
- (setq compilation-error-list (cdr compilation-error-list)))
-
- ;; Move to another window, so that next-error's window changes
- ;; result in the desired setup.
- (or (one-window-p)
- (progn
- (other-window -1)
- ;; other-window changed the selected buffer,
- ;; but we didn't want to do that.
- (set-buffer compilation-last-buffer)))
-
- (push-mark)
- (next-error 1))
-
-;; Return a compilation buffer.
-;; If the current buffer is a compilation buffer, return it.
-;; If compilation-last-buffer is set to a live buffer, use that.
-;; Otherwise, look for a compilation buffer and signal an error
-;; if there are none.
-(defun compilation-find-buffer (&optional other-buffer)
- (if (and (not other-buffer)
- (compilation-buffer-p (current-buffer)))
- ;; The current buffer is a compilation buffer.
- (current-buffer)
- (if (and compilation-last-buffer (buffer-name compilation-last-buffer)
- (or (not other-buffer) (not (eq compilation-last-buffer
- (current-buffer)))))
- compilation-last-buffer
- (let ((buffers (buffer-list)))
- (while (and buffers (or (not (compilation-buffer-p (car buffers)))
- (and other-buffer
- (eq (car buffers) (current-buffer)))))
- (setq buffers (cdr buffers)))
- (if buffers
- (car buffers)
- (or (and other-buffer
- (compilation-buffer-p (current-buffer))
- ;; The current buffer is a compilation buffer.
- (progn
- (if other-buffer
- (message "This is the only compilation buffer."))
- (current-buffer)))
- (error "No compilation started!")))))))
-
-;;;###autoload
-(defun next-error (&optional argp)
- "Visit next compilation error message and corresponding source code.
-This operates on the output from the \\[compile] command.
-If all preparsed error messages have been processed,
-the error message buffer is checked for new ones.
-
-A prefix arg specifies how many error messages to move;
-negative means move back to previous error messages.
-Just C-u as a prefix means reparse the error message buffer
-and start at the first error.
-
-\\[next-error] normally applies to the most recent compilation started,
-but as long as you are in the middle of parsing errors from one compilation
-output buffer, you stay with that compilation output buffer.
-
-Use \\[next-error] in a compilation output buffer to switch to
-processing errors from that compilation.
-
-See variables `compilation-parse-errors-function' and
-\`compilation-error-regexp-alist' for customization ideas."
- (interactive "P")
- (setq compilation-last-buffer (compilation-find-buffer))
- (compilation-goto-locus (compilation-next-error-locus
- ;; We want to pass a number here only if
- ;; we got a numeric prefix arg, not just C-u.
- (and (not (consp argp))
- (prefix-numeric-value argp))
- (consp argp))))
-;;;###autoload (define-key ctl-x-map "`" 'next-error)
-
-(defun compilation-next-error-locus (&optional move reparse)
- "Visit next compilation error and return locus in corresponding source code.
-This operates on the output from the \\[compile] command.
-If all preparsed error messages have been processed,
-the error message buffer is checked for new ones.
-
-Returns a cons (ERROR . SOURCE) of two markers: ERROR is a marker at the
-location of the error message in the compilation buffer, and SOURCE is a
-marker at the location in the source code indicated by the error message.
-
-Optional first arg MOVE says how many error messages to move forwards (or
-backwards, if negative); default is 1. Optional second arg REPARSE, if
-non-nil, says to reparse the error message buffer and reset to the first
-error (plus MOVE - 1).
-
-The current buffer should be the desired compilation output buffer."
- (or move (setq move 1))
- (compile-reinitialize-errors reparse nil (and (not reparse)
- (if (< move 1) 0 (1- move))))
- (let (next-errors next-error)
- (save-excursion
- (set-buffer compilation-last-buffer)
- ;; compilation-error-list points to the "current" error.
- (setq next-errors
- (if (> move 0)
- (nthcdr (1- move)
- compilation-error-list)
- ;; Zero or negative arg; we need to move back in the list.
- (let ((n (1- move))
- (i 0)
- (e compilation-old-error-list))
- ;; See how many cdrs away the current error is from the start.
- (while (not (eq e compilation-error-list))
- (setq i (1+ i)
- e (cdr e)))
- (if (> (- n) i)
- (error "Moved back past first error")
- (nthcdr (+ i n) compilation-old-error-list))))
- next-error (car next-errors))
- (while
- (if (null next-error)
- (progn
- (if move (if (> move 0)
- (error "Moved past last error")
- (error "Moved back past first error")))
- (compilation-forget-errors)
- (error (concat compilation-error-message
- (and (get-buffer-process (current-buffer))
- (eq (process-status
- (get-buffer-process
- (current-buffer)))
- 'run)
- " yet"))))
- (setq compilation-error-list (cdr next-errors))
- (if (null (cdr next-error))
- ;; This error is boring. Go to the next.
- t
- (or (markerp (cdr next-error))
- ;; This error has a filename/lineno pair.
- ;; Find the file and turn it into a marker.
- (let* ((fileinfo (car (cdr next-error)))
- (buffer (compilation-find-file (cdr fileinfo)
- (car fileinfo)
- (car next-error))))
- (if (null buffer)
- ;; We can't find this error's file.
- ;; Remove all errors in the same file.
- (progn
- (setq next-errors compilation-old-error-list)
- (while next-errors
- (and (consp (cdr (car next-errors)))
- (equal (car (cdr (car next-errors)))
- fileinfo)
- (progn
- (set-marker (car (car next-errors)) nil)
- (setcdr (car next-errors) nil)))
- (setq next-errors (cdr next-errors)))
- ;; Look for the next error.
- t)
- ;; We found the file. Get a marker for this error.
- ;; compilation-old-error-list is a buffer-local
- ;; variable, so we must be careful to extract its value
- ;; before switching to the source file buffer.
- (let ((errors compilation-old-error-list)
- (last-line (nth 1 (cdr next-error)))
- (column (nth 2 (cdr next-error))))
- (set-buffer buffer)
- (save-excursion
- (save-restriction
- (widen)
- (goto-line last-line)
- (if column
- (move-to-column column)
- (beginning-of-line))
- (setcdr next-error (point-marker))
- ;; Make all the other error messages referring
- ;; to the same file have markers into the buffer.
- (while errors
- (and (consp (cdr (car errors)))
- (equal (car (cdr (car errors))) fileinfo)
- (let* ((this (nth 1 (cdr (car errors))))
- (column (nth 2 (cdr (car errors))))
- (lines (- this last-line)))
- (if (eq selective-display t)
- ;; When selective-display is t,
- ;; each C-m is a line boundary,
- ;; as well as each newline.
- (if (< lines 0)
- (re-search-backward "[\n\C-m]"
- nil 'end
- (- lines))
- (re-search-forward "[\n\C-m]"
- nil 'end
- lines))
- (forward-line lines))
- (if column
- (move-to-column column))
- (setq last-line this)
- (setcdr (car errors) (point-marker))))
- (setq errors (cdr errors)))))))))
- ;; If we didn't get a marker for this error, or this
- ;; marker's buffer was killed, go on to the next one.
- (or (not (markerp (cdr next-error)))
- (not (marker-buffer (cdr next-error))))))
- (setq next-errors compilation-error-list
- next-error (car next-errors))))
-
- ;; Skip over multiple error messages for the same source location,
- ;; so the next C-x ` won't go to an error in the same place.
- (while (and compilation-error-list
- (equal (cdr (car compilation-error-list)) (cdr next-error)))
- (setq compilation-error-list (cdr compilation-error-list)))
-
- ;; We now have a marker for the position of the error source code.
- ;; NEXT-ERROR is a cons (ERROR . SOURCE) of two markers.
- next-error))
-
-(defun compilation-goto-locus (next-error)
- "Jump to an error locus returned by `compilation-next-error-locus'.
-Takes one argument, a cons (ERROR . SOURCE) of two markers.
-Selects a window with point at SOURCE, with another window displaying ERROR."
- (switch-to-buffer (marker-buffer (cdr next-error)))
- (goto-char (cdr next-error))
- ;; If narrowing got in the way of
- ;; going to the right place, widen.
- (or (= (point) (marker-position (cdr next-error)))
- (progn
- (widen)
- (goto-char (cdr next-error))))
-
- ;; Show compilation buffer in other window, scrolled to this error.
- (let* ((pop-up-windows t)
- (w (display-buffer (marker-buffer (car next-error)))))
- (set-window-point w (car next-error))
- (set-window-start w (car next-error))))
-
-;; Find a buffer for file FILENAME.
-;; Search the directories in compilation-search-path.
-;; A nil in compilation-search-path means to try the
-;; current directory, which is passed in DIR.
-;; If FILENAME is not found at all, ask the user where to find it.
-;; Pop up the buffer containing MARKER and scroll to MARKER if we ask the user.
-(defun compilation-find-file (filename dir marker)
- (let ((dirs compilation-search-path)
- result name)
- (while (and dirs (null result))
- (setq name (expand-file-name filename (or (car dirs) dir))
- result (and (file-exists-p name)
- (find-file-noselect name))
- dirs (cdr dirs)))
- (or result
- ;; The file doesn't exist.
- ;; Ask the user where to find it.
- ;; If he hits C-g, then the next time he does
- ;; next-error, he'll skip past it.
- (progn
- (let* ((pop-up-windows t)
- (w (display-buffer (marker-buffer marker))))
- (set-window-point w marker)
- (set-window-start w marker))
- (setq name
- (expand-file-name
- (read-file-name
- (format "Find this error in: (default %s) "
- filename) dir filename t)))
- (if (file-directory-p name)
- (setq name (concat (file-name-as-directory name) filename)))
- (if (file-exists-p name)
- (find-file-noselect name))))))
-
-;; Set compilation-error-list to nil, and unchain the markers that point to the
-;; error messages and their text, so that they no longer slow down gap motion.
-;; This would happen anyway at the next garbage collection, but it is better to
-;; do it right away.
-(defun compilation-forget-errors ()
- (while compilation-old-error-list
- (let ((next-error (car compilation-old-error-list)))
- (set-marker (car next-error) nil)
- (if (markerp (cdr next-error))
- (set-marker (cdr next-error) nil)))
- (setq compilation-old-error-list (cdr compilation-old-error-list)))
- (setq compilation-error-list nil
- compilation-directory-stack nil
- compilation-parsing-end 1))
-
-
-(defun count-regexp-groupings (regexp)
- "Return the number of \\( ... \\) groupings in REGEXP (a string)."
- (let ((groupings 0)
- (len (length regexp))
- (i 0)
- c)
- (while (< i len)
- (setq c (aref regexp i)
- i (1+ i))
- (cond ((= c ?\[)
- ;; Find the end of this [...].
- (while (and (< i len)
- (not (= (aref regexp i) ?\])))
- (setq i (1+ i))))
- ((= c ?\\)
- (if (< i len)
- (progn
- (setq c (aref regexp i)
- i (1+ i))
- (if (= c ?\))
- ;; We found the end of a grouping,
- ;; so bump our counter.
- (setq groupings (1+ groupings))))))))
- groupings))
-
-(defun compilation-parse-errors (limit-search find-at-least)
- "Parse the current buffer as grep, cc or lint error messages.
-See variable `compilation-parse-errors-function' for the interface it uses."
- (setq compilation-error-list nil)
- (message "Parsing error messages...")
- (let (text-buffer orig orig-expanded parent-expanded
- regexp enter-group leave-group error-group
- alist subexpr error-regexp-groups
- (found-desired nil)
- (compilation-num-errors-found 0))
-
- ;; Don't reparse messages already seen at last parse.
- (goto-char compilation-parsing-end)
- ;; Don't parse the first two lines as error messages.
- ;; This matters for grep.
- (if (bobp)
- (progn
- (forward-line 2)
- ;; Move back so point is before the newline.
- ;; This matters because some error regexps use \n instead of ^
- ;; to be faster.
- (forward-char -1)))
-
- ;; Compile all the regexps we want to search for into one.
- (setq regexp (concat "\\(" compilation-enter-directory-regexp "\\)\\|"
- "\\(" compilation-leave-directory-regexp "\\)\\|"
- "\\(" (mapconcat (function
- (lambda (elt)
- (concat "\\(" (car elt) "\\)")))
- compilation-error-regexp-alist
- "\\|") "\\)"))
-
- ;; Find out how many \(...\) groupings are in each of the regexps, and set
- ;; *-GROUP to the grouping containing each constituent regexp (whose
- ;; subgroups will come immediately thereafter) of the big regexp we have
- ;; just constructed.
- (setq enter-group 1
- leave-group (+ enter-group
- (count-regexp-groupings
- compilation-enter-directory-regexp)
- 1)
- error-group (+ leave-group
- (count-regexp-groupings
- compilation-leave-directory-regexp)
- 1))
-
- ;; Compile an alist (IDX FILE LINE [COL]), where IDX is the number of
- ;; the subexpression for an entire error-regexp, and FILE and LINE (and
- ;; possibly COL) are the numbers for the subexpressions giving the file
- ;; name and line number (and possibly column number).
- (setq alist (or compilation-error-regexp-alist
- (error "compilation-error-regexp-alist is empty!"))
- subexpr (1+ error-group))
- (while alist
- (setq error-regexp-groups
- (cons (list subexpr
- (+ subexpr (nth 1 (car alist)))
- (+ subexpr (nth 2 (car alist)))
- (and (nth 2 (car alist))
- (+ subexpr (nth 2 (car alist)))))
- error-regexp-groups))
- (setq subexpr (+ subexpr 1 (count-regexp-groupings (car (car alist)))))
- (setq alist (cdr alist)))
-
- (setq orig default-directory)
- (setq orig-expanded (file-truename orig))
- (setq parent-expanded (expand-file-name "../" orig-expanded))
-
- (while (and (not found-desired)
- ;; We don't just pass LIMIT-SEARCH to re-search-forward
- ;; because we want to find matches containing LIMIT-SEARCH
- ;; but which extend past it.
- (re-search-forward regexp nil t))
-
- ;; Figure out which constituent regexp matched.
- (cond ((match-beginning enter-group)
- ;; The match was the enter-directory regexp.
- (let ((dir
- (file-name-as-directory
- (expand-file-name
- (buffer-substring (match-beginning (+ enter-group 1))
- (match-end (+ enter-group 1)))))))
- ;; The directory name in the "entering" message
- ;; is a truename. Try to convert it to a form
- ;; like what the user typed in.
- (setq dir
- (compile-abbreviate-directory dir orig orig-expanded
- parent-expanded))
- (setq compilation-directory-stack
- (cons dir compilation-directory-stack))
- (and (file-directory-p dir)
- (setq default-directory dir)))
-
- (and limit-search (>= (point) limit-search)
- ;; The user wanted a specific error, and we're past it.
- ;; We do this check here (and in the leave-group case)
- ;; rather than at the end of the loop because if the last
- ;; thing seen is an error message, we must carefully
- ;; discard the last error when it is the first in a new
- ;; file (see below in the error-group case).
- (setq found-desired t)))
-
- ((match-beginning leave-group)
- ;; The match was the leave-directory regexp.
- (let ((beg (match-beginning (+ leave-group 1)))
- (stack compilation-directory-stack))
- (if beg
- (let ((dir
- (file-name-as-directory
- (expand-file-name
- (buffer-substring beg
- (match-end (+ leave-group
- 1)))))))
- ;; The directory name in the "entering" message
- ;; is a truename. Try to convert it to a form
- ;; like what the user typed in.
- (setq dir
- (compile-abbreviate-directory dir orig orig-expanded
- parent-expanded))
- (while (and stack
- (not (string-equal (car stack) dir)))
- (setq stack (cdr stack)))))
- (setq compilation-directory-stack (cdr stack))
- (setq stack (car compilation-directory-stack))
- (if stack
- (setq default-directory stack))
- )
-
- (and limit-search (>= (point) limit-search)
- ;; The user wanted a specific error, and we're past it.
- ;; We do this check here (and in the enter-group case)
- ;; rather than at the end of the loop because if the last
- ;; thing seen is an error message, we must carefully
- ;; discard the last error when it is the first in a new
- ;; file (see below in the error-group case).
- (setq found-desired t)))
-
- ((match-beginning error-group)
- ;; The match was the composite error regexp.
- ;; Find out which individual regexp matched.
- (setq alist error-regexp-groups)
- (while (and alist
- (null (match-beginning (car (car alist)))))
- (setq alist (cdr alist)))
- (if alist
- (setq alist (car alist))
- (error "compilation-parse-errors: impossible regexp match!"))
-
- ;; Extract the file name and line number from the error message.
- (let ((beginning-of-match (match-beginning 0)) ;looking-at nukes
- (filename (buffer-substring (match-beginning (nth 1 alist))
- (match-end (nth 1 alist))))
- (linenum (string-to-int
- (buffer-substring
- (match-beginning (nth 2 alist))
- (match-end (nth 2 alist)))))
- (column (and (nth 3 alist)
- (string-to-int
- (buffer-substring
- (match-beginning (nth 3 alist))
- (match-end (nth 3 alist)))))))
-
- ;; Check for a comint-file-name-prefix and prepend it if
- ;; appropriate. (This is very useful for
- ;; compilation-minor-mode in an rlogin-mode buffer.)
- (and (boundp 'comint-file-name-prefix)
- ;; If the file name is relative, default-directory will
- ;; already contain the comint-file-name-prefix (done by
- ;; compile-abbreviate-directory).
- (file-name-absolute-p filename)
- (setq filename (concat comint-file-name-prefix filename)))
- (setq filename (cons default-directory filename))
-
- ;; Locate the erring file and line.
- ;; Cons a new elt onto compilation-error-list,
- ;; giving a marker for the current compilation buffer
- ;; location, and the file and line number of the error.
- (save-excursion
- (beginning-of-line 1)
- (let ((this (cons (point-marker)
- (list filename linenum column))))
- ;; Don't add the same source line more than once.
- (if (equal (cdr this) (cdr (car compilation-error-list)))
- nil
- (setq compilation-error-list
- (cons this
- compilation-error-list))
- (setq compilation-num-errors-found
- (1+ compilation-num-errors-found)))))
- (and (or (and find-at-least (> compilation-num-errors-found
- find-at-least))
- (and limit-search (>= (point) limit-search)))
- ;; We have found as many new errors as the user wants,
- ;; or past the buffer position he indicated. We
- ;; continue to parse until we have seen all the
- ;; consecutive errors in the same file, so the error
- ;; positions will be recorded as markers in this buffer
- ;; that might change.
- (cdr compilation-error-list) ; Must check at least two.
- (not (equal (car (cdr (nth 0 compilation-error-list)))
- (car (cdr (nth 1 compilation-error-list)))))
- (progn
- ;; Discard the error just parsed, so that the next
- ;; parsing run can get it and the following errors in
- ;; the same file all at once. If we didn't do this, we
- ;; would have the same problem we are trying to avoid
- ;; with the test above, just delayed until the next run!
- (setq compilation-error-list
- (cdr compilation-error-list))
- (goto-char beginning-of-match)
- (setq found-desired t)))
- )
- )
- (t
- (error "compilation-parse-errors: known groups didn't match!")))
-
- (message "Parsing error messages...%d (%.0f%% of buffer)"
- compilation-num-errors-found
- ;; Use floating-point because (* 100 (point)) frequently
- ;; exceeds the range of Emacs Lisp integers.
- (/ (* 100.0 (point)) (point-max)))
-
- (and limit-search (>= (point) limit-search)
- ;; The user wanted a specific error, and we're past it.
- (setq found-desired t)))
- (setq compilation-parsing-end (if found-desired
- (point)
- ;; We have searched the whole buffer.
- (point-max))))
- (setq compilation-error-list (nreverse compilation-error-list))
- (message "Parsing error messages...done"))
-
-;; If directory DIR is a subdir of ORIG or of ORIG's parent,
-;; return a relative name for it starting from ORIG or its parent.
-;; ORIG-EXPANDED is an expanded version of ORIG.
-;; PARENT-EXPANDED is an expanded version of ORIG's parent.
-;; Those two args could be computed here, but we run faster by
-;; having the caller compute them just once.
-(defun compile-abbreviate-directory (dir orig orig-expanded parent-expanded)
- ;; Check for a comint-file-name-prefix and prepend it if appropriate.
- ;; (This is very useful for compilation-minor-mode in an rlogin-mode
- ;; buffer.)
- (if (boundp 'comint-file-name-prefix)
- (setq dir (concat comint-file-name-prefix dir)))
-
- (if (and (> (length dir) (length orig-expanded))
- (string= orig-expanded
- (substring dir 0 (length orig-expanded))))
- (setq dir
- (concat orig
- (substring dir (length orig-expanded)))))
- (if (and (> (length dir) (length parent-expanded))
- (string= parent-expanded
- (substring dir 0 (length parent-expanded))))
- (setq dir
- (concat (file-name-directory
- (directory-file-name orig))
- (substring dir (length parent-expanded)))))
- dir)
-
-(provide 'compile)
-
-;;; compile.el ends here
diff --git a/lisp/progmodes/cplus-md.el b/lisp/progmodes/cplus-md.el
deleted file mode 100644
index af26f52138c..00000000000
--- a/lisp/progmodes/cplus-md.el
+++ /dev/null
@@ -1,917 +0,0 @@
-;;; cplus-md.el --- C++ code editing commands for Emacs
-;;; Copyright (C) 1985, 1992 Free Software Foundation, Inc.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-;; Maintainer: Dave Detlefs <dld@cs.cmu.edu>
-;; Keywords: c
-
-;;; Commentary:
-
-;; 1987 Dave Detlefs <dld@cs.cmu.edu>
-;; and Stewart Clamen <clamen@cs.cmu.edu>.
-;; Done by fairly faithful modification of:
-
-;;; Change Log:
-
-;; Feb, 1990 (Dave Detlefs, dld@cs.cmu.edu)
-;; Fixed electric-c++-terminator to handle double colons, at the
-;; request of John Hagerman.
-;;
-;; Jan, 1990 (Doug Lea, dl@oswego.edu)
-;; Replaced c++-comment-region and c++-uncomment-region with
-;; versions from Igor Metz that avoid potential infinite loops.
-;;
-;; Oct, 1989 (Dave Detlefs, dld@cs.cmu.edu)
-;; Added contribution from Igor Metz <metz@iam.unibe.ch>:
-;; functions c++-comment-region and c++-uncomment-region and
-;; corresponding key-binding.
-;; Also fixed bug in indentation of second line after an empty
-;; arglist with empty-arglist non-null.
-;;
-;; Sept, 1989 (Glen Ditchfield, gjditchfield@violet.uwaterloo.ca):
-;; Textual changes to more closely imitate Emacs 18.55's c-mode.
-;; Fixed handling of "default:", where ":" was the last character in the
-;; buffer. Fixed indentation of comments starting in column 0, and when
-;; previous line contained more than one comment start string. Fixed
-;; handling of "friend".
-;;
-;; Aug 7, 1989; John Hagerman (hagerman@ece.cmu.edu):
-;; Changed calculate-c++-indent to handle member initializations
-;; more flexibly. Two new variables are used to control behavior:
-;; c++-member-init-indent and c++-continued-member-init-offset.
-;; Note the assumption that member initializations and argument
-;; declarations are not mixed in one function definition.
-;;
-;; June 1989 (Dave Detlefs, dld@cs.cmu.edu)
-;; Fixed calculate-c++-indent to handle continued lines ending in
-;; {'s. (I wasn't following C-mode closely enough, or C-mode
-;; changed.) Made ' a quote character, at the behest of someone
-;; whose mail I apparently deleted (if they send me mail I'll credit
-;; them here in a future revision.)
-;; Dan Weinreb (dlw@odi.com) pointed out that 'c++-mode successively
-;; bound c++-indent-exp and c++-indent-defun to ESC-^q. ESC-^q is
-;; now bound to c++-indent-exp, while, c++-indent-defun is invoked
-;; with ESC-^x.
-
-;; February 1989 (Dave Detlefs, dld@cs.cmu.edu)
-;; Fixed some errors in c++-indent-defun, as pointed out by Sam
-;; Haradhvala (odi!sam@talcott.harvard.edu).
-;; October 1988 (Dave Detlefs, dld@cs.cmu.edu)
-;; It turns out I had only *thought* I had made
-;; beginning(end)-of-defun work. It should work better now -- you
-;; can either attempt to match defun headers "strongly," using a
-;; very complicated regexp, or "weakly," using a simple one. This
-;; is settable by a variable; the default is the cheaper weak
-;; method. (Stewart Clamen was intimately involved in this, too.)
-;;
-;; I made "'" *not* be a string delimiter, because that was causing
-;; comments containing contractions to ("// don't") to mess up paren
-;; balancing.
-;;
-;; I also incorporated another slight indentation fix from Glen
-;; Ditchfield.
-;;
-;; We hope this is will make into version 19 of gnu-emacs.
-;;
-;; September 1988: incorporated changes from Fred Calm at Schlumberger.
-;; Also, made beginning(end)-of-defun, indent-defun work.
-;;
-;; August 1987: incorporated changes done by Glen Ditchfield of Waterloo.
-
-;;; Code:
-
-(defvar c++-mode-abbrev-table nil
- "Abbrev table used in C++ mode.")
-(define-abbrev-table 'c++-mode-abbrev-table ())
-
-(defvar c++-mode-map ()
- "Keymap used in C++ mode.")
-(if c++-mode-map
- ()
- (setq c++-mode-map (make-sparse-keymap))
- (define-key c++-mode-map "\C-j" 'reindent-then-newline-and-indent)
- (define-key c++-mode-map "{" 'electric-c++-brace)
- (define-key c++-mode-map "}" 'electric-c++-brace)
- (define-key c++-mode-map ";" 'electric-c++-semi)
- (define-key c++-mode-map "\e\C-h" 'mark-c-function)
- (define-key c++-mode-map "\e\C-q" 'indent-c++-exp)
- (define-key c++-mode-map "\177" 'backward-delete-char-untabify)
- (define-key c++-mode-map "\t" 'c++-indent-command)
-;; (define-key c++-mode-map "\C-c\C-i" 'c++-insert-header)
- (define-key c++-mode-map "\C-c\C-\\" 'c-backslash-region))
-;; (define-key c++-mode-map "\e\C-a" 'c++-beginning-of-defun)
-;; (define-key c++-mode-map "\e\C-e" 'c++-end-of-defun)
-;; (define-key c++-mode-map "\e\C-x" 'c++-indent-defun))
-
-(defvar c++-mode-syntax-table nil
- "Syntax table used in C++ mode.")
-
-(if c++-mode-syntax-table
- ()
- (setq c++-mode-syntax-table (copy-syntax-table c-mode-syntax-table))
- (modify-syntax-entry ?* ". 23b" c++-mode-syntax-table)
- (modify-syntax-entry ?/ ". 124" c++-mode-syntax-table)
- (modify-syntax-entry ?\n ">" c++-mode-syntax-table))
-
-(defvar c++-continued-member-init-offset nil
- "*Extra indent for continuation lines of member inits;
-nil means to align with previous initializations rather than
-with the colon on the first line.")
-(defvar c++-member-init-indent 0
- "*Indentation level of member initializations in function declarations.")
-(defvar c++-friend-offset -4
- "*Offset of C++ friend declarations relative to member declarations.")
-(defvar c++-electric-colon t
- "*If t, colon is an electric terminator.")
-(defvar c++-empty-arglist-indent nil
- "*Indicates how far to indent an line following an empty argument
-list. Nil indicates to just after the paren.")
-
-
-;;;###autoload
-(defun c++-mode ()
- "Major mode for editing C++ code. Very much like editing C code.
-Expression and list commands understand all C++ brackets.
-Tab at left margin indents for C++ code
-Comments are delimited with /* ... */ {or with // ... <newline>}
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-\\{c++-mode-map}
-Variables controlling indentation style:
- c-tab-always-indent
- Non-nil means TAB in C mode should always reindent the current line,
- regardless of where in the line point is when the TAB command is used.
- Default is t.
- c-auto-newline
- Non-nil means automatically newline before and after braces,
- and after colons and semicolons, inserted in C code.
- c-indent-level
- Indentation of C statements within surrounding block.
- The surrounding block's indentation is the indentation
- of the line on which the open-brace appears.
- c-continued-statement-offset
- Extra indentation given to a substatement, such as the
- then-clause of an if or body of a while.
- c-continued-brace-offset
- Extra indentation given to a brace that starts a substatement.
- This is in addition to c-continued-statement-offset.
- c-brace-offset
- Extra indentation for line if it starts with an open brace.
- c-brace-imaginary-offset
- An open brace following other text is treated as if it were
- this far to the right of the start of its line.
- c-argdecl-indent
- Indentation level of declarations of C function arguments.
- c-label-offset
- Extra indentation for line that is a label, or case or ``default:'', or
- ``public:'' or ``private:'', or ``protected:''.
- c++-electric-colon
- If non-nil at invocation of c++-mode (t is the default) colon electricly
- indents.
- c++-empty-arglist-indent
- If non-nil, a function declaration or invocation which ends a line with a
- left paren is indented this many extra spaces, instead of flush with the
- left paren.
- c++-friend-offset
- Offset of C++ friend declarations relative to member declarations.
- c++-member-init-indent
- Indentation level of member initializations in function declarations,
- if they are on a separate line beginning with a colon.
- c++-continued-member-init-offset
- Extra indentation for continuation lines of member initializations; NIL
- means to align with previous initializations rather than with the colon.
-
-Settings for K&R, BSD, and Stroustrup indentation styles are
- c-indent-level 5 8 4
- c-continued-statement-offset 5 8 4
- c-continued-brace-offset 0
- c-brace-offset -5 -8 0
- c-brace-imaginary-offset 0
- c-argdecl-indent 0 8 4
- c-label-offset -5 -8 -4
- c++-empty-arglist-indent 4
- c++-friend-offset 0
-
-Turning on C++ mode calls the value of the variable `c++-mode-hook' with
-no args if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map c++-mode-map)
- (set-syntax-table c++-mode-syntax-table)
- (setq major-mode 'c++-mode
- mode-name "C++"
- comment-column 32
- local-abbrev-table c++-mode-abbrev-table)
- (set (make-local-variable 'indent-line-function) 'c++-indent-line)
- (set (make-local-variable 'comment-start) "// ")
- (set (make-local-variable 'comment-end) "")
- (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|// *")
- (set (make-local-variable 'comment-indent-function) 'c++-comment-indent)
- (set (make-local-variable 'paragraph-start) (concat "^$\\|" page-delimiter))
- (set (make-local-variable 'paragraph-separate) paragraph-start)
- (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
- (set (make-local-variable 'require-final-newline) t)
- (set (make-local-variable 'parse-sexp-ignore-comments) t)
- (run-hooks 'c++-mode-hook)
- (if c++-electric-colon
- (define-key c++-mode-map ":" 'electric-c++-terminator)))
-
-;; This is used by indent-for-comment
-;; to decide how much to indent a comment in C++ code
-;; based on its context.
-(defun c++-comment-indent ()
- (if (looking-at "^\\(/\\*\\|//\\)")
- 0 ; Existing comment at bol stays there.
- (save-excursion
- (skip-chars-backward " \t")
- (max
- ;; leave at least one space on non-empty lines.
- (if (zerop (current-column)) 0 (1+ (current-column)))
- (let ((cur-pt (point)))
- (beginning-of-line 0)
- ;; If previous line had a comment, use it's indent
- (if (re-search-forward comment-start-skip cur-pt t)
- (progn
- (goto-char (match-beginning 0))
- (current-column))
- comment-column)))))) ; otherwise indent at comment column.
-
-(defun electric-c++-brace (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (let (insertpos)
- (if (and (not arg)
- (eolp)
- (or (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (if c-auto-newline (progn (c++-indent-line) (newline) t))))
- (progn
- (insert last-command-char)
- (c++-indent-line)
- (if c-auto-newline
- (progn
- (newline)
- ;; (newline) may have done auto-fill
- (setq insertpos (- (point) 2))
- (c++-indent-line)))
- (save-excursion
- (if insertpos (goto-char (1+ insertpos)))
- (delete-char -1))))
- (if insertpos
- (save-excursion
- (goto-char insertpos)
- (self-insert-command (prefix-numeric-value arg)))
- (self-insert-command (prefix-numeric-value arg)))))
-
-(defun electric-c++-semi (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (if c-auto-newline
- (electric-c++-terminator arg)
- (self-insert-command (prefix-numeric-value arg))))
-
-(defun electric-c++-terminator (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (let (insertpos (end (point)))
- (if (and (not arg) (eolp)
- (not (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (or (= (following-char) ?#)
- ;; Colon is special only after a label, or
- ;; case, or another colon.
- ;; So quickly rule out most other uses of colon
- ;; and do no indentation for them.
- (and (eq last-command-char ?:)
- (not (looking-at "case[ \t]"))
- (save-excursion
- (forward-word 1)
- (skip-chars-forward " \t")
- (< (point) end))
- ;; Do re-indent double colons
- (save-excursion
- (end-of-line 1)
- (looking-at ":")))
- (progn
- (beginning-of-defun)
- (let ((pps (parse-partial-sexp (point) end)))
- (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))))
- (progn
- (insert last-command-char)
- (c++-indent-line)
- (and c-auto-newline
- (not (c-inside-parens-p))
- (progn
- ;; the new marker object, used to be just an integer
- (setq insertpos (make-marker))
- ;; changed setq to set-marker
- (set-marker insertpos (1- (point)))
- ;; do this before the newline, since in auto fill can break
- (newline)
- (c-indent-line)))
- (save-excursion
- (if insertpos (goto-char (1+ insertpos)))
- (delete-char -1))))
- (if insertpos
- (save-excursion
- (goto-char insertpos)
- (self-insert-command (prefix-numeric-value arg)))
- (self-insert-command (prefix-numeric-value arg)))))
-
-(defun c++-indent-command (&optional whole-exp)
- "Indent current line as C++ code, or in some cases insert a tab character.
-If `c-tab-always-indent' is non-nil (the default), always indent current
-line. Otherwise, indent the current line only if point is at the left
-margin or in the line's indentation; otherwise insert a tab.
-
-A numeric argument, regardless of its value, means indent rigidly all means
-indent rigidly all the lines of the expression starting after point so that
-this line becomes properly indented. The relative indentation among the
-lines of the expression are preserved."
- (interactive "P")
- (if whole-exp
- ;; If arg, always indent this line as C
- ;; and shift remaining lines of expression the same amount.
- (let ((shift-amt (c++-indent-line))
- beg end)
- (save-excursion
- (if c-tab-always-indent
- (beginning-of-line))
- (setq beg (point))
- (forward-sexp 1)
- (setq end (point))
- (goto-char beg)
- (forward-line 1)
- (setq beg (point)))
- (if (> end beg)
- (indent-code-rigidly beg end shift-amt "#")))
- (if (and (not c-tab-always-indent)
- (save-excursion
- (skip-chars-backward " \t")
- (not (bolp))))
- (insert-tab)
- (c++-indent-line))))
-
-(defun c++-indent-line ()
- "Indent current line as C++ code.
-Return the amount the indentation changed by."
- (let ((indent (calculate-c++-indent nil))
- beg shift-amt
- (case-fold-search nil)
- (pos (- (point-max) (point))))
- (beginning-of-line)
- (setq beg (point))
- (cond ((eq indent nil)
- (setq indent (current-indentation)))
- ((eq indent t)
- (setq indent (calculate-c-indent-within-comment)))
- ((looking-at "[ \t]*#")
- (setq indent 0))
- (t
- (skip-chars-forward " \t")
- (if (listp indent) (setq indent (car indent)))
- (cond ((looking-at "\\(default\\|public\\|private\\|protected\\):")
- (setq indent (+ indent c-label-offset)))
- ((or (looking-at "case\\b")
- (and (looking-at "[A-Za-z]")
- (save-excursion
- (forward-sexp 1)
- (looking-at ":[^:]"))))
- (setq indent (max 1 (+ indent c-label-offset))))
- ((and (looking-at "else\\b")
- (not (looking-at "else\\s_")))
- (setq indent (save-excursion
- (c-backward-to-start-of-if)
- (current-indentation))))
- ((looking-at "friend\[ \t]")
- (setq indent (+ indent c++-friend-offset)))
- ((= (following-char) ?})
- (setq indent (- indent c-indent-level)))
- ((= (following-char) ?{)
- (setq indent (+ indent c-brace-offset))))))
- (skip-chars-forward " \t")
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- (delete-region beg (point))
- (indent-to indent)
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos))))
- shift-amt))
-
-(defun calculate-c++-indent (&optional parse-start)
- "Return appropriate indentation for current line as C++ code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment."
- (save-excursion
- (beginning-of-line)
- (let ((indent-point (point))
- (case-fold-search nil)
- state
- containing-sexp)
- (if parse-start
- (goto-char parse-start)
- (beginning-of-defun))
- (while (< (point) indent-point)
- (setq parse-start (point))
- (setq state (parse-partial-sexp (point) indent-point 0))
- (setq containing-sexp (car (cdr state))))
- (cond ((or (nth 3 state) (nth 4 state))
- ;; return nil or t if should not change this line
- (nth 4 state))
- ((null containing-sexp)
- ;; Line is at top level. May be data or function definition, or
- ;; may be function argument declaration or member initialization.
- ;; Indent like the previous top level line unless
- ;; (1) the previous line ends in a closeparen without semicolon,
- ;; in which case this line is the first argument declaration or
- ;; member initialization, or
- ;; (2) the previous line begins with a colon,
- ;; in which case this is the second line of member inits.
- ;; It is assumed that arg decls and member inits are not mixed.
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (if (= (following-char) ?{)
- 0 ; Unless it starts a function body
- (c++-backward-to-noncomment (or parse-start (point-min)))
- (if (= (preceding-char) ?\))
- (progn ; first arg decl or member init
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (if (= (following-char) ?:)
- c++-member-init-indent
- c-argdecl-indent))
- (if (= (preceding-char) ?\;)
- (backward-char 1))
- (if (= (preceding-char) ?})
- 0
- (beginning-of-line) ; continued arg decls or member inits
- (skip-chars-forward " \t")
- (if (= (following-char) ?:)
- (if c++-continued-member-init-offset
- (+ (current-indentation)
- c++-continued-member-init-offset)
- (progn
- (forward-char 1)
- (skip-chars-forward " \t")
- (current-column)))
- (current-indentation)))
- )))
- ((/= (char-after containing-sexp) ?{)
- ;; line is expression, not statement:
- ;; indent to just after the surrounding open -- unless
- ;; empty arg list, in which case we do what
- ;; c++-empty-arglist-indent says to do.
- (if (and c++-empty-arglist-indent
- (or (null (nth 2 state)) ;; indicates empty arg
- ;; list.
- ;; Use a heuristic: if the first
- ;; non-whitespace following left paren on
- ;; same line is not a comment,
- ;; is not an empty arglist.
- (save-excursion
- (goto-char (1+ containing-sexp))
- (not
- (looking-at "\\( \\|\t\\)*[^/\n]")))))
- (progn
- (goto-char containing-sexp)
- (beginning-of-line)
- (skip-chars-forward " \t")
- (goto-char (min (+ (point) c++-empty-arglist-indent)
- (1+ containing-sexp)))
- (current-column))
- ;; In C-mode, we would always indent to one after the
- ;; left paren. Here, though, we may have an
- ;; empty-arglist, so we'll indent to the min of that
- ;; and the beginning of the first argument.
- (goto-char (1+ containing-sexp))
- (current-column)))
- (t
- ;; Statement. Find previous non-comment character.
- (goto-char indent-point)
- (c++-backward-to-noncomment containing-sexp)
- (if (not (memq (preceding-char) '(nil ?\, ?\; ?} ?: ?\{)))
- ;; This line is continuation of preceding line's statement;
- ;; indent c-continued-statement-offset more than the
- ;; previous line of the statement.
- (progn
- (c-backward-to-start-of-continued-exp containing-sexp)
- (+ c-continued-statement-offset (current-column)
- (if (save-excursion (goto-char indent-point)
- (skip-chars-forward " \t")
- (eq (following-char) ?{))
- c-continued-brace-offset 0)))
- ;; This line starts a new statement.
- ;; Position following last unclosed open.
- (goto-char containing-sexp)
- ;; Is line first statement after an open-brace?
- (or
- ;; If no, find that first statement and indent like it.
- (save-excursion
- (forward-char 1)
- (while (progn (skip-chars-forward " \t\n")
- (looking-at
- (concat
- "#\\|/\\*\\|//"
- "\\|case[ \t]"
- "\\|[a-zA-Z0-9_$]*:[^:]"
- "\\|friend[ \t]")))
- ;; Skip over comments and labels following openbrace.
- (cond ((= (following-char) ?\#)
- (forward-line 1))
- ((looking-at "/\\*")
- (search-forward "*/" nil 'move))
- ((looking-at "//\\|friend[ \t]")
- (forward-line 1))
- (t
- (re-search-forward ":[^:]" nil 'move))))
- ;; The first following code counts
- ;; if it is before the line we want to indent.
- (and (< (point) indent-point)
- (current-column)))
- ;; If no previous statement,
- ;; indent it relative to line brace is on.
- ;; For open brace in column zero, don't let statement
- ;; start there too. If c-indent-offset is zero,
- ;; use c-brace-offset + c-continued-statement-offset instead.
- ;; For open-braces not the first thing in a line,
- ;; add in c-brace-imaginary-offset.
- (+ (if (and (bolp) (zerop c-indent-level))
- (+ c-brace-offset c-continued-statement-offset)
- c-indent-level)
- ;; Move back over whitespace before the openbrace.
- ;; If openbrace is not first nonwhite thing on the line,
- ;; add the c-brace-imaginary-offset.
- (progn (skip-chars-backward " \t")
- (if (bolp) 0 c-brace-imaginary-offset))
- ;; If the openbrace is preceded by a parenthesized exp,
- ;; move to the beginning of that;
- ;; possibly a different line
- (progn
- (if (eq (preceding-char) ?\))
- (forward-sexp -1))
- ;; Get initial indentation of the line we are on.
- (current-indentation))))))))))
-
-(defun c++-backward-to-noncomment (lim)
- (let (opoint stop)
- (while (not stop)
- (skip-chars-backward " \t\n\r\f" lim)
- (setq opoint (point))
- (cond ((and (>= (point) (+ 2 lim))
- (save-excursion
- (forward-char -2)
- (looking-at "\\*/")))
- (search-backward "/*" lim 'move))
- ((and
- (search-backward "//" (max (c++-point-bol) lim) 'move)
- (not (c++-within-string-p (point) opoint))))
- (t (beginning-of-line)
- (skip-chars-forward " \t")
- (if (looking-at "#")
- (setq stop (<= (point) lim))
- (setq stop t)
- (goto-char opoint)))))))
-
-(defun indent-c++-exp ()
- "Indent each line of the C++ grouping following point."
- (interactive)
- (let ((indent-stack (list nil))
- (contain-stack (list (point)))
- (case-fold-search nil)
- restart outer-loop-done inner-loop-done state ostate
- this-indent last-sexp last-depth
- at-else at-brace
- (opoint (point))
- (next-depth 0))
- (save-excursion
- (forward-sexp 1))
- (save-excursion
- (setq outer-loop-done nil)
- (while (and (not (eobp)) (not outer-loop-done))
- (setq last-depth next-depth)
- ;; Compute how depth changes over this line
- ;; plus enough other lines to get to one that
- ;; does not end inside a comment or string.
- ;; Meanwhile, do appropriate indentation on comment lines.
- (setq inner-loop-done nil)
- (while (and (not inner-loop-done)
- (not (and (eobp) (setq outer-loop-done t))))
- (setq ostate state)
- (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
- nil nil state))
- (setq next-depth (car state))
- (if (and (car (cdr (cdr state)))
- (>= (car (cdr (cdr state))) 0))
- (setq last-sexp (car (cdr (cdr state)))))
- (if (or (nth 4 ostate))
- (c++-indent-line))
- (if (or (nth 3 state))
- (forward-line 1)
- (setq inner-loop-done t)))
- (if (<= next-depth 0)
- (setq outer-loop-done t))
- (if outer-loop-done
- nil
- ;; If this line had ..))) (((.. in it, pop out of the levels
- ;; that ended anywhere in this line, even if the final depth
- ;; doesn't indicate that they ended.
- (while (> last-depth (nth 6 state))
- (setq indent-stack (cdr indent-stack)
- contain-stack (cdr contain-stack)
- last-depth (1- last-depth)))
- (if (/= last-depth next-depth)
- (setq last-sexp nil))
- ;; Add levels for any parens that were started in this line.
- (while (< last-depth next-depth)
- (setq indent-stack (cons nil indent-stack)
- contain-stack (cons nil contain-stack)
- last-depth (1+ last-depth)))
- (if (null (car contain-stack))
- (setcar contain-stack (or (car (cdr state))
- (save-excursion (forward-sexp -1)
- (point)))))
- (forward-line 1)
- (skip-chars-forward " \t")
- (if (eolp)
- nil
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- ;; Line is on an existing nesting level.
- ;; Lines inside parens are handled specially.
- (if (/= (char-after (car contain-stack)) ?\{)
- (setq this-indent (car indent-stack))
- ;; Line is at statement level.
- ;; Is it a new statement? Is it an else?
- ;; Find last non-comment character before this line
- (save-excursion
- (setq at-else (looking-at "else\\W"))
- (setq at-brace (= (following-char) ?\{))
- (c++-backward-to-noncomment opoint)
- (if (not (memq (preceding-char) '(nil ?\, ?\; ?\} ?: ?\{)))
- ;; Preceding line did not end in comma or semi;
- ;; indent this line c-continued-statement-offset
- ;; more than previous.
- (progn
- (c-backward-to-start-of-continued-exp
- (car contain-stack))
- (setq this-indent
- (+ c-continued-statement-offset
- (current-column)
- (if at-brace c-continued-brace-offset 0))))
- ;; Preceding line ended in comma or semi;
- ;; use the standard indent for this level.
- (if at-else
- (progn (c-backward-to-start-of-if opoint)
- (setq this-indent (current-indentation)))
- (setq this-indent (car indent-stack))))))
- ;; Just started a new nesting level.
- ;; Compute the standard indent for this level.
- (let ((val (calculate-c++-indent
- (if (car indent-stack)
- (- (car indent-stack))))))
- (setcar indent-stack
- (setq this-indent val))))
- ;; Adjust line indentation according to its contents
- (if (looking-at "\\(public\\|private\\|protected\\):")
- (setq this-indent (- this-indent c-indent-level)))
- (if (or (looking-at "case[ \t]")
- (and (looking-at "[A-Za-z]")
- (save-excursion
- (forward-sexp 1)
- (looking-at ":[^:]"))))
- (setq this-indent (max 1 (+ this-indent c-label-offset))))
- (if (looking-at "friend[ \t]")
- (setq this-indent (+ this-indent c++-friend-offset)))
- (if (= (following-char) ?\})
- (setq this-indent (- this-indent c-indent-level)))
- (if (= (following-char) ?\{)
- (setq this-indent (+ this-indent c-brace-offset)))
- ;; Put chosen indentation into effect.
- (or (= (current-column) this-indent)
- (= (following-char) ?\#)
- (progn
- (delete-region (point) (progn (beginning-of-line) (point)))
- (indent-to this-indent)))
- ;; Indent any comment following the text.
- (or (looking-at comment-start-skip)
- (if (re-search-forward comment-start-skip
- (save-excursion (end-of-line)
- (point)) t)
- (progn
- (indent-for-comment)
- (beginning-of-line))))))))))
-
-(defun fill-c++-comment ()
- "Fill a comment contained in consecutive lines containing point.
-The fill lines remain a comment."
- (interactive)
- (save-excursion
- (let ((save fill-prefix))
- (beginning-of-line 1)
- (save-excursion
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line) (point))
- t)
- (goto-char (match-end 0))
- (set-fill-prefix))
- (while (looking-at fill-prefix)
- (previous-line 1))
- (next-line 1)
- (insert-string "\n")
- (fill-paragraph nil)
- (delete-char -1)
- (setq fill-prefix save))))
-
-(defun c++-point-bol ()
- "Returns the value of the point at the beginning of the current line."
- (save-excursion
- (beginning-of-line)
- (point)))
-
-;; (defun c++-insert-header ()
-;; "Insert header denoting C++ code at top of buffer."
-;; (interactive)
-;; (save-excursion
-;; (goto-char (point-min))
-;; (insert "// "
-;; "This may look like C code, but it is really "
-;; "-*- C++ -*-"
-;; "\n\n")))
-
-(defun c++-within-string-p (point1 point2)
- "Returns true if number of double quotes between two points is odd."
- (let ((s (buffer-substring point1 point2)))
- (not (zerop (% (c++-count-char-in-string ?\" s) 2)))))
-
-(defun c++-count-char-in-string (c s)
- (let ((count 0)
- (pos 0))
- (while (< pos (length s))
- (setq count (+ count (if (\= (aref s pos) c) 1 0)))
- (setq pos (1+ pos)))
- count))
-
-;; rms: This page is creeping featurism, and not worth having.
-
-;;; Below are two regular expressions that attempt to match defuns
-;;; "strongly" and "weakly." The strong one almost reconstructs the
-;;; grammar of C++; the weak one just figures anything id or curly on
-;;; the left begins a defun. The constant "c++-match-header-strongly"
-;;; determines which to use; the default is the weak one.
-
-;; (defvar c++-match-header-strongly nil
-;; "*If nil, use `c++-defun-header-weak' to identify beginning of definitions.
-;; If non-nil, use `c++-defun-header-strong'.")
-;;
-;; (defvar c++-defun-header-strong-struct-equivs "\\(class\\|struct\\|enum\\)"
-;; "Regexp to match names of structure declaration blocks in C++.")
-;;
-;; (defconst c++-defun-header-strong
-;; (let*
-;; (; valid identifiers
-;; ;; There's a real weirdness here -- if I switch the below
-;; (id "\\(\\w\\|_\\)+")
-;; ;; to be
-;; ;; (id "\\(_\\|\\w\\)+")
-;; ;; things no longer work right. Try it and see!
-;;
-;; ; overloadable operators
-;; (op-sym1
-;; "[-+*/%^&|~!=<>]\\|[-+*/%^&|<>=!]=\\|<<=?\\|>>=?")
-;; (op-sym2
-;; "&&\\|||\\|\\+\\+\\|--\\|()\\|\\[\\]")
-;; (op-sym (concat "\\(" op-sym1 "\\|" op-sym2 "\\)"))
-;; ; whitespace
-;; (middle "[^\\*]*\\(\\*+[^/\\*][^\\*]*\\)*")
-;; (c-comment (concat "/\\*" middle "\\*+/"))
-;; (wh (concat "\\(\\s \\|\n\\|//.*$\\|" c-comment "\\)"))
-;; (wh-opt (concat wh "*"))
-;; (wh-nec (concat wh "+"))
-;; (oper (concat "\\(" "operator" "\\("
-;; wh-opt op-sym "\\|" wh-nec id "\\)" "\\)"))
-;; (dcl-list "([^():]*)")
-;; (func-name (concat "\\(" oper "\\|" id "::" id "\\|" id "\\)"))
-;; (inits
-;; (concat "\\(:"
-;; "\\(" wh-opt id "(.*\\()" wh-opt "," "\\)\\)*"
-;; wh-opt id "(.*)" wh-opt "{"
-;; "\\|" wh-opt "{\\)"))
-;; (type-name (concat
-;; "\\(" c++-defun-header-strong-struct-equivs wh-nec "\\)?"
-;; id))
-;; (type (concat "\\(const" wh-nec "\\)?"
-;; "\\(" type-name "\\|" type-name wh-opt "\\*+" "\\|"
-;; type-name wh-opt "&" "\\)"))
-;; (modifier "\\(inline\\|virtual\\|overload\\|auto\\|static\\)")
-;; (modifiers (concat "\\(" modifier wh-nec "\\)*"))
-;; (func-header
-;; ;; type arg-dcl
-;; (concat modifiers type wh-nec func-name wh-opt dcl-list wh-opt inits))
-;; (inherit (concat "\\(:" wh-opt "\\(public\\|private\\)?"
-;; wh-nec id "\\)"))
-;; (cs-header (concat
-;; c++-defun-header-strong-struct-equivs
-;; wh-nec id wh-opt inherit "?" wh-opt "{")))
-;; (concat "^\\(" func-header "\\|" cs-header "\\)"))
-;; "Strongly-defined regexp to match beginning of structure or function def.")
-;;
-;;
-;; ;; This part has to do with recognizing defuns.
-;;
-;; ;; The weak convention we will use is that a defun begins any time
-;; ;; there is a left curly brace, or some identifier on the left margin,
-;; ;; followed by a left curly somewhere on the line. (This will also
-;; ;; incorrectly match some continued strings, but this is after all
-;; ;; just a weak heuristic.) Suggestions for improvement (short of the
-;; ;; strong scheme shown above) are welcomed.
-;;
-;; (defconst c++-defun-header-weak "^{\\|^[_a-zA-Z].*{"
-;; "Weakly-defined regexp to match beginning of structure or function def.")
-;;
-;; (defun c++-beginning-of-defun (arg)
-;; (interactive "p")
-;; (let ((c++-defun-header (if c++-match-header-strongly
-;; c++-defun-header-strong
-;; c++-defun-header-weak)))
-;; (cond ((or (= arg 0) (and (> arg 0) (bobp))) nil)
-;; ((and (not (looking-at c++-defun-header))
-;; (let ((curr-pos (point))
-;; (open-pos (if (search-forward "{" nil 'move)
-;; (point)))
-;; (beg-pos
-;; (if (re-search-backward c++-defun-header nil 'move)
-;; (match-beginning 0))))
-;; (if (and open-pos beg-pos
-;; (< beg-pos curr-pos)
-;; (> open-pos curr-pos))
-;; (progn
-;; (goto-char beg-pos)
-;; (if (= arg 1) t nil));; Are we done?
-;; (goto-char curr-pos)
-;; nil))))
-;; (t
-;; (if (and (looking-at c++-defun-header) (not (bobp)))
-;; (forward-char (if (< arg 0) 1 -1)))
-;; (and (re-search-backward c++-defun-header nil 'move (or arg 1))
-;; (goto-char (match-beginning 0)))))))
-;;
-;;
-;; (defun c++-end-of-defun (arg)
-;; (interactive "p")
-;; (let ((c++-defun-header (if c++-match-header-strongly
-;; c++-defun-header-strong
-;; c++-defun-header-weak)))
-;; (if (and (eobp) (> arg 0))
-;; nil
-;; (if (and (> arg 0) (looking-at c++-defun-header)) (forward-char 1))
-;; (let ((pos (point)))
-;; (c++-beginning-of-defun
-;; (if (< arg 0)
-;; (- (- arg (if (eobp) 0 1)))
-;; arg))
-;; (if (and (< arg 0) (bobp))
-;; t
-;; (if (re-search-forward c++-defun-header nil 'move)
-;; (progn (forward-char -1)
-;; (forward-sexp)
-;; (beginning-of-line 2)))
-;; (if (and (= pos (point))
-;; (re-search-forward c++-defun-header nil 'move))
-;; (c++-end-of-defun 1))))
-;; t)))
-;;
-;; (defun c++-indent-defun ()
-;; "Indents the current function definition, struct or class declaration."
-;; (interactive)
-;; (let ((restore (point)))
-;; (c++-end-of-defun 1)
-;; (beginning-of-line 1)
-;; (let ((end (point)))
-;; (c++-beginning-of-defun 1)
-;; (while (<= (point) end)
-;; (c++-indent-line)
-;; (next-line 1)
-;; (beginning-of-line 1)))
-;; (goto-char restore)))
-
-;;; cplus-md.el ends here
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
deleted file mode 100644
index bbcf7e96828..00000000000
--- a/lisp/progmodes/etags.el
+++ /dev/null
@@ -1,1447 +0,0 @@
-;;; etags.el --- etags facility for Emacs
-
-;; Copyright (C) 1985, 1986, 1988, 1989, 1992, 1993, 1994
-;; Free Software Foundation, Inc.
-
-;; Author: Roland McGrath <roland@gnu.ai.mit.edu>
-;; Keywords: tools
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Code:
-
-;;;###autoload
-(defvar tags-file-name nil
- "*File name of tags table.
-To switch to a new tags table, setting this variable is sufficient.
-If you set this variable, do not also set `tags-table-list'.
-Use the `etags' program to make a tags table file.")
-;; Make M-x set-variable tags-file-name like M-x visit-tags-table.
-;;;###autoload (put 'tags-file-name 'variable-interactive "fVisit tags table: ")
-
-;;;###autoload
-;; Use `visit-tags-table-buffer' to cycle through tags tables in this list.
-(defvar tags-table-list nil
- "*List of file names of tags tables to search.
-An element that is a directory means the file \"TAGS\" in that directory.
-To switch to a new list of tags tables, setting this variable is sufficient.
-If you set this variable, do not also set `tags-file-name'.
-Use the `etags' program to make a tags table file.")
-
-;;;###autoload
-(defvar tags-add-tables 'ask-user
- "*T means always add a new tags table to the current list.
-Nil means never add to the current list; always start a new list.
-Non-nil but not t says to ask the user whether to add a new tags table
-to the current list (as opposed to starting a new list).")
-
-(defvar tags-table-list-pointer nil
- "Pointer into `tags-table-list' where the current state of searching is.
-Might instead point into a list of included tags tables.
-Use `visit-tags-table-buffer' to cycle through tags tables in this list.")
-
-(defvar tags-table-list-started-at nil
- "Pointer into `tags-table-list', where the current search started.")
-
-(defvar tags-table-parent-pointer-list nil
- "Saved state of the tags table that included this one.
-Each element is (POINTER . STARTED-AT), giving the values of
- `tags-table-list-pointer' and `tags-table-list-started-at' from
- before we moved into the current table.")
-
-(defvar tags-table-set-list nil
- "List of sets of tags table which have been used together in the past.
-Each element is a list of strings which are file names.")
-
-;;;###autoload
-(defvar find-tag-hook nil
- "*Hook to be run by \\[find-tag] after finding a tag. See `run-hooks'.
-The value in the buffer in which \\[find-tag] is done is used,
-not the value in the buffer \\[find-tag] goes to.")
-
-;;;###autoload
-(defvar find-tag-default-function nil
- "*A function of no arguments used by \\[find-tag] to pick a default tag.
-If nil, and the symbol that is the value of `major-mode'
-has a `find-tag-default-function' property (see `put'), that is used.
-Otherwise, `find-tag-default' is used.")
-
-(defvar default-tags-table-function nil
- "If non-nil, a function to choose a default tags file for a buffer.
-This function receives no arguments and should return the default
-tags table file to use for the current buffer.")
-
-(defvar tags-location-stack nil
- "List of markers which are locations visited by \\[find-tag].
-Pop back to the last location with \\[negative-argument] \\[find-tag].")
-
-;; Tags table state.
-;; These variables are local in tags table buffers.
-
-(defvar tag-lines-already-matched nil
- "List of positions of beginnings of lines within the tags table
-that are already matched.")
-
-(defvar tags-table-files nil
- "List of file names covered by current tags table.
-nil means it has not yet been computed; use `tags-table-files' to do so.")
-
-(defvar tags-completion-table nil
- "Alist of tag names defined in current tags table.")
-
-(defvar tags-included-tables nil
- "List of tags tables included by the current tags table.")
-
-(defvar next-file-list nil
- "List of files for \\[next-file] to process.")
-
-;; Hooks for file formats.
-
-(defvar tags-table-format-hooks '(etags-recognize-tags-table
- recognize-empty-tags-table)
- "List of functions to be called in a tags table buffer to identify
-the type of tags table. The functions are called in order, with no arguments,
-until one returns non-nil. The function should make buffer-local bindings
-of the format-parsing tags function variables if successful.")
-
-(defvar file-of-tag-function nil
- "Function to do the work of `file-of-tag' (which see).")
-(defvar tags-table-files-function nil
- "Function to do the work of `tags-table-files' (which see).")
-(defvar tags-completion-table-function nil
- "Function to build the tags-completion-table.")
-(defvar snarf-tag-function nil
- "Function to get info about a matched tag for `goto-tag-location-function'.")
-(defvar goto-tag-location-function nil
- "Function of to go to the location in the buffer specified by a tag.
-One argument, the tag info returned by `snarf-tag-function'.")
-(defvar find-tag-regexp-search-function nil
- "Search function passed to `find-tag-in-order' for finding a regexp tag.")
-(defvar find-tag-regexp-tag-order nil
- "Tag order passed to `find-tag-in-order' for finding a regexp tag.")
-(defvar find-tag-regexp-next-line-after-failure-p nil
- "Flag passed to `find-tag-in-order' for finding a regexp tag.")
-(defvar find-tag-search-function nil
- "Search function passed to `find-tag-in-order' for finding a tag.")
-(defvar find-tag-tag-order nil
- "Tag order passed to `find-tag-in-order' for finding a tag.")
-(defvar find-tag-next-line-after-failure-p nil
- "Flag passed to `find-tag-in-order' for finding a tag.")
-(defvar list-tags-function nil
- "Function to do the work of `list-tags' (which see).")
-(defvar tags-apropos-function nil
- "Function to do the work of `tags-apropos' (which see).")
-(defvar tags-included-tables-function nil
- "Function to do the work of `tags-included-tables' (which see).")
-(defvar verify-tags-table-function nil
- "Function to return t iff the current buffer contains a valid
-\(already initialized\) tags file.")
-
-;; Initialize the tags table in the current buffer.
-;; Returns non-nil iff it is a valid tags table. On
-;; non-nil return, the tags table state variable are
-;; made buffer-local and initialized to nil.
-(defun initialize-new-tags-table ()
- (set (make-local-variable 'tag-lines-already-matched) nil)
- (set (make-local-variable 'tags-table-files) nil)
- (set (make-local-variable 'tags-completion-table) nil)
- (set (make-local-variable 'tags-included-tables) nil)
- ;; Value is t if we have found a valid tags table buffer.
- (let ((hooks tags-table-format-hooks))
- (while (and hooks
- (not (funcall (car hooks))))
- (setq hooks (cdr hooks)))
- hooks))
-
-;;;###autoload
-(defun visit-tags-table (file &optional local)
- "Tell tags commands to use tags table file FILE.
-FILE should be the name of a file created with the `etags' program.
-A directory name is ok too; it means file TAGS in that directory.
-
-Normally \\[visit-tags-table] sets the global value of `tags-file-name'.
-With a prefix arg, set the buffer-local value instead.
-When you find a tag with \\[find-tag], the buffer it finds the tag
-in is given a local value of this variable which is the name of the tags
-file the tag was in."
- (interactive (list (read-file-name "Visit tags table: (default TAGS) "
- default-directory
- (expand-file-name "TAGS"
- default-directory)
- t)
- current-prefix-arg))
- ;; Calling visit-tags-table-buffer with tags-file-name set to FILE will
- ;; initialize a buffer for FILE and set tags-file-name to the
- ;; fully-expanded name.
- (let ((tags-file-name file))
- (save-excursion
- (or (visit-tags-table-buffer 'same)
- (signal 'file-error (list "Visiting tags table"
- "file does not exist"
- file)))
- ;; Set FILE to the expanded name.
- (setq file tags-file-name)))
- (if local
- ;; Set the local value of tags-file-name.
- (set (make-local-variable 'tags-file-name) file)
- ;; Set the global value of tags-file-name.
- (setq-default tags-file-name file)))
-
-;; Move tags-table-list-pointer along and set tags-file-name.
-;; If NO-INCLUDES is non-nil, ignore included tags tables.
-;; Returns nil when out of tables.
-(defun tags-next-table (&optional no-includes)
- ;; Do we have any included tables?
- (if (and (not no-includes)
- (visit-tags-table-buffer 'same)
- (tags-included-tables))
-
- ;; Move into the included tags tables.
- (setq tags-table-parent-pointer-list
- ;; Save the current state of what table we are in.
- (cons (cons tags-table-list-pointer tags-table-list-started-at)
- tags-table-parent-pointer-list)
- ;; Start the pointer in the list of included tables.
- tags-table-list-pointer tags-included-tables
- tags-table-list-started-at tags-included-tables)
-
- ;; No included tables. Go to the next table in the list.
- (setq tags-table-list-pointer
- (cdr tags-table-list-pointer))
- (or tags-table-list-pointer
- ;; Wrap around.
- (setq tags-table-list-pointer tags-table-list))
-
- (if (eq tags-table-list-pointer tags-table-list-started-at)
- ;; We have come full circle. No more tables.
- (if tags-table-parent-pointer-list
- ;; Pop back to the tags table which includes this one.
- (progn
- ;; Restore the state variables.
- (setq tags-table-list-pointer
- (car (car tags-table-parent-pointer-list))
- tags-table-list-started-at
- (cdr (car tags-table-parent-pointer-list))
- tags-table-parent-pointer-list
- (cdr tags-table-parent-pointer-list))
- ;; Recurse to skip to the next table after the parent.
- (tags-next-table t))
- ;; All out of tags tables.
- (setq tags-table-list-pointer nil))))
-
- (and tags-table-list-pointer
- ;; Set tags-file-name to the fully-expanded name.
- (setq tags-file-name
- (tags-expand-table-name (car tags-table-list-pointer)))))
-
-;; Expand tags table name FILE into a complete file name.
-(defun tags-expand-table-name (file)
- (setq file (expand-file-name file))
- (if (file-directory-p file)
- (expand-file-name "TAGS" file)
- file))
-
-;; Return the cdr of LIST (default: tags-table-list) whose car
-;; is equal to FILE after tags-expand-table-name on both sides.
-(defun tags-table-list-member (file &optional list)
- (or list
- (setq list tags-table-list))
- (setq file (tags-expand-table-name file))
- (while (and list
- (not (string= file (tags-expand-table-name (car list)))))
- (setq list (cdr list)))
- list)
-
-;; Local var in visit-tags-table-buffer-cont
-;; which is set by tags-table-including.
-(defvar visit-tags-table-buffer-cont)
-
-;; Subroutine of visit-tags-table-buffer. Frobs its local vars.
-;; Search TABLES for one that has tags for THIS-FILE. Recurses on
-;; included tables. Returns the tail of TABLES (or of an inner
-;; included list) whose car is a table listing THIS-FILE. If
-;; CORE-ONLY is non-nil, check only tags tables that are already in
-;; buffers--don't visit any new files.
-(defun tags-table-including (this-file tables core-only &optional recursing)
- (let ((found nil))
- ;; Loop over TABLES, looking for one containing tags for THIS-FILE.
- (while (and (not found)
- tables)
- (let ((tags-file-name (tags-expand-table-name (car tables))))
- (if (or (get-file-buffer tags-file-name)
- (and (not core-only)
- (file-exists-p tags-file-name)))
- (progn
- ;; Select the tags table buffer and get the file list up to date.
- (visit-tags-table-buffer 'same)
- (or tags-table-files
- (setq tags-table-files
- (funcall tags-table-files-function)))
-
- (cond ((member this-file tags-table-files)
- ;; Found it.
- (setq found tables))
-
- ((tags-included-tables)
- ;; This table has included tables. Check them.
- (let ((old tags-table-parent-pointer-list))
- (unwind-protect
- (progn
- (or recursing
- ;; At top level (not in an included tags
- ;; table), set the list to nil so we can
- ;; collect just the elts from this run.
- (setq tags-table-parent-pointer-list nil))
- (setq found
- ;; Recurse on the list of included tables.
- (tags-table-including this-file
- tags-included-tables
- core-only
- t))
- (if found
- ;; One of them lists THIS-FILE.
- ;; Set the table list state variables to move
- ;; us inside the list of included tables.
- (setq tags-table-parent-pointer-list
- (cons
- (cons tags-table-list-pointer
- tags-table-list-started-at)
- tags-table-parent-pointer-list)
- tags-table-list-pointer found
- tags-table-list-started-at found
- ;; Set a local variable of
- ;; our caller, visit-tags-table-buffer.
- ;; Set it so we won't frob lists later.
- visit-tags-table-buffer-cont
- 'included)))
- (or recursing
- ;; tags-table-parent-pointer-list now describes
- ;; the path of included tables taken by recursive
- ;; invocations of this function. The recursive
- ;; calls have consed onto the front of the list,
- ;; so it is now outermost first. We want it
- ;; innermost first, so reverse it. Then append
- ;; the old list (from before we were called the
- ;; outermost time), to get the complete current
- ;; state of included tables.
- (setq tags-table-parent-pointer-list
- (nconc (nreverse
- tags-table-parent-pointer-list)
- old))))))))))
- (setq tables (cdr tables)))
- found))
-
-(defun visit-tags-table-buffer (&optional cont)
- "Select the buffer containing the current tags table.
-If optional arg is t, visit the next table in `tags-table-list'.
-If optional arg is the atom `same', don't look for a new table;
- just select the buffer visiting `tags-file-name'.
-If arg is nil or absent, choose a first buffer from information in
- `tags-file-name', `tags-table-list', `tags-table-list-pointer'.
-Returns t if it visits a tags table, or nil if there are no more in the list."
-
- ;; Set tags-file-name to the tags table file we want to visit.
- (let ((visit-tags-table-buffer-cont cont))
- (cond ((eq visit-tags-table-buffer-cont 'same)
- ;; Use the ambient value of tags-file-name.
- (or tags-file-name
- (error (substitute-command-keys
- (concat "No tags table in use! "
- "Use \\[visit-tags-table] to select one.")))))
-
- (visit-tags-table-buffer-cont
- ;; Find the next table.
- (if (tags-next-table)
- ;; Skip over nonexistent files.
- (let (file)
- (while (and (setq file
- (tags-expand-table-name tags-file-name))
- (not (or (get-file-buffer file)
- (file-exists-p file))))
- (tags-next-table)))))
-
- (t
- ;; Pick a table out of our hat.
- (setq tags-file-name
- (or
- ;; First, try a local variable.
- (cdr (assq 'tags-file-name (buffer-local-variables)))
- ;; Second, try a user-specified function to guess.
- (and default-tags-table-function
- (funcall default-tags-table-function))
- ;; Third, look for a tags table that contains
- ;; tags for the current buffer's file.
- ;; If one is found, the lists will be frobnicated,
- ;; and VISIT-TAGS-TABLE-BUFFER-CONT
- ;; will be set non-nil so we don't do it below.
- (car (or
- ;; First check only tables already in buffers.
- (save-excursion (tags-table-including buffer-file-name
- tags-table-list
- t))
- ;; Since that didn't find any, now do the
- ;; expensive version: reading new files.
- (save-excursion (tags-table-including buffer-file-name
- tags-table-list
- nil))))
- ;; Fourth, use the user variable tags-file-name, if it is not
- ;; already in tags-table-list.
- (and tags-file-name
- (not (tags-table-list-member tags-file-name))
- tags-file-name)
- ;; Fifth, use the user variable giving the table list.
- ;; Find the first element of the list that actually exists.
- (let ((list tags-table-list)
- file)
- (while (and list
- (setq file (tags-expand-table-name (car list)))
- (not (get-file-buffer file))
- (not (file-exists-p file)))
- (setq list (cdr list)))
- (car list))
- ;; Finally, prompt the user for a file name.
- (expand-file-name
- (read-file-name "Visit tags table: (default TAGS) "
- default-directory
- "TAGS"
- t))))))
-
- ;; Expand the table name into a full file name.
- (setq tags-file-name (tags-expand-table-name tags-file-name))
-
- (if (and (eq visit-tags-table-buffer-cont t)
- (null tags-table-list-pointer))
- ;; All out of tables.
- nil
-
- ;; Verify that tags-file-name is a valid tags table.
- (if (if (get-file-buffer tags-file-name)
- ;; The file is already in a buffer. Check for the visited file
- ;; having changed since we last used it.
- (let (win)
- (set-buffer (get-file-buffer tags-file-name))
- (setq win (or verify-tags-table-function
- (initialize-new-tags-table)))
- (if (or (verify-visited-file-modtime (current-buffer))
- (not (yes-or-no-p
- "Tags file has changed, read new contents? ")))
- (and win (funcall verify-tags-table-function))
- (revert-buffer t t)
- (initialize-new-tags-table)))
- (set-buffer (find-file-noselect tags-file-name))
- (or (string= tags-file-name buffer-file-name)
- ;; find-file-noselect has changed the file name.
- ;; Propagate the change to tags-file-name and tags-table-list.
- (let ((tail (member tags-file-name tags-table-list)))
- (if tail
- (setcar tail buffer-file-name))
- (setq tags-file-name buffer-file-name)))
- (initialize-new-tags-table))
-
- ;; We have a valid tags table.
- (progn
- ;; Bury the tags table buffer so it
- ;; doesn't get in the user's way.
- (bury-buffer (current-buffer))
-
- (if (memq visit-tags-table-buffer-cont '(same nil))
- ;; Look in the list for the table we chose.
- (let ((elt (tags-table-list-member tags-file-name)))
- (or elt
- ;; The table is not in the current set.
- ;; Try to find it in another previously used set.
- (let ((sets tags-table-set-list))
- (while (and sets
- (not (setq elt
- (tags-table-list-member
- tags-file-name (car sets)))))
- (setq sets (cdr sets)))
- (if sets
- ;; Found in some other set. Switch to that set.
- (progn
- (or (memq tags-table-list tags-table-set-list)
- ;; Save the current list.
- (setq tags-table-set-list
- (cons tags-table-list
- tags-table-set-list)))
- (setq tags-table-list (car sets)))
-
- ;; Not found in any existing set.
- (if (and tags-table-list
- (or (eq t tags-add-tables)
- (and tags-add-tables
- (y-or-n-p
- (concat "Keep current list of "
- "tags tables also? ")))))
- ;; Add it to the current list.
- (setq tags-table-list (cons tags-file-name
- tags-table-list))
- ;; Make a fresh list, and store the old one.
- (message "Starting a new list of tags tables")
- (or (memq tags-table-list tags-table-set-list)
- (setq tags-table-set-list
- (cons tags-table-list
- tags-table-set-list)))
- (setq tags-table-list (list tags-file-name)))
- (setq elt tags-table-list))))
-
- (or visit-tags-table-buffer-cont
- ;; Set the tags table list state variables to point
- ;; at the table we want to use first.
- (setq tags-table-list-started-at elt
- tags-table-list-pointer elt))))
-
- ;; Return of t says the tags table is valid.
- t)
-
- ;; The buffer was not valid. Don't use it again.
- (let ((file tags-file-name))
- (kill-local-variable 'tags-file-name)
- (if (eq file tags-file-name)
- (setq tags-file-name nil)))
- (error "File %s is not a valid tags table" buffer-file-name)))))
-
-(defun file-of-tag ()
- "Return the file name of the file whose tags point is within.
-Assumes the tags table is the current buffer.
-File name returned is relative to tags table file's directory."
- (funcall file-of-tag-function))
-
-;;;###autoload
-(defun tags-table-files ()
- "Return a list of files in the current tags table.
-Assumes the tags table is the current buffer.
-File names returned are absolute."
- (or tags-table-files
- (setq tags-table-files
- (funcall tags-table-files-function))))
-
-(defun tags-included-tables ()
- "Return a list of tags tables included by the current table.
-Assumes the tags table is the current buffer."
- (or tags-included-tables
- (setq tags-included-tables (funcall tags-included-tables-function))))
-
-;; Build tags-completion-table on demand. The single current tags table
-;; and its included tags tables (and their included tables, etc.) have
-;; their tags included in the completion table.
-(defun tags-completion-table ()
- (or tags-completion-table
- (condition-case ()
- (prog2
- (message "Making tags completion table for %s..." buffer-file-name)
- (let ((included (tags-included-tables))
- (table (funcall tags-completion-table-function)))
- (save-excursion
- ;; Iterate over the list of included tables, and combine each
- ;; included table's completion obarray to the parent obarray.
- (while included
- ;; Visit the buffer.
- (let ((tags-file-name (car included)))
- (visit-tags-table-buffer 'same))
- ;; Recurse in that buffer to compute its completion table.
- (if (tags-completion-table)
- ;; Combine the tables.
- (mapatoms (function
- (lambda (sym)
- (intern (symbol-name sym) table)))
- tags-completion-table))
- (setq included (cdr included))))
- (setq tags-completion-table table))
- (message "Making tags completion table for %s...done"
- buffer-file-name))
- (quit (message "Tags completion table construction aborted.")
- (setq tags-completion-table nil)))))
-
-;; Completion function for tags. Does normal try-completion,
-;; but builds tags-completion-table on demand.
-(defun tags-complete-tag (string predicate what)
- (save-excursion
- ;; If we need to ask for the tag table, allow that.
- (let ((enable-recursive-minibuffers t))
- (visit-tags-table-buffer))
- (if (eq what t)
- (all-completions string (tags-completion-table) predicate)
- (try-completion string (tags-completion-table) predicate))))
-
-;; Return a default tag to search for, based on the text at point.
-(defun find-tag-default ()
- (save-excursion
- (while (looking-at "\\sw\\|\\s_")
- (forward-char 1))
- (if (or (re-search-backward "\\sw\\|\\s_"
- (save-excursion (beginning-of-line) (point))
- t)
- (re-search-forward "\\(\\sw\\|\\s_\\)+"
- (save-excursion (end-of-line) (point))
- t))
- (progn (goto-char (match-end 0))
- (buffer-substring (point)
- (progn (forward-sexp -1)
- (while (looking-at "\\s'")
- (forward-char 1))
- (point))))
- nil)))
-
-;; Read a tag name from the minibuffer with defaulting and completion.
-(defun find-tag-tag (string)
- (let* ((default (funcall (or find-tag-default-function
- (get major-mode 'find-tag-default-function)
- 'find-tag-default)))
- (spec (completing-read (if default
- (format "%s(default %s) " string default)
- string)
- 'tags-complete-tag)))
- (if (equal spec "")
- (or default (error "There is no default tag"))
- spec)))
-
-(defvar last-tag nil
- "Last tag found by \\[find-tag].")
-
-;; Get interactive args for find-tag{-noselect,-other-window,-regexp}.
-(defun find-tag-interactive (prompt &optional no-default)
- (if current-prefix-arg
- (list nil (if (< (prefix-numeric-value current-prefix-arg) 0)
- '-
- t))
- (list (if no-default
- (read-string prompt)
- (find-tag-tag prompt)))))
-
-;;;###autoload
-(defun find-tag-noselect (tagname &optional next-p regexp-p)
- "Find tag (in current tags table) whose name contains TAGNAME.
-Returns the buffer containing the tag's definition and moves its point there,
-but does not select the buffer.
-The default for TAGNAME is the expression in the buffer near point.
-
-If second arg NEXT-P is t (interactively, with prefix arg), search for
-another tag that matches the last tagname or regexp used. When there are
-multiple matches for a tag, more exact matches are found first. If NEXT-P
-is the atom `-' (interactively, with prefix arg that is a negative number
-or just \\[negative-argument]), pop back to the previous tag gone to.
-
-If third arg REGEXP-P is non-nil, treat TAGNAME as a regexp.
-
-See documentation of variable `tags-file-name'."
- (interactive (find-tag-interactive "Find tag: "))
-
- ;; Save the current buffer's value of `find-tag-hook' before selecting the
- ;; tags table buffer.
- (let ((local-find-tag-hook find-tag-hook))
- (if (eq '- next-p)
- ;; Pop back to a previous location.
- (if (null tags-location-stack)
- (error "No previous tag locations")
- (let ((marker (car tags-location-stack)))
- ;; Pop the stack.
- (setq tags-location-stack (cdr tags-location-stack))
- (prog1
- ;; Move to the saved location.
- (set-buffer (marker-buffer marker))
- (goto-char (marker-position marker))
- ;; Kill that marker so it doesn't slow down editing.
- (set-marker marker nil nil)
- ;; Run the user's hook. Do we really want to do this for pop?
- (run-hooks 'local-find-tag-hook))))
- (if next-p
- ;; Find the same table we last used.
- (visit-tags-table-buffer 'same)
- ;; Pick a table to use.
- (visit-tags-table-buffer)
- ;; Record TAGNAME for a future call with NEXT-P non-nil.
- (setq last-tag tagname))
- (prog1
- ;; Record the location so we can pop back to it later.
- (marker-buffer
- (car
- (setq tags-location-stack
- (cons (let ((marker (make-marker)))
- (save-excursion
- (set-buffer
- ;; find-tag-in-order does the real work.
- (find-tag-in-order
- (if next-p last-tag tagname)
- (if regexp-p
- find-tag-regexp-search-function
- find-tag-search-function)
- (if regexp-p
- find-tag-regexp-tag-order
- find-tag-tag-order)
- (if regexp-p
- find-tag-regexp-next-line-after-failure-p
- find-tag-next-line-after-failure-p)
- (if regexp-p "matching" "containing")
- (not next-p)))
- (set-marker marker (point))))
- tags-location-stack))))
- (run-hooks 'local-find-tag-hook)))))
-
-;;;###autoload
-(defun find-tag (tagname &optional next-p regexp-p)
- "Find tag (in current tags table) whose name contains TAGNAME.
-Select the buffer containing the tag's definition, and move point there.
-The default for TAGNAME is the expression in the buffer around or before point.
-
-If second arg NEXT-P is t (interactively, with prefix arg), search for
-another tag that matches the last tagname or regexp used. When there are
-multiple matches for a tag, more exact matches are found first. If NEXT-P
-is the atom `-' (interactively, with prefix arg that is a negative number
-or just \\[negative-argument]), pop back to the previous tag gone to.
-
-See documentation of variable `tags-file-name'."
- (interactive (find-tag-interactive "Find tag: "))
- (switch-to-buffer (find-tag-noselect tagname next-p regexp-p)))
-;;;###autoload (define-key esc-map "." 'find-tag)
-
-;;;###autoload
-(defun find-tag-other-window (tagname &optional next-p regexp-p)
- "Find tag (in current tags table) whose name contains TAGNAME.
-Select the buffer containing the tag's definition in another window, and
-move point there. The default for TAGNAME is the expression in the buffer
-around or before point.
-
-If second arg NEXT-P is t (interactively, with prefix arg), search for
-another tag that matches the last tagname or regexp used. When there are
-multiple matches for a tag, more exact matches are found first. If NEXT-P
-is negative (interactively, with prefix arg that is a negative number or
-just \\[negative-argument]), pop back to the previous tag gone to.
-
-See documentation of variable `tags-file-name'."
- (interactive (find-tag-interactive "Find tag other window: "))
-
- ;; This hair is to deal with the case where the tag is found in the
- ;; selected window's buffer; without the hair, point is moved in both
- ;; windows. To prevent this, we save the selected window's point before
- ;; doing find-tag-noselect, and restore it after.
- (let* ((window-point (window-point (selected-window)))
- (tagbuf (find-tag-noselect tagname next-p regexp-p))
- (tagpoint (progn (set-buffer tagbuf) (point))))
- (set-window-point (prog1
- (selected-window)
- (switch-to-buffer-other-window tagbuf)
- ;; We have to set this new window's point; it
- ;; might already have been displaying a
- ;; different portion of tagbuf, in which case
- ;; switch-to-buffer-other-window doesn't set
- ;; the window's point from the buffer.
- (set-window-point (selected-window) tagpoint))
- window-point)))
-;;;###autoload (define-key ctl-x-4-map "." 'find-tag-other-window)
-
-;;;###autoload
-(defun find-tag-other-frame (tagname &optional next-p)
- "Find tag (in current tags table) whose name contains TAGNAME.
-Select the buffer containing the tag's definition in another frame, and
-move point there. The default for TAGNAME is the expression in the buffer
-around or before point.
-
-If second arg NEXT-P is t (interactively, with prefix arg), search for
-another tag that matches the last tagname or regexp used. When there are
-multiple matches for a tag, more exact matches are found first. If NEXT-P
-is negative (interactively, with prefix arg that is a negative number or
-just \\[negative-argument]), pop back to the previous tag gone to.
-
-See documentation of variable `tags-file-name'."
- (interactive (find-tag-interactive "Find tag other frame: "))
- (let ((pop-up-frames t))
- (find-tag-other-window tagname next-p)))
-;;;###autoload (define-key ctl-x-5-map "." 'find-tag-other-frame)
-
-;;;###autoload
-(defun find-tag-regexp (regexp &optional next-p other-window)
- "Find tag (in current tags table) whose name matches REGEXP.
-Select the buffer containing the tag's definition and move point there.
-
-If second arg NEXT-P is t (interactively, with prefix arg), search for
-another tag that matches the last tagname or regexp used. When there are
-multiple matches for a tag, more exact matches are found first. If NEXT-P
-is negative (interactively, with prefix arg that is a negative number or
-just \\[negative-argument]), pop back to the previous tag gone to.
-
-If third arg OTHER-WINDOW is non-nil, select the buffer in another window.
-
-See documentation of variable `tags-file-name'."
- (interactive (find-tag-interactive "Find tag regexp: " t))
- ;; We go through find-tag-other-window to do all the display hair there.
- (funcall (if other-window 'find-tag-other-window 'find-tag)
- regexp next-p t))
-
-;; Internal tag finding function.
-
-;; PATTERN is a string to pass to second arg SEARCH-FORWARD-FUNC, and to
-;; any member of the function list ORDER (third arg). If ORDER is nil,
-;; use saved state to continue a previous search.
-
-;; Fourth arg MATCHING is a string, an English '-ing' word, to be used in
-;; an error message.
-
-;; Fifth arg NEXT-LINE-AFTER-FAILURE-P is non-nil if after a failed match,
-;; point should be moved to the next line.
-
-;; Algorithm is as follows. For each qualifier-func in ORDER, go to
-;; beginning of tags file, and perform inner loop: for each naive match for
-;; PATTERN found using SEARCH-FORWARD-FUNC, qualify the naive match using
-;; qualifier-func. If it qualifies, go to the specified line in the
-;; specified source file and return. Qualified matches are remembered to
-;; avoid repetition. State is saved so that the loop can be continued.
-
-(defun find-tag-in-order (pattern
- search-forward-func
- order
- next-line-after-failure-p
- matching
- first-search)
- (let (file ;name of file containing tag
- tag-info ;where to find the tag in FILE
- tags-table-file ;name of tags file
- (first-table t)
- (tag-order order)
- goto-func
- )
- (save-excursion
- (or first-search ;find-tag-noselect has already done it.
- (visit-tags-table-buffer 'same))
-
- ;; Get a qualified match.
- (catch 'qualified-match-found
-
- ;; Iterate over the list of tags tables.
- (while (or first-table
- (visit-tags-table-buffer t))
-
- (if first-search
- (setq tag-lines-already-matched nil))
-
- (and first-search first-table
- ;; Start at beginning of tags file.
- (goto-char (point-min)))
- (setq first-table nil)
-
- (setq tags-table-file buffer-file-name)
- ;; Iterate over the list of ordering predicates.
- (while order
- (while (funcall search-forward-func pattern nil t)
- ;; Naive match found. Qualify the match.
- (and (funcall (car order) pattern)
- ;; Make sure it is not a previous qualified match.
- ;; Use of `memq' depends on numbers being eq.
- (not (memq (save-excursion (beginning-of-line) (point))
- tag-lines-already-matched))
- (throw 'qualified-match-found nil))
- (if next-line-after-failure-p
- (forward-line 1)))
- ;; Try the next flavor of match.
- (setq order (cdr order))
- (goto-char (point-min)))
- (setq order tag-order))
- ;; We throw out on match, so only get here if there were no matches.
- (error "No %stags %s %s" (if first-search "" "more ")
- matching pattern))
-
- ;; Found a tag; extract location info.
- (beginning-of-line)
- (setq tag-lines-already-matched (cons (point)
- tag-lines-already-matched))
- ;; Expand the filename, using the tags table buffer's default-directory.
- (setq file (expand-file-name (file-of-tag))
- tag-info (funcall snarf-tag-function))
-
- ;; Get the local value in the tags table buffer before switching buffers.
- (setq goto-func goto-tag-location-function)
-
- ;; Find the right line in the specified file.
- (set-buffer (find-file-noselect file))
- (widen)
- (push-mark)
- (funcall goto-func tag-info)
-
- ;; Give this buffer a local value of tags-file-name.
- ;; The next time visit-tags-table-buffer is called,
- ;; it will use the same tags table that found a match in this buffer.
- (make-local-variable 'tags-file-name)
- (setq tags-file-name tags-table-file)
-
- ;; Return the buffer where the tag was found.
- (current-buffer))))
-
-;; `etags' TAGS file format support.
-
-;; If the current buffer is a valid etags TAGS file, give it local values of
-;; the tags table format variables, and return non-nil.
-(defun etags-recognize-tags-table ()
- (and (etags-verify-tags-table)
- ;; It is annoying to flash messages on the screen briefly,
- ;; and this message is not useful. -- rms
- ;; (message "%s is an `etags' TAGS file" buffer-file-name)
- (mapcar (function (lambda (elt)
- (set (make-local-variable (car elt)) (cdr elt))))
- '((file-of-tag-function . etags-file-of-tag)
- (tags-table-files-function . etags-tags-table-files)
- (tags-completion-table-function . etags-tags-completion-table)
- (snarf-tag-function . etags-snarf-tag)
- (goto-tag-location-function . etags-goto-tag-location)
- (find-tag-regexp-search-function . re-search-forward)
- (find-tag-regexp-tag-order . (tag-re-match-p))
- (find-tag-regexp-next-line-after-failure-p . t)
- (find-tag-search-function . search-forward)
- (find-tag-tag-order . (tag-exact-match-p tag-word-match-p
- tag-any-match-p))
- (find-tag-next-line-after-failure-p . nil)
- (list-tags-function . etags-list-tags)
- (tags-apropos-function . etags-tags-apropos)
- (tags-included-tables-function . etags-tags-included-tables)
- (verify-tags-table-function . etags-verify-tags-table)
- ))))
-
-;; Return non-nil iff the current buffer is a valid etags TAGS file.
-(defun etags-verify-tags-table ()
- ;; Use eq instead of = in case char-after returns nil.
- (eq (char-after 1) ?\f))
-
-(defun etags-file-of-tag ()
- (save-excursion
- (search-backward "\f\n")
- (forward-char 2)
- (buffer-substring (point)
- (progn (skip-chars-forward "^,") (point)))))
-
-(defun etags-tags-completion-table ()
- (let ((table (make-vector 511 0)))
- (save-excursion
- (goto-char (point-min))
- ;; This monster regexp matches an etags tag line.
- ;; \1 is the string to match;
- ;; \2 is not interesting;
- ;; \3 is the guessed tag name; XXX guess should be better eg DEFUN
- ;; \4 is not interesting;
- ;; \5 is the explicitly-specified tag name.
- ;; \6 is the line to start searching at;
- ;; \7 is the char to start searching at.
- (while (re-search-forward
- "^\\(\\(.+[^-a-zA-Z0-9_$]+\\)?\\([-a-zA-Z0-9_$]+\\)\
-\[^-a-zA-Z0-9_$]*\\)\177\\(\\([^\n\001]+\\)\001\\)?\
-\\([0-9]+\\)?,\\([0-9]+\\)?\n"
- nil t)
- (intern (if (match-beginning 5)
- ;; There is an explicit tag name.
- (buffer-substring (match-beginning 5) (match-end 5))
- ;; No explicit tag name. Best guess.
- (buffer-substring (match-beginning 3) (match-end 3)))
- table)))
- table))
-
-(defun etags-snarf-tag ()
- (let (tag-text line startpos)
- (search-forward "\177")
- (setq tag-text (buffer-substring (1- (point))
- (save-excursion (beginning-of-line)
- (point))))
- ;; Skip explicit tag name if present.
- (search-forward "\001" (save-excursion (forward-line 1) (point)) t)
- (if (looking-at "[0-9]")
- (setq line (string-to-int (buffer-substring
- (point)
- (progn (skip-chars-forward "0-9")
- (point))))))
- (search-forward ",")
- (if (looking-at "[0-9]")
- (setq startpos (string-to-int (buffer-substring
- (point)
- (progn (skip-chars-forward "0-9")
- (point))))))
- ;; Leave point on the next line of the tags file.
- (forward-line 1)
- (cons tag-text (cons line startpos))))
-
-;; TAG-INFO is a cons (TEXT LINE . POSITION) where TEXT is the initial part
-;; of a line containing the tag and POSITION is the character position of
-;; TEXT within the file (starting from 1); LINE is the line number. Either
-;; LINE or POSITION may be nil; POSITION is used if present. If the tag
-;; isn't exactly at the given position then look around that position using
-;; a search window which expands until it hits the start of file.
-(defun etags-goto-tag-location (tag-info)
- (let ((startpos (cdr (cdr tag-info)))
- ;; This constant is 1/2 the initial search window.
- ;; There is no sense in making it too small,
- ;; since just going around the loop once probably
- ;; costs about as much as searching 2000 chars.
- (offset 1000)
- (found nil)
- (pat (concat (if (eq selective-display t)
- "\\(^\\|\^m\\)" "^")
- (regexp-quote (car tag-info)))))
- ;; If no char pos was given, try the given line number.
- (or startpos
- (if (car (cdr tag-info))
- (setq startpos (progn (goto-line (car (cdr tag-info)))
- (point)))))
- (or startpos
- (setq startpos (point-min)))
- ;; First see if the tag is right at the specified location.
- (goto-char startpos)
- (setq found (looking-at pat))
- (while (and (not found)
- (progn
- (goto-char (- startpos offset))
- (not (bobp))))
- (setq found
- (re-search-forward pat (+ startpos offset) t)
- offset (* 3 offset))) ; expand search window
- (or found
- (re-search-forward pat nil t)
- (error "Rerun etags: `%s' not found in %s"
- pat buffer-file-name)))
- ;; Position point at the right place
- ;; if the search string matched an extra Ctrl-m at the beginning.
- (and (eq selective-display t)
- (looking-at "\^m")
- (forward-char 1))
- (beginning-of-line))
-
-(defun etags-list-tags (file)
- (goto-char 1)
- (if (not (search-forward (concat "\f\n" file ",") nil t))
- nil
- (forward-line 1)
- (while (not (or (eobp) (looking-at "\f")))
- (let ((tag (buffer-substring (point)
- (progn (skip-chars-forward "^\177")
- (point)))))
- (princ (if (looking-at "[^\n]+\001")
- ;; There is an explicit tag name; use that.
- (buffer-substring (point)
- (progn (skip-chars-forward "^\001")
- (point)))
- tag)))
- (terpri)
- (forward-line 1))
- t))
-
-(defun etags-tags-apropos (string)
- (goto-char 1)
- (while (re-search-forward string nil t)
- (beginning-of-line)
- (princ (buffer-substring (point)
- (progn (skip-chars-forward "^\177")
- (point))))
- (terpri)
- (forward-line 1)))
-
-(defun etags-tags-table-files ()
- (let ((files nil)
- beg)
- (goto-char (point-min))
- (while (search-forward "\f\n" nil t)
- (setq beg (point))
- (skip-chars-forward "^,\n")
- (or (looking-at ",include$")
- ;; Expand in the default-directory of the tags table buffer.
- (setq files (cons (expand-file-name (buffer-substring beg (point)))
- files))))
- (nreverse files)))
-
-(defun etags-tags-included-tables ()
- (let ((files nil)
- beg)
- (goto-char (point-min))
- (while (search-forward "\f\n" nil t)
- (setq beg (point))
- (skip-chars-forward "^,\n")
- (if (looking-at ",include$")
- ;; Expand in the default-directory of the tags table buffer.
- (setq files (cons (expand-file-name (buffer-substring beg (point)))
- files))))
- (nreverse files)))
-
-;; Empty tags file support.
-
-;; Recognize an empty file and give it local values of the tags table format
-;; variables which do nothing.
-(defun recognize-empty-tags-table ()
- (and (zerop (buffer-size))
- (mapcar (function (lambda (sym)
- (set (make-local-variable sym) 'ignore)))
- '(tags-table-files-function
- tags-completion-table-function
- find-tag-regexp-search-function
- find-tag-search-function
- tags-apropos-function
- tags-included-tables-function))
- (set (make-local-variable 'verify-tags-table-function)
- (function (lambda ()
- (zerop (buffer-size)))))))
-
-;;; Match qualifier functions for tagnames.
-;;; XXX these functions assume etags file format.
-
-;; This might be a neat idea, but it's too hairy at the moment.
-;;(defmacro tags-with-syntax (&rest body)
-;; (` (let ((current (current-buffer))
-;; (otable (syntax-table))
-;; (buffer (find-file-noselect (file-of-tag)))
-;; table)
-;; (unwind-protect
-;; (progn
-;; (set-buffer buffer)
-;; (setq table (syntax-table))
-;; (set-buffer current)
-;; (set-syntax-table table)
-;; (,@ body))
-;; (set-syntax-table otable)))))
-;;(put 'tags-with-syntax 'edebug-form-spec '(&rest form))
-
-;; t if point is at a tag line that matches TAG "exactly".
-;; point should be just after a string that matches TAG.
-(defun tag-exact-match-p (tag)
- ;; The match is really exact if there is an explicit tag name.
- (or (looking-at (concat "[^\177]*\177" (regexp-quote tag) "\001"))
- ;; We also call it "exact" if it is surrounded by symbol boundaries.
- ;; This is needed because etags does not always generate explicit names.
- (and (looking-at "\\Sw.*\177") (looking-at "\\S_.*\177")
- (save-excursion
- (backward-char (1+ (length tag)))
- (and (looking-at "\\Sw") (looking-at "\\S_"))))))
-
-;; t if point is at a tag line that matches TAG as a word.
-;; point should be just after a string that matches TAG.
-(defun tag-word-match-p (tag)
- (and (looking-at "\\b.*\177")
- (save-excursion (backward-char (1+ (length tag)))
- (looking-at "\\b"))))
-
-;; t if point is in a tag line with a tag containing TAG as a substring.
-(defun tag-any-match-p (tag)
- (looking-at ".*\177"))
-
-;; t if point is at a tag line that matches RE as a regexp.
-(defun tag-re-match-p (re)
- (save-excursion
- (beginning-of-line)
- (let ((bol (point)))
- (and (search-forward "\177" (save-excursion (end-of-line) (point)) t)
- (re-search-backward re bol t)))))
-
-;;;###autoload
-(defun next-file (&optional initialize novisit)
- "Select next file among files in current tags table.
-
-A first argument of t (prefix arg, if interactive) initializes to the
-beginning of the list of files in the tags table. If the argument is
-neither nil nor t, it is evalled to initialize the list of files.
-
-Non-nil second argument NOVISIT means use a temporary buffer
- to save time and avoid uninteresting warnings.
-
-Value is nil if the file was already visited;
-if the file was newly read in, the value is the filename."
- (interactive "P")
- (cond ((not initialize)
- ;; Not the first run.
- )
- ((eq initialize t)
- ;; Initialize the list from the tags table.
- (save-excursion
- ;; Visit the tags table buffer to get its list of files.
- (visit-tags-table-buffer)
- (setq next-file-list (tags-table-files))))
- (t
- ;; Initialize the list by evalling the argument.
- (setq next-file-list (eval initialize))))
- (or next-file-list
- (save-excursion
- ;; Get the files from the next tags table.
- ;; When doing (visit-tags-table-buffer t),
- ;; the tags table buffer must be current.
- (if (and (visit-tags-table-buffer 'same)
- (visit-tags-table-buffer t))
- (setq next-file-list (tags-table-files))
- (and novisit
- (get-buffer " *next-file*")
- (kill-buffer " *next-file*"))
- (error "All files processed."))))
- (let ((new (not (get-file-buffer (car next-file-list)))))
- (if (not (and new novisit))
- (set-buffer (find-file-noselect (car next-file-list) novisit))
- ;; Like find-file, but avoids random warning messages.
- (set-buffer (get-buffer-create " *next-file*"))
- (kill-all-local-variables)
- (erase-buffer)
- (setq new (car next-file-list))
- (insert-file-contents new nil))
- (setq next-file-list (cdr next-file-list))
- new))
-
-(defvar tags-loop-operate nil
- "Form for `tags-loop-continue' to eval to change one file.")
-
-(defvar tags-loop-scan
- '(error (substitute-command-keys
- "No \\[tags-search] or \\[tags-query-replace] in progress."))
- "Form for `tags-loop-continue' to eval to scan one file.
-If it returns non-nil, this file needs processing by evalling
-\`tags-loop-operate'. Otherwise, move on to the next file.")
-
-;;;###autoload
-(defun tags-loop-continue (&optional first-time)
- "Continue last \\[tags-search] or \\[tags-query-replace] command.
-Used noninteractively with non-nil argument to begin such a command (the
-argument is passed to `next-file', which see).
-Two variables control the processing we do on each file:
-the value of `tags-loop-scan' is a form to be executed on each file
-to see if it is interesting (it returns non-nil if so)
-and `tags-loop-operate' is a form to execute to operate on an interesting file
-If the latter returns non-nil, we exit; otherwise we scan the next file."
- (interactive)
- (let (new
- (messaged nil))
- (while
- (progn
- ;; Scan files quickly for the first or next interesting one.
- (while (or first-time
- (save-restriction
- (widen)
- (not (eval tags-loop-scan))))
- (setq new (next-file first-time t))
- ;; If NEW is non-nil, we got a temp buffer,
- ;; and NEW is the file name.
- (if (or messaged
- (and (not first-time)
- (> baud-rate search-slow-speed)
- (setq messaged t)))
- (message "Scanning file %s..." (or new buffer-file-name)))
- (setq first-time nil)
- (goto-char (point-min)))
-
- ;; If we visited it in a temp buffer, visit it now for real.
- (if new
- (let ((pos (point)))
- (erase-buffer)
- (set-buffer (find-file-noselect new))
- (widen)
- (goto-char pos)))
-
- (switch-to-buffer (current-buffer))
-
- ;; Now operate on the file.
- ;; If value is non-nil, continue to scan the next file.
- (eval tags-loop-operate)))
- (and messaged
- (null tags-loop-operate)
- (message "Scanning file %s...found" buffer-file-name))))
-;;;###autoload (define-key esc-map "," 'tags-loop-continue)
-
-;;;###autoload
-(defun tags-search (regexp &optional file-list-form)
- "Search through all files listed in tags table for match for REGEXP.
-Stops when a match is found.
-To continue searching for next match, use command \\[tags-loop-continue].
-
-See documentation of variable `tags-file-name'."
- (interactive "sTags search (regexp): ")
- (if (and (equal regexp "")
- (eq (car tags-loop-scan) 're-search-forward)
- (null tags-loop-operate))
- ;; Continue last tags-search as if by M-,.
- (tags-loop-continue nil)
- (setq tags-loop-scan
- (list 're-search-forward regexp nil t)
- tags-loop-operate nil)
- (tags-loop-continue (or file-list-form t))))
-
-;;;###autoload
-(defun tags-query-replace (from to &optional delimited file-list-form)
- "Query-replace-regexp FROM with TO through all files listed in tags table.
-Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
-If you exit (\\[keyboard-quit] or ESC), you can resume the query-replace
-with the command \\[tags-loop-continue].
-
-See documentation of variable `tags-file-name'."
- (interactive
- "sTags query replace (regexp): \nsTags query replace %s by: \nP")
- (setq tags-loop-scan (list 'prog1
- (list 'if (list 're-search-forward from nil t)
- ;; When we find a match, move back
- ;; to the beginning of it so perform-replace
- ;; will see it.
- '(goto-char (match-beginning 0))))
- tags-loop-operate (list 'perform-replace from to t t delimited))
- (tags-loop-continue (or file-list-form t)))
-
-;;;###autoload
-(defun list-tags (file)
- "Display list of tags in file FILE.
-FILE should not contain a directory specification."
- (interactive (list (completing-read "List tags in file: "
- (save-excursion
- (visit-tags-table-buffer)
- (mapcar 'list
- (mapcar 'file-name-nondirectory
- (tags-table-files))))
- nil t nil)))
- (with-output-to-temp-buffer "*Tags List*"
- (princ "Tags in file ")
- (princ file)
- (terpri)
- (save-excursion
- (let ((first-time t)
- (gotany nil))
- (while (visit-tags-table-buffer (not first-time))
- (setq first-time nil)
- (if (funcall list-tags-function file)
- (setq gotany t)))
- (or gotany
- (error "File %s not in current tags tables" file))))))
-
-;;;###autoload
-(defun tags-apropos (regexp)
- "Display list of all tags in tags table REGEXP matches."
- (interactive "sTags apropos (regexp): ")
- (with-output-to-temp-buffer "*Tags List*"
- (princ "Tags matching regexp ")
- (prin1 regexp)
- (terpri)
- (save-excursion
- (let ((first-time t))
- (while (visit-tags-table-buffer (not first-time))
- (setq first-time nil)
- (funcall tags-apropos-function regexp))))))
-
-;;; XXX Kludge interface.
-
-;; XXX If a file is in multiple tables, selection may get the wrong one.
-;;;###autoload
-(defun select-tags-table ()
- "Select a tags table file from a menu of those you have already used.
-The list of tags tables to select from is stored in `tags-table-file-list';
-see the doc of that variable if you want to add names to the list."
- (interactive)
- (pop-to-buffer "*Tags Table List*")
- (setq buffer-read-only nil)
- (erase-buffer)
- (setq selective-display t
- selective-display-ellipses nil)
- (let ((set-list tags-table-set-list)
- (desired-point nil))
- (if tags-table-list
- (progn
- (setq desired-point (point-marker))
- (princ tags-table-list (current-buffer))
- (insert "\C-m")
- (prin1 (car tags-table-list) (current-buffer)) ;invisible
- (insert "\n")))
- (while set-list
- (if (eq (car set-list) tags-table-list)
- ;; Already printed it.
- ()
- (princ (car set-list) (current-buffer))
- (insert "\C-m")
- (prin1 (car (car set-list)) (current-buffer)) ;invisible
- (insert "\n"))
- (setq set-list (cdr set-list)))
- (if tags-file-name
- (progn
- (or desired-point
- (setq desired-point (point-marker)))
- (insert tags-file-name "\C-m")
- (prin1 tags-file-name (current-buffer)) ;invisible
- (insert "\n")))
- (setq set-list (delete tags-file-name
- (apply 'nconc (cons tags-table-list
- (mapcar 'copy-sequence
- tags-table-set-list)))))
- (while set-list
- (insert (car set-list) "\C-m")
- (prin1 (car set-list) (current-buffer)) ;invisible
- (insert "\n")
- (setq set-list (delete (car set-list) set-list)))
- (goto-char 1)
- (insert-before-markers
- "Type `t' to select a tags table or set of tags tables:\n\n")
- (if desired-point
- (goto-char desired-point))
- (set-window-start (selected-window) 1 t))
- (set-buffer-modified-p nil)
- (setq buffer-read-only t
- mode-name "Select Tags Table")
- (let ((map (make-sparse-keymap)))
- (define-key map "t" 'select-tags-table-select)
- (define-key map " " 'next-line)
- (define-key map "\^?" 'previous-line)
- (define-key map "n" 'next-line)
- (define-key map "p" 'previous-line)
- (define-key map "q" 'select-tags-table-quit)
- (use-local-map map)))
-
-(defun select-tags-table-select ()
- "Select the tags table named on this line."
- (interactive)
- (search-forward "\C-m")
- (let ((name (read (current-buffer))))
- (visit-tags-table name)
- (select-tags-table-quit)
- (message "Tags table now %s" name)))
-
-(defun select-tags-table-quit ()
- "Kill the buffer and delete the selected window."
- (interactive)
- (kill-buffer (current-buffer))
- (or (one-window-p)
- (delete-window)))
-
-;;;###autoload
-(defun complete-tag ()
- "Perform tags completion on the text around point.
-Completes to the set of names listed in the current tags table.
-The string to complete is chosen in the same way as the default
-for \\[find-tag] (which see)."
- (interactive)
- (or tags-table-list
- tags-file-name
- (error (substitute-command-keys
- "No tags table loaded. Try \\[visit-tags-table].")))
- (let ((pattern (funcall (or find-tag-default-function
- (get major-mode 'find-tag-default-function)
- 'find-tag-default)))
- beg
- completion)
- (or pattern
- (error "Nothing to complete"))
- (search-backward pattern)
- (setq beg (point))
- (forward-char (length pattern))
- (setq completion (try-completion pattern 'tags-complete-tag nil))
- (cond ((eq completion t))
- ((null completion)
- (message "Can't find completion for \"%s\"" pattern)
- (ding))
- ((not (string= pattern completion))
- (delete-region beg (point))
- (insert completion))
- (t
- (message "Making completion list...")
- (with-output-to-temp-buffer " *Completions*"
- (display-completion-list
- (all-completions pattern 'tags-complete-tag nil)))
- (message "Making completion list...%s" "done")))))
-
-;;;###autoload (define-key esc-map "\t" 'complete-tag)
-
-(provide 'etags)
-
-;;; etags.el ends here
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
deleted file mode 100644
index 462f38b29b4..00000000000
--- a/lisp/progmodes/fortran.el
+++ /dev/null
@@ -1,1292 +0,0 @@
-;;; fortran.el --- Fortran mode for GNU Emacs
-
-;;; Copyright (c) 1986, 1993, 1994 Free Software Foundation, Inc.
-
-;; Author: Michael D. Prange <prange@erl.mit.edu>
-;; Maintainer: bug-fortran-mode@erl.mit.edu
-;; Version 1.30.4 (January 20, 1994)
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; Fortran mode has been upgraded and is now maintained by Stephen A. Wood
-;; (saw@cebaf.gov). It now will use either fixed format continuation line
-;; markers (character in 6th column), or tab format continuation line style
-;; (digit after a TAB character.) A auto-fill mode has been added to
-;; automatically wrap fortran lines that get too long.
-
-;; We acknowledge many contributions and valuable suggestions by
-;; Lawrence R. Dodd, Ralf Fassel, Ralph Finch, Stephen Gildea,
-;; Dr. Anil Gokhale, Ulrich Mueller, Mark Neale, Eric Prestemon,
-;; Gary Sabot and Richard Stallman.
-
-;;; This file may be used with GNU Emacs version 18.xx if the following
-;;; variable and function substitutions are made.
-;;; Replace:
-;;; frame-width with screen-width
-;;; auto-fill-function with auto-fill-hook
-;;; comment-indent-function with comment-indent-hook
-;;; (setq unread-command-events (list c)) with (setq unread-command-char c)
-
-;;; Bugs to bug-fortran-mode@erl.mit.edu
-
-(defconst fortran-mode-version "version 1.30.4")
-
-;;; Code:
-
-;;;###autoload
-(defvar fortran-tab-mode-default nil
- "*Default tabbing/carriage control style for empty files in Fortran mode.
-A value of t specifies tab-digit style of continuation control.
-A value of nil specifies that continuation lines are marked
-with a character in column 6.")
-
-;; Buffer local, used to display mode line.
-(defvar fortran-tab-mode-string nil
- "String to appear in mode line when TAB format mode is on.")
-
-(defvar fortran-do-indent 3
- "*Extra indentation applied to DO blocks.")
-
-(defvar fortran-if-indent 3
- "*Extra indentation applied to IF blocks.")
-
-(defvar fortran-structure-indent 3
- "*Extra indentation applied to STRUCTURE, UNION, MAP and INTERFACE blocks.")
-
-(defvar fortran-continuation-indent 5
- "*Extra indentation applied to Fortran continuation lines.")
-
-(defvar fortran-comment-indent-style 'fixed
- "*nil forces comment lines not to be touched,
-'fixed makes fixed comment indentation to `fortran-comment-line-extra-indent'
-columns beyond `fortran-minimum-statement-indent-fixed' (for
-`indent-tabs-mode' of nil) or `fortran-minimum-statement-indent-tab' (for
-`indent-tabs-mode' of t), and 'relative indents to current
-Fortran indentation plus `fortran-comment-line-extra-indent'.")
-
-(defvar fortran-comment-line-extra-indent 0
- "*Amount of extra indentation for text within full-line comments.")
-
-(defvar comment-line-start nil
- "*Delimiter inserted to start new full-line comment.")
-
-(defvar comment-line-start-skip nil
- "*Regexp to match the start of a full-line comment.")
-
-(defvar fortran-minimum-statement-indent-fixed 6
- "*Minimum statement indentation for fixed format continuation style.")
-
-(defvar fortran-minimum-statement-indent-tab (max tab-width 6)
- "*Minimum statement indentation for TAB format continuation style.")
-
-;; Note that this is documented in the v18 manuals as being a string
-;; of length one rather than a single character.
-;; The code in this file accepts either format for compatibility.
-(defvar fortran-comment-indent-char " "
- "*Single-character string inserted for Fortran comment indentation.
-Normally a space.")
-
-(defvar fortran-line-number-indent 1
- "*Maximum indentation for Fortran line numbers.
-5 means right-justify them within their five-column field.")
-
-(defvar fortran-check-all-num-for-matching-do nil
- "*Non-nil causes all numbered lines to be treated as possible DO loop ends.")
-
-(defvar fortran-blink-matching-if nil
- "*From a Fortran ENDIF statement, blink the matching IF statement.
-Also, from an ENDDO statement, blink on matching DO [WHILE] statement.")
-
-(defvar fortran-continuation-string "$"
- "*Single-character string used for Fortran continuation lines.
-In fixed format continuation style, this character is inserted in
-column 6 by \\[fortran-split-line] to begin a continuation line.
-Also, if \\[fortran-indent-line] finds this at the beginning of a line, it will
-convert the line into a continuation line of the appropriate style.
-Normally $.")
-
-(defvar fortran-comment-region "c$$$"
- "*String inserted by \\[fortran-comment-region]\
- at start of each line in region.")
-
-(defvar fortran-electric-line-number t
- "*Non-nil causes line number digits to be moved to the correct column as\
- typed.")
-
-(defvar fortran-startup-message t
- "*Non-nil displays a startup message when Fortran mode is first called.")
-
-(defvar fortran-column-ruler-fixed
- "0 4 6 10 20 30 40 5\
-0 60 70\n\
-[ ]|{ | | | | | | | | \
-| | | | |}\n"
- "*String displayed above current line by \\[fortran-column-ruler].
-This variable used in fixed format mode.")
-
-(defvar fortran-column-ruler-tab
- "0 810 20 30 40 5\
-0 60 70\n\
-[ ]| { | | | | | | | | \
-| | | | |}\n"
- "*String displayed above current line by \\[fortran-column-ruler].
-This variable used in TAB format mode.")
-
-(defconst bug-fortran-mode "bug-fortran-mode@erl.mit.edu"
- "Address of mailing list for Fortran mode bugs.")
-
-(defvar fortran-mode-syntax-table nil
- "Syntax table in use in Fortran mode buffers.")
-
-(defvar fortran-analyze-depth 100
- "Number of lines to scan to determine whether to use fixed or TAB format\
- style.")
-
-(defvar fortran-break-before-delimiters t
- "*Non-nil causes `fortran-do-auto-fill' to break lines before delimiters.")
-
-(if fortran-mode-syntax-table
- ()
- (setq fortran-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\; "w" fortran-mode-syntax-table)
- (modify-syntax-entry ?\r " " fortran-mode-syntax-table)
- (modify-syntax-entry ?+ "." fortran-mode-syntax-table)
- (modify-syntax-entry ?- "." fortran-mode-syntax-table)
- (modify-syntax-entry ?= "." fortran-mode-syntax-table)
- (modify-syntax-entry ?* "." fortran-mode-syntax-table)
- (modify-syntax-entry ?/ "." fortran-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" fortran-mode-syntax-table)
- (modify-syntax-entry ?\" "\"" fortran-mode-syntax-table)
- (modify-syntax-entry ?\\ "/" fortran-mode-syntax-table)
- (modify-syntax-entry ?. "w" fortran-mode-syntax-table)
- (modify-syntax-entry ?_ "w" fortran-mode-syntax-table)
- (modify-syntax-entry ?\n ">" fortran-mode-syntax-table))
-
-(defvar fortran-mode-map ()
- "Keymap used in Fortran mode.")
-(if fortran-mode-map
- ()
- (setq fortran-mode-map (make-sparse-keymap))
- (define-key fortran-mode-map ";" 'fortran-abbrev-start)
- (define-key fortran-mode-map "\C-c;" 'fortran-comment-region)
- (define-key fortran-mode-map "\e\C-a" 'beginning-of-fortran-subprogram)
- (define-key fortran-mode-map "\e\C-e" 'end-of-fortran-subprogram)
- (define-key fortran-mode-map "\e;" 'fortran-indent-comment)
- (define-key fortran-mode-map "\e\C-h" 'mark-fortran-subprogram)
- (define-key fortran-mode-map "\e\n" 'fortran-split-line)
- (define-key fortran-mode-map "\n" 'fortran-indent-new-line)
- (define-key fortran-mode-map "\e\C-q" 'fortran-indent-subprogram)
- (define-key fortran-mode-map "\C-c\C-w" 'fortran-window-create-momentarily)
- (define-key fortran-mode-map "\C-c\C-r" 'fortran-column-ruler)
- (define-key fortran-mode-map "\C-c\C-p" 'fortran-previous-statement)
- (define-key fortran-mode-map "\C-c\C-n" 'fortran-next-statement)
- (define-key fortran-mode-map "\t" 'fortran-indent-line)
- (define-key fortran-mode-map "0" 'fortran-electric-line-number)
- (define-key fortran-mode-map "1" 'fortran-electric-line-number)
- (define-key fortran-mode-map "2" 'fortran-electric-line-number)
- (define-key fortran-mode-map "3" 'fortran-electric-line-number)
- (define-key fortran-mode-map "4" 'fortran-electric-line-number)
- (define-key fortran-mode-map "5" 'fortran-electric-line-number)
- (define-key fortran-mode-map "6" 'fortran-electric-line-number)
- (define-key fortran-mode-map "7" 'fortran-electric-line-number)
- (define-key fortran-mode-map "8" 'fortran-electric-line-number)
- (define-key fortran-mode-map "9" 'fortran-electric-line-number))
-
-(defvar fortran-mode-abbrev-table nil)
-(if fortran-mode-abbrev-table
- ()
- (let ((ac abbrevs-changed))
- (define-abbrev-table 'fortran-mode-abbrev-table ())
- (define-abbrev fortran-mode-abbrev-table ";au" "automatic" nil)
- (define-abbrev fortran-mode-abbrev-table ";b" "byte" nil)
- (define-abbrev fortran-mode-abbrev-table ";bd" "block data" nil)
- (define-abbrev fortran-mode-abbrev-table ";ch" "character" nil)
- (define-abbrev fortran-mode-abbrev-table ";cl" "close" nil)
- (define-abbrev fortran-mode-abbrev-table ";c" "continue" nil)
- (define-abbrev fortran-mode-abbrev-table ";cm" "common" nil)
- (define-abbrev fortran-mode-abbrev-table ";cx" "complex" nil)
- (define-abbrev fortran-mode-abbrev-table ";df" "define" nil)
- (define-abbrev fortran-mode-abbrev-table ";di" "dimension" nil)
- (define-abbrev fortran-mode-abbrev-table ";do" "double" nil)
- (define-abbrev fortran-mode-abbrev-table ";dc" "double complex" nil)
- (define-abbrev fortran-mode-abbrev-table ";dp" "double precision" nil)
- (define-abbrev fortran-mode-abbrev-table ";dw" "do while" nil)
- (define-abbrev fortran-mode-abbrev-table ";e" "else" nil)
- (define-abbrev fortran-mode-abbrev-table ";ed" "enddo" nil)
- (define-abbrev fortran-mode-abbrev-table ";el" "elseif" nil)
- (define-abbrev fortran-mode-abbrev-table ";en" "endif" nil)
- (define-abbrev fortran-mode-abbrev-table ";eq" "equivalence" nil)
- (define-abbrev fortran-mode-abbrev-table ";ew" "endwhere" nil)
- (define-abbrev fortran-mode-abbrev-table ";ex" "external" nil)
- (define-abbrev fortran-mode-abbrev-table ";ey" "entry" nil)
- (define-abbrev fortran-mode-abbrev-table ";f" "format" nil)
- (define-abbrev fortran-mode-abbrev-table ";fa" ".false." nil)
- (define-abbrev fortran-mode-abbrev-table ";fu" "function" nil)
- (define-abbrev fortran-mode-abbrev-table ";g" "goto" nil)
- (define-abbrev fortran-mode-abbrev-table ";im" "implicit" nil)
- (define-abbrev fortran-mode-abbrev-table ";ib" "implicit byte" nil)
- (define-abbrev fortran-mode-abbrev-table ";ic" "implicit complex" nil)
- (define-abbrev fortran-mode-abbrev-table ";ich" "implicit character" nil)
- (define-abbrev fortran-mode-abbrev-table ";ii" "implicit integer" nil)
- (define-abbrev fortran-mode-abbrev-table ";il" "implicit logical" nil)
- (define-abbrev fortran-mode-abbrev-table ";ir" "implicit real" nil)
- (define-abbrev fortran-mode-abbrev-table ";inc" "include" nil)
- (define-abbrev fortran-mode-abbrev-table ";in" "integer" nil)
- (define-abbrev fortran-mode-abbrev-table ";intr" "intrinsic" nil)
- (define-abbrev fortran-mode-abbrev-table ";l" "logical" nil)
- (define-abbrev fortran-mode-abbrev-table ";n" "namelist" nil)
- (define-abbrev fortran-mode-abbrev-table ";o" "open" nil) ; was ;op
- (define-abbrev fortran-mode-abbrev-table ";pa" "parameter" nil)
- (define-abbrev fortran-mode-abbrev-table ";pr" "program" nil)
- (define-abbrev fortran-mode-abbrev-table ";ps" "pause" nil)
- (define-abbrev fortran-mode-abbrev-table ";p" "print" nil)
- (define-abbrev fortran-mode-abbrev-table ";rc" "record" nil)
- (define-abbrev fortran-mode-abbrev-table ";re" "real" nil)
- (define-abbrev fortran-mode-abbrev-table ";r" "read" nil)
- (define-abbrev fortran-mode-abbrev-table ";rt" "return" nil)
- (define-abbrev fortran-mode-abbrev-table ";rw" "rewind" nil)
- (define-abbrev fortran-mode-abbrev-table ";s" "stop" nil)
- (define-abbrev fortran-mode-abbrev-table ";sa" "save" nil)
- (define-abbrev fortran-mode-abbrev-table ";st" "structure" nil)
- (define-abbrev fortran-mode-abbrev-table ";sc" "static" nil)
- (define-abbrev fortran-mode-abbrev-table ";su" "subroutine" nil)
- (define-abbrev fortran-mode-abbrev-table ";tr" ".true." nil)
- (define-abbrev fortran-mode-abbrev-table ";ty" "type" nil)
- (define-abbrev fortran-mode-abbrev-table ";vo" "volatile" nil)
- (define-abbrev fortran-mode-abbrev-table ";w" "write" nil)
- (define-abbrev fortran-mode-abbrev-table ";wh" "where" nil)
- (setq abbrevs-changed ac)))
-
-;;;###autoload
-(defun fortran-mode ()
- "Major mode for editing Fortran code.
-\\[fortran-indent-line] indents the current Fortran line correctly.
-DO statements must not share a common CONTINUE.
-
-Type ;? or ;\\[help-command] to display a list of built-in\
- abbrevs for Fortran keywords.
-
-Key definitions:
-\\{fortran-mode-map}
-
-Variables controlling indentation style and extra features:
-
- comment-start
- Normally nil in Fortran mode. If you want to use comments
- starting with `!', set this to the string \"!\".
- fortran-do-indent
- Extra indentation within do blocks. (default 3)
- fortran-if-indent
- Extra indentation within if blocks. (default 3)
- fortran-structure-indent
- Extra indentation within structure, union, map and interface blocks.
- (default 3)
- fortran-continuation-indent
- Extra indentation applied to continuation statements. (default 5)
- fortran-comment-line-extra-indent
- Amount of extra indentation for text within full-line comments. (default 0)
- fortran-comment-indent-style
- nil means don't change indentation of text in full-line comments,
- fixed means indent that text at `fortran-comment-line-extra-indent' beyond
- the value of `fortran-minimum-statement-indent-fixed' (for fixed
- format continuation style) or `fortran-minimum-statement-indent-tab'
- (for TAB format continuation style).
- relative means indent at `fortran-comment-line-extra-indent' beyond the
- indentation for a line of code.
- (default 'fixed)
- fortran-comment-indent-char
- Single-character string to be inserted instead of space for
- full-line comment indentation. (default \" \")
- fortran-minimum-statement-indent-fixed
- Minimum indentation for Fortran statements in fixed format mode. (def.6)
- fortran-minimum-statement-indent-tab
- Minimum indentation for Fortran statements in TAB format mode. (default 9)
- fortran-line-number-indent
- Maximum indentation for line numbers. A line number will get
- less than this much indentation if necessary to avoid reaching
- column 5. (default 1)
- fortran-check-all-num-for-matching-do
- Non-nil causes all numbered lines to be treated as possible \"continue\"
- statements. (default nil)
- fortran-blink-matching-if
- From a Fortran ENDIF statement, blink the matching IF statement.
- Also, from an ENDDO statement, blink on matching DO [WHILE] statement.
- (default nil)
- fortran-continuation-string
- Single-character string to be inserted in column 5 of a continuation
- line. (default \"$\")
- fortran-comment-region
- String inserted by \\[fortran-comment-region] at start of each line in
- region. (default \"c$$$\")
- fortran-electric-line-number
- Non-nil causes line number digits to be moved to the correct column
- as typed. (default t)
- fortran-break-before-delimiters
- Non-nil causes `fortran-do-auto-fill' breaks lines before delimiters.
- (default t)
- fortran-startup-message
- Set to nil to inhibit message first time Fortran mode is used.
-
-Turning on Fortran mode calls the value of the variable `fortran-mode-hook'
-with no args, if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (if fortran-startup-message
- (message "Emacs Fortran mode %s. Bugs to %s"
- fortran-mode-version bug-fortran-mode))
- (setq fortran-startup-message nil)
- (setq local-abbrev-table fortran-mode-abbrev-table)
- (set-syntax-table fortran-mode-syntax-table)
- (make-local-variable 'fortran-break-before-delimiters)
- (setq fortran-break-before-delimiters t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'fortran-indent-line)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'fortran-comment-hook)
- (make-local-variable 'comment-line-start-skip)
- (setq comment-line-start-skip
- "^[Cc*]\\(\\([^ \t\n]\\)\\2\\2*\\)?[ \t]*\\|^#.*")
- (make-local-variable 'comment-line-start)
- (setq comment-line-start "c")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "![ \t]*")
- (make-local-variable 'comment-start)
- (setq comment-start nil)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'abbrev-all-caps)
- (setq abbrev-all-caps t)
- (make-local-variable 'indent-tabs-mode)
- (setq indent-tabs-mode nil)
-;;;(setq abbrev-mode t) ; ?? (abbrev-mode 1) instead??
- (setq fill-column 72) ; Already local?
- (use-local-map fortran-mode-map)
- (setq mode-name "Fortran")
- (setq major-mode 'fortran-mode)
-;;;(make-local-variable 'fortran-tab-mode)
- (make-local-variable 'fortran-comment-line-extra-indent)
- (make-local-variable 'fortran-minimum-statement-indent-fixed)
- (make-local-variable 'fortran-minimum-statement-indent-tab)
- (make-local-variable 'fortran-column-ruler-fixed)
- (make-local-variable 'fortran-column-ruler-tab)
- (make-local-variable 'fortran-tab-mode-string)
- (setq fortran-tab-mode-string " TAB-format")
- (setq indent-tabs-mode (fortran-analyze-file-format))
- (run-hooks 'fortran-mode-hook))
-
-(defun fortran-comment-hook ()
- (save-excursion
- (skip-chars-backward " \t")
- (max (+ 1 (current-column))
- comment-column)))
-
-(defun fortran-indent-comment ()
- "Align or create comment on current line.
-Existing comments of all types are recognized and aligned.
-If the line has no comment, a side-by-side comment is inserted and aligned
-if the value of comment-start is not nil.
-Otherwise, a separate-line comment is inserted, on this line
-or on a new line inserted before this line if this line is not blank."
- (interactive)
- (beginning-of-line)
- ;; Recognize existing comments of either kind.
- (cond ((looking-at comment-line-start-skip)
- (fortran-indent-line))
- ((fortran-find-comment-start-skip) ; catches any inline comment and
- ; leaves point after comment-start-skip
- (if comment-start-skip
- (progn (goto-char (match-beginning 0))
- (if (not (= (current-column) (fortran-comment-hook)))
- (progn (delete-horizontal-space)
- (indent-to (fortran-comment-hook)))))
- (end-of-line))) ; otherwise goto end of line or sth else?
- ;; No existing comment.
- ;; If side-by-side comments are defined, insert one,
- ;; unless line is now blank.
- ((and comment-start (not (looking-at "^[ \t]*$")))
- (end-of-line)
- (delete-horizontal-space)
- (indent-to (fortran-comment-hook))
- (insert comment-start))
- ;; Else insert separate-line comment, making a new line if nec.
- (t
- (if (looking-at "^[ \t]*$")
- (delete-horizontal-space)
- (beginning-of-line)
- (insert "\n")
- (forward-char -1))
- (insert comment-line-start)
- (insert-char (if (stringp fortran-comment-indent-char)
- (aref fortran-comment-indent-char 0)
- fortran-comment-indent-char)
- (- (calculate-fortran-indent) (current-column))))))
-
-(defun fortran-comment-region (beg-region end-region arg)
- "Comments every line in the region.
-Puts fortran-comment-region at the beginning of every line in the region.
-BEG-REGION and END-REGION are args which specify the region boundaries.
-With non-nil ARG, uncomments the region."
- (interactive "*r\nP")
- (let ((end-region-mark (make-marker)) (save-point (point-marker)))
- (set-marker end-region-mark end-region)
- (goto-char beg-region)
- (beginning-of-line)
- (if (not arg) ;comment the region
- (progn (insert fortran-comment-region)
- (while (and (= (forward-line 1) 0)
- (< (point) end-region-mark))
- (insert fortran-comment-region)))
- (let ((com (regexp-quote fortran-comment-region))) ;uncomment the region
- (if (looking-at com)
- (delete-region (point) (match-end 0)))
- (while (and (= (forward-line 1) 0)
- (< (point) end-region-mark))
- (if (looking-at com)
- (delete-region (point) (match-end 0))))))
- (goto-char save-point)
- (set-marker end-region-mark nil)
- (set-marker save-point nil)))
-
-(defun fortran-abbrev-start ()
- "Typing ;\\[help-command] or ;? lists all the Fortran abbrevs.
-Any other key combination is executed normally."
- (interactive)
- (let (c)
- (insert last-command-char)
- (if (or (eq (setq c (read-event)) ??) ;insert char if not equal to `?'
- (eq c help-char))
- (fortran-abbrev-help)
- (setq unread-command-events (list c)))))
-
-(defun fortran-abbrev-help ()
- "List the currently defined abbrevs in Fortran mode."
- (interactive)
- (message "Listing abbrev table...")
- (display-buffer (fortran-prepare-abbrev-list-buffer))
- (message "Listing abbrev table...done"))
-
-(defun fortran-prepare-abbrev-list-buffer ()
- (save-excursion
- (set-buffer (get-buffer-create "*Abbrevs*"))
- (erase-buffer)
- (insert-abbrev-table-description 'fortran-mode-abbrev-table t)
- (goto-char (point-min))
- (set-buffer-modified-p nil)
- (edit-abbrevs-mode))
- (get-buffer-create "*Abbrevs*"))
-
-(defun fortran-column-ruler ()
- "Inserts a column ruler momentarily above current line, till next keystroke.
-The ruler is defined by the value of `fortran-column-ruler-fixed' when in fixed
-format mode, and `fortran-column-ruler-tab' when in TAB format mode.
-The key typed is executed unless it is SPC."
- (interactive)
- (momentary-string-display
- (if indent-tabs-mode
- fortran-column-ruler-tab
- fortran-column-ruler-fixed)
- (save-excursion
- (beginning-of-line)
- (if (eq (window-start (selected-window))
- (window-point (selected-window)))
- (progn (forward-line) (point))
- (point)))
- nil "Type SPC or any command to erase ruler."))
-
-(defun fortran-window-create ()
- "Makes the window 72 columns wide.
-See also `fortran-window-create-momentarily'."
- (interactive)
- (condition-case error
- (progn
- (let ((window-min-width 2))
- (if (< (window-width) (frame-width))
- (enlarge-window-horizontally (- (frame-width)
- (window-width) 1)))
- (split-window-horizontally 73)
- (other-window 1)
- (switch-to-buffer " fortran-window-extra" t)
- (select-window (previous-window))))
- (error (message "No room for Fortran window.")
- 'error)))
-
-(defun fortran-window-create-momentarily (&optional arg)
- "Momentarily makes the window 72 columns wide.
-Optional ARG non-nil and non-unity disables the momentary feature.
-See also `fortran-window-create'."
- (interactive "p")
- (if (or (not arg)
- (= arg 1))
- (save-window-excursion
- (if (not (equal (fortran-window-create) 'error))
- (progn (message "Type SPC to continue editing.")
- (let ((char (read-event)))
- (or (equal char (string-to-char " "))
- (setq unread-command-events (list char)))))))
- (fortran-window-create)))
-
-(defun fortran-split-line ()
- "Break line at point and insert continuation marker and alignment."
- (interactive)
- (delete-horizontal-space)
- (if (save-excursion (beginning-of-line) (looking-at comment-line-start-skip))
- (insert "\n" comment-line-start " ")
- (if indent-tabs-mode
- (progn
- (insert "\n\t")
- (insert-char (fortran-numerical-continuation-char) 1))
- (insert "\n " fortran-continuation-string)));Space after \n important
- (fortran-indent-line)) ;when the cont string is C, c or *.
-
-(defun fortran-numerical-continuation-char ()
- "Return a digit for tab-digit style of continuation lines.
-If, previous line is a tab-digit continuation line, returns that digit
-plus one. Otherwise return 1. Zero not allowed."
- (save-excursion
- (forward-line -1)
- (if (looking-at "\t[1-9]")
- (+ ?1 (% (- (char-after (+ (point) 1)) ?0) 9))
- ?1)))
-
-(defun delete-horizontal-regexp (chars)
- "Delete all characters in CHARS around point.
-CHARS is like the inside of a [...] in a regular expression
-except that ] is never special and \ quotes ^, - or \."
- (interactive "*s")
- (skip-chars-backward chars)
- (delete-region (point) (progn (skip-chars-forward chars) (point))))
-
-(defun fortran-electric-line-number (arg)
- "Self insert, but if part of a Fortran line number indent it automatically.
-Auto-indent does not happen if a numeric arg is used."
- (interactive "P")
- (if (or arg (not fortran-electric-line-number))
- (if arg
- (self-insert-command (prefix-numeric-value arg))
- (self-insert-command 1))
- (if (or (and (= 5 (current-column))
- (save-excursion
- (beginning-of-line)
- (looking-at " ")));In col 5 with only spaces to left.
- (and (= (if indent-tabs-mode
- fortran-minimum-statement-indent-tab
- fortran-minimum-statement-indent-fixed) (current-column))
- (save-excursion
- (beginning-of-line)
- (looking-at "\t"));In col 8 with a single tab to the left.
- (not (or (eq last-command 'fortran-indent-line)
- (eq last-command
- 'fortran-indent-new-line))))
- (save-excursion
- (re-search-backward "[^ \t0-9]"
- (save-excursion
- (beginning-of-line)
- (point))
- t)) ;not a line number
- (looking-at "[0-9]") ;within a line number
- )
- (self-insert-command (prefix-numeric-value arg))
- (skip-chars-backward " \t")
- (insert last-command-char)
- (fortran-indent-line))))
-
-(defun beginning-of-fortran-subprogram ()
- "Moves point to the beginning of the current Fortran subprogram."
- (interactive)
- (let ((case-fold-search t))
- (beginning-of-line -1)
- (re-search-backward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move)
- (if (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")
- (forward-line 1))))
-
-(defun end-of-fortran-subprogram ()
- "Moves point to the end of the current Fortran subprogram."
- (interactive)
- (let ((case-fold-search t))
- (beginning-of-line 2)
- (re-search-forward "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]" nil 'move)
- (goto-char (match-beginning 0))
- (forward-line 1)))
-
-(defun mark-fortran-subprogram ()
- "Put mark at end of Fortran subprogram, point at beginning.
-The marks are pushed."
- (interactive)
- (end-of-fortran-subprogram)
- (push-mark (point))
- (beginning-of-fortran-subprogram))
-
-(defun fortran-previous-statement ()
- "Moves point to beginning of the previous Fortran statement.
-Returns `first-statement' if that statement is the first
-non-comment Fortran statement in the file, and nil otherwise."
- (interactive)
- (let (not-first-statement continue-test)
- (beginning-of-line)
- (setq continue-test
- (and
- (not (looking-at comment-line-start-skip))
- (or (looking-at
- (concat "[ \t]*" (regexp-quote fortran-continuation-string)))
- (or (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]")))))
- (while (and (setq not-first-statement (= (forward-line -1) 0))
- (or (looking-at comment-line-start-skip)
- (looking-at "[ \t]*$")
- (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]")
- (looking-at (concat "[ \t]*" comment-start-skip)))))
- (cond ((and continue-test
- (not not-first-statement))
- (message "Incomplete continuation statement."))
- (continue-test
- (fortran-previous-statement))
- ((not not-first-statement)
- 'first-statement))))
-
-(defun fortran-next-statement ()
- "Moves point to beginning of the next Fortran statement.
-Returns `last-statement' if that statement is the last
-non-comment Fortran statement in the file, and nil otherwise."
- (interactive)
- (let (not-last-statement)
- (beginning-of-line)
- (while (and (setq not-last-statement
- (and (= (forward-line 1) 0)
- (not (eobp))))
- (or (looking-at comment-line-start-skip)
- (looking-at "[ \t]*$")
- (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]")
- (looking-at (concat "[ \t]*" comment-start-skip)))))
- (if (not not-last-statement)
- 'last-statement)))
-
-(defun fortran-blink-matching-if ()
- "From a Fortran ENDIF statement, blink the matching IF statement."
- (let ((count 1) (top-of-window (window-start)) matching-if
- (endif-point (point)) message)
- (if (save-excursion (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "end[ \t]*if\\b"))
- (progn
- (save-excursion
- (while (and (not (= count 0))
- (not (eq (fortran-previous-statement)
- 'first-statement))
- (not (looking-at
- "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
- ; Keep local to subprogram
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "if[ \t]*(")
- (save-excursion
- (if (or
- (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
- (let (then-test);multi-line if-then
- (while
- (and (= (forward-line 1) 0)
- ;search forward for then
- (or (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]"))
- (not
- (setq
- then-test
- (looking-at
- ".*then\\b[ \t]*[^ \t(=a-z0-9]")))))
- then-test))
- (setq count (- count 1)))))
- ((looking-at "end[ \t]*if\\b")
- (setq count (+ count 1)))))
- (if (not (= count 0))
- (setq message "No matching if.")
- (if (< (point) top-of-window)
- (setq message (concat "Matches " (buffer-substring
- (progn (beginning-of-line)
- (point))
- (progn (end-of-line)
- (point)))))
- (setq matching-if (point)))))
- (if message
- (message "%s" message)
- (goto-char matching-if)
- (sit-for 1)
- (goto-char endif-point))))))
-
-(defun fortran-blink-matching-do ()
- ;; From a Fortran ENDDO statement, blink on the matching DO or DO WHILE
- ;; statement. This is basically copied from fortran-blink-matching-if.
- (let ((count 1) (top-of-window (window-start)) matching-do
- (enddo-point (point)) message)
- (if (save-excursion (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "end[ \t]*do\\b"))
- (progn
- (save-excursion
- (while (and (not (= count 0))
- (not (eq (fortran-previous-statement)
- 'first-statement))
- (not (looking-at
- "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
- ; Keep local to subprogram
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "do[ \t]+")
- (setq count (- count 1)))
- ((looking-at "end[ \t]*do\\b")
- (setq count (+ count 1)))))
- (if (not (= count 0))
- (setq message "No matching do.")
- (if (< (point) top-of-window)
- (setq message (concat "Matches " (buffer-substring
- (progn (beginning-of-line)
- (point))
- (progn (end-of-line)
- (point)))))
- (setq matching-do (point)))))
- (if message
- (message "%s" message)
- (goto-char matching-do)
- (sit-for 1)
- (goto-char enddo-point))))))
-
-(defun fortran-indent-line ()
- "Indents current Fortran line based on its contents and on previous lines."
- (interactive)
- (let ((cfi (calculate-fortran-indent)))
- (save-excursion
- (beginning-of-line)
- (if (or (not (= cfi (fortran-current-line-indentation)))
- (and (re-search-forward "^[ \t]*[0-9]+" (+ (point) 4) t)
- (not (fortran-line-number-indented-correctly-p))))
- (fortran-indent-to-column cfi)
- (beginning-of-line)
- (if (and (not (looking-at comment-line-start-skip))
- (fortran-find-comment-start-skip))
- (fortran-indent-comment))))
- ;; Never leave point in left margin.
- (if (< (current-column) cfi)
- (move-to-column cfi))
- (if (and auto-fill-function
- (> (save-excursion (end-of-line) (current-column)) fill-column))
- (save-excursion
- (end-of-line)
- (fortran-do-auto-fill)))
- (if fortran-blink-matching-if
- (progn
- (fortran-blink-matching-if)
- (fortran-blink-matching-do)))))
-
-(defun fortran-indent-new-line ()
- "Reindent the current Fortran line, insert a newline and indent the newline.
-An abbrev before point is expanded if `abbrev-mode' is non-nil."
- (interactive)
- (if abbrev-mode (expand-abbrev))
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (if (or (looking-at "[0-9]") ;Reindent only where it is most
- (looking-at "end") ;likely to be necessary
- (looking-at "else")
- (looking-at (regexp-quote fortran-continuation-string)))
- (fortran-indent-line)))
- (newline)
- (fortran-indent-line))
-
-(defun fortran-indent-subprogram ()
- "Properly indents the Fortran subprogram which contains point."
- (interactive)
- (save-excursion
- (mark-fortran-subprogram)
- (message "Indenting subprogram...")
- (indent-region (point) (mark) nil))
- (message "Indenting subprogram...done."))
-
-(defun calculate-fortran-indent ()
- "Calculates the Fortran indent column based on previous lines."
- (let (icol first-statement (case-fold-search t)
- (fortran-minimum-statement-indent
- (if indent-tabs-mode
- fortran-minimum-statement-indent-tab
- fortran-minimum-statement-indent-fixed)))
- (save-excursion
- (setq first-statement (fortran-previous-statement))
- (if first-statement
- (setq icol fortran-minimum-statement-indent)
- (progn
- (if (= (point) (point-min))
- (setq icol fortran-minimum-statement-indent)
- (setq icol (fortran-current-line-indentation)))
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "if[ \t]*(")
- (if (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t_$(=a-z0-9]")
- (let (then-test) ;multi-line if-then
- (while (and (= (forward-line 1) 0)
- ;;search forward for then
- (or (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]"))
- (not (setq then-test (looking-at
- ".*then\\b[ \t]\
-*[^ \t_$(=a-z0-9]")))))
- then-test))
- (setq icol (+ icol fortran-if-indent))))
- ((looking-at "\\(else\\|elseif\\)\\b")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "select[ \t]*case[ \t](.*)\\b")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "case[ \t]*(.*)[ \t]*\n")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "case[ \t]*default\\b")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "where[ \t]*(.*)[ \t]*\n")
- (setq icol (+ icol fortran-if-indent)))
- ((looking-at "do\\b")
- (setq icol (+ icol fortran-do-indent)))
- ((looking-at
- "\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]")
- (setq icol (+ icol fortran-structure-indent)))
- ((looking-at "end\\b[ \t]*[^ \t=(a-z]")
- ;; Previous END resets indent to minimum
- (setq icol fortran-minimum-statement-indent))))))
- (save-excursion
- (beginning-of-line)
- (cond ((looking-at "[ \t]*$"))
- ((looking-at comment-line-start-skip)
- (cond ((eq fortran-comment-indent-style 'relative)
- (setq icol (+ icol fortran-comment-line-extra-indent)))
- ((eq fortran-comment-indent-style 'fixed)
- (setq icol (+ fortran-minimum-statement-indent
- fortran-comment-line-extra-indent))))
- (setq fortran-minimum-statement-indent 0))
- ((or (looking-at (concat "[ \t]*"
- (regexp-quote
- fortran-continuation-string)))
- (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]"))
- (setq icol (+ icol fortran-continuation-indent)))
- ((looking-at "[ \t]*#") ; Check for cpp directive.
- (setq fortran-minimum-statement-indent 0 icol 0))
- (first-statement)
- ((and fortran-check-all-num-for-matching-do
- (looking-at "[ \t]*[0-9]+")
- (fortran-check-for-matching-do))
- (setq icol (- icol fortran-do-indent)))
- (t
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "end[ \t]*if\\b")
- (setq icol (- icol fortran-if-indent)))
- ((looking-at "\\(else\\|elseif\\)\\b")
- (setq icol (- icol fortran-if-indent)))
- ((looking-at "case[ \t]*(.*)[ \t]*\n")
- (setq icol (- icol fortran-if-indent)))
- ((looking-at "case[ \t]*default\\b")
- (setq icol (- icol fortran-if-indent)))
- ((looking-at "\\(otherwise\\|else[ \t]*where\\)\\b")
- (setq icol (- icol fortran-if-indent)))
- ((looking-at "end[ \t]*where\\b")
- (setq icol (- icol fortran-if-indent)))
- ((and (looking-at "continue\\b")
- (fortran-check-for-matching-do))
- (setq icol (- icol fortran-do-indent)))
- ((looking-at "end[ \t]*do\\b")
- (setq icol (- icol fortran-do-indent)))
- ((looking-at
- "end[ \t]*\
-\\(structure\\|union\\|map\\|interface\\)\\b[ \t]*[^ \t=(a-z]")
- (setq icol (- icol fortran-structure-indent)))
- ((looking-at
- "end[ \t]*select\\b[ \t]*[^ \t=(a-z]")
- (setq icol (- icol fortran-if-indent)))
- ((and (looking-at "end\\b[ \t]*[^ \t=(a-z]")
- (not (= icol fortran-minimum-statement-indent)))
- (message "Warning: `end' not in column %d. Probably\
- an unclosed block." fortran-minimum-statement-indent))))))
- (max fortran-minimum-statement-indent icol)))
-
-(defun fortran-current-line-indentation ()
- "Indentation of current line, ignoring Fortran line number or continuation.
-This is the column position of the first non-whitespace character
-aside from the line number and/or column 5/8 line-continuation character.
-For comment lines, returns indentation of the first
-non-indentation text within the comment."
- (save-excursion
- (beginning-of-line)
- (cond ((looking-at comment-line-start-skip)
- (goto-char (match-end 0))
- (skip-chars-forward
- (if (stringp fortran-comment-indent-char)
- fortran-comment-indent-char
- (char-to-string fortran-comment-indent-char))))
- ((or (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]"))
- (goto-char (match-end 0)))
- (t
- ;; Move past line number.
- (skip-chars-forward "[ \t0-9]");From Uli
- ))
- ;; Move past whitespace.
- (skip-chars-forward " \t")
- (current-column)))
-
-(defun fortran-indent-to-column (col)
- "Indents current line with spaces to column COL.
-notes: 1) A non-zero/non-blank character in column 5 indicates a continuation
- line, and this continuation character is retained on indentation;
- 2) If `fortran-continuation-string' is the first non-whitespace
- character, this is a continuation line;
- 3) A non-continuation line which has a number as the first
- non-whitespace character is a numbered line.
- 4) A TAB followed by a digit indicates a continuation line."
- (save-excursion
- (beginning-of-line)
- (if (looking-at comment-line-start-skip)
- (if fortran-comment-indent-style
- (let ((char (if (stringp fortran-comment-indent-char)
- (aref fortran-comment-indent-char 0)
- fortran-comment-indent-char)))
- (goto-char (match-end 0))
- (delete-horizontal-regexp (concat " \t" (char-to-string char)))
- (insert-char char (- col (current-column)))))
- (if (looking-at "\t[1-9]")
- (if indent-tabs-mode
- (goto-char (match-end 0))
- (delete-char 2)
- (insert " ")
- (insert fortran-continuation-string))
- (if (looking-at " [^ 0\n]")
- (if indent-tabs-mode
- (progn (delete-char 6)
- (insert "\t")
- (insert-char (fortran-numerical-continuation-char) 1))
- (forward-char 6))
- (delete-horizontal-space)
- ;; Put line number in columns 0-4
- ;; or put continuation character in column 5.
- (cond ((eobp))
- ((looking-at (regexp-quote fortran-continuation-string))
- (if indent-tabs-mode
- (progn
- (indent-to
- (if indent-tabs-mode
- fortran-minimum-statement-indent-tab
- fortran-minimum-statement-indent-fixed))
- (delete-char 1)
- (insert-char (fortran-numerical-continuation-char) 1))
- (indent-to 5)
- (forward-char 1)))
- ((looking-at "[0-9]+")
- (let ((extra-space (- 5 (- (match-end 0) (point)))))
- (if (< extra-space 0)
- (message "Warning: line number exceeds 5-digit limit.")
- (indent-to (min fortran-line-number-indent extra-space))))
- (skip-chars-forward "0-9")))))
- ;; Point is now after any continuation character or line number.
- ;; Put body of statement where specified.
- (delete-horizontal-space)
- (indent-to col)
- ;; Indent any comment following code on the same line.
- (if (and comment-start-skip
- (fortran-find-comment-start-skip))
- (progn (goto-char (match-beginning 0))
- (if (not (= (current-column) (fortran-comment-hook)))
- (progn (delete-horizontal-space)
- (indent-to (fortran-comment-hook)))))))))
-
-(defun fortran-line-number-indented-correctly-p ()
- "Return t if current line's line number is correctly indented.
-Do not call if there is no line number."
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (and (<= (current-column) fortran-line-number-indent)
- (or (= (current-column) fortran-line-number-indent)
- (progn (skip-chars-forward "0-9")
- (= (current-column) 5))))))
-
-(defun fortran-check-for-matching-do ()
- "When called from a numbered statement, returns t if matching DO is found.
-Otherwise return a nil."
- (let (charnum
- (case-fold-search t))
- (save-excursion
- (beginning-of-line)
- (if (looking-at "[ \t]*[0-9]+")
- (progn
- (skip-chars-forward " \t")
- (skip-chars-forward "0") ;skip past leading zeros
- (setq charnum (buffer-substring (point)
- (progn (skip-chars-forward "0-9")
- (point))))
- (beginning-of-line)
- (and (re-search-backward
- (concat
- "\\(^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]\\)\\|\\(^[ \t0-9]*do\
-[ \t]*0*"
- charnum "\\b\\)\\|\\(^[ \t]*0*" charnum "\\b\\)")
- nil t)
- (looking-at (concat "^[ \t0-9]*do[ \t]*0*" charnum))))))))
-
-(defun fortran-find-comment-start-skip ()
- "Move to past `comment-start-skip' found on current line.
-Return t if `comment-start-skip' found, nil if not."
-;;; In order to move point only if comment-start-skip is found,
-;;; this one uses a lot of save-excursions. Note that re-search-forward
-;;; moves point even if comment-start-skip is inside a string-constant.
-;;; Some code expects certain values for match-beginning and end
- (interactive)
- (let ((save-match-beginning) (save-match-end))
- (if (save-excursion
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line) (point)) t))
- (progn
- (setq save-match-beginning (match-beginning 0))
- (setq save-match-end (match-end 0))
- (if (fortran-is-in-string-p (match-beginning 0))
- (progn
- (save-excursion
- (goto-char save-match-end)
- (fortran-find-comment-start-skip)) ; recurse for rest of line
- )
- (goto-char save-match-beginning)
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line) (point)) t)
- (goto-char (match-end 0))
- t))
- nil)))
-
-;;;From: ralf@up3aud1.gwdg.de (Ralf Fassel)
-;;; Test if TAB format continuation lines work.
-(defun fortran-is-in-string-p (where)
- "Return non-nil if POS (a buffer position) is inside a Fortran string,
-nil else."
- (save-excursion
- (goto-char where)
- (cond
- ((bolp) nil) ; bol is never inside a string
- ((save-excursion ; comment lines too
- (beginning-of-line)(looking-at comment-line-start-skip)) nil)
- (t (let (;; ok, serious now. Init some local vars:
- (parse-state '(0 nil nil nil nil nil 0))
- (quoted-comment-start (if comment-start
- (regexp-quote comment-start)))
- (not-done t)
- parse-limit
- end-of-line
- )
- ;; move to start of current statement
- (fortran-next-statement)
- (fortran-previous-statement)
- ;; now parse up to WHERE
- (while not-done
- (if (or ;; skip to next line if:
- ;; - comment line?
- (looking-at comment-line-start-skip)
- ;; - at end of line?
- (eolp)
- ;; - not in a string and after comment-start?
- (and (not (nth 3 parse-state))
- comment-start
- (equal comment-start
- (char-to-string (preceding-char)))))
- ;; get around a bug in forward-line in versions <= 18.57
- (if (or (> (forward-line 1) 0) (eobp))
- (setq not-done nil))
- ;; else:
- ;; if we are at beginning of code line, skip any
- ;; whitespace, labels and tab continuation markers.
- (if (bolp) (skip-chars-forward " \t0-9"))
- ;; if we are in column <= 5 now, check for continuation char
- (cond ((= 5 (current-column)) (forward-char 1))
- ((and (< (current-column) 5)
- (equal fortran-continuation-string
- (char-to-string (following-char)))
- (forward-char 1))))
- ;; find out parse-limit from here
- (setq end-of-line (save-excursion (end-of-line)(point)))
- (setq parse-limit (min where end-of-line))
- ;; parse max up to comment-start, if non-nil and in current line
- (if comment-start
- (save-excursion
- (if (re-search-forward quoted-comment-start end-of-line t)
- (setq parse-limit (min (point) parse-limit)))))
- ;; now parse if still in limits
- (if (< (point) where)
- (setq parse-state (parse-partial-sexp
- (point) parse-limit nil nil parse-state))
- (setq not-done nil))
- ))
- ;; result is
- (nth 3 parse-state))))))
-
-(defun fortran-auto-fill-mode (arg)
- "Toggle fortran-auto-fill mode.
-With ARG, turn `fortran-auto-fill' mode on iff ARG is positive.
-In `fortran-auto-fill' mode, inserting a space at a column beyond `fill-column'
-automatically breaks the line at a previous space."
- (interactive "P")
- (prog1 (setq auto-fill-function
- (if (if (null arg)
- (not auto-fill-function)
- (> (prefix-numeric-value arg) 0))
- 'fortran-indent-line
- nil))
- ;; update mode-line
- (set-buffer-modified-p (buffer-modified-p))))
-
-(defun fortran-do-auto-fill ()
- (interactive)
- (let* ((opoint (point))
- (bol (save-excursion (beginning-of-line) (point)))
- (eol (save-excursion (end-of-line) (point)))
- (bos (min eol (+ bol (fortran-current-line-indentation))))
- (quote
- (save-excursion
- (goto-char bol)
- (if (looking-at comment-line-start-skip)
- nil ; OK to break quotes on comment lines.
- (move-to-column fill-column)
- (cond ((fortran-is-in-string-p (point))
- (save-excursion (re-search-backward "[^']'[^']" bol t)
- (if fortran-break-before-delimiters
- (point)
- (1+ (point)))))
- (t nil)))))
- ;;
- ;; decide where to split the line. If a position for a quoted
- ;; string was found above then use that, else break the line
- ;; before the last delimiter.
- ;; Delimiters are whitespace, commas, and operators.
- ;; Will break before a pair of *'s.
- ;;
- (fill-point
- (or quote
- (save-excursion
- (move-to-column (1+ fill-column))
- (skip-chars-backward "^ \t\n,'+-/*=)"
-;;; (if fortran-break-before-delimiters
-;;; "^ \t\n,'+-/*=" "^ \t\n,'+-/*=)")
- )
- (if (<= (point) (1+ bos))
- (progn
- (move-to-column (1+ fill-column))
-;;;what is this doing???
- (if (not (re-search-forward "[\t\n,'+-/*)=]" eol t))
- (goto-char bol))))
- (if (bolp)
- (re-search-forward "[ \t]" opoint t)
- (forward-char -1)
- (if (looking-at "'")
- (forward-char 1)
- (skip-chars-backward " \t\*")))
- (if fortran-break-before-delimiters
- (point)
- (1+ (point))))))
- )
- ;; if we are in an in-line comment, don't break unless the
- ;; line of code is longer than it should be. Otherwise
- ;; break the line at the column computed above.
- ;;
- ;; Need to use fortran-find-comment-start-skip to make sure that quoted !'s
- ;; don't prevent a break.
- (if (not (or (save-excursion
- (if (and (re-search-backward comment-start-skip bol t)
- (not (fortran-is-in-string-p (point))))
- (progn
- (skip-chars-backward " \t")
- (< (current-column) (1+ fill-column)))))
- (save-excursion
- (goto-char fill-point)
- (bolp))))
- (if (> (save-excursion
- (goto-char fill-point) (current-column))
- (1+ fill-column))
- (progn (goto-char fill-point)
- (fortran-break-line))
- (save-excursion
- (if (> (save-excursion
- (goto-char fill-point)
- (current-column))
- (+ (calculate-fortran-indent) fortran-continuation-indent))
- (progn
- (goto-char fill-point)
- (fortran-break-line))))))
- ))
-(defun fortran-break-line ()
- (let ((opoint (point))
- (bol (save-excursion (beginning-of-line) (point)))
- (eol (save-excursion (end-of-line) (point)))
- (comment-string nil))
-
- (save-excursion
- (if (and comment-start-skip (fortran-find-comment-start-skip))
- (progn
- (re-search-backward comment-start-skip bol t)
- (setq comment-string (buffer-substring (point) eol))
- (delete-region (point) eol))))
-;;; Forward line 1 really needs to go to next non white line
- (if (save-excursion (forward-line 1)
- (or (looking-at " [^ 0\n]")
- (looking-at "\t[1-9]")))
- (progn
- (forward-line 1)
- (delete-indentation)
- (delete-char 2)
- (delete-horizontal-space)
- (fortran-do-auto-fill))
- (fortran-split-line))
- (if comment-string
- (save-excursion
- (goto-char bol)
- (end-of-line)
- (delete-horizontal-space)
- (indent-to (fortran-comment-hook))
- (insert comment-string)))))
-
-(defun fortran-analyze-file-format ()
- "Returns nil if fixed format is used, t if TAB formatting is used.
-Use `fortran-tab-mode-default' if no non-comment statements are found in the
-file before the end or the first `fortran-analyze-depth' lines."
- (let ((i 0))
- (save-excursion
- (goto-char (point-min))
- (setq i 0)
- (while (not (or
- (eobp)
- (looking-at "\t")
- (looking-at " ")
- (> i fortran-analyze-depth)))
- (forward-line)
- (setq i (1+ i)))
- (cond
- ((looking-at "\t") t)
- ((looking-at " ") nil)
- (fortran-tab-mode-default t)
- (t nil)))))
-
-(or (assq 'fortran-tab-mode-string minor-mode-alist)
- (setq minor-mode-alist (cons
- '(fortran-tab-mode-string
- (indent-tabs-mode fortran-tab-mode-string))
- minor-mode-alist)))
-
-(provide 'fortran)
-
-;;; fortran.el ends here
-
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
deleted file mode 100644
index a48e471f753..00000000000
--- a/lisp/progmodes/hideif.el
+++ /dev/null
@@ -1,1041 +0,0 @@
-;;; hide-ifdef-mode.el --- hides selected code within ifdef.
-
-;;; Copyright (C) 1988 Free Software Foundation, Inc.
-
-;; Author: Dan LaLiberte <liberte@a.cs.uiuc.edu>
-;; Keywords: c
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;; To initialize, toggle the hide-ifdef minor mode with
-;;;
-;;; M-x hide-ifdef-mode
-;;;
-;;; This will set up key bindings and call hide-ifdef-mode-hook if it
-;;; has a value. To explicitly hide ifdefs using a buffer-local
-;;; define list (default empty), type
-;;;
-;;; M-x hide-ifdefs or C-c h
-;;;
-;;; Hide-ifdef suppresses the display of code that the preprocessor wouldn't
-;;; pass through. The support of constant expressions in #if lines is
-;;; limited to identifiers, parens, and the operators: &&, ||, !, and
-;;; "defined". Please extend this.
-;;;
-;;; The hidden code is marked by ellipses (...). Be
-;;; cautious when editing near ellipses, since the hidden text is
-;;; still in the buffer, and you can move the point into it and modify
-;;; text unawares. If you don't want to see the ellipses, set
-;;; selective-display-ellipses to nil. But this can be dangerous.
-;;; You can make your buffer read-only while hide-ifdef-hiding by setting
-;;; hide-ifdef-read-only to a non-nil value. You can toggle this
-;;; variable with hide-ifdef-toggle-read-only (C-c C-q).
-;;;
-;;; You can undo the effect of hide-ifdefs by typing
-;;;
-;;; M-x show-ifdefs or C-c s
-;;;
-;;; Use M-x hide-ifdef-define (C-c d) to define a symbol.
-;;; Use M-x hide-ifdef-undef (C-c u) to undefine a symbol.
-;;;
-;;; If you define or undefine a symbol while hide-ifdef-mode is in effect,
-;;; the display will be updated. Only the define list for the current
-;;; buffer will be affected. You can save changes to the local define
-;;; list with hide-ifdef-set-define-alist. This adds entries
-;;; to hide-ifdef-define-alist.
-;;;
-;;; If you have defined a hide-ifdef-mode-hook, you can set
-;;; up a list of symbols that may be used by hide-ifdefs as in the
-;;; following example:
-;;;
-;;; (setq hide-ifdef-mode-hook
-;;; '(lambda ()
-;;; (if (not hide-ifdef-define-alist)
-;;; (setq hide-ifdef-define-alist
-;;; '((list1 ONE TWO)
-;;; (list2 TWO THREE)
-;;; )))
-;;; (hide-ifdef-use-define-alist 'list2) ; use list2 by default
-;;; ))
-;;;
-;;; You can call hide-ifdef-use-define-alist (C-c u) at any time to specify
-;;; another list to use.
-;;;
-;;; To cause ifdefs to be hidden as soon as hide-ifdef-mode is called,
-;;; set hide-ifdef-initially to non-nil.
-;;;
-;;; If you set hide-ifdef-lines to t, hide-ifdefs hides all the #ifdef lines.
-;;; In the absence of highlighting, that might be a bad idea. If you set
-;;; hide-ifdef-lines to nil (the default), the surrounding preprocessor
-;;; lines will be displayed. That can be confusing in its own
-;;; right. Other variations on display are possible, but not much
-;;; better.
-;;;
-;;; You can explicitly hide or show individual ifdef blocks irrespective
-;;; of the define list by using hide-ifdef-block and show-ifdef-block.
-;;;
-;;; You can move the point between ifdefs with forward-ifdef, backward-ifdef,
-;;; up-ifdef, down-ifdef, next-ifdef, and previous-ifdef.
-;;;
-;;; If you have minor-mode-alist in your mode line (the default) two labels
-;;; may appear. "Ifdef" will appear when hide-ifdef-mode is active. "Hiding"
-;;; will appear when text may be hidden ("hide-ifdef-hiding" is non-nil).
-;;;
-;;; Written by Brian Marick, at Gould, Computer Systems Division, Urbana IL.
-;;; Extensively modified by Daniel LaLiberte (while at Gould).
-;;;
-;;; You may freely modify and distribute this, but keep a record
-;;; of modifications and send comments to:
-;;; liberte@a.cs.uiuc.edu or ihnp4!uiucdcs!liberte
-;;; I will continue to upgrade hide-ifdef-mode
-;;; with your contributions.
-
-;;; Change Log:
-;;;
-;;; Revision 1.7 88/02/16 03:12:58 liberte
-;;; Fixed comments and doc strings.
-;;; Added optional prefix arg for ifdef motion commands.
-;;;
-;;; Revision 1.6 88/02/05 00:36:18 liberte
-;;; Bug fixes.
-;;; 1. A multi-line comment that starts on an #ifdef line
-;;; now ends on that line.
-;;; 2. Fix bad function name: hide-hif-ifdef-toggle-read-only
-;;; 3. Make ifdef-block hiding work outside of ifdefs.
-;;;
-;;; Revision 1.5 88/01/31 23:19:31 liberte
-;;; Major clean up.
-;;; Prefix internal names with "hif-".
-;;;
-;;; Revision 1.4 88/01/30 14:09:38 liberte
-;;; Add hide-ifdef-hiding and hide-ifdef-mode to minor-mode-alist.
-;;;
-;;; Revision 1.3 88/01/29 00:38:19 liberte
-;;; Fix three bugs.
-;;; 1. Function "defined" is just like lookup.
-;;; 2. Skip to newline or cr in case text is hidden.
-;;; 3. Use car of token list if just one symbol.
-;;;
-;;; Revision 1.2 88/01/28 23:32:46 liberte
-;;; Use hide-ifdef-mode-prefix-key.
-;;; Copy current-local-map so other buffers do not get
-;;; hide-ifdef-mode bindings.
-;;;
-
-;;; Code:
-
-(defvar hide-ifdef-mode-map nil
- "Keymap used with Hide-Ifdef mode")
-
-(defconst hide-ifdef-mode-prefix-key "\C-c"
- "Prefix key for all Hide-Ifdef mode commands.")
-
-(defvar hide-ifdef-mode-map-before nil
- "Buffer-local variable to store a copy of the local keymap
-before `hide-ifdef-mode' modifies it.")
-
-(defun define-hide-ifdef-mode-map ()
- (if hide-ifdef-mode-map
- () ; dont redefine it.
- (setq hide-ifdef-mode-map (make-sparse-keymap))
- (define-key hide-ifdef-mode-map "\ed" 'hide-ifdef-define)
- (define-key hide-ifdef-mode-map "\eu" 'hide-ifdef-undef)
- (define-key hide-ifdef-mode-map "\eD" 'hide-ifdef-set-define-alist)
- (define-key hide-ifdef-mode-map "\eU" 'hide-ifdef-use-define-alist)
-
- (define-key hide-ifdef-mode-map "\eh" 'hide-ifdefs)
- (define-key hide-ifdef-mode-map "\es" 'show-ifdefs)
- (define-key hide-ifdef-mode-map "\C-h" 'hide-ifdef-block)
- (define-key hide-ifdef-mode-map "\C-s" 'show-ifdef-block)
-
- (define-key hide-ifdef-mode-map "\C-f" 'forward-ifdef)
- (define-key hide-ifdef-mode-map "\C-b" 'backward-ifdef)
- (define-key hide-ifdef-mode-map "\C-d" 'down-ifdef)
- (define-key hide-ifdef-mode-map "\C-u" 'up-ifdef)
- (define-key hide-ifdef-mode-map "\C-n" 'next-ifdef)
- (define-key hide-ifdef-mode-map "\C-p" 'previous-ifdef)
- (define-key hide-ifdef-mode-map "\C-q" 'hide-ifdef-toggle-read-only)
- (let ((where (where-is-internal 'toggle-read-only nil nil t)))
- (if where
- (define-key hide-ifdef-mode-map
- where
- 'hide-ifdef-toggle-outside-read-only)))
- )
- (fset 'hide-ifdef-mode-map hide-ifdef-mode-map) ; the function is the map
- )
-
-(defun hif-update-mode-line ()
- "Update mode-line by setting buffer-modified to itself."
- (set-buffer-modified-p (buffer-modified-p)))
-
-(defvar hide-ifdef-mode nil
- "non-nil when hide-ifdef-mode is activated.")
-
-(defvar hide-ifdef-hiding nil
- "non-nil when text may be hidden.")
-
-(or (assq 'hide-ifdef-hiding minor-mode-alist)
- (setq minor-mode-alist
- (cons '(hide-ifdef-hiding " Hiding")
- minor-mode-alist)))
-
-(or (assq 'hide-ifdef-mode minor-mode-alist)
- (setq minor-mode-alist
- (cons '(hide-ifdef-mode " Ifdef")
- minor-mode-alist)))
-
-;;;###autoload
-(defun hide-ifdef-mode (arg)
- "Toggle Hide-Ifdef mode. This is a minor mode, albeit a large one.
-With ARG, turn Hide-Ifdef mode on iff arg is positive.
-In Hide-Ifdef mode, code within #ifdef constructs that the C preprocessor
-would eliminate may be hidden from view. Several variables affect
-how the hiding is done:
-
-hide-ifdef-env
- An association list of defined and undefined symbols for the
- current buffer. Initially, the global value of `hide-ifdef-env'
- is used.
-
-hide-ifdef-define-alist
- An association list of defined symbol lists.
- Use `hide-ifdef-set-define-alist' to save the current `hide-ifdef-env'
- and `hide-ifdef-use-define-alist' to set the current `hide-ifdef-env'
- from one of the lists in `hide-ifdef-define-alist'.
-
-hide-ifdef-lines
- Set to non-nil to not show #if, #ifdef, #ifndef, #else, and
- #endif lines when hiding.
-
-hide-ifdef-initially
- Indicates whether `hide-ifdefs' should be called when Hide-Ifdef mode
- is activated.
-
-hide-ifdef-read-only
- Set to non-nil if you want to make buffers read only while hiding.
- After `show-ifdefs', read-only status is restored to previous value.
-
-\\{hide-ifdef-mode-map}"
-
- (interactive "P")
- (make-local-variable 'hide-ifdef-mode)
- (setq hide-ifdef-mode
- (if (null arg)
- (not hide-ifdef-mode)
- (> (prefix-numeric-value arg) 0)))
-
- (hif-update-mode-line)
-
- (if hide-ifdef-mode
- (progn
- ; fix c-mode syntax table so we can recognize whole symbols.
- (modify-syntax-entry ?_ "w")
- (modify-syntax-entry ?& ".")
- (modify-syntax-entry ?\| ".")
-
- ; inherit global values
- (make-local-variable 'hide-ifdef-env)
- (setq hide-ifdef-env (default-value 'hide-ifdef-env))
-
- (make-local-variable 'hide-ifdef-hiding)
- (setq hide-ifdef-hiding (default-value 'hide-ifdef-hiding))
-
- (make-local-variable 'hif-outside-read-only)
- (setq hif-outside-read-only buffer-read-only)
-
- (make-local-variable 'hide-ifdef-mode-map-before)
- (setq hide-ifdef-mode-map-before (current-local-map))
- (use-local-map (copy-keymap (current-local-map)))
- (local-unset-key hide-ifdef-mode-prefix-key)
- (local-set-key hide-ifdef-mode-prefix-key 'hide-ifdef-mode-map)
- (define-hide-ifdef-mode-map)
-
- (run-hooks 'hide-ifdef-mode-hook)
-
- (if hide-ifdef-initially
- (hide-ifdefs)
- (show-ifdefs))
- (message "Enter hide-ifdef-mode.")
- )
- ; else end hide-ifdef-mode
- (if hide-ifdef-hiding
- (show-ifdefs))
- (use-local-map hide-ifdef-mode-map-before)
- (message "Exit hide-ifdef-mode.")
- ))
-
-
-;; from outline.el with docstring fixed.
-(defun hif-outline-flag-region (from to flag)
- "Hides or shows lines from FROM to TO, according to FLAG. If FLAG
-is \\n (newline character) then text is shown, while if FLAG is \\^M
-\(control-M) the text is hidden."
- (let ((modp (buffer-modified-p)))
- (unwind-protect (progn
- (subst-char-in-region from to
- (if (= flag ?\n) ?\^M ?\n)
- flag t) )
- (set-buffer-modified-p modp))
- ))
-
-(defun hif-show-all ()
- "Show all of the text in the current buffer."
- (interactive)
- (hif-outline-flag-region (point-min) (point-max) ?\n))
-
-(defun hide-ifdef-region (start end)
- "START is the start of a #if or #else form. END is the ending part.
-Everything including these lines is made invisible."
- (hif-outline-flag-region start end ?\^M)
- )
-
-(defun hif-show-ifdef-region (start end)
- "Everything between START and END is made visible."
- (hif-outline-flag-region start end ?\n)
- )
-
-
-
-;===%%SF%% evaluation (Start) ===
-
-(defvar hide-ifdef-evaluator 'eval
- "The evaluator is given a canonical form and returns T if text under
-that form should be displayed.")
-
-(defvar hif-undefined-symbol nil
- "...is by default considered to be false.")
-
-(defvar hide-ifdef-env nil
- "An alist of defined symbols and their values.")
-
-
-(defun hif-set-var (var value)
- "Prepend (var value) pair to hide-ifdef-env."
- (setq hide-ifdef-env (cons (cons var value) hide-ifdef-env)))
-
-
-(defun hif-lookup (var)
-; (message "hif-lookup %s" var)
- (let ((val (assoc var hide-ifdef-env)))
- (if val
- (cdr val)
- hif-undefined-symbol)))
-
-(defun hif-defined (var)
- (hif-lookup var)
- ; when #if expressions are fully supported, defined result should be 1
- ; (if (assoc var hide-ifdef-env)
- ; 1
- ; nil)
-)
-
-
-;===%%SF%% evaluation (End) ===
-
-
-
-;===%%SF%% parsing (Start) ===
-;;; The code that understands what ifs and ifdef in files look like.
-
-(defconst hif-cpp-prefix "\\(^\\|\r\\)[ \t]*#[ \t]*")
-(defconst hif-ifndef-regexp (concat hif-cpp-prefix "ifndef"))
-(defconst hif-ifx-regexp (concat hif-cpp-prefix "if\\(n?def\\)?[ \t]+"))
-(defconst hif-else-regexp (concat hif-cpp-prefix "else"))
-(defconst hif-endif-regexp (concat hif-cpp-prefix "endif"))
-(defconst hif-ifx-else-endif-regexp
- (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp))
-
-
-(defun hif-infix-to-prefix (token-list)
- "Convert list of tokens in infix into prefix list"
-; (message "hif-infix-to-prefix: %s" token-list)
- (if (= 1 (length token-list))
- (` (hif-lookup (quote (, (car token-list)))))
- (hif-parse-if-exp token-list))
- )
-
-; pattern to match initial identifier, !, &&, ||, (, or ).
-(defconst hif-token-regexp "^\\(!\\|&&\\|||\\|[()]\\|\\w+\\)")
-(defconst hif-end-of-comment "\\*/")
-
-
-(defun hif-tokenize (expr-string)
- "Separate string into a list of tokens"
- (let ((token-list nil)
- (expr-start 0)
- (expr-length (length expr-string)))
-
- (while (< expr-start expr-length)
-; (message "expr-start = %d" expr-start) (sit-for 1)
- (cond
- ((string-match "^[ \t]+" expr-string expr-start)
- ; skip whitespace
- (setq expr-start (match-end 0))
- ; stick newline in string so ^ matches on the next string-match
- (aset expr-string (1- expr-start) ?\n)
- )
-
- ((string-match "^/\\*" expr-string expr-start)
- (setq expr-start (match-end 0))
- (aset expr-string (1- expr-start) ?\n)
- (or
- (string-match hif-end-of-comment
- expr-string expr-start) ; eat comment
- (string-match "$" expr-string expr-start)) ; multi-line comment
- (setq expr-start (match-end 0))
- (aset expr-string (1- expr-start) ?\n)
- )
-
- ((string-match "^//" expr-string expr-start)
- (string-match "$" expr-string expr-start)
- (setq expr-start (match-end 0))
- )
-
- ((string-match hif-token-regexp expr-string expr-start)
- (let ((token (substring expr-string expr-start (match-end 0))))
- (setq expr-start (match-end 0))
- (aset expr-string (1- expr-start) ?\n)
-; (message "token: %s" token) (sit-for 1)
- (setq token-list
- (cons
- (cond
- ((string-equal token "||") 'or)
- ((string-equal token "&&") 'and)
- ((string-equal token "!") 'not)
- ((string-equal token "defined") 'hif-defined)
- ((string-equal token "(") 'lparen)
- ((string-equal token ")") 'rparen)
- (t (intern token)))
- token-list))
- ))
- (t (error "Bad #if expression: %s" expr-string))
- ))
- (nreverse token-list)
- ))
-
-;;;-----------------------------------------------------------------
-;;; Translate C preprocessor #if expressions using recursive descent.
-;;; This parser is limited to the operators &&, ||, !, and "defined".
-
-(defun hif-parse-if-exp (token-list)
- "Parse the TOKEN-LIST. Return translated list in prefix form."
- (hif-nexttoken)
- (prog1
- (hif-expr)
- (if token ; is there still a token?
- (error "Error: unexpected token: %s" token))))
-
-(defun hif-nexttoken ()
- "Pop the next token from token-list into the let variable \"token\"."
- (setq token (car token-list))
- (setq token-list (cdr token-list))
- token)
-
-(defun hif-expr ()
- "Parse and expression of the form
- expr : term | expr '||' term."
- (let ((result (hif-term)))
- (while (eq token 'or)
- (hif-nexttoken)
- (setq result (list 'or result (hif-term))))
- result))
-
-(defun hif-term ()
- "Parse a term of the form
- term : factor | term '&&' factor."
- (let ((result (hif-factor)))
- (while (eq token 'and)
- (hif-nexttoken)
- (setq result (list 'and result (hif-factor))))
- result))
-
-(defun hif-factor ()
- "Parse a factor of the form
- factor : '!' factor | '(' expr ')' | 'defined(' id ')' | id."
- (cond
- ((eq token 'not)
- (hif-nexttoken)
- (list 'not (hif-factor)))
-
- ((eq token 'lparen)
- (hif-nexttoken)
- (let ((result (hif-expr)))
- (if (not (eq token 'rparen))
- (error "Bad token in parenthesized expression: %s" token)
- (hif-nexttoken)
- result)))
-
- ((eq token 'hif-defined)
- (hif-nexttoken)
- (if (not (eq token 'lparen))
- (error "Error: expected \"(\" after \"defined\""))
- (hif-nexttoken)
- (let ((ident token))
- (if (memq token '(or and not hif-defined lparen rparen))
- (error "Error: unexpected token: %s" token))
- (hif-nexttoken)
- (if (not (eq token 'rparen))
- (error "Error: expected \")\" after identifier"))
- (hif-nexttoken)
- (` (hif-defined (quote (, ident))))
- ))
-
- (t ; identifier
- (let ((ident token))
- (if (memq ident '(or and))
- (error "Error: missing identifier"))
- (hif-nexttoken)
- (` (hif-lookup (quote (, ident))))
- ))
- ))
-
-;;;----------- end of parser -----------------------
-
-
-(defun hif-canonicalize ()
- "When at beginning of #ifX, returns a canonical (evaluatable)
- form for the expression."
- (save-excursion
- (let ((negate (looking-at hif-ifndef-regexp)))
- (re-search-forward hif-ifx-regexp)
- (let* ((expr-string
- (buffer-substring (point)
- (progn (skip-chars-forward "^\n\r") (point))))
- (expr (hif-infix-to-prefix (hif-tokenize expr-string))))
-; (message "hif-canonicalized: %s" expr)
- (if negate
- (list 'not expr)
- expr)))))
-
-
-(defun hif-find-any-ifX ()
- "Position at beginning of next #if, #ifdef, or #ifndef, including one on
-this line."
-; (message "find ifX at %d" (point))
- (prog1
- (re-search-forward hif-ifx-regexp (point-max) t)
- (beginning-of-line)))
-
-
-(defun hif-find-next-relevant ()
- "Position at beginning of next #ifdef, #ifndef, #else, #endif,
-NOT including one on this line."
-; (message "hif-find-next-relevant at %d" (point))
- (end-of-line)
- ; avoid infinite recursion by only going to beginning of line if match found
- (if (re-search-forward hif-ifx-else-endif-regexp (point-max) t)
- (beginning-of-line)))
-
-(defun hif-find-previous-relevant ()
- "Position at beginning of previous #ifdef, #ifndef, #else, #endif,
-NOT including one on this line."
-; (message "hif-find-previous-relevant at %d" (point))
- (beginning-of-line)
- ; avoid infinite recursion by only going to beginning of line if match found
- (if (re-search-backward hif-ifx-else-endif-regexp (point-min) t)
- (beginning-of-line)))
-
-
-(defun hif-looking-at-ifX () ;; Should eventually see #if
- (looking-at hif-ifx-regexp))
-(defun hif-looking-at-endif ()
- (looking-at hif-endif-regexp))
-(defun hif-looking-at-else ()
- (looking-at hif-else-regexp))
-
-
-
-(defun hif-ifdef-to-endif ()
- "If positioned at #ifX or #else form, skip to corresponding #endif."
-; (message "hif-ifdef-to-endif at %d" (point)) (sit-for 1)
- (hif-find-next-relevant)
- (cond ((hif-looking-at-ifX)
- (hif-ifdef-to-endif) ; find endif of nested if
- (hif-ifdef-to-endif)) ; find outer endif or else
- ((hif-looking-at-else)
- (hif-ifdef-to-endif)) ; find endif following else
- ((hif-looking-at-endif)
- 'done)
- (t
- (error "Mismatched #ifdef #endif pair"))))
-
-
-(defun hif-endif-to-ifdef ()
- "If positioned at #endif form, skip backward to corresponding #ifX."
-; (message "hif-endif-to-ifdef at %d" (point))
- (let ((start (point)))
- (hif-find-previous-relevant)
- (if (= start (point))
- (error "Mismatched #ifdef #endif pair")))
- (cond ((hif-looking-at-endif)
- (hif-endif-to-ifdef) ; find beginning of nested if
- (hif-endif-to-ifdef)) ; find beginning of outer if or else
- ((hif-looking-at-else)
- (hif-endif-to-ifdef))
- ((hif-looking-at-ifX)
- 'done)
- (t))) ; never gets here
-
-
-(defun forward-ifdef (&optional arg)
- "Move point to beginning of line of the next ifdef-endif.
-With argument, do this that many times."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0)
- (backward-ifdef (- arg)))
- (while (< 0 arg)
- (setq arg (- arg))
- (let ((start (point)))
- (if (not (hif-looking-at-ifX))
- (hif-find-next-relevant))
- (if (hif-looking-at-ifX)
- (hif-ifdef-to-endif)
- (goto-char start)
- (error "No following #ifdef")
- ))))
-
-
-(defun backward-ifdef (&optional arg)
- "Move point to beginning of the previous ifdef-endif.
-With argument, do this that many times."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0)
- (forward-ifdef (- arg)))
- (while (< 0 arg)
- (setq arg (1- arg))
- (beginning-of-line)
- (let ((start (point)))
- (if (not (hif-looking-at-endif))
- (hif-find-previous-relevant))
- (if (hif-looking-at-endif)
- (hif-endif-to-ifdef)
- (goto-char start)
- (error "No previous #ifdef")))))
-
-
-(defun down-ifdef ()
- "Move point to beginning of nested ifdef or else-part."
- (interactive)
- (let ((start (point)))
- (hif-find-next-relevant)
- (if (or (hif-looking-at-ifX) (hif-looking-at-else))
- ()
- (goto-char start)
- (error "No following #ifdef"))))
-
-
-(defun up-ifdef ()
- "Move point to beginning of enclosing ifdef or else-part."
- (interactive)
- (beginning-of-line)
- (let ((start (point)))
- (if (not (hif-looking-at-endif))
- (hif-find-previous-relevant))
- (if (hif-looking-at-endif)
- (hif-endif-to-ifdef))
- (if (= start (point))
- (error "No previous #ifdef"))))
-
-(defun next-ifdef (&optional arg)
- "Move to the beginning of the next #ifX, #else, or #endif.
-With argument, do this that many times."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0)
- (previous-ifdef (- arg)))
- (while (< 0 arg)
- (setq arg (1- arg))
- (hif-find-next-relevant)
- (if (eolp)
- (progn
- (beginning-of-line)
- (error "No following #ifdefs, #elses, or #endifs")))))
-
-(defun previous-ifdef (&optional arg)
- "Move to the beginning of the previous #ifX, #else, or #endif.
-With argument, do this that many times."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0)
- (next-ifdef (- arg)))
- (while (< 0 arg)
- (setq arg (1- arg))
- (let ((start (point)))
- (hif-find-previous-relevant)
- (if (= start (point))
- (error "No previous #ifdefs, #elses, or #endifs")
- ))))
-
-
-;===%%SF%% parsing (End) ===
-
-
-;===%%SF%% hide-ifdef-hiding (Start) ===
-
-
-;;; A range is a structure with four components:
-;;; ELSE-P True if there was an else clause for the ifdef.
-;;; START The start of the range. (beginning of line)
-;;; ELSE The else marker (beginning of line)
-;;; Only valid if ELSE-P is true.
-;;; END The end of the range. (beginning of line)
-
-(defun hif-make-range (else-p start end &optional else)
- (list else-p start else end))
-
-(defun hif-range-else-p (range) (elt range 0))
-(defun hif-range-start (range) (elt range 1))
-(defun hif-range-else (range) (elt range 2))
-(defun hif-range-end (range) (elt range 3))
-
-
-
-;;; Find-Range
-;;; The workhorse, it delimits the #if region. Reasonably simple:
-;;; Skip until an #else or #endif is found, remembering positions. If
-;;; an #else was found, skip some more, looking for the true #endif.
-
-(defun hif-find-range ()
- "Returns a Range structure describing the current #if region.
-Point is left unchanged."
-; (message "hif-find-range at %d" (point))
- (save-excursion
- (beginning-of-line)
- (let ((start (point))
- (else-p nil)
- (else nil)
- (end nil))
- ;; Part one. Look for either #endif or #else.
- ;; This loop-and-a-half dedicated to E. Dijkstra.
- (hif-find-next-relevant)
- (while (hif-looking-at-ifX) ; Skip nested ifdef
- (hif-ifdef-to-endif)
- (hif-find-next-relevant))
- ;; Found either a #else or an #endif.
- (cond ((hif-looking-at-else)
- (setq else-p t)
- (setq else (point)))
- (t
- (setq end (point)) ; (save-excursion (end-of-line) (point))
- ))
- ;; If found #else, look for #endif.
- (if else-p
- (progn
- (hif-find-next-relevant)
- (while (hif-looking-at-ifX) ; Skip nested ifdef
- (hif-ifdef-to-endif)
- (hif-find-next-relevant))
- (if (hif-looking-at-else)
- (error "Found two elses in a row? Broken!"))
- (setq end (point)) ; (save-excursion (end-of-line) (point))
- ))
- (hif-make-range else-p start end else))))
-
-
-;;; A bit slimy.
-;;; NOTE: If there's an #ifdef at the beginning of the file, we can't
-;;; hide it. There's no previous newline to replace. If we added
-;;; one, we'd throw off all the counts. Feh.
-
-(defun hif-hide-line (point)
- "Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil."
- (if hide-ifdef-lines
- (save-excursion
- (goto-char point)
- (let ((modp (buffer-modified-p)))
- (unwind-protect
- (progn
- (beginning-of-line)
- (if (not (= (point) 1))
- (hide-ifdef-region (1- (point)) (point))))
- (set-buffer-modified-p modp))
- ))
- ))
-
-
-;;; Hif-Possibly-Hide
-;;; There are four cases. The #ifX expression is "taken" if it
-;;; the hide-ifdef-evaluator returns T. Presumably, this means the code
-;;; inside the #ifdef would be included when the program was
-;;; compiled.
-;;;
-;;; Case 1: #ifX taken, and there's an #else.
-;;; The #else part must be hidden. The #if (then) part must be
-;;; processed for nested #ifX's.
-;;; Case 2: #ifX taken, and there's no #else.
-;;; The #if part must be processed for nested #ifX's.
-;;; Case 3: #ifX not taken, and there's an #else.
-;;; The #if part must be hidden. The #else part must be processed
-;;; for nested #ifs.
-;;; Case 4: #ifX not taken, and there's no #else.
-;;; The #ifX part must be hidden.
-;;;
-;;; Further processing is done by narrowing to the relevant region
-;;; and just recursively calling hide-ifdef-guts.
-;;;
-;;; When hif-possibly-hide returns, point is at the end of the
-;;; possibly-hidden range.
-
-(defun hif-recurse-on (start end)
- "Call `hide-ifdef-guts' after narrowing to end of START line and END line."
- (save-excursion
- (save-restriction
- (goto-char start)
- (end-of-line)
- (narrow-to-region (point) end)
- (hide-ifdef-guts))))
-
-(defun hif-possibly-hide ()
- "Called at #ifX expression, this hides those parts that should be
-hidden, according to judgement of `hide-ifdef-evaluator'."
-; (message "hif-possibly-hide") (sit-for 1)
- (let ((test (hif-canonicalize))
- (range (hif-find-range)))
-; (message "test = %s" test) (sit-for 1)
-
- (hif-hide-line (hif-range-end range))
- (if (funcall hide-ifdef-evaluator test)
- (cond ((hif-range-else-p range) ; case 1
- (hif-hide-line (hif-range-else range))
- (hide-ifdef-region (hif-range-else range)
- (1- (hif-range-end range)))
- (hif-recurse-on (hif-range-start range)
- (hif-range-else range)))
- (t ; case 2
- (hif-recurse-on (hif-range-start range)
- (hif-range-end range))))
- (cond ((hif-range-else-p range) ; case 3
- (hif-hide-line (hif-range-else range))
- (hide-ifdef-region (hif-range-start range)
- (1- (hif-range-else range)))
- (hif-recurse-on (hif-range-else range)
- (hif-range-end range)))
- (t ; case 4
- (hide-ifdef-region (point)
- (1- (hif-range-end range))))
- ))
- (hif-hide-line (hif-range-start range)) ; Always hide start.
- (goto-char (hif-range-end range))
- (end-of-line)
- ))
-
-
-
-(defun hide-ifdef-guts ()
- "Does the work of `hide-ifdefs', except for the work that's pointless
-to redo on a recursive entry."
-; (message "hide-ifdef-guts")
- (save-excursion
- (goto-char (point-min))
- (while (hif-find-any-ifX)
- (hif-possibly-hide))))
-
-;===%%SF%% hide-ifdef-hiding (End) ===
-
-
-;===%%SF%% exports (Start) ===
-
-;;;###autoload
-(defvar hide-ifdef-initially nil
- "*Non-nil if `hide-ifdefs' should be called when Hide-Ifdef mode
-is first activated.")
-
-(defvar hide-ifdef-hiding nil
- "Non-nil if text might be hidden.")
-
-;;;###autoload
-(defvar hide-ifdef-read-only nil
- "*Set to non-nil if you want buffer to be read-only while hiding text.")
-
-(defvar hif-outside-read-only nil
- "Internal variable. Saves the value of `buffer-read-only' while hiding.")
-
-;;;###autoload
-(defvar hide-ifdef-lines nil
- "*Set to t if you don't want to see the #ifX, #else, and #endif lines.")
-
-(defun hide-ifdef-toggle-read-only ()
- "Toggle hide-ifdef-read-only."
- (interactive)
- (setq hide-ifdef-read-only (not hide-ifdef-read-only))
- (message "Hide-Read-Only %s"
- (if hide-ifdef-read-only "ON" "OFF"))
- (if hide-ifdef-hiding
- (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)))
- (hif-update-mode-line))
-
-(defun hide-ifdef-toggle-outside-read-only ()
- "Replacement for `toggle-read-only' within Hide Ifdef mode."
- (interactive)
- (setq hif-outside-read-only (not hif-outside-read-only))
- (message "Read only %s"
- (if hif-outside-read-only "ON" "OFF"))
- (setq buffer-read-only
- (or (and hide-ifdef-hiding hide-ifdef-read-only)
- hif-outside-read-only)
- )
- (hif-update-mode-line))
-
-
-(defun hide-ifdef-define (var)
- "Define a VAR so that #ifdef VAR would be included."
- (interactive "SDefine what? ")
- (hif-set-var var t)
- (if hide-ifdef-hiding (hide-ifdefs)))
-
-(defun hide-ifdef-undef (var)
- "Undefine a VAR so that #ifdef VAR would not be included."
- (interactive "SUndefine what? ")
- (hif-set-var var nil)
- (if hide-ifdef-hiding (hide-ifdefs)))
-
-
-(defun hide-ifdefs ()
- "Hide the contents of some #ifdefs.
-Assume that defined symbols have been added to `hide-ifdef-env'.
-The text hidden is the text that would not be included by the C
-preprocessor if it were given the file with those symbols defined.
-
-Turn off hiding by calling `show-ifdef'."
-
- (interactive)
- (message "Hiding...")
- (if (not hide-ifdef-mode)
- (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode
- (if hide-ifdef-hiding
- (show-ifdefs)) ; Otherwise, deep confusion.
- (if buffer-read-only (toggle-read-only)) ; make it writable temporarily
- (setq selective-display t)
- (setq hide-ifdef-hiding t)
- (hide-ifdef-guts)
- (if (or hide-ifdef-read-only hif-outside-read-only)
- (toggle-read-only)) ; make it read only
- (message "Hiding done"))
-
-
-(defun show-ifdefs ()
- "Cancel the effects of `hide-ifdef'. The contents of all #ifdefs is shown."
- (interactive)
- (if buffer-read-only (toggle-read-only)) ; make it writable temporarily
- (setq selective-display nil) ; defaults
- (hif-show-all)
- (if hif-outside-read-only
- (toggle-read-only)) ; make it read only
- (setq hide-ifdef-hiding nil))
-
-
-(defun hif-find-ifdef-block ()
- "Utility for hide and show `ifdef-block'.
-Set top and bottom of ifdef block."
- (let (max-bottom)
- (save-excursion
- (beginning-of-line)
- (if (not (or (hif-looking-at-else) (hif-looking-at-ifX)))
- (up-ifdef))
- (setq top (point))
- (hif-ifdef-to-endif)
- (setq max-bottom (1- (point))))
- (save-excursion
- (beginning-of-line)
- (if (not (hif-looking-at-endif))
- (hif-find-next-relevant))
- (while (hif-looking-at-ifX)
- (hif-ifdef-to-endif)
- (hif-find-next-relevant))
- (setq bottom (min max-bottom (1- (point))))))
- )
-
-
-(defun hide-ifdef-block ()
- "Hide the ifdef block (true or false part) enclosing or before the cursor."
- (interactive)
- (if (not hide-ifdef-mode)
- (hide-ifdef-mode 1))
- (if buffer-read-only (toggle-read-only))
- (setq selective-display t)
- (let (top bottom)
- (hif-find-ifdef-block) ; set top and bottom - dynamic scoping
- (hide-ifdef-region top bottom)
- (if hide-ifdef-lines
- (progn
- (hif-hide-line top)
- (hif-hide-line (1+ bottom))))
- (setq hide-ifdef-hiding t))
- (if (or hide-ifdef-read-only hif-outside-read-only)
- (toggle-read-only)))
-
-
-(defun show-ifdef-block ()
- "Show the ifdef block (true or false part) enclosing or before the cursor."
- (interactive)
- (let ((old-read-only buffer-read-only))
- (if old-read-only (toggle-read-only))
- (if hide-ifdef-lines
- (save-excursion
- (beginning-of-line)
- (hif-show-ifdef-region (1- (point)) (progn (end-of-line) (point))))
-
- (let (top bottom)
- (hif-find-ifdef-block)
- (hif-show-ifdef-region (1- top) bottom))
- )
-
- ; restore read only status since we dont know if all is shown.
- (if old-read-only (toggle-read-only))))
-
-
-;;; definition alist support
-
-(defvar hide-ifdef-define-alist nil
- "A global assoc list of pre-defined symbol lists")
-
-(defun hif-compress-define-list (env)
- "Compress the define list ENV into a list of defined symbols only."
- (let ((defs (mapcar '(lambda (arg)
- (if (hif-lookup (car arg)) (car arg)))
- env))
- (new-defs nil))
- (while defs
- (if (car defs)
- (setq new-defs (cons (car defs) new-defs)))
- (setq defs (cdr defs)))
- new-defs))
-
-(defun hide-ifdef-set-define-alist (name)
- "Set the association for NAME to `hide-ifdef-env'."
- (interactive "SSet define list: ")
- (setq hide-ifdef-define-alist
- (cons (cons name (hif-compress-define-list hide-ifdef-env))
- hide-ifdef-define-alist)))
-
-(defun hide-ifdef-use-define-alist (name)
- "Set `hide-ifdef-env' to the define list specified by NAME."
- (interactive "SUse define list: ")
- (let ((define-list (assoc name hide-ifdef-define-alist)))
- (if define-list
- (setq hide-ifdef-env
- (mapcar '(lambda (arg) (cons arg t))
- (cdr define-list)))
- (error "No define list for %s" name))
- (if hide-ifdef-hiding (hide-ifdefs))))
-
-;;; hideif.el ends here
-
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
deleted file mode 100644
index f64ed19dd37..00000000000
--- a/lisp/progmodes/icon.el
+++ /dev/null
@@ -1,559 +0,0 @@
-;;; icon.el --- mode for editing Icon code
-
-;; Copyright (C) 1989 Free Software Foundation, Inc.
-
-;; Author: Chris Smith <convex!csmith>
-;; Created: 15 Feb 89
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; A major mode for editing the Icon programming language.
-;;
-;; Note: use
-;; (autoload 'icon-mode "icon" nil t)
-;; (setq auto-mode-alist (cons '("\\.icn$" . icon-mode) auto-mode-alist))
-;; if not permanently installed in your emacs
-
-;;; Code:
-
-(defvar icon-mode-abbrev-table nil
- "Abbrev table in use in Icon-mode buffers.")
-(define-abbrev-table 'icon-mode-abbrev-table ())
-
-(defvar icon-mode-map ()
- "Keymap used in Icon mode.")
-(if icon-mode-map
- ()
- (setq icon-mode-map (make-sparse-keymap))
- (define-key icon-mode-map "{" 'electric-icon-brace)
- (define-key icon-mode-map "}" 'electric-icon-brace)
- (define-key icon-mode-map "\e\C-h" 'mark-icon-function)
- (define-key icon-mode-map "\e\C-a" 'beginning-of-icon-defun)
- (define-key icon-mode-map "\e\C-e" 'end-of-icon-defun)
- (define-key icon-mode-map "\e\C-q" 'indent-icon-exp)
- (define-key icon-mode-map "\177" 'backward-delete-char-untabify)
- (define-key icon-mode-map "\t" 'icon-indent-command))
-
-(defvar icon-mode-syntax-table nil
- "Syntax table in use in Icon-mode buffers.")
-
-(if icon-mode-syntax-table
- ()
- (setq icon-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\\ "\\" icon-mode-syntax-table)
- (modify-syntax-entry ?# "<" icon-mode-syntax-table)
- (modify-syntax-entry ?\n ">" icon-mode-syntax-table)
- (modify-syntax-entry ?$ "." icon-mode-syntax-table)
- (modify-syntax-entry ?/ "." icon-mode-syntax-table)
- (modify-syntax-entry ?* "." icon-mode-syntax-table)
- (modify-syntax-entry ?+ "." icon-mode-syntax-table)
- (modify-syntax-entry ?- "." icon-mode-syntax-table)
- (modify-syntax-entry ?= "." icon-mode-syntax-table)
- (modify-syntax-entry ?% "." icon-mode-syntax-table)
- (modify-syntax-entry ?< "." icon-mode-syntax-table)
- (modify-syntax-entry ?> "." icon-mode-syntax-table)
- (modify-syntax-entry ?& "." icon-mode-syntax-table)
- (modify-syntax-entry ?| "." icon-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" icon-mode-syntax-table))
-
-(defconst icon-indent-level 4
- "*Indentation of Icon statements with respect to containing block.")
-(defconst icon-brace-imaginary-offset 0
- "*Imagined indentation of a Icon open brace that actually follows a statement.")
-(defconst icon-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context.")
-(defconst icon-continued-statement-offset 4
- "*Extra indent for lines not starting new statements.")
-(defconst icon-continued-brace-offset 0
- "*Extra indent for substatements that start with open-braces.
-This is in addition to icon-continued-statement-offset.")
-
-(defconst icon-auto-newline nil
- "*Non-nil means automatically newline before and after braces
-inserted in Icon code.")
-
-(defconst icon-tab-always-indent t
- "*Non-nil means TAB in Icon mode should always reindent the current line,
-regardless of where in the line point is when the TAB command is used.")
-
-(defun icon-mode ()
- "Major mode for editing Icon code.
-Expression and list commands understand all Icon brackets.
-Tab indents for Icon code.
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-\\{icon-mode-map}
-Variables controlling indentation style:
- icon-tab-always-indent
- Non-nil means TAB in Icon mode should always reindent the current line,
- regardless of where in the line point is when the TAB command is used.
- icon-auto-newline
- Non-nil means automatically newline before and after braces
- inserted in Icon code.
- icon-indent-level
- Indentation of Icon statements within surrounding block.
- The surrounding block's indentation is the indentation
- of the line on which the open-brace appears.
- icon-continued-statement-offset
- Extra indentation given to a substatement, such as the
- then-clause of an if or body of a while.
- icon-continued-brace-offset
- Extra indentation given to a brace that starts a substatement.
- This is in addition to `icon-continued-statement-offset'.
- icon-brace-offset
- Extra indentation for line if it starts with an open brace.
- icon-brace-imaginary-offset
- An open brace following other text is treated as if it were
- this far to the right of the start of its line.
-
-Turning on Icon mode calls the value of the variable `icon-mode-hook'
-with no args, if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map icon-mode-map)
- (setq major-mode 'icon-mode)
- (setq mode-name "Icon")
- (setq local-abbrev-table icon-mode-abbrev-table)
- (set-syntax-table icon-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'icon-indent-line)
- (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 "")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "# *")
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'icon-comment-indent)
- (run-hooks 'icon-mode-hook))
-
-;; This is used by indent-for-comment to decide how much to
-;; indent a comment in Icon code based on its context.
-(defun icon-comment-indent ()
- (if (looking-at "^#")
- 0
- (save-excursion
- (skip-chars-backward " \t")
- (max (if (bolp) 0 (1+ (current-column)))
- comment-column))))
-
-(defun electric-icon-brace (arg)
- "Insert character and correct line's indentation."
- (interactive "P")
- (let (insertpos)
- (if (and (not arg)
- (eolp)
- (or (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (if icon-auto-newline
- (progn (icon-indent-line) (newline) t)
- nil)))
- (progn
- (insert last-command-char)
- (icon-indent-line)
- (if icon-auto-newline
- (progn
- (newline)
- ;; (newline) may have done auto-fill
- (setq insertpos (- (point) 2))
- (icon-indent-line)))
- (save-excursion
- (if insertpos (goto-char (1+ insertpos)))
- (delete-char -1))))
- (if insertpos
- (save-excursion
- (goto-char insertpos)
- (self-insert-command (prefix-numeric-value arg)))
- (self-insert-command (prefix-numeric-value arg)))))
-
-(defun icon-indent-command (&optional whole-exp)
- (interactive "P")
- "Indent current line as Icon code, or in some cases insert a tab character.
-If `icon-tab-always-indent' is non-nil (the default), always indent current
-line. Otherwise, indent the current line only if point is at the left margin
-or in the line's indentation; otherwise insert a tab.
-
-A numeric argument, regardless of its value, means indent rigidly all the
-lines of the expression starting after point so that this line becomes
-properly indented. The relative indentation among the lines of the
-expression are preserved."
- (if whole-exp
- ;; If arg, always indent this line as Icon
- ;; and shift remaining lines of expression the same amount.
- (let ((shift-amt (icon-indent-line))
- beg end)
- (save-excursion
- (if icon-tab-always-indent
- (beginning-of-line))
- (setq beg (point))
- (forward-sexp 1)
- (setq end (point))
- (goto-char beg)
- (forward-line 1)
- (setq beg (point)))
- (if (> end beg)
- (indent-code-rigidly beg end shift-amt "#")))
- (if (and (not icon-tab-always-indent)
- (save-excursion
- (skip-chars-backward " \t")
- (not (bolp))))
- (insert-tab)
- (icon-indent-line))))
-
-(defun icon-indent-line ()
- "Indent current line as Icon code.
-Return the amount the indentation changed by."
- (let ((indent (calculate-icon-indent nil))
- beg shift-amt
- (case-fold-search nil)
- (pos (- (point-max) (point))))
- (beginning-of-line)
- (setq beg (point))
- (cond ((eq indent nil)
- (setq indent (current-indentation)))
- ((eq indent t)
- (setq indent (calculate-icon-indent-within-comment)))
- ((looking-at "[ \t]*#")
- (setq indent 0))
- (t
- (skip-chars-forward " \t")
- (if (listp indent) (setq indent (car indent)))
- (cond ((and (looking-at "else\\b")
- (not (looking-at "else\\s_")))
- (setq indent (save-excursion
- (icon-backward-to-start-of-if)
- (current-indentation))))
- ((or (= (following-char) ?})
- (looking-at "end\\b"))
- (setq indent (- indent icon-indent-level)))
- ((= (following-char) ?{)
- (setq indent (+ indent icon-brace-offset))))))
- (skip-chars-forward " \t")
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- (delete-region beg (point))
- (indent-to indent)
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos))))
- shift-amt))
-
-(defun calculate-icon-indent (&optional parse-start)
- "Return appropriate indentation for current line as Icon code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment."
- (save-excursion
- (beginning-of-line)
- (let ((indent-point (point))
- (case-fold-search nil)
- state
- containing-sexp
- toplevel)
- (if parse-start
- (goto-char parse-start)
- (setq toplevel (beginning-of-icon-defun)))
- (while (< (point) indent-point)
- (setq parse-start (point))
- (setq state (parse-partial-sexp (point) indent-point 0))
- (setq containing-sexp (car (cdr state))))
- (cond ((or (nth 3 state) (nth 4 state))
- ;; return nil or t if should not change this line
- (nth 4 state))
- ((and containing-sexp
- (/= (char-after containing-sexp) ?{))
- ;; line is expression, not statement:
- ;; indent to just after the surrounding open.
- (goto-char (1+ containing-sexp))
- (current-column))
- (t
- (if toplevel
- ;; Outside any procedures.
- (progn (icon-backward-to-noncomment (point-min))
- (if (icon-is-continuation-line)
- icon-continued-statement-offset 0))
- ;; Statement level.
- (if (null containing-sexp)
- (progn (beginning-of-icon-defun)
- (setq containing-sexp (point))))
- (goto-char indent-point)
- ;; Is it a continuation or a new statement?
- ;; Find previous non-comment character.
- (icon-backward-to-noncomment containing-sexp)
- ;; Now we get the answer.
- (if (icon-is-continuation-line)
- ;; This line is continuation of preceding line's statement;
- ;; indent icon-continued-statement-offset more than the
- ;; first line of the statement.
- (progn
- (icon-backward-to-start-of-continued-exp containing-sexp)
- (+ icon-continued-statement-offset (current-column)
- (if (save-excursion (goto-char indent-point)
- (skip-chars-forward " \t")
- (eq (following-char) ?{))
- icon-continued-brace-offset 0)))
- ;; This line starts a new statement.
- ;; Position following last unclosed open.
- (goto-char containing-sexp)
- ;; Is line first statement after an open-brace?
- (or
- ;; If no, find that first statement and indent like it.
- (save-excursion
- (if (looking-at "procedure\\s ")
- (forward-sexp 3)
- (forward-char 1))
- (while (progn (skip-chars-forward " \t\n")
- (looking-at "#"))
- ;; Skip over comments following openbrace.
- (forward-line 1))
- ;; The first following code counts
- ;; if it is before the line we want to indent.
- (and (< (point) indent-point)
- (current-column)))
- ;; If no previous statement,
- ;; indent it relative to line brace is on.
- ;; For open brace in column zero, don't let statement
- ;; start there too. If icon-indent-level is zero,
- ;; use icon-brace-offset + icon-continued-statement-offset
- ;; instead.
- ;; For open-braces not the first thing in a line,
- ;; add in icon-brace-imaginary-offset.
- (+ (if (and (bolp) (zerop icon-indent-level))
- (+ icon-brace-offset
- icon-continued-statement-offset)
- icon-indent-level)
- ;; Move back over whitespace before the openbrace.
- ;; If openbrace is not first nonwhite thing on the line,
- ;; add the icon-brace-imaginary-offset.
- (progn (skip-chars-backward " \t")
- (if (bolp) 0 icon-brace-imaginary-offset))
- ;; Get initial indentation of the line we are on.
- (current-indentation))))))))))
-
-;; List of words to check for as the last thing on a line.
-;; If cdr is t, next line is a continuation of the same statement,
-;; if cdr is nil, next line starts a new (possibly indented) statement.
-
-(defconst icon-resword-alist
- '(("by" . t) ("case" . t) ("create") ("do") ("dynamic" . t) ("else")
- ("every" . t) ("if" . t) ("global" . t) ("initial" . t)
- ("link" . t) ("local" . t) ("of") ("record" . t) ("repeat" . t)
- ("static" . t) ("then") ("to" . t) ("until" . t) ("while" . t)))
-
-(defun icon-is-continuation-line ()
- (let* ((ch (preceding-char))
- (ch-syntax (char-syntax ch)))
- (if (eq ch-syntax ?w)
- (assoc (buffer-substring
- (progn (forward-word -1) (point))
- (progn (forward-word 1) (point)))
- icon-resword-alist)
- (not (memq ch '(0 ?\; ?\} ?\{ ?\) ?\] ?\" ?\' ?\n))))))
-
-(defun icon-backward-to-noncomment (lim)
- (let (opoint stop)
- (while (not stop)
- (skip-chars-backward " \t\n\f" lim)
- (setq opoint (point))
- (beginning-of-line)
- (if (and (nth 5 (parse-partial-sexp (point) opoint))
- (< lim (point)))
- (search-backward "#")
- (setq stop t)))))
-
-(defun icon-backward-to-start-of-continued-exp (lim)
- (if (memq (preceding-char) '(?\) ?\]))
- (forward-sexp -1))
- (beginning-of-line)
- (skip-chars-forward " \t")
- (cond
- ((<= (point) lim) (goto-char (1+ lim)))
- ((not (icon-is-continued-line)) 0)
- ((and (eq (char-syntax (following-char)) ?w)
- (cdr
- (assoc (buffer-substring (point)
- (save-excursion (forward-word 1) (point)))
- icon-resword-alist))) 0)
- (t (end-of-line 0) (icon-backward-to-start-of-continued-exp lim))))
-
-(defun icon-is-continued-line ()
- (save-excursion
- (end-of-line 0)
- (icon-is-continuation-line)))
-
-(defun icon-backward-to-start-of-if (&optional limit)
- "Move to the start of the last \"unbalanced\" if."
- (or limit (setq limit (save-excursion (beginning-of-icon-defun) (point))))
- (let ((if-level 1)
- (case-fold-search nil))
- (while (not (zerop if-level))
- (backward-sexp 1)
- (cond ((looking-at "else\\b")
- (setq if-level (1+ if-level)))
- ((looking-at "if\\b")
- (setq if-level (1- if-level)))
- ((< (point) limit)
- (setq if-level 0)
- (goto-char limit))))))
-
-(defun mark-icon-function ()
- "Put mark at end of Icon function, point at beginning."
- (interactive)
- (push-mark (point))
- (end-of-icon-defun)
- (push-mark (point))
- (beginning-of-line 0)
- (beginning-of-icon-defun))
-
-(defun beginning-of-icon-defun ()
- "Go to the start of the enclosing procedure; return t if at top level."
- (interactive)
- (if (re-search-backward "^procedure\\s \\|^end[ \t\n]" (point-min) 'move)
- (looking-at "e")
- t))
-
-(defun end-of-icon-defun ()
- (interactive)
- (if (not (bobp)) (forward-char -1))
- (re-search-forward "\\(\\s \\|^\\)end\\(\\s \\|$\\)" (point-max) 'move)
- (forward-word -1)
- (forward-line 1))
-
-(defun indent-icon-exp ()
- "Indent each line of the Icon grouping following point."
- (interactive)
- (let ((indent-stack (list nil))
- (contain-stack (list (point)))
- (case-fold-search nil)
- restart outer-loop-done inner-loop-done state ostate
- this-indent last-sexp
- at-else at-brace at-do
- (opoint (point))
- (next-depth 0))
- (save-excursion
- (forward-sexp 1))
- (save-excursion
- (setq outer-loop-done nil)
- (while (and (not (eobp)) (not outer-loop-done))
- (setq last-depth next-depth)
- ;; Compute how depth changes over this line
- ;; plus enough other lines to get to one that
- ;; does not end inside a comment or string.
- ;; Meanwhile, do appropriate indentation on comment lines.
- (setq innerloop-done nil)
- (while (and (not innerloop-done)
- (not (and (eobp) (setq outer-loop-done t))))
- (setq ostate state)
- (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
- nil nil state))
- (setq next-depth (car state))
- (if (and (car (cdr (cdr state)))
- (>= (car (cdr (cdr state))) 0))
- (setq last-sexp (car (cdr (cdr state)))))
- (if (or (nth 4 ostate))
- (icon-indent-line))
- (if (or (nth 3 state))
- (forward-line 1)
- (setq innerloop-done t)))
- (if (<= next-depth 0)
- (setq outer-loop-done t))
- (if outer-loop-done
- nil
- (if (/= last-depth next-depth)
- (setq last-sexp nil))
- (while (> last-depth next-depth)
- (setq indent-stack (cdr indent-stack)
- contain-stack (cdr contain-stack)
- last-depth (1- last-depth)))
- (while (< last-depth next-depth)
- (setq indent-stack (cons nil indent-stack)
- contain-stack (cons nil contain-stack)
- last-depth (1+ last-depth)))
- (if (null (car contain-stack))
- (setcar contain-stack (or (car (cdr state))
- (save-excursion (forward-sexp -1)
- (point)))))
- (forward-line 1)
- (skip-chars-forward " \t")
- (if (eolp)
- nil
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- ;; Line is on an existing nesting level.
- ;; Lines inside parens are handled specially.
- (if (/= (char-after (car contain-stack)) ?{)
- (setq this-indent (car indent-stack))
- ;; Line is at statement level.
- ;; Is it a new statement? Is it an else?
- ;; Find last non-comment character before this line
- (save-excursion
- (setq at-else (looking-at "else\\W"))
- (setq at-brace (= (following-char) ?{))
- (icon-backward-to-noncomment opoint)
- (if (icon-is-continuation-line)
- ;; Preceding line did not end in comma or semi;
- ;; indent this line icon-continued-statement-offset
- ;; more than previous.
- (progn
- (icon-backward-to-start-of-continued-exp (car contain-stack))
- (setq this-indent
- (+ icon-continued-statement-offset (current-column)
- (if at-brace icon-continued-brace-offset 0))))
- ;; Preceding line ended in comma or semi;
- ;; use the standard indent for this level.
- (if at-else
- (progn (icon-backward-to-start-of-if opoint)
- (setq this-indent (current-indentation)))
- (setq this-indent (car indent-stack))))))
- ;; Just started a new nesting level.
- ;; Compute the standard indent for this level.
- (let ((val (calculate-icon-indent
- (if (car indent-stack)
- (- (car indent-stack))))))
- (setcar indent-stack
- (setq this-indent val))))
- ;; Adjust line indentation according to its contents
- (if (or (= (following-char) ?})
- (looking-at "end\\b"))
- (setq this-indent (- this-indent icon-indent-level)))
- (if (= (following-char) ?{)
- (setq this-indent (+ this-indent icon-brace-offset)))
- ;; Put chosen indentation into effect.
- (or (= (current-column) this-indent)
- (progn
- (delete-region (point) (progn (beginning-of-line) (point)))
- (indent-to this-indent)))
- ;; Indent any comment following the text.
- (or (looking-at comment-start-skip)
- (if (re-search-forward comment-start-skip (save-excursion (end-of-line) (point)) t)
- (progn (indent-for-comment) (beginning-of-line))))))))))
-
-;;; icon.el ends here
diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el
deleted file mode 100644
index a6b4f76713f..00000000000
--- a/lisp/progmodes/inf-lisp.el
+++ /dev/null
@@ -1,634 +0,0 @@
-;;; inf-lisp.el --- an inferior-lisp mode
-;;; Copyright (C) 1988, 1993 Free Software Foundation, Inc.
-
-;; Author: Olin Shivers <shivers@cs.cmu.edu>
-;; Keywords: processes, lisp
-
-;;; This file is part of GNU Emacs.
-
-;;; GNU Emacs is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2, or (at your option)
-;;; any later version.
-
-;;; GNU Emacs is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-
-;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Emacs; see the file COPYING. If not, write to
-;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;; Hacked from tea.el by Olin Shivers (shivers@cs.cmu.edu). 8/88
-
-;;; This file defines a a lisp-in-a-buffer package (inferior-lisp
-;;; mode) built on top of comint mode. This version is more
-;;; featureful, robust, and uniform than the Emacs 18 version. The
-;;; key bindings are also more compatible with the bindings of Hemlock
-;;; and Zwei (the Lisp Machine emacs).
-
-;;; Since this mode is built on top of the general command-interpreter-in-
-;;; a-buffer mode (comint mode), it shares a common base functionality,
-;;; and a common set of bindings, with all modes derived from comint mode.
-;;; This makes these modes easier to use.
-
-;;; For documentation on the functionality provided by comint mode, and
-;;; the hooks available for customising it, see the file comint.el.
-;;; For further information on inferior-lisp mode, see the comments below.
-
-;;; Needs fixin:
-;;; The load-file/compile-file default mechanism could be smarter -- it
-;;; doesn't know about the relationship between filename extensions and
-;;; whether the file is source or executable. If you compile foo.lisp
-;;; with compile-file, then the next load-file should use foo.bin for
-;;; the default, not foo.lisp. This is tricky to do right, particularly
-;;; because the extension for executable files varies so much (.o, .bin,
-;;; .lbin, .mo, .vo, .ao, ...).
-;;;
-;;; It would be nice if inferior-lisp (and inferior scheme, T, ...) modes
-;;; had a verbose minor mode wherein sending or compiling defuns, etc.
-;;; would be reflected in the transcript with suitable comments, e.g.
-;;; ";;; redefining fact". Several ways to do this. Which is right?
-;;;
-;;; When sending text from a source file to a subprocess, the process-mark can
-;;; move off the window, so you can lose sight of the process interactions.
-;;; Maybe I should ensure the process mark is in the window when I send
-;;; text to the process? Switch selectable?
-
-;;; Code:
-
-(require 'comint)
-(require 'lisp-mode)
-
-
-;;;###autoload
-(defvar inferior-lisp-filter-regexp "\\`\\s *\\(:\\(\\w\\|\\s_\\)\\)?\\s *\\'"
- "*What not to save on inferior Lisp's input history.
-Input matching this regexp is not saved on the input history in Inferior Lisp
-mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword
-(as in :a, :c, etc.)")
-
-(defvar inferior-lisp-mode-map nil)
-(cond ((not inferior-lisp-mode-map)
- (setq inferior-lisp-mode-map
- (copy-keymap comint-mode-map))
- (setq inferior-lisp-mode-map
- (nconc inferior-lisp-mode-map shared-lisp-mode-map))
- (define-key inferior-lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp)
- (define-key inferior-lisp-mode-map "\C-c\C-l" 'lisp-load-file)
- (define-key inferior-lisp-mode-map "\C-c\C-k" 'lisp-compile-file)
- (define-key inferior-lisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
- (define-key inferior-lisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
- (define-key inferior-lisp-mode-map "\C-c\C-f"
- 'lisp-show-function-documentation)
- (define-key inferior-lisp-mode-map "\C-c\C-v"
- 'lisp-show-variable-documentation)))
-
-;;; These commands augment Lisp mode, so you can process Lisp code in
-;;; the source files.
-(define-key lisp-mode-map "\M-\C-x" 'lisp-eval-defun) ; Gnu convention
-(define-key lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) ; Gnu convention
-(define-key lisp-mode-map "\C-c\C-e" 'lisp-eval-defun)
-(define-key lisp-mode-map "\C-c\C-r" 'lisp-eval-region)
-(define-key lisp-mode-map "\C-c\C-c" 'lisp-compile-defun)
-(define-key lisp-mode-map "\C-c\C-z" 'switch-to-lisp)
-(define-key lisp-mode-map "\C-c\C-l" 'lisp-load-file)
-(define-key lisp-mode-map "\C-c\C-k" 'lisp-compile-file) ; "kompile" file
-(define-key lisp-mode-map "\C-c\C-a" 'lisp-show-arglist)
-(define-key lisp-mode-map "\C-c\C-d" 'lisp-describe-sym)
-(define-key lisp-mode-map "\C-c\C-f" 'lisp-show-function-documentation)
-(define-key lisp-mode-map "\C-c\C-v" 'lisp-show-variable-documentation)
-
-
-;;; This function exists for backwards compatibility.
-;;; Previous versions of this package bound commands to C-c <letter>
-;;; bindings, which is not allowed by the gnumacs standard.
-
-;;; "This function binds many inferior-lisp commands to C-c <letter> bindings,
-;;;where they are more accessible. C-c <letter> bindings are reserved for the
-;;;user, so these bindings are non-standard. If you want them, you should
-;;;have this function called by the inferior-lisp-load-hook:
-;;; (setq inferior-lisp-load-hook '(inferior-lisp-install-letter-bindings))
-;;;You can modify this function to install just the bindings you want."
-(defun inferior-lisp-install-letter-bindings ()
- (define-key lisp-mode-map "\C-ce" 'lisp-eval-defun-and-go)
- (define-key lisp-mode-map "\C-cr" 'lisp-eval-region-and-go)
- (define-key lisp-mode-map "\C-cc" 'lisp-compile-defun-and-go)
- (define-key lisp-mode-map "\C-cz" 'switch-to-lisp)
- (define-key lisp-mode-map "\C-cl" 'lisp-load-file)
- (define-key lisp-mode-map "\C-ck" 'lisp-compile-file)
- (define-key lisp-mode-map "\C-ca" 'lisp-show-arglist)
- (define-key lisp-mode-map "\C-cd" 'lisp-describe-sym)
- (define-key lisp-mode-map "\C-cf" 'lisp-show-function-documentation)
- (define-key lisp-mode-map "\C-cv" 'lisp-show-variable-documentation)
-
- (define-key inferior-lisp-mode-map "\C-cl" 'lisp-load-file)
- (define-key inferior-lisp-mode-map "\C-ck" 'lisp-compile-file)
- (define-key inferior-lisp-mode-map "\C-ca" 'lisp-show-arglist)
- (define-key inferior-lisp-mode-map "\C-cd" 'lisp-describe-sym)
- (define-key inferior-lisp-mode-map "\C-cf" 'lisp-show-function-documentation)
- (define-key inferior-lisp-mode-map "\C-cv"
- 'lisp-show-variable-documentation))
-
-
-;;;###autoload
-(defvar inferior-lisp-program "lisp"
- "*Program name for invoking an inferior Lisp with for Inferior Lisp mode.")
-
-;;;###autoload
-(defvar inferior-lisp-load-command "(load \"%s\")\n"
- "*Format-string for building a Lisp expression to load a file.
-This format string should use `%s' to substitute a file name
-and should result in a Lisp expression that will command the inferior Lisp
-to load that file. The default works acceptably on most Lisps.
-The string \"(progn (load \\\"%s\\\" :verbose nil :print t) (values))\\\n\"
-produces cosmetically superior output for this application,
-but it works only in Common Lisp.")
-
-;;;###autoload
-(defvar inferior-lisp-prompt "^[^> \n]*>+:? *"
- "Regexp to recognise prompts in the Inferior Lisp mode.
-Defaults to \"^[^> \\n]*>+:? *\", which works pretty good for Lucid, kcl,
-and franz. This variable is used to initialize `comint-prompt-regexp' in the
-Inferior Lisp buffer.
-
-More precise choices:
-Lucid Common Lisp: \"^\\(>\\|\\(->\\)+\\) *\"
-franz: \"^\\(->\\|<[0-9]*>:\\) *\"
-kcl: \"^>+ *\"
-
-This is a fine thing to set in your .emacs file.")
-
-(defvar inferior-lisp-buffer nil "*The current inferior-lisp process buffer.
-
-MULTIPLE PROCESS SUPPORT
-===========================================================================
-To run multiple Lisp processes, you start the first up
-with \\[inferior-lisp]. It will be in a buffer named `*inferior-lisp*'.
-Rename this buffer with \\[rename-buffer]. You may now start up a new
-process with another \\[inferior-lisp]. It will be in a new buffer,
-named `*inferior-lisp*'. You can switch between the different process
-buffers with \\[switch-to-buffer].
-
-Commands that send text from source buffers to Lisp processes --
-like `lisp-eval-defun' or `lisp-show-arglist' -- have to choose a process
-to send to, when you have more than one Lisp process around. This
-is determined by the global variable `inferior-lisp-buffer'. Suppose you
-have three inferior Lisps running:
- Buffer Process
- foo inferior-lisp
- bar inferior-lisp<2>
- *inferior-lisp* inferior-lisp<3>
-If you do a \\[lisp-eval-defun] command on some Lisp source code,
-what process do you send it to?
-
-- If you're in a process buffer (foo, bar, or *inferior-lisp*),
- you send it to that process.
-- If you're in some other buffer (e.g., a source file), you
- send it to the process attached to buffer `inferior-lisp-buffer'.
-This process selection is performed by function `inferior-lisp-proc'.
-
-Whenever \\[inferior-lisp] fires up a new process, it resets
-`inferior-lisp-buffer' to be the new process's buffer. If you only run
-one process, this does the right thing. If you run multiple
-processes, you can change `inferior-lisp-buffer' to another process
-buffer with \\[set-variable].")
-
-;;;###autoload
-(defvar inferior-lisp-mode-hook '()
- "*Hook for customising Inferior Lisp mode.")
-
-(defun inferior-lisp-mode ()
- "Major mode for interacting with an inferior Lisp process.
-Runs a Lisp interpreter as a subprocess of Emacs, with Lisp I/O through an
-Emacs buffer. Variable `inferior-lisp-program' controls which Lisp interpreter
-is run. Variables `inferior-lisp-prompt', `inferior-lisp-filter-regexp' and
-`inferior-lisp-load-command' can customize this mode for different Lisp
-interpreters.
-
-For information on running multiple processes in multiple buffers, see
-documentation for variable `inferior-lisp-buffer'.
-
-\\{inferior-lisp-mode-map}
-
-Customisation: Entry to this mode runs the hooks on `comint-mode-hook' and
-`inferior-lisp-mode-hook' (in that order).
-
-You can send text to the inferior Lisp process from other buffers containing
-Lisp source.
- switch-to-lisp switches the current buffer to the Lisp process buffer.
- lisp-eval-defun sends the current defun to the Lisp process.
- lisp-compile-defun compiles the current defun.
- lisp-eval-region sends the current region to the Lisp process.
- lisp-compile-region compiles the current region.
-
- Prefixing the lisp-eval/compile-defun/region commands with
- a \\[universal-argument] causes a switch to the Lisp process buffer after sending
- the text.
-
-Commands:
-Return after the end of the process' output sends the text from the
- end of process to point.
-Return before the end of the process' output copies the sexp ending at point
- to the end of the process' output, and sends it.
-Delete converts tabs to spaces as it moves back.
-Tab indents for Lisp; with argument, shifts rest
- of expression rigidly with the current line.
-C-M-q does Tab on each line starting within following expression.
-Paragraphs are separated only by blank lines. Semicolons start comments.
-If you accidentally suspend your process, use \\[comint-continue-subjob]
-to continue it."
- (interactive)
- (comint-mode)
- (setq comint-prompt-regexp inferior-lisp-prompt)
- (setq major-mode 'inferior-lisp-mode)
- (setq mode-name "Inferior Lisp")
- (setq mode-line-process '(": %s"))
- (lisp-mode-variables t)
- (use-local-map inferior-lisp-mode-map) ;c-c c-k for "kompile" file
- (setq comint-get-old-input (function lisp-get-old-input))
- (setq comint-input-filter (function lisp-input-filter))
- (setq comint-input-sentinel 'ignore)
- (run-hooks 'inferior-lisp-mode-hook))
-
-(defun lisp-get-old-input ()
- "Return a string containing the sexp ending at point."
- (save-excursion
- (let ((end (point)))
- (backward-sexp)
- (buffer-substring (point) end))))
-
-(defun lisp-input-filter (str)
- "t if STR does not match `inferior-lisp-filter-regexp'."
- (not (string-match inferior-lisp-filter-regexp str)))
-
-;;;###autoload
-(defun inferior-lisp (cmd)
- "Run an inferior Lisp process, input and output via buffer `*inferior-lisp*'.
-If there is a process already running in `*inferior-lisp*', just switch
-to that buffer.
-With argument, allows you to edit the command line (default is value
-of `inferior-lisp-program'). Runs the hooks from
-`inferior-lisp-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 lisp: " inferior-lisp-program)
- inferior-lisp-program)))
- (if (not (comint-check-proc "*inferior-lisp*"))
- (let ((cmdlist (inferior-lisp-args-to-list cmd)))
- (set-buffer (apply (function make-comint)
- "inferior-lisp" (car cmdlist) nil (cdr cmdlist)))
- (inferior-lisp-mode)))
- (setq inferior-lisp-buffer "*inferior-lisp*")
- (switch-to-buffer "*inferior-lisp*"))
-
-;;;###autoload
-(defalias 'run-lisp 'inferior-lisp)
-
-;;; Break a string up into a list of arguments.
-;;; This will break if you have an argument with whitespace, as in
-;;; string = "-ab +c -x 'you lose'".
-(defun inferior-lisp-args-to-list (string)
- (let ((where (string-match "[ \t]" string)))
- (cond ((null where) (list string))
- ((not (= where 0))
- (cons (substring string 0 where)
- (inferior-lisp-args-to-list (substring string (+ 1 where)
- (length string)))))
- (t (let ((pos (string-match "[^ \t]" string)))
- (if (null pos)
- nil
- (inferior-lisp-args-to-list (substring string pos
- (length string)))))))))
-
-(defun lisp-eval-region (start end &optional and-go)
- "Send the current region to the inferior Lisp process.
-Prefix argument means switch to the Lisp buffer afterwards."
- (interactive "r\nP")
- (comint-send-region (inferior-lisp-proc) start end)
- (comint-send-string (inferior-lisp-proc) "\n")
- (if and-go (switch-to-lisp t)))
-
-(defun lisp-eval-defun (&optional and-go)
- "Send the current defun to the inferior Lisp process.
-Prefix argument means switch to the Lisp buffer afterwards."
- (interactive "P")
- (save-excursion
- (end-of-defun)
- (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
- (let ((end (point)))
- (beginning-of-defun)
- (lisp-eval-region (point) end)))
- (if and-go (switch-to-lisp t)))
-
-(defun lisp-eval-last-sexp (&optional and-go)
- "Send the previous sexp to the inferior Lisp process.
-Prefix argument means switch to the Lisp buffer afterwards."
- (interactive "P")
- (lisp-eval-region (save-excursion (backward-sexp) (point)) (point) and-go))
-
-;;; Common Lisp COMPILE sux.
-(defun lisp-compile-region (start end &optional and-go)
- "Compile the current region in the inferior Lisp process.
-Prefix argument means switch to the Lisp buffer afterwards."
- (interactive "r\nP")
- (comint-send-string
- (inferior-lisp-proc)
- (format "(funcall (compile nil `(lambda () (progn 'compile %s))))\n"
- (buffer-substring start end)))
- (if and-go (switch-to-lisp t)))
-
-(defun lisp-compile-defun (&optional and-go)
- "Compile the current defun in the inferior Lisp process.
-Prefix argument means switch to the Lisp buffer afterwards."
- (interactive "P")
- (save-excursion
- (end-of-defun)
- (skip-chars-backward " \t\n\r\f") ; Makes allegro happy
- (let ((e (point)))
- (beginning-of-defun)
- (lisp-compile-region (point) e)))
- (if and-go (switch-to-lisp t)))
-
-(defun switch-to-lisp (eob-p)
- "Switch to the inferior Lisp process buffer.
-With argument, positions cursor at end of buffer."
- (interactive "P")
- (if (get-buffer inferior-lisp-buffer)
- (pop-to-buffer inferior-lisp-buffer)
- (error "No current inferior Lisp buffer"))
- (cond (eob-p
- (push-mark)
- (goto-char (point-max)))))
-
-
-;;; Now that lisp-compile/eval-defun/region takes an optional prefix arg,
-;;; these commands are redundant. But they are kept around for the user
-;;; to bind if he wishes, for backwards functionality, and because it's
-;;; easier to type C-c e than C-u C-c C-e.
-
-(defun lisp-eval-region-and-go (start end)
- "Send the current region to the inferior Lisp, and switch to its buffer."
- (interactive "r")
- (lisp-eval-region start end t))
-
-(defun lisp-eval-defun-and-go ()
- "Send the current defun to the inferior Lisp, and switch to its buffer."
- (interactive)
- (lisp-eval-defun t))
-
-(defun lisp-compile-region-and-go (start end)
- "Compile the current region in the inferior Lisp, and switch to its buffer."
- (interactive "r")
- (lisp-compile-region start end t))
-
-(defun lisp-compile-defun-and-go ()
- "Compile the current defun in the inferior Lisp, and switch to its buffer."
- (interactive)
- (lisp-compile-defun t))
-
-;;; A version of the form in H. Shevis' soar-mode.el package. Less robust.
-;;; (defun lisp-compile-sexp (start end)
-;;; "Compile the s-expression bounded by START and END in the inferior lisp.
-;;; If the sexp isn't a DEFUN form, it is evaluated instead."
-;;; (cond ((looking-at "(defun\\s +")
-;;; (goto-char (match-end 0))
-;;; (let ((name-start (point)))
-;;; (forward-sexp 1)
-;;; (process-send-string "inferior-lisp"
-;;; (format "(compile '%s #'(lambda "
-;;; (buffer-substring name-start
-;;; (point)))))
-;;; (let ((body-start (point)))
-;;; (goto-char start) (forward-sexp 1) ; Can't use end-of-defun.
-;;; (process-send-region "inferior-lisp"
-;;; (buffer-substring body-start (point))))
-;;; (process-send-string "inferior-lisp" ")\n"))
-;;; (t (lisp-eval-region start end)))))
-;;;
-;;; (defun lisp-compile-region (start end)
-;;; "Each s-expression in the current region is compiled (if a DEFUN)
-;;; or evaluated (if not) in the inferior lisp."
-;;; (interactive "r")
-;;; (save-excursion
-;;; (goto-char start) (end-of-defun) (beginning-of-defun) ; error check
-;;; (if (< (point) start) (error "region begins in middle of defun"))
-;;; (goto-char start)
-;;; (let ((s start))
-;;; (end-of-defun)
-;;; (while (<= (point) end) ; Zip through
-;;; (lisp-compile-sexp s (point)) ; compiling up defun-sized chunks.
-;;; (setq s (point))
-;;; (end-of-defun))
-;;; (if (< s end) (lisp-compile-sexp s end)))))
-;;;
-;;; End of HS-style code
-
-
-(defvar lisp-prev-l/c-dir/file nil
- "Record last directory and file used in loading or compiling.
-This holds a cons cell of the form `(DIRECTORY . FILE)'
-describing the last `lisp-load-file' or `lisp-compile-file' command.")
-
-(defvar lisp-source-modes '(lisp-mode)
- "*Used to determine if a buffer contains Lisp source code.
-If it's loaded into a buffer that is in one of these major modes, it's
-considered a Lisp source file by `lisp-load-file' and `lisp-compile-file'.
-Used by these commands to determine defaults.")
-
-(defun lisp-load-file (file-name)
- "Load a Lisp file into the inferior Lisp process."
- (interactive (comint-get-source "Load Lisp file: " lisp-prev-l/c-dir/file
- lisp-source-modes nil)) ; NIL because LOAD
- ; doesn't need an exact name
- (comint-check-source file-name) ; Check to see if buffer needs saved.
- (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
- (file-name-nondirectory file-name)))
- (comint-send-string (inferior-lisp-proc)
- (format inferior-lisp-load-command file-name))
- (switch-to-lisp t))
-
-
-(defun lisp-compile-file (file-name)
- "Compile a Lisp file in the inferior Lisp process."
- (interactive (comint-get-source "Compile Lisp file: " lisp-prev-l/c-dir/file
- lisp-source-modes nil)) ; NIL = don't need
- ; suffix .lisp
- (comint-check-source file-name) ; Check to see if buffer needs saved.
- (setq lisp-prev-l/c-dir/file (cons (file-name-directory file-name)
- (file-name-nondirectory file-name)))
- (comint-send-string (inferior-lisp-proc) (concat "(compile-file \""
- file-name
- "\"\)\n"))
- (switch-to-lisp t))
-
-
-
-;;; Documentation functions: function doc, var doc, arglist, and
-;;; describe symbol.
-;;; ===========================================================================
-
-;;; Command strings
-;;; ===============
-
-(defvar lisp-function-doc-command
- "(let ((fn '%s))
- (format t \"Documentation for ~a:~&~a\"
- fn (documentation fn 'function))
- (values))\n"
- "Command to query inferior Lisp for a function's documentation.")
-
-(defvar lisp-var-doc-command
- "(let ((v '%s))
- (format t \"Documentation for ~a:~&~a\"
- v (documentation v 'variable))
- (values))\n"
- "Command to query inferior Lisp for a variable's documentation.")
-
-(defvar lisp-arglist-command
- "(let ((fn '%s))
- (format t \"Arglist for ~a: ~a\" fn (arglist fn))
- (values))\n"
- "Command to query inferior Lisp for a function's arglist.")
-
-(defvar lisp-describe-sym-command
- "(describe '%s)\n"
- "Command to query inferior Lisp for a variable's documentation.")
-
-
-;;; Ancillary functions
-;;; ===================
-
-;;; Reads a string from the user.
-(defun lisp-symprompt (prompt default)
- (list (let* ((prompt (if default
- (format "%s (default %s): " prompt default)
- (concat prompt ": ")))
- (ans (read-string prompt)))
- (if (zerop (length ans)) default ans))))
-
-
-;;; Adapted from function-called-at-point in help.el.
-(defun lisp-fn-called-at-pt ()
- "Returns the name of the function called in the current call.
-The value is nil if it can't find one."
- (condition-case nil
- (save-excursion
- (save-restriction
- (narrow-to-region (max (point-min) (- (point) 1000)) (point-max))
- (backward-up-list 1)
- (forward-char 1)
- (let ((obj (read (current-buffer))))
- (and (symbolp obj) obj))))
- (error nil)))
-
-
-;;; Adapted from variable-at-point in help.el.
-(defun lisp-var-at-pt ()
- (condition-case ()
- (save-excursion
- (forward-sexp -1)
- (skip-chars-forward "'")
- (let ((obj (read (current-buffer))))
- (and (symbolp obj) obj)))
- (error nil)))
-
-
-;;; Documentation functions: fn and var doc, arglist, and symbol describe.
-;;; ======================================================================
-
-(defun lisp-show-function-documentation (fn)
- "Send a command to the inferior Lisp to give documentation for function FN.
-See variable `lisp-function-doc-command'."
- (interactive (lisp-symprompt "Function doc" (lisp-fn-called-at-pt)))
- (comint-proc-query (inferior-lisp-proc)
- (format lisp-function-doc-command fn)))
-
-(defun lisp-show-variable-documentation (var)
- "Send a command to the inferior Lisp to give documentation for function FN.
-See variable `lisp-var-doc-command'."
- (interactive (lisp-symprompt "Variable doc" (lisp-var-at-pt)))
- (comint-proc-query (inferior-lisp-proc) (format lisp-var-doc-command var)))
-
-(defun lisp-show-arglist (fn)
- "Send a query to the inferior Lisp for the arglist for function FN.
-See variable `lisp-arglist-command'."
- (interactive (lisp-symprompt "Arglist" (lisp-fn-called-at-pt)))
- (comint-proc-query (inferior-lisp-proc) (format lisp-arglist-command fn)))
-
-(defun lisp-describe-sym (sym)
- "Send a command to the inferior Lisp to describe symbol SYM.
-See variable `lisp-describe-sym-command'."
- (interactive (lisp-symprompt "Describe" (lisp-var-at-pt)))
- (comint-proc-query (inferior-lisp-proc)
- (format lisp-describe-sym-command sym)))
-
-
-;; "Returns the current inferior Lisp process.
-;; See variable `inferior-lisp-buffer'."
-(defun inferior-lisp-proc ()
- (let ((proc (get-buffer-process (if (eq major-mode 'inferior-lisp-mode)
- (current-buffer)
- inferior-lisp-buffer))))
- (or proc
- (error "No Lisp subprocess; see variable `inferior-lisp-buffer'"))))
-
-
-;;; Do the user's customisation...
-;;;===============================
-(defvar inferior-lisp-load-hook nil
- "This hook is run when the library `inf-lisp' is loaded.
-This is a good place to put keybindings.")
-
-(run-hooks 'inferior-lisp-load-hook)
-
-;;; CHANGE LOG
-;;; ===========================================================================
-;;; 7/21/92 Jim Blandy
-;;; - Changed all uses of the cmulisp name or prefix to inferior-lisp;
-;;; this is now the official inferior lisp package. Use the global
-;;; ChangeLog from now on.
-;;; 5/24/90 Olin
-;;; - Split cmulisp and cmushell modes into separate files.
-;;; Not only is this a good idea, it's apparently the way it'll be rel 19.
-;;; - Upgraded process sends to use comint-send-string instead of
-;;; process-send-string.
-;;; - Explicit references to process "cmulisp" have been replaced with
-;;; (cmulisp-proc). This allows better handling of multiple process bufs.
-;;; - Added process query and var/function/symbol documentation
-;;; commands. Based on code written by Douglas Roberts.
-;;; - Added lisp-eval-last-sexp, bound to C-x C-e.
-;;;
-;;; 9/20/90 Olin
-;;; Added a save-restriction to lisp-fn-called-at-pt. This bug and fix
-;;; reported by Lennart Staflin.
-;;;
-;;; 3/12/90 Olin
-;;; - lisp-load-file and lisp-compile-file no longer switch-to-lisp.
-;;; Tale suggested this.
-;;; - Reversed this decision 7/15/91. You need the visual feedback.
-;;;
-;;; 7/25/91 Olin
-;;; Changed all keybindings of the form C-c <letter>. These are
-;;; supposed to be reserved for the user to bind. This affected
-;;; mainly the compile/eval-defun/region[-and-go] commands.
-;;; This was painful, but necessary to adhere to the gnumacs standard.
-;;; For some backwards compatibility, see the
-;;; cmulisp-install-letter-bindings
-;;; function.
-;;;
-;;; 8/2/91 Olin
-;;; - The lisp-compile/eval-defun/region commands now take a prefix arg,
-;;; which means switch-to-lisp after sending the text to the Lisp process.
-;;; This obsoletes all the -and-go commands. The -and-go commands are
-;;; kept around for historical reasons, and because the user can bind
-;;; them to key sequences shorter than C-u C-c C-<letter>.
-;;; - If M-x cmulisp is invoked with a prefix arg, it allows you to
-;;; edit the command line.
-
-(provide 'inf-lisp)
-
-;;; inf-lisp.el ends here
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
deleted file mode 100644
index 042ca570ac1..00000000000
--- a/lisp/progmodes/make-mode.el
+++ /dev/null
@@ -1,1073 +0,0 @@
-;;; makefile.el --- makefile editing commands for Emacs
-
-;; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
-
-;; Author: Thomas Neumann <tom@smart.bo.open.de>
-;; Eric S. Raymond <esr@snark.thyrsus.com>
-;; Adapted-By: ESR
-;; Keywords: unix, tools
-
-;; RMS:
-;; This needs work. The electric characters are too obnoxious.
-;; It should not define C-c LETTER.
-;; It should support knowing the list of existing macros and targets
-;; via M-TAB completion, not by preempting insertion of references.
-;; Also, the doc strings need fixing: the first line doesn't stand alone,
-;; and other usage is not high quality. Symbol names don't have `...'.
-
-;; So, for the meantime, this is not the default mode for makefiles.
-
-;; $Id: makefile.el,v 1.16 1994/02/28 18:05:55 tom Exp $
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 1, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; A major mode for editing makefiles. The mode knows about Makefile
-;; syntax and defines M-n and M-p to move to next and previous productions.
-;;
-;; The keys $, =, : and . are electric; they try to help you fill in a
-;; macro reference, macro definition, ordinary target name, or special
-;; target name, respectively. Such names are completed using a list of
-;; targets and macro names parsed out of the makefile. This list is
-;; automatically updated, if necessary, whenever you invoke one of
-;; these commands. You can force it to be updated with C-c C-p.
-;;
-;; The command C-c f adds certain filenames in the current directory
-;; as targets. You can filter out filenames by setting the variable
-;; makefile-ignored-files-in-pickup-regex.
-;;
-;; The command C-c C-u grinds for a bit, then pops up a report buffer
-;; showing which target names are up-to-date with respect to their
-;; prerequisites, which targets are out-of-date, and which have no
-;; prerequisites.
-;;
-;; The command C-c b pops up a browser window listing all target and
-;; macro names. You can mark or unmark items wit C-c SPC, and insert
-;; all marked items back in the Makefile with C-c TAB.
-;;
-;; The command C-c TAB in the makefile buffer inserts a GNU make builtin.
-;; You will be prompted for the builtin's args.
-;;
-;; There are numerous other customization variables.
-
-;;; Code:
-
-(provide 'makefile)
-
-;;; ------------------------------------------------------------
-;;; Configurable stuff
-;;; ------------------------------------------------------------
-
-(defconst makefile-mode-name "Makefile"
- "The \"pretty name\" of makefile-mode, as it appears in the modeline.")
-
-(defvar makefile-browser-buffer-name "*Macros and Targets*"
- "Name of the macro- and target browser buffer.")
-
-(defvar makefile-target-colon ":"
- "The string that gets appended to all target names
-inserted by makefile-insert-target.
-\":\" or \"::\" are quite common values.")
-
-(defvar makefile-macro-assign " = "
- "The string that gets appended to all macro names
-inserted by makefile-insert-macro.
-The normal value should be \" = \", since this is what
-standard make expects. However, newer makes such as dmake
-allow a larger variety of different macro assignments, so you
-might prefer to use \" += \" or \" := \" .")
-
-(defvar makefile-use-curly-braces-for-macros-p nil
- "Controls the style of generated macro references.
-Set this variable to a non-nil value if you prefer curly braces
-in macro-references, so it looks like ${this}. A value of nil
-will cause makefile-mode to use parentheses, making macro references
-look like $(this) .")
-
-(defvar makefile-tab-after-target-colon t
- "If you want a TAB (instead of a space) to be appended after the
-target colon, then set this to a non-nil value.")
-
-(defvar makefile-browser-leftmost-column 10
- "Number of blanks to the left of the browser selection mark.")
-
-(defvar makefile-browser-cursor-column 10
- "Column in which the cursor is positioned when it moves
-up or down in the browser.")
-
-(defvar makefile-browser-selected-mark "+ "
- "String used to mark selected entries in the browser.")
-
-(defvar makefile-browser-unselected-mark " "
- "String used to mark unselected entries in the browser.")
-
-(defvar makefile-browser-auto-advance-after-selection-p t
- "If non-nil, the cursor will automagically advance to the next line after
-an item has been selected in the browser.")
-
-(defvar makefile-pickup-everything-picks-up-filenames-p nil
- "If non-nil, makefile-pickup-everything also picks up filenames as targets
-(i.e. it calls makefile-find-filenames-as-targets), otherwise filenames are
-omitted.")
-
-(defvar makefile-cleanup-continuations-p t
- "If non-nil, makefile-mode will assure that no line in the file ends with a
-backslash (the continuation character) followed by any whitespace. This is
-done by silently removing the trailing whitespace, leaving the backslash itself
-intact. IMPORTANT: Please note that enabling this option causes makefile-mode
-to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \'it seems necessary\'.")
-
-(defvar makefile-browser-hook '()
- "A function or list of functions to be called just before the
-browser is entered. This is executed in the makefile buffer.")
-
-;;
-;; Special targets for DMake, Sun's make ...
-;;
-(defvar makefile-special-targets-list
- '(("DEFAULT") ("DONE") ("ERROR") ("EXPORT")
- ("FAILED") ("GROUPEPILOG") ("GROUPPROLOG") ("IGNORE")
- ("IMPORT") ("INCLUDE") ("INCLUDEDIRS") ("INIT")
- ("KEEP_STATE") ("MAKEFILES") ("MAKE_VERSION") ("NO_PARALLEL")
- ("PARALLEL") ("PHONY") ("PRECIOUS") ("REMOVE")
- ("SCCS_GET") ("SILENT") ("SOURCE") ("SUFFIXES")
- ("WAIT") ("c.o") ("C.o") ("m.o")
- ("el.elc") ("y.c") ("s.o"))
- "List of special targets. You will be offered to complete
-on one of those in the minibuffer whenever you enter a \".\"
-at the beginning of a line in makefile-mode.")
-
-(defvar makefile-runtime-macros-list
- '(("@") ("&") (">") ("<") ("*") ("^") ("?") ("%"))
- "List of macros that are resolved by make at runtime.
-If you insert a macro reference using makefile-insert-macro-ref, the name
-of the macro is checked against this list. If it can be found its name will
-not be enclosed in { } or ( ).")
-
-(defconst makefile-dependency-regex
- "^[^ \t#:]+\\([ \t]+[^ \t#:]+\\)*[ \t]*:\\([ \t]*$\\|\\([^=\n].*$\\)\\)"
- "Regex used to find dependency lines in a makefile.")
-
-(defconst makefile-macroassign-regex
- "^[^ \t][^:#=]*[\\*:\\+]?:?=.*$"
- "Regex used to find macro assignment lines in a makefile.")
-
-(defconst makefile-ignored-files-in-pickup-regex
- "\\(^\\..*\\)\\|\\(.*~$\\)\\|\\(.*,v$\\)\\|\\(\\.[chy]\\)"
- "Regex for filenames that will NOT be included in the target list.")
-
-;;; ------------------------------------------------------------
-;;; The following configurable variables are used in the
-;;; up-to-date overview .
-;;; The standard configuration assumes that your `make' program
-;;; can be run in question/query mode using the `-q' option, this
-;;; means that the command
-;;;
-;;; make -q foo
-;;;
-;;; should return an exit status of zero if the target `foo' is
-;;; up to date and a nonzero exit status otherwise.
-;;; Many makes can do this although the docs/manpages do not mention
-;;; it. Try it with your favourite one. GNU make, System V make, and
-;;; Dennis Vadura's DMake have no problems.
-;;; Set the variable `makefile-brave-make' to the name of the
-;;; make utility that does this on your system.
-;;; To understand what this is all about see the function definition
-;;; of `makefile-query-by-make-minus-q' .
-;;; ------------------------------------------------------------
-
-(defvar makefile-brave-make "make"
- "A make that can handle the \'-q\' option.")
-
-(defvar makefile-query-one-target-method 'makefile-query-by-make-minus-q
- "A function symbol [one that can be used as the first argument to
-funcall] that provides a function that must conform to the following
-interface:
-
-* As its first argument, it must accept the name of the target to
- be checked, as a string.
-
-* As its second argument, it may accept the name of a makefile
- as a string. Depending on what you're going to do you may
- not need this.
-
-* It must return the integer value 0 (zero) if the given target
- should be considered up-to-date in the context of the given
- makefile, any nonzero integer value otherwise.")
-
-(defvar makefile-up-to-date-buffer-name "*Makefile Up-to-date overview*"
- "Name of the Up-to-date overview buffer.")
-
-;;; --- end of up-to-date-overview configuration ------------------
-
-(defvar makefile-mode-map nil
- "The keymap that is used in makefile-mode.")
-(if makefile-mode-map
- ()
- (setq makefile-mode-map (make-sparse-keymap))
- ;; set up the keymap
- (define-key makefile-mode-map "$" 'makefile-insert-macro-ref)
- (define-key makefile-mode-map "\C-c:" 'makefile-insert-target-ref)
- (define-key makefile-mode-map ":" 'makefile-electric-colon)
- (define-key makefile-mode-map "=" 'makefile-electric-equal)
- (define-key makefile-mode-map "." 'makefile-electric-dot)
- (define-key makefile-mode-map "\C-c\C-f" 'makefile-pickup-filenames-as-targets)
- (define-key makefile-mode-map "\C-c\C-b" 'makefile-switch-to-browser)
- (define-key makefile-mode-map "\C-c\C-p" 'makefile-pickup-everything)
- (define-key makefile-mode-map "\C-c\C-u" 'makefile-create-up-to-date-overview)
- (define-key makefile-mode-map "\C-c\C-i" 'makefile-insert-gmake-function)
- (define-key makefile-mode-map "\M-p" 'makefile-previous-dependency)
- (define-key makefile-mode-map "\M-n" 'makefile-next-dependency))
-
-(defvar makefile-browser-map nil
- "The keymap that is used in the macro- and target browser.")
-(if makefile-browser-map
- ()
- (setq makefile-browser-map (make-sparse-keymap))
- (define-key makefile-browser-map "n" 'makefile-browser-next-line)
- (define-key makefile-browser-map "\C-n" 'makefile-browser-next-line)
- (define-key makefile-browser-map "p" 'makefile-browser-previous-line)
- (define-key makefile-browser-map "\C-p" 'makefile-browser-previous-line)
- (define-key makefile-browser-map " " 'makefile-browser-toggle)
- (define-key makefile-browser-map "i" 'makefile-browser-insert-selection)
- (define-key makefile-browser-map "I" 'makefile-browser-insert-selection-and-quit)
- (define-key makefile-browser-map "\C-c\C-m" 'makefile-browser-insert-continuation)
- (define-key makefile-browser-map "q" 'makefile-browser-quit)
- ;; disable horizontal movement
- (define-key makefile-browser-map "\C-b" 'undefined)
- (define-key makefile-browser-map "\C-f" 'undefined))
-
-
-(defvar makefile-mode-syntax-table nil
- "The syntax-table used in makefile mode.")
-(if makefile-mode-syntax-table
- ()
- (setq makefile-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\( "() " makefile-mode-syntax-table)
- (modify-syntax-entry ?\) ")( " makefile-mode-syntax-table)
- (modify-syntax-entry ?\[ "(] " makefile-mode-syntax-table)
- (modify-syntax-entry ?\] "([ " makefile-mode-syntax-table)
- (modify-syntax-entry ?\{ "(} " makefile-mode-syntax-table)
- (modify-syntax-entry ?\} "){ " makefile-mode-syntax-table)
- (modify-syntax-entry ?# "< " makefile-mode-syntax-table)
- (modify-syntax-entry ?\n "> " makefile-mode-syntax-table))
-
-
-;;; ------------------------------------------------------------
-;;; Internal variables.
-;;; You don't need to configure below this line.
-;;; ------------------------------------------------------------
-
-(defvar makefile-target-table nil
- "Table of all targets that have been inserted in
-this Makefile buffer using makefile-insert-target or picked up
-using makefile-pickup-targets.")
-
-(defvar makefile-macro-table nil
- "Table of all macros that have been iserted in
-this Makefile buffer using makefile-insert-macro or picked up
-using makefile-pickup-macros.")
-
-(defvar makefile-browser-client
- "A buffer in makefile-mode that is currently using the browser.")
-
-(defvar makefile-browser-selection-vector nil)
-(defvar makefile-has-prereqs nil)
-(defvar makefile-need-target-pickup t)
-(defvar makefile-need-macro-pickup t)
-
-(defvar makefile-mode-hook '())
-
-(defconst makefile-gnumake-functions-alist
- '(
- ;; Text functions
- ("subst" "From" "To" "In")
- ("patsubst" "Pattern" "Replacement" "In")
- ("strip" "Text")
- ("findstring" "Find what" "In")
- ("filter" "Pattern" "Text")
- ("filter-out" "Pattern" "Text")
- ("sort" "List")
- ;; Filename functions
- ("dir" "Names")
- ("notdir" "Names")
- ("suffix" "Names")
- ("basename" "Names")
- ("addsuffix" "Suffix" "Names")
- ("join" "List 1" "List 2")
- ("word" "Index" "Text")
- ("words" "Text")
- ("firstword" "Text")
- ("wildcard" "Pattern")
- ;; Misc functions
- ("foreach" "Variable" "List" "Text")
- ("origin" "Variable")
- ("shell" "Command"))
- "A list of GNU make function names associated with
-the prompts for each function.
-This is used in the function makefile-insert-gmake-function .")
-
-
-;;; ------------------------------------------------------------
-;;; The mode function itself.
-;;; ------------------------------------------------------------
-
-;;;###autoload
-(defun makefile-mode ()
- "Major mode for editing Makefiles.
-Calling this function invokes the function(s) \"makefile-mode-hook\" before
-doing anything else.
-
-\\{makefile-mode-map}
-
-In the browser, use the following keys:
-
-\\{makefile-browser-map}
-
-makefile-mode can be configured by modifying the following
-variables:
-
-makefile-mode-name:
- The \"pretty name\" of makefile-mode, as it
- appears in the modeline.
-
-makefile-browser-buffer-name:
- Name of the macro- and target browser buffer.
-
-makefile-target-colon:
- The string that gets appended to all target names
- inserted by makefile-insert-target.
- \":\" or \"::\" are quite common values.
-
-makefile-macro-assign:
- The string that gets appended to all macro names
- inserted by makefile-insert-macro.
- The normal value should be \" = \", since this is what
- standard make expects. However, newer makes such as dmake
- allow a larger variety of different macro assignments, so you
- might prefer to use \" += \" or \" := \" .
-
-makefile-tab-after-target-colon:
- If you want a TAB (instead of a space) to be appended after the
- target colon, then set this to a non-nil value.
-
-makefile-browser-leftmost-column:
- Number of blanks to the left of the browser selection mark.
-
-makefile-browser-cursor-column:
- Column in which the cursor is positioned when it moves
- up or down in the browser.
-
-makefile-browser-selected-mark:
- String used to mark selected entries in the browser.
-
-makefile-browser-unselected-mark:
- String used to mark unselected entries in the browser.
-
-makefile-browser-auto-advance-after-selection-p:
- If this variable is set to a non-nil value the cursor
- will automagically advance to the next line after an item
- has been selected in the browser.
-
-makefile-pickup-everything-picks-up-filenames-p:
- If this variable is set to a non-nil value then
- makefile-pickup-everything also picks up filenames as targets
- (i.e. it calls makefile-find-filenames-as-targets), otherwise
- filenames are omitted.
-
-makefile-cleanup-continuations-p:
- If this variable is set to a non-nil value then makefile-mode
- will assure that no line in the file ends with a backslash
- (the continuation character) followed by any whitespace.
- This is done by silently removing the trailing whitespace, leaving
- the backslash itself intact.
- IMPORTANT: Please note that enabling this option causes makefile-mode
- to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \'it seems necessary\'.
-
-makefile-browser-hook:
- A function or list of functions to be called just before the
- browser is entered. This is executed in the makefile buffer.
-
-makefile-special-targets-list:
- List of special targets. You will be offered to complete
- on one of those in the minibuffer whenever you enter a \".\"
- at the beginning of a line in makefile-mode."
- (interactive)
- (kill-all-local-variables)
- (make-local-file 'local-write-file-hooks)
- (setq local-write-file-hooks
- '(makefile-cleanup-continuations 'makefile-warn-suspicious-lines))
- (make-local-variable 'makefile-target-table)
- (make-local-variable 'makefile-macro-table)
- (make-local-variable 'makefile-has-prereqs)
- (make-local-variable 'makefile-need-target-pickup)
- (make-local-variable 'makefile-need-macro-pickup)
- (make-local-variable 'comment-start)
- (make-local-variable 'comment-end)
- (make-local-variable 'comment-start-skip)
- (setq comment-start "#")
- (setq comment-end "")
- (setq comment-start-skip "#[ \t]*")
- ;; become the current major mode
- (setq major-mode 'makefile-mode)
- (setq mode-name makefile-mode-name)
- ;; activate keymap
- (use-local-map makefile-mode-map)
- (set-syntax-table makefile-mode-syntax-table)
- (setq indent-tabs-mode t) ;real TABs are important in makefiles
- (run-hooks 'makefile-mode-hook))
-
-(defun makefile-next-dependency ()
- "Move (point) to the beginning of the next dependency line below (point)."
- (interactive)
- (let ((here (point)))
- (end-of-line)
- (if (re-search-forward makefile-dependency-regex (point-max) t)
- (progn (beginning-of-line) t) ; indicate success
- (goto-char here) nil)))
-
-(defun makefile-previous-dependency ()
- "Move (point) to the beginning of the next dependency line above (point)."
- (interactive)
- (let ((here (point)))
- (beginning-of-line)
- (if (re-search-backward makefile-dependency-regex (point-min) t)
- (progn (beginning-of-line) t) ; indicate success
- (goto-char here) nil)))
-
-
-;;; Stuff below here depends on the pickup state
-
-(defun makefile-electric-dot ()
- "At (bol), offer completion on makefile-special-targets-list.
-Anywhere else just insert a dot."
- (interactive)
- (if (bolp)
- (makefile-insert-special-target)
- (insert ".")))
-
-(defun makefile-insert-special-target ()
- "Complete on makefile-special-targets-list, insert result at (point)."
- (interactive)
- (makefile-pickup-targets)
- (let
- ((special-target
- (completing-read "Special target: "
- makefile-special-targets-list nil nil nil)))
- (if (zerop (length special-target))
- ()
- (insert (format ".%s:" special-target))
- (makefile-forward-after-target-colon))))
-
-(defun makefile-electric-equal ()
- "At (bol) do makefile-insert-macro. Anywhere else just self-insert."
- (interactive)
- (makefile-pickup-macros)
- (if (bolp)
- (call-interactively 'makefile-insert-macro)
- (insert "=")))
-
-(defun makefile-insert-macro (macro-name)
- "Prepare definition of a new macro."
- (interactive "sMacro Name: ")
- (makefile-pickup-macros)
- (if (not (zerop (length macro-name)))
- (progn
- (beginning-of-line)
- (insert (format "%s%s" macro-name makefile-macro-assign))
- (setq makefile-need-macro-pickup t)
- (makefile-remember-macro macro-name))))
-
-(defun makefile-insert-macro-ref (macro-name)
- "Complete on a list of known macros, then insert complete ref at (point)."
- (interactive
- (list
- (progn
- (makefile-pickup-macros)
- (completing-read "Refer to macro: " makefile-macro-table nil nil nil))))
- (if (not (zerop (length macro-name)))
- (if (assoc macro-name makefile-runtime-macros-list)
- (insert (format "$%s" macro-name))
- (insert (makefile-format-macro-ref macro-name)))))
-
-(defun makefile-insert-target (target-name)
- "Prepare definition of a new target (dependency line)."
- (interactive "sTarget: ")
- (if (not (zerop (length target-name)))
- (progn
- (beginning-of-line)
- (insert (format "%s%s" target-name makefile-target-colon))
- (makefile-forward-after-target-colon)
- (end-of-line)
- (setq makefile-need-target-pickup t)
- (makefile-remember-target target-name))))
-
-(defun makefile-insert-target-ref (target-name)
- "Complete on a list of known targets, then insert target-ref at (point) ."
- (interactive
- (list
- (progn
- (makefile-pickup-targets)
- (completing-read "Refer to target: " makefile-target-table nil nil nil))))
- (if (not (zerop (length target-name)))
- (progn
- (insert (format "%s " target-name)))))
-
-(defun makefile-electric-colon ()
- "At (bol) defines a new target, anywhere else just self-insert ."
- (interactive)
- (if (bolp)
- (call-interactively 'makefile-insert-target)
- (insert ":")))
-
-;;; ------------------------------------------------------------
-;;; Extracting targets and macros from an existing makefile
-;;; ------------------------------------------------------------
-
-(defun makefile-pickup-targets ()
- "Scan a buffer that contains a makefile for target definitions (dependencies)
-and add them to the list of known targets."
- (interactive)
- (if (not makefile-need-target-pickup)
- nil
- (setq makefile-need-target-pickup nil)
- (setq makefile-target-table nil)
- (setq makefile-has-prereqs nil)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward makefile-dependency-regex (point-max) t)
- (makefile-add-this-line-targets)))
- (message "Read targets OK.")))
-
-(defun makefile-add-this-line-targets ()
- (save-excursion
- (beginning-of-line)
- (let ((done-with-line nil)
- (line-number (1+ (count-lines (point-min) (point)))))
- (while (not done-with-line)
- (skip-chars-forward " \t")
- (if (not (setq done-with-line (or (eolp)
- (char-equal (char-after (point)) ?:))))
- (progn
- (let* ((start-of-target-name (point))
- (target-name
- (progn
- (skip-chars-forward "^ \t:#")
- (buffer-substring start-of-target-name (point))))
- (has-prereqs
- (not (looking-at ":[ \t]*$"))))
- (if (makefile-remember-target target-name has-prereqs)
- (message "Picked up target \"%s\" from line %d"
- target-name line-number)))))))))
-
-
-(defun makefile-pickup-macros ()
- "Scan a buffer that contains a makefile for macro definitions
-and add them to the list of known macros."
- (interactive)
- (if (not makefile-need-macro-pickup)
- nil
- (setq makefile-need-macro-pickup nil)
- (setq makefile-macro-table nil)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward makefile-macroassign-regex (point-max) t)
- (makefile-add-this-line-macro)
- (forward-line 1)))
- (message "Read macros OK.")))
-
-(defun makefile-add-this-line-macro ()
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (if (not (eolp))
- (let* ((start-of-macro-name (point))
- (line-number (1+ (count-lines (point-min) (point))))
- (macro-name (progn
- (skip-chars-forward "^ \t:#=*")
- (buffer-substring start-of-macro-name (point)))))
- (if (makefile-remember-macro macro-name)
- (message "Picked up macro \"%s\" from line %d"
- macro-name line-number))))))
-
-(defun makefile-pickup-everything ()
- "Calls makefile-pickup-targets and makefile-pickup-macros.
-See their documentation for what they do."
- (interactive)
- (makefile-pickup-macros)
- (makefile-pickup-targets)
- (if makefile-pickup-everything-picks-up-filenames-p
- (makefile-pickup-filenames-as-targets)))
-
-
-(defun makefile-pickup-filenames-as-targets ()
- "Scan the current directory for filenames, check each filename
-against makefile-ignored-files-in-pickup-regex and add all qualifying
-names to the list of known targets."
- (interactive)
- (let* ((dir (file-name-directory (buffer-file-name)))
- (raw-filename-list (if dir
- (file-name-all-completions "" dir)
- (file-name-all-completions "" ""))))
- (mapcar '(lambda (name)
- (if (and (not (file-directory-p name))
- (not (string-match makefile-ignored-files-in-pickup-regex
- name)))
- (if (makefile-remember-target name)
- (message "Picked up file \"%s\" as target" name))))
- raw-filename-list)))
-
-;;; ------------------------------------------------------------
-;;; The browser window
-;;; ------------------------------------------------------------
-
-(defun makefile-browser-format-target-line (target selected)
- (format
- (concat (make-string makefile-browser-leftmost-column ?\ )
- (if selected
- makefile-browser-selected-mark
- makefile-browser-unselected-mark)
- "%s%s")
- target makefile-target-colon))
-
-(defun makefile-browser-format-macro-line (macro selected)
- (format
- (concat (make-string makefile-browser-leftmost-column ?\ )
- (if selected
- makefile-browser-selected-mark
- makefile-browser-unselected-mark)
- (makefile-format-macro-ref macro))))
-
-(defun makefile-browser-fill (targets macros)
- (let ((inhibit-read-only t))
- (goto-char (point-min))
- (erase-buffer)
- (mapconcat
- (function
- (lambda (item) (insert (makefile-browser-format-target-line (car item) nil) "\n")))
- targets
- "")
- (mapconcat
- (function
- (lambda (item) (insert (makefile-browser-format-macro-line (car item) nil) "\n")))
- macros
- "")
- (sort-lines nil (point-min) (point-max))
- (goto-char (1- (point-max)))
- (delete-char 1) ; remove unnecessary newline at eob
- (goto-char (point-min))
- (forward-char makefile-browser-cursor-column)))
-
-;;;
-;;; Moving up and down in the browser
-;;;
-
-(defun makefile-browser-next-line ()
- "Move the browser selection cursor to the next line."
- (interactive)
- (if (not (makefile-last-line-p))
- (progn
- (forward-line 1)
- (forward-char makefile-browser-cursor-column))))
-
-(defun makefile-browser-previous-line ()
- "Move the browser selection cursor to the previous line."
- (interactive)
- (if (not (makefile-first-line-p))
- (progn
- (forward-line -1)
- (forward-char makefile-browser-cursor-column))))
-
-;;;
-;;; Quitting the browser (returns to client buffer)
-;;;
-
-(defun makefile-browser-quit ()
- "Leave the makefile-browser-buffer and return to the buffer
-from that it has been entered."
- (interactive)
- (let ((my-client makefile-browser-client))
- (setq makefile-browser-client nil) ; we quitted, so NO client!
- (set-buffer-modified-p nil)
- (kill-buffer (current-buffer))
- (pop-to-buffer my-client)))
-
-;;;
-;;; Toggle state of a browser item
-;;;
-
-(defun makefile-browser-toggle ()
- "Toggle the selection state of the browser item at the cursor position."
- (interactive)
- (let ((this-line (count-lines (point-min) (point))))
- (setq this-line (max 1 this-line))
- (makefile-browser-toggle-state-for-line this-line)
- (goto-line this-line)
- (let ((inhibit-read-only t))
- (beginning-of-line)
- (if (makefile-browser-on-macro-line-p)
- (let ((macro-name (makefile-browser-this-line-macro-name)))
- (kill-line)
- (insert
- (makefile-browser-format-macro-line
- macro-name
- (makefile-browser-get-state-for-line this-line))))
- (let ((target-name (makefile-browser-this-line-target-name)))
- (kill-line)
- (insert
- (makefile-browser-format-target-line
- target-name
- (makefile-browser-get-state-for-line this-line))))))
- (beginning-of-line)
- (forward-char makefile-browser-cursor-column)
- (if makefile-browser-auto-advance-after-selection-p
- (makefile-browser-next-line))))
-
-;;;
-;;; Making insertions into the client buffer
-;;;
-
-(defun makefile-browser-insert-continuation ()
- "Insert a makefile continuation.
-In the browser\'s client buffer, go to (end-of-line), insert a \'\\\'
-character, insert a new blank line, go to that line and indent by one TAB.
-This is most useful in the process of creating continued lines when copying
-large dependencies from the browser to the client buffer.
-(point) advances accordingly in the client buffer."
- (interactive)
- (save-excursion
- (set-buffer makefile-browser-client)
- (end-of-line)
- (insert "\\\n\t")))
-
-(defun makefile-browser-insert-selection ()
- "Insert all browser-selected targets and/or macros in the browser\'s
-client buffer.
-Insertion takes place at (point)."
- (interactive)
- (save-excursion
- (goto-line 1)
- (let ((current-line 1))
- (while (not (eobp))
- (if (makefile-browser-get-state-for-line current-line)
- (makefile-browser-send-this-line-item))
- (forward-line 1)
- (setq current-line (1+ current-line))))))
-
-(defun makefile-browser-insert-selection-and-quit ()
- (interactive)
- (makefile-browser-insert-selection)
- (makefile-browser-quit))
-
-(defun makefile-browser-send-this-line-item ()
- (if (makefile-browser-on-macro-line-p)
- (save-excursion
- (let ((macro-name (makefile-browser-this-line-macro-name)))
- (set-buffer makefile-browser-client)
- (insert (makefile-format-macro-ref macro-name) " ")))
- (save-excursion
- (let ((target-name (makefile-browser-this-line-target-name)))
- (set-buffer makefile-browser-client)
- (insert target-name " ")))))
-
-(defun makefile-browser-start-interaction ()
- (use-local-map makefile-browser-map)
- (setq buffer-read-only t))
-
-(defun makefile-browse (targets macros)
- (interactive)
- (if (zerop (+ (length targets) (length macros)))
- (progn
- (beep)
- (message "No macros or targets to browse! Consider running 'makefile-pickup-everything\'"))
- (let ((browser-buffer (get-buffer-create makefile-browser-buffer-name)))
- (pop-to-buffer browser-buffer)
- (make-variable-buffer-local 'makefile-browser-selection-vector)
- (makefile-browser-fill targets macros)
- (shrink-window-if-larger-than-buffer)
- (setq makefile-browser-selection-vector
- (make-vector (+ (length targets) (length macros)) nil))
- (makefile-browser-start-interaction))))
-
-(defun makefile-switch-to-browser ()
- (interactive)
- (run-hooks 'makefile-browser-hook)
- (setq makefile-browser-client (current-buffer))
- (makefile-pickup-targets)
- (makefile-pickup-macros)
- (makefile-browse makefile-target-table makefile-macro-table))
-
-
-;;; ------------------------------------------------------------
-;;; Up-to-date overview buffer
-;;; ------------------------------------------------------------
-
-(defun makefile-create-up-to-date-overview ()
- "Create a buffer containing an overview of the state of all known targets.
-Known targets are targets that are explicitly defined in that makefile;
-in other words, all targets that appear on the left hand side of a
-dependency in the makefile."
- (interactive)
- (if (y-or-n-p "Are you sure that the makefile being edited is consistent? ")
- ;;
- ;; The rest of this function operates on a temporary makefile, created by
- ;; writing the current contents of the makefile buffer.
- ;;
- (let ((saved-target-table makefile-target-table)
- (this-buffer (current-buffer))
- (makefile-up-to-date-buffer
- (get-buffer-create makefile-up-to-date-buffer-name))
- (filename (makefile-save-temporary))
- ;;
- ;; Forget the target table because it may contain picked-up filenames
- ;; that are not really targets in the current makefile.
- ;; We don't want to query these, so get a new target-table with just the
- ;; targets that can be found in the makefile buffer.
- ;; The 'old' target table will be restored later.
- ;;
- (real-targets (progn
- (makefile-pickup-targets)
- makefile-target-table))
- (prereqs makefile-has-prereqs)
- )
-
- (set-buffer makefile-up-to-date-buffer)
- (setq buffer-read-only nil)
- (erase-buffer)
- (makefile-query-targets filename real-targets prereqs)
- (if (zerop (buffer-size)) ; if it did not get us anything
- (progn
- (kill-buffer (current-buffer))
- (message "No overview created!")))
- (set-buffer this-buffer)
- (setq makefile-target-table saved-target-table)
- (if (get-buffer makefile-up-to-date-buffer-name)
- (progn
- (pop-to-buffer (get-buffer makefile-up-to-date-buffer-name))
- (shrink-window-if-larger-than-buffer)
- (sort-lines nil (point-min) (point-max))
- (setq buffer-read-only t))))))
-
-(defun makefile-save-temporary ()
- "Create a temporary file from the current makefile buffer."
- (let ((filename (makefile-generate-temporary-filename)))
- (write-region (point-min) (point-max) filename nil 0)
- filename)) ; return the filename
-
-(defun makefile-generate-temporary-filename ()
- "Create a filename suitable for use in makefile-save-temporary.
-Be careful to allow brain-dead file systems (DOS, SYSV ...) to cope
-with the generated name !"
- (let ((my-name (user-login-name))
- (my-uid (int-to-string (user-uid))))
- (concat "mktmp"
- (if (> (length my-name) 3)
- (substring my-name 0 3)
- my-name)
- "."
- (if (> (length my-uid) 3)
- (substring my-uid 0 3)
- my-uid))))
-
-(defun makefile-query-targets (filename target-table prereq-list)
- "This function fills the up-to-date-overview-buffer.
-It checks each target in target-table using makefile-query-one-target-method
-and generates the overview, one line per target name."
- (insert
- (mapconcat
- (function (lambda (item)
- (let* ((target-name (car item))
- (no-prereqs (not (member target-name prereq-list)))
- (needs-rebuild (or no-prereqs
- (funcall
- makefile-query-one-target-method
- target-name
- filename))))
- (format "\t%s%s"
- target-name
- (cond (no-prereqs " .. has no prerequisites")
- (needs-rebuild " .. NEEDS REBUILD")
- (t " .. is up to date"))))
- ))
- target-table "\n"))
- (goto-char (point-min))
- (delete-file filename)) ; remove the tmpfile
-
-(defun makefile-query-by-make-minus-q (target &optional filename)
- (not (zerop (call-process makefile-brave-make nil nil nil "-f" filename "-q" target))))
-
-;;; ------------------------------------------------------------
-;;; Continuation cleanup
-;;; ------------------------------------------------------------
-
-(defun makefile-cleanup-continuations ()
- (if (eq major-mode 'makefile-mode)
- (if (and makefile-cleanup-continuations-p
- (not buffer-read-only))
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "\\\\[ \t]+$" (point-max) t)
- (replace-match "\\" t t))))))
-
-
-;;; ------------------------------------------------------------
-;;; Warn of suspicious lines
-;;; ------------------------------------------------------------
-
-(defun makefile-warn-suspicious-lines ()
- (let ((dont-save nil))
- (if (eq major-mode 'makefile-mode)
- (let ((suspicious
- (save-excursion
- (goto-char (point-min))
- (re-search-forward
- "\\(^[\t]+$\\)\\|\\(^[ ]+[\t]\\)" (point-max) t))))
- (if suspicious
- (let ((line-nr (count-lines (point-min) suspicious)))
- (setq dont-save
- (not (y-or-n-p
- (format "Suspicious line %d. Save anyway "
- line-nr))))))))
- dont-save))
-
-
-;;; ------------------------------------------------------------
-;;; GNU make function support
-;;; ------------------------------------------------------------
-
-(defun makefile-insert-gmake-function ()
- "This function is intended to help you using the numerous
-macro-like \'function calls\' of GNU make.
-It will ask you for the name of the function you wish to
-use (with completion), then, after you selected the function,
-it will prompt you for all required parameters.
-This function \'knows\' about the required parameters of every
-GNU make function and will use meaningfull prompts for the
-various args, making it much easier to take advantage of this
-powerful GNU make feature."
- (interactive)
- (let* ((gm-function-name (completing-read
- "Function: "
- makefile-gnumake-functions-alist
- nil t nil))
- (gm-function-prompts
- (cdr (assoc gm-function-name makefile-gnumake-functions-alist))))
- (if (not (zerop (length gm-function-name)))
- (insert (makefile-format-macro-ref
- (concat gm-function-name " "
- (makefile-prompt-for-gmake-funargs
- gm-function-name gm-function-prompts)))
- " "))))
-
-(defun makefile-prompt-for-gmake-funargs (function-name prompt-list)
- (mapconcat
- (function (lambda (one-prompt)
- (read-string (format "[%s] %s: " function-name one-prompt) nil)))
- prompt-list
- ","))
-
-
-
-;;; ------------------------------------------------------------
-;;; Utility functions
-;;; ------------------------------------------------------------
-
-(defun makefile-remember-target (target-name &optional has-prereqs)
- "Remember a given target if it is not already remembered for this buffer."
- (if (not (zerop (length target-name)))
- (progn
- (if (not (assoc target-name makefile-target-table))
- (setq makefile-target-table
- (cons (list target-name) makefile-target-table)))
- (if has-prereqs
- (setq makefile-has-prereqs
- (cons target-name makefile-has-prereqs))))))
-
-(defun makefile-remember-macro (macro-name)
- "Remember a given macro if it is not already remembered for this buffer."
- (if (not (zerop (length macro-name)))
- (if (not (assoc macro-name makefile-macro-table))
- (setq makefile-macro-table
- (cons (list macro-name) makefile-macro-table)))))
-
-(defun makefile-forward-after-target-colon ()
-"Move point forward after the terminating colon
-of a target has been inserted.
-This accts according to the value of makefile-tab-after-target-colon ."
- (if makefile-tab-after-target-colon
- (insert "\t")
- (insert " ")))
-
-(defun makefile-browser-on-macro-line-p ()
- "Determine if point is on a macro line in the browser."
- (save-excursion
- (beginning-of-line)
- (re-search-forward "\\$[{(]" (makefile-end-of-line-point) t)))
-
-(defun makefile-browser-this-line-target-name ()
- "Extract the target name from a line in the browser."
- (save-excursion
- (end-of-line)
- (skip-chars-backward "^ \t")
- (buffer-substring (point) (1- (makefile-end-of-line-point)))))
-
-(defun makefile-browser-this-line-macro-name ()
- "Extract the macro name from a line in the browser."
- (save-excursion
- (beginning-of-line)
- (re-search-forward "\\$[{(]" (makefile-end-of-line-point) t)
- (let ((macro-start (point)))
- (skip-chars-forward "^})")
- (buffer-substring macro-start (point)))))
-
-(defun makefile-format-macro-ref (macro-name)
- "Format a macro reference according to the value of the
-configuration variable makefile-use-curly-braces-for-macros-p ."
- (if (or (char-equal ?\( (string-to-char macro-name))
- (char-equal ?\{ (string-to-char macro-name)))
- (format "$%s" macro-name)
- (if makefile-use-curly-braces-for-macros-p
- (format "${%s}" macro-name)
- (format "$(%s)" macro-name))))
-
-(defun makefile-browser-get-state-for-line (n)
- (aref makefile-browser-selection-vector (1- n)))
-
-(defun makefile-browser-set-state-for-line (n to-state)
- (aset makefile-browser-selection-vector (1- n) to-state))
-
-(defun makefile-browser-toggle-state-for-line (n)
- (makefile-browser-set-state-for-line n (not (makefile-browser-get-state-for-line n))))
-
-(defun makefile-beginning-of-line-point ()
- (save-excursion
- (beginning-of-line)
- (point)))
-
-(defun makefile-end-of-line-point ()
- (save-excursion
- (end-of-line)
- (point)))
-
-(defun makefile-last-line-p ()
- (= (makefile-end-of-line-point) (point-max)))
-
-(defun makefile-first-line-p ()
- (= (makefile-beginning-of-line-point) (point-min)))
-
-;; makefile.el ends here
diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el
deleted file mode 100644
index 21b7d475b30..00000000000
--- a/lisp/progmodes/modula2.el
+++ /dev/null
@@ -1,454 +0,0 @@
-;;; modula2.el --- Modula-2 editing support package
-
-;; Author: Michael Schmidt <michael@pbinfo.UUCP>
-;; Tom Perrine <Perrin@LOGICON.ARPA>
-;; Keywords: languages
-
-;; The authors distributed this without a copyright notice
-;; back in 1988, so it is in the public domain. The original included
-;; the following credit:
-
-;; Author Mick Jordan
-;; amended Peter Robinson
-
-;;; Commentary:
-
-;; A major mode for editing Modula-2 code. It provides convenient abbrevs
-;; for Modula-2 keywords, knows about the standard layout rules, and supports
-;; a native compile command.
-
-;;; Code:
-
-;;; Added by Tom Perrine (TEP)
-(defvar m2-mode-syntax-table nil
- "Syntax table in use in Modula-2 buffers.")
-
-(defvar m2-compile-command "m2c"
- "Command to compile Modula-2 programs")
-
-(defvar m2-link-command "m2l"
- "Command to link Modula-2 programs")
-
-(defvar m2-link-name nil
- "Name of the executable.")
-
-
-(if m2-mode-syntax-table
- ()
- (let ((table (make-syntax-table)))
- (modify-syntax-entry ?\\ "\\" table)
- (modify-syntax-entry ?\( ". 1" table)
- (modify-syntax-entry ?\) ". 4" table)
- (modify-syntax-entry ?* ". 23" table)
- (modify-syntax-entry ?+ "." table)
- (modify-syntax-entry ?- "." table)
- (modify-syntax-entry ?= "." table)
- (modify-syntax-entry ?% "." table)
- (modify-syntax-entry ?< "." table)
- (modify-syntax-entry ?> "." table)
- (modify-syntax-entry ?\' "\"" table)
- (setq m2-mode-syntax-table table)))
-
-;;; Added by TEP
-(defvar m2-mode-map nil
- "Keymap used in Modula-2 mode.")
-
-(if m2-mode-map ()
- (let ((map (make-sparse-keymap)))
- (define-key map "\^i" 'm2-tab)
- (define-key map "\C-cb" 'm2-begin)
- (define-key map "\C-cc" 'm2-case)
- (define-key map "\C-cd" 'm2-definition)
- (define-key map "\C-ce" 'm2-else)
- (define-key map "\C-cf" 'm2-for)
- (define-key map "\C-ch" 'm2-header)
- (define-key map "\C-ci" 'm2-if)
- (define-key map "\C-cm" 'm2-module)
- (define-key map "\C-cl" 'm2-loop)
- (define-key map "\C-co" 'm2-or)
- (define-key map "\C-cp" 'm2-procedure)
- (define-key map "\C-c\C-w" 'm2-with)
- (define-key map "\C-cr" 'm2-record)
- (define-key map "\C-cs" 'm2-stdio)
- (define-key map "\C-ct" 'm2-type)
- (define-key map "\C-cu" 'm2-until)
- (define-key map "\C-cv" 'm2-var)
- (define-key map "\C-cw" 'm2-while)
- (define-key map "\C-cx" 'm2-export)
- (define-key map "\C-cy" 'm2-import)
- (define-key map "\C-c{" 'm2-begin-comment)
- (define-key map "\C-c}" 'm2-end-comment)
- (define-key map "\C-j" 'm2-newline)
- (define-key map "\C-c\C-z" 'suspend-emacs)
- (define-key map "\C-c\C-v" 'm2-visit)
- (define-key map "\C-c\C-t" 'm2-toggle)
- (define-key map "\C-c\C-l" 'm2-link)
- (define-key map "\C-c\C-c" 'm2-compile)
- (setq m2-mode-map map)))
-
-(defvar m2-indent 5 "*This variable gives the indentation in Modula-2-Mode")
-
-;;;###autoload
-(defun modula-2-mode ()
- "This is a mode intended to support program development in Modula-2.
-All control constructs of Modula-2 can be reached by typing C-c
-followed by the first character of the construct.
-\\<m2-mode-map>
- \\[m2-begin] begin \\[m2-case] case
- \\[m2-definition] definition \\[m2-else] else
- \\[m2-for] for \\[m2-header] header
- \\[m2-if] if \\[m2-module] module
- \\[m2-loop] loop \\[m2-or] or
- \\[m2-procedure] procedure Control-c Control-w with
- \\[m2-record] record \\[m2-stdio] stdio
- \\[m2-type] type \\[m2-until] until
- \\[m2-var] var \\[m2-while] while
- \\[m2-export] export \\[m2-import] import
- \\[m2-begin-comment] begin-comment \\[m2-end-comment] end-comment
- \\[suspend-emacs] suspend Emacs \\[m2-toggle] toggle
- \\[m2-compile] compile \\[m2-next-error] next-error
- \\[m2-link] link
-
- `m2-indent' controls the number of spaces for each indentation.
- `m2-compile-command' holds the command to compile a Modula-2 program.
- `m2-link-command' holds the command to link a Modula-2 program."
- (interactive)
- (kill-all-local-variables)
- (use-local-map m2-mode-map)
- (setq major-mode 'modula-2-mode)
- (setq mode-name "Modula-2")
- (make-local-variable 'comment-column)
- (setq comment-column 41)
- (make-local-variable 'end-comment-column)
- (setq end-comment-column 75)
- (set-syntax-table m2-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
-; (make-local-variable 'indent-line-function)
-; (setq indent-line-function 'c-indent-line)
- (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 " *)")
- (make-local-variable 'comment-column)
- (setq comment-column 41)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "/\\*+ *")
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'c-comment-indent)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (run-hooks 'm2-mode-hook))
-
-(defun m2-newline ()
- "Insert a newline and indent following line like previous line."
- (interactive)
- (let ((hpos (current-indentation)))
- (newline)
- (indent-to hpos)))
-
-(defun m2-tab ()
- "Indent to next tab stop."
- (interactive)
- (indent-to (* (1+ (/ (current-indentation) m2-indent)) m2-indent)))
-
-(defun m2-begin ()
- "Insert a BEGIN keyword and indent for the next line."
- (interactive)
- (insert "BEGIN")
- (m2-newline)
- (m2-tab))
-
-(defun m2-case ()
- "Build skeleton CASE statment, prompting for the <expression>."
- (interactive)
- (let ((name (read-string "Case-Expression: ")))
- (insert "CASE " name " OF")
- (m2-newline)
- (m2-newline)
- (insert "END (* case " name " *);"))
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-definition ()
- "Build skeleton DEFINITION MODULE, prompting for the <module name>."
- (interactive)
- (insert "DEFINITION MODULE ")
- (let ((name (read-string "Name: ")))
- (insert name ";\n\n\n\nEND " name ".\n"))
- (previous-line 3))
-
-(defun m2-else ()
- "Insert ELSE keyword and indent for next line."
- (interactive)
- (m2-newline)
- (backward-delete-char-untabify m2-indent ())
- (insert "ELSE")
- (m2-newline)
- (m2-tab))
-
-(defun m2-for ()
- "Build skeleton FOR loop statment, prompting for the loop parameters."
- (interactive)
- (insert "FOR ")
- (let ((name (read-string "Loop Initialiser: ")) limit by)
- (insert name " TO ")
- (setq limit (read-string "Limit: "))
- (insert limit)
- (setq by (read-string "Step: "))
- (if (not (string-equal by ""))
- (insert " BY " by))
- (insert " DO")
- (m2-newline)
- (m2-newline)
- (insert "END (* for " name " to " limit " *);"))
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-header ()
- "Insert a comment block containing the module title, author, etc."
- (interactive)
- (insert "(*\n Title: \t")
- (insert (read-string "Title: "))
- (insert "\n Created:\t")
- (insert (current-time-string))
- (insert "\n Author: \t")
- (insert (user-full-name))
- (insert (concat "\n\t\t<" (user-login-name) "@" (system-name) ">\n"))
- (insert "*)\n\n"))
-
-(defun m2-if ()
- "Insert skeleton IF statment, prompting for <boolean-expression>."
- (interactive)
- (insert "IF ")
- (let ((thecondition (read-string "<boolean-expression>: ")))
- (insert thecondition " THEN")
- (m2-newline)
- (m2-newline)
- (insert "END (* if " thecondition " *);"))
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-loop ()
- "Build skeleton LOOP (with END)."
- (interactive)
- (insert "LOOP")
- (m2-newline)
- (m2-newline)
- (insert "END (* loop *);")
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-module ()
- "Build skeleton IMPLEMENTATION MODULE, prompting for <module-name>."
- (interactive)
- (insert "IMPLEMENTATION MODULE ")
- (let ((name (read-string "Name: ")))
- (insert name ";\n\n\n\nEND " name ".\n")
- (previous-line 3)
- (m2-header)
- (m2-type)
- (newline)
- (m2-var)
- (newline)
- (m2-begin)
- (m2-begin-comment)
- (insert " Module " name " Initialisation Code "))
- (m2-end-comment)
- (newline)
- (m2-tab))
-
-(defun m2-or ()
- (interactive)
- (m2-newline)
- (backward-delete-char-untabify m2-indent)
- (insert "|")
- (m2-newline)
- (m2-tab))
-
-(defun m2-procedure ()
- (interactive)
- (insert "PROCEDURE ")
- (let ((name (read-string "Name: " ))
- args)
- (insert name " (")
- (insert (read-string "Arguments: ") ")")
- (setq args (read-string "Result Type: "))
- (if (not (string-equal args ""))
- (insert " : " args))
- (insert ";")
- (m2-newline)
- (insert "BEGIN")
- (m2-newline)
- (m2-newline)
- (insert "END ")
- (insert name)
- (insert ";")
- (end-of-line 0)
- (m2-tab)))
-
-(defun m2-with ()
- (interactive)
- (insert "WITH ")
- (let ((name (read-string "Record-Type: ")))
- (insert name)
- (insert " DO")
- (m2-newline)
- (m2-newline)
- (insert "END (* with " name " *);"))
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-record ()
- (interactive)
- (insert "RECORD")
- (m2-newline)
- (m2-newline)
- (insert "END (* record *);")
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-stdio ()
- (interactive)
- (insert "
-FROM TextIO IMPORT
- WriteCHAR, ReadCHAR, WriteINTEGER, ReadINTEGER,
- WriteCARDINAL, ReadCARDINAL, WriteBOOLEAN, ReadBOOLEAN,
- WriteREAL, ReadREAL, WriteBITSET, ReadBITSET,
- WriteBasedCARDINAL, ReadBasedCARDINAL, WriteChars, ReadChars,
- WriteString, ReadString, WhiteSpace, EndOfLine;
-
-FROM SysStreams IMPORT sysIn, sysOut, sysErr;
-
-"))
-
-(defun m2-type ()
- (interactive)
- (insert "TYPE")
- (m2-newline)
- (m2-tab))
-
-(defun m2-until ()
- (interactive)
- (insert "REPEAT")
- (m2-newline)
- (m2-newline)
- (insert "UNTIL ")
- (insert (read-string "<boolean-expression>: ") ";")
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-var ()
- (interactive)
- (m2-newline)
- (insert "VAR")
- (m2-newline)
- (m2-tab))
-
-(defun m2-while ()
- (interactive)
- (insert "WHILE ")
- (let ((name (read-string "<boolean-expression>: ")))
- (insert name " DO" )
- (m2-newline)
- (m2-newline)
- (insert "END (* while " name " *);"))
- (end-of-line 0)
- (m2-tab))
-
-(defun m2-export ()
- (interactive)
- (insert "EXPORT QUALIFIED "))
-
-(defun m2-import ()
- (interactive)
- (insert "FROM ")
- (insert (read-string "Module: "))
- (insert " IMPORT "))
-
-(defun m2-begin-comment ()
- (interactive)
- (if (not (bolp))
- (indent-to comment-column 0))
- (insert "(* "))
-
-(defun m2-end-comment ()
- (interactive)
- (if (not (bolp))
- (indent-to end-comment-column))
- (insert "*)"))
-
-(defun m2-compile ()
- (interactive)
- (setq modulename (buffer-name))
- (compile (concat m2-compile-command " " modulename)))
-
-(defun m2-link ()
- (interactive)
- (setq modulename (buffer-name))
- (if m2-link-name
- (compile (concat m2-link-command " " m2-link-name))
- (compile (concat m2-link-command " "
- (setq m2-link-name (read-string "Name of executable: "
- modulename))))))
-
-(defun execute-monitor-command (command)
- (let* ((shell shell-file-name)
- (csh (equal (file-name-nondirectory shell) "csh")))
- (call-process shell nil t t "-cf" (concat "exec " command))))
-
-(defun m2-visit ()
- (interactive)
- (let ((deffile nil)
- (modfile nil)
- modulename)
- (save-excursion
- (setq modulename
- (read-string "Module name: "))
- (switch-to-buffer "*Command Execution*")
- (execute-monitor-command (concat "m2whereis " modulename))
- (goto-char (point-min))
- (condition-case ()
- (progn (re-search-forward "\\(.*\\.def\\) *$")
- (setq deffile (buffer-substring (match-beginning 1)
- (match-end 1))))
- (search-failed ()))
- (condition-case ()
- (progn (re-search-forward "\\(.*\\.mod\\) *$")
- (setq modfile (buffer-substring (match-beginning 1)
- (match-end 1))))
- (search-failed ()))
- (if (not (or deffile modfile))
- (error "I can find neither definition nor implementation of %s"
- modulename)))
- (cond (deffile
- (find-file deffile)
- (if modfile
- (save-excursion
- (find-file modfile))))
- (modfile
- (find-file modfile)))))
-
-(defun m2-toggle ()
- "Toggle between .mod and .def files for the module."
- (interactive)
- (cond ((string-equal (substring (buffer-name) -4) ".def")
- (find-file-other-window
- (concat (substring (buffer-name) 0 -4) ".mod")))
- ((string-equal (substring (buffer-name) -4) ".mod")
- (find-file-other-window
- (concat (substring (buffer-name) 0 -4) ".def")))
- ((string-equal (substring (buffer-name) -3) ".mi")
- (find-file-other-window
- (concat (substring (buffer-name) 0 -3) ".md")))
- ((string-equal (substring (buffer-name) -3) ".md")
- (find-file-other-window
- (concat (substring (buffer-name) 0 -3) ".mi")))))
-
-;;; modula2.el ends here
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
deleted file mode 100644
index 026c383fe90..00000000000
--- a/lisp/progmodes/pascal.el
+++ /dev/null
@@ -1,1404 +0,0 @@
-;;; pascal.el - Major mode for editing pascal source in emacs.
-
-;;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-
-;;; Author: Espen Skoglund (espensk@stud.cs.uit.no)
-;;; Keywords: languages
-
-;;; This file is part of GNU Emacs.
-
-;;; This program is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 2 of the License, or
-;;; (at your option) any later version.
-
-;;; This program is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-
-;;; You should have received a copy of the GNU General Public License
-;;; along with this program; if not, write to the Free Software
-;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;;; USAGE
-;;; =====
-
-;;; Emacs should enter Pascal mode when you find a Pascal source file.
-;;; When you have entered Pascal mode, you may get more info by pressing
-;;; C-h m. You may also get online help describing various functions by:
-;;; C-h f <Name of function you want described>
-
-;;; If you want to customize Pascal mode to fit you better, you may add
-;;; these lines (the values of the variables presented here are the defaults):
-;;;
-;;; ;; User customization for Pascal mode
-;;; (setq pascal-indent-level 3
-;;; pascal-case-indent 2
-;;; pascal-auto-newline nil
-;;; pascal-tab-always-indent t
-;;; pascal-auto-endcomments t
-;;; pascal-toggle-completions nil
-;;; pascal-type-keywords '("array" "file" "packed" "char"
-;;; "integer" "real" "string" "record")
-;;; pascal-start-keywords '("begin" "end" "function" "procedure"
-;;; "repeat" "until" "while" "read" "readln"
-;;; "reset" "rewrite" "write" "writeln")
-;;; pascal-separator-keywords '("downto" "else" "mod" "div" "then"))
-
-;;; KNOWN BUGS / BUGREPORTS
-;;; =======================
-;;; As far as I know, there are no bugs in the current version of this
-;;; package. This may not be true however, since I never use this mode
-;;; myself and therefore would never notice them anyway. If you do
-;;; find any bugs, you may submit them to: espensk@stud.cs.uit.no
-;;; as well as to bug-gnu-emacs@prep.ai.mit.edu.
-
-;;; Code:
-
-(defconst pascal-mode-version "2.1a"
- "Version of `pascal-mode.el'.")
-
-(defvar pascal-mode-abbrev-table nil
- "Abbrev table in use in Pascal-mode buffers.")
-(define-abbrev-table 'pascal-mode-abbrev-table ())
-
-(defvar pascal-mode-map ()
- "Keymap used in Pascal mode.")
-(if pascal-mode-map
- ()
- (setq pascal-mode-map (make-sparse-keymap))
- (define-key pascal-mode-map ";" 'electric-pascal-semi-or-dot)
- (define-key pascal-mode-map "." 'electric-pascal-semi-or-dot)
- (define-key pascal-mode-map ":" 'electric-pascal-colon)
- (define-key pascal-mode-map "=" 'electric-pascal-equal)
- (define-key pascal-mode-map "\r" 'electric-pascal-terminate-line)
- (define-key pascal-mode-map "\t" 'electric-pascal-tab)
- (define-key pascal-mode-map "\e\t" 'pascal-complete-word)
- (define-key pascal-mode-map "\e?" 'pascal-show-completions)
- (define-key pascal-mode-map "\177" 'backward-delete-char-untabify)
- (define-key pascal-mode-map "\e\C-h" 'pascal-mark-defun)
- (define-key pascal-mode-map "\C-cb" 'pascal-insert-block)
- (define-key pascal-mode-map "\M-*" 'pascal-star-comment)
- (define-key pascal-mode-map "\C-c\C-c" 'pascal-comment-area)
- (define-key pascal-mode-map "\C-c\C-u" 'pascal-uncomment-area)
- (define-key pascal-mode-map "\e\C-a" 'pascal-beg-of-defun)
- (define-key pascal-mode-map "\e\C-e" 'pascal-end-of-defun)
- (define-key pascal-mode-map "\C-cg" 'pascal-goto-defun)
- (define-key pascal-mode-map "\C-c\C-o" 'pascal-outline)
-;;; A command to change the whole buffer won't be used terribly
-;;; often, so no need for a key binding.
-; (define-key pascal-mode-map "\C-cd" 'pascal-downcase-keywords)
-; (define-key pascal-mode-map "\C-cu" 'pascal-upcase-keywords)
-; (define-key pascal-mode-map "\C-cc" 'pascal-capitalize-keywords)
- )
-
-(defvar pascal-keywords
- '("and" "array" "begin" "case" "const" "div" "do" "downto" "else" "end"
- "file" "for" "function" "goto" "if" "in" "label" "mod" "nil" "not" "of"
- "or" "packed" "procedure" "program" "record" "repeat" "set" "then" "to"
- "type" "until" "var" "while" "with"
- ;; The following are not standard in pascal, but widely used.
- "get" "put" "input" "output" "read" "readln" "reset" "rewrite" "write"
- "writeln"))
-
-;;;
-;;; Regular expressions used to calculate indent, etc.
-;;;
-(defconst pascal-symbol-re "\\<[a-zA-Z_][a-zA-Z_0-9.]*\\>")
-(defconst pascal-beg-block-re "\\<\\(begin\\|case\\|record\\|repeat\\)\\>")
-(defconst pascal-end-block-re "\\<\\(end\\|until\\)\\>")
-(defconst pascal-declaration-re "\\<\\(const\\|label\\|type\\|var\\)\\>")
-(defconst pascal-defun-re "\\<\\(function\\|procedure\\|program\\)\\>")
-(defconst pascal-sub-block-re "\\<\\(if\\|else\\|for\\|while\\|with\\)\\>")
-(defconst pascal-noindent-re "\\<\\(begin\\|end\\|until\\|else\\)\\>")
-(defconst pascal-nosemi-re "\\<\\(begin\\|repeat\\|then\\|do\\|else\\)\\>")
-(defconst pascal-autoindent-lines-re
- "\\<\\(label\\|var\\|type\\|const\\|until\\|end\\|begin\\|repeat\\|else\\)\\>")
-
-;;; Strings used to mark beginning and end of excluded text
-(defconst pascal-exclude-str-start "{-----\\/----- EXCLUDED -----\\/-----")
-(defconst pascal-exclude-str-end " -----/\\----- EXCLUDED -----/\\-----}")
-
-(defvar pascal-mode-syntax-table nil
- "Syntax table in use in Pascal-mode buffers.")
-
-(if pascal-mode-syntax-table
- ()
- (setq pascal-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\\ "\\" pascal-mode-syntax-table)
- (modify-syntax-entry ?( "()1" pascal-mode-syntax-table)
- (modify-syntax-entry ?) ")(4" pascal-mode-syntax-table)
- (modify-syntax-entry ?* ". 23" pascal-mode-syntax-table)
- (modify-syntax-entry ?{ "<" pascal-mode-syntax-table)
- (modify-syntax-entry ?} ">" pascal-mode-syntax-table)
- (modify-syntax-entry ?+ "." pascal-mode-syntax-table)
- (modify-syntax-entry ?- "." pascal-mode-syntax-table)
- (modify-syntax-entry ?= "." pascal-mode-syntax-table)
- (modify-syntax-entry ?% "." pascal-mode-syntax-table)
- (modify-syntax-entry ?< "." pascal-mode-syntax-table)
- (modify-syntax-entry ?> "." pascal-mode-syntax-table)
- (modify-syntax-entry ?& "." pascal-mode-syntax-table)
- (modify-syntax-entry ?| "." pascal-mode-syntax-table)
- (modify-syntax-entry ?_ "w" pascal-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" pascal-mode-syntax-table))
-
-(defvar pascal-indent-level 3
- "*Indentation of Pascal statements with respect to containing block.")
-(defvar pascal-case-indent 2
- "*Indentation for case statements.")
-(defvar pascal-auto-newline nil
- "*Non-nil means automatically newline after simcolons and the punctation mark
-after an end.")
-(defvar pascal-tab-always-indent t
- "*Non-nil means TAB in Pascal mode should always reindent the current line,
-regardless of where in the line point is when the TAB command is used.")
-(defvar pascal-auto-endcomments t
- "*Non-nil means a comment { ... } is set after the ends which ends cases and
-functions. The name of the function or case will be set between the braces.")
-(defvar pascal-toggle-completions nil
- "*Non-nil means that \\<pascal-mode-map>\\[pascal-complete-label] should \
-not display a completion buffer when
-the label couldn't be completed, but instead toggle the possible completions
-with repeated \\[pascal-complete-label]'s.")
-(defvar pascal-type-keywords
- '("array" "file" "packed" "char" "integer" "real" "string" "record")
- "*Keywords for types used when completing a word in a declaration or parmlist.
-\(eg. integer, real, char.) The types defined within the Pascal program
-will be completed runtime, and should not be added to this list.")
-(defvar pascal-start-keywords
- '("begin" "end" "function" "procedure" "repeat" "until" "while"
- "read" "readln" "reset" "rewrite" "write" "writeln")
- "*Keywords to complete when standing at the first word of a statement.
-\(eg. begin, repeat, until, readln.)
-The procedures and variables defined within the Pascal program
-will be completed runtime and should not be added to this list.")
-(defvar pascal-separator-keywords
- '("downto" "else" "mod" "div" "then")
- "*Keywords to complete when NOT standing at the first word of a statement.
-\(eg. downto, else, mod, then.)
-Variables and function names defined within the
-Pascal program are completed runtime and should not be added to this list.")
-
-;;;
-;;; Macros
-;;;
-
-(defsubst pascal-get-beg-of-line (&optional arg)
- (save-excursion
- (beginning-of-line arg)
- (point)))
-
-(defsubst pascal-get-end-of-line (&optional arg)
- (save-excursion
- (end-of-line arg)
- (point)))
-
-(defun pascal-declaration-end ()
- (let ((nest 1))
- (while (and (> nest 0)
- (re-search-forward
- "[:=]\\|\\(\\<record\\>\\)\\|\\(\\<end\\>\\)"
- (save-excursion (end-of-line 2) (point)) t))
- (cond ((match-beginning 1) (setq nest (1+ nest)))
- ((match-beginning 2) (setq nest (1- nest)))))))
-
-(defun pascal-declaration-beg ()
- (let ((nest 1))
- (while (and (> nest 0)
- (re-search-backward "[:=]\\|\\<\\(type\\|var\\|label\\|const\\)\\>\\|\\(\\<record\\>\\)\\|\\(\\<end\\>\\)" (pascal-get-beg-of-line -0) t))
- (cond ((match-beginning 1) (setq nest 0))
- ((match-beginning 2) (setq nest (1- nest)))
- ((match-beginning 3) (setq nest (1+ nest)))))
- (= nest 0)))
-
-(defsubst pascal-within-string ()
- (save-excursion
- (nth 3 (parse-partial-sexp (pascal-get-beg-of-line) (point)))))
-
-
-;;;###autoload
-(defun pascal-mode ()
- "Major mode for editing Pascal code. \\<pascal-mode-map>
-TAB indents for Pascal code. Delete converts tabs to spaces as it moves back.
-
-\\[pascal-complete-word] completes the word around current point with respect \
-to position in code
-\\[pascal-show-completions] shows all possible completions at this point.
-
-Other useful functions are:
-
-\\[pascal-mark-defun]\t- Mark function.
-\\[pascal-insert-block]\t- insert begin ... end;
-\\[pascal-star-comment]\t- insert (* ... *)
-\\[pascal-comment-area]\t- Put marked area in a comment, fixing nested comments.
-\\[pascal-uncomment-area]\t- Uncomment an area commented with \
-\\[pascal-comment-area].
-\\[pascal-beg-of-defun]\t- Move to beginning of current function.
-\\[pascal-end-of-defun]\t- Move to end of current function.
-\\[pascal-goto-defun]\t- Goto function prompted for in the minibuffer.
-\\[pascal-outline]\t- Enter pascal-outline-mode (see also pascal-outline).
-
-Variables controlling indentation/edit style:
-
- pascal-indent-level (default 3)
- Indentation of Pascal statements with respect to containing block.
- pascal-case-indent (default 2)
- Indentation for case statements.
- pascal-auto-newline (default nil)
- Non-nil means automatically newline after simcolons and the punctation mark
- after an end.
- pascal-tab-always-indent (defualt t)
- Non-nil means TAB in Pascal mode should always reindent the current line,
- regardless of where in the line point is when the TAB command is used.
- pascal-auto-endcomments (default t)
- Non-nil means a comment { ... } is set after the ends which ends cases and
- functions. The name of the function or case will be set between the braces.
-
-See also the user variables pascal-type-keywords, pascal-start-keywords and
-pascal-separator-keywords.
-
-Turning on Pascal mode calls the value of the variable pascal-mode-hook with
-no args, if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map pascal-mode-map)
- (setq major-mode 'pascal-mode)
- (setq mode-name "Pascal")
- (setq local-abbrev-table pascal-mode-abbrev-table)
- (set-syntax-table pascal-mode-syntax-table)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'pascal-indent-line)
- (setq comment-indent-function 'pascal-indent-comment)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (make-local-variable 'case-fold-search)
- (setq case-fold-search t)
- (run-hooks 'pascal-mode-hook))
-
-
-
-;;;
-;;; Electric functions
-;;;
-(defun electric-pascal-terminate-line ()
- "Terminate line and indent next line."
- (interactive)
- ;; First, check if current line should be indented
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (if (looking-at pascal-autoindent-lines-re)
- (pascal-indent-line)))
- (delete-horizontal-space) ; Removes trailing whitespaces
- (newline)
- ;; Indent next line
- (pascal-indent-line)
- ;; Maybe we should set some endcomments
- (if pascal-auto-endcomments
- (pascal-set-auto-comments))
- ;; Check if we shall indent inside comment
- (let ((setstar nil))
- (save-excursion
- (forward-line -1)
- (skip-chars-forward " \t")
- (cond ((looking-at "\\*[ \t]+)")
- ;; Delete region between `*' and `)' if there is only whitespaces.
- (forward-char 1)
- (delete-horizontal-space))
- ((and (looking-at "(\\*\\|\\*[^)]")
- (not (save-excursion
- (search-forward "*)" (pascal-get-end-of-line) t))))
- (setq setstar t))))
- ;; If last line was a star comment line then this one shall be too.
- (if (null setstar)
- (pascal-indent-line)
- (insert "* "))))
-
-
-(defun electric-pascal-semi-or-dot ()
- "Insert `;' or `.' character and reindent the line."
- (interactive)
- (insert last-command-char)
- (save-excursion
- (beginning-of-line)
- (pascal-indent-line))
- (if pascal-auto-newline
- (electric-pascal-terminate-line)))
-
-(defun electric-pascal-colon ()
- "Insert `:' and do all indentions except line indent on this line."
- (interactive)
- (insert last-command-char)
- ;; Do nothing if within string.
- (if (pascal-within-string)
- ()
- (save-excursion
- (beginning-of-line)
- (pascal-indent-line))
- (let ((pascal-tab-always-indent nil))
- (pascal-indent-command))))
-
-(defun electric-pascal-equal ()
- "Insert `=', and do indention if within type declaration."
- (interactive)
- (insert last-command-char)
- (if (eq (car (pascal-calculate-indent)) 'declaration)
- (let ((pascal-tab-always-indent nil))
- (pascal-indent-command))))
-
-(defun electric-pascal-tab ()
- "Function called when TAB is pressed in Pascal mode."
- (interactive)
- ;; Do nothing if within a string.
- (if (pascal-within-string)
- (insert "\t")
- ;; If pascal-tab-always-indent, indent the beginning of the line.
- (if pascal-tab-always-indent
- (save-excursion
- (beginning-of-line)
- (pascal-indent-line))
- (insert "\t"))
- (pascal-indent-command)))
-
-
-
-;;;
-;;; Interactive functions
-;;;
-(defun pascal-insert-block ()
- "Insert Pascal begin ... end; block in the code with right indentation."
- (interactive)
- (pascal-indent-line)
- (insert "begin")
- (electric-pascal-terminate-line)
- (save-excursion
- (electric-pascal-terminate-line)
- (insert "end;")
- (beginning-of-line)
- (pascal-indent-line)))
-
-(defun pascal-star-comment ()
- "Insert Pascal star comment at point."
- (interactive)
- (pascal-indent-line)
- (insert "(*")
- (electric-pascal-terminate-line)
- (save-excursion
- (electric-pascal-terminate-line)
- (delete-horizontal-space)
- (insert ")"))
- (insert " "))
-
-(defun pascal-mark-defun ()
- "Mark the current pascal function (or procedure).
-This puts the mark at the end, and point at the beginning."
- (interactive)
- (push-mark (point))
- (pascal-end-of-defun)
- (push-mark (point))
- (pascal-beg-of-defun)
- (if (fboundp 'zmacs-activate-region)
- (zmacs-activate-region)))
-
-(defun pascal-comment-area (start end)
- "Put the region into a Pascal comment.
-The comments that are in this area are \"deformed\":
-`*)' becomes `!(*' and `}' becomes `!{'.
-These deformed comments are returned to normal if you use
-\\[pascal-uncomment-area] to undo the commenting.
-
-The commented area starts with `pascal-exclude-str-start', and ends with
-`pascal-include-str-end'. But if you change these variables,
-\\[pascal-uncomment-area] won't recognize the comments."
- (interactive "r")
- (save-excursion
- ;; Insert start and endcomments
- (goto-char end)
- (if (and (save-excursion (skip-chars-forward " \t") (eolp))
- (not (save-excursion (skip-chars-backward " \t") (bolp))))
- (forward-line 1)
- (beginning-of-line))
- (insert pascal-exclude-str-end)
- (setq end (point))
- (newline)
- (goto-char start)
- (beginning-of-line)
- (insert pascal-exclude-str-start)
- (newline)
- ;; Replace end-comments within commented area
- (goto-char end)
- (save-excursion
- (while (re-search-backward "\\*)" start t)
- (replace-match "!(*" t t)))
- (save-excursion
- (while (re-search-backward "}" start t)
- (replace-match "!{" t t)))))
-
-(defun pascal-uncomment-area ()
- "Uncomment a commented area; change deformed comments back to normal.
-This command does nothing if the pointer is not in a commented
-area. See also `pascal-comment-area'."
- (interactive)
- (save-excursion
- (let ((start (point))
- (end (point)))
- ;; Find the boundaries of the comment
- (save-excursion
- (setq start (progn (search-backward pascal-exclude-str-start nil t)
- (point)))
- (setq end (progn (search-forward pascal-exclude-str-end nil t)
- (point))))
- ;; Check if we're really inside a comment
- (if (or (equal start (point)) (<= end (point)))
- (message "Not standing within commented area.")
- (progn
- ;; Remove endcomment
- (goto-char end)
- (beginning-of-line)
- (let ((pos (point)))
- (end-of-line)
- (delete-region pos (1+ (point))))
- ;; Change comments back to normal
- (save-excursion
- (while (re-search-backward "!{" start t)
- (replace-match "}" t t)))
- (save-excursion
- (while (re-search-backward "!(\\*" start t)
- (replace-match "*)" t t)))
- ;; Remove startcomment
- (goto-char start)
- (beginning-of-line)
- (let ((pos (point)))
- (end-of-line)
- (delete-region pos (1+ (point)))))))))
-
-(defun pascal-beg-of-defun ()
- "Move backward to the beginning of the current function or procedure."
- (interactive)
- (catch 'found
- (if (not (looking-at (concat "\\s \\|\\s)\\|" pascal-defun-re)))
- (forward-sexp 1))
- (let ((nest 0) (max -1) (func 0)
- (reg (concat pascal-beg-block-re "\\|"
- pascal-end-block-re "\\|"
- pascal-defun-re)))
- (while (re-search-backward reg nil 'move)
- (cond ((let ((state (save-excursion
- (parse-partial-sexp (point-min) (point)))))
- (or (nth 3 state) (nth 4 state))) ; Inside string or comment
- ())
- ((match-end 1) ; begin|case|record|repeat
- (if (and (looking-at "\\<record\\>") (>= max 0))
- (setq func (1- func)))
- (setq nest (1+ nest)
- max (max nest max)))
- ((match-end 2) ; end|until
- (if (and (= nest max) (>= max 0))
- (setq func (1+ func)))
- (setq nest (1- nest)))
- ((match-end 3) ; function|procedure
- (if (= 0 func)
- (throw 'found t)
- (setq func (1- func)))))))
- nil))
-
-(defun pascal-end-of-defun ()
- "Move forward to the end of the current function or procedure."
- (interactive)
- (if (looking-at "\\s ")
- (forward-sexp 1))
- (if (not (looking-at pascal-defun-re))
- (pascal-beg-of-defun))
- (forward-char 1)
- (let ((nest 0) (func 1)
- (reg (concat pascal-beg-block-re "\\|"
- pascal-end-block-re "\\|"
- pascal-defun-re)))
- (while (and (/= func 0)
- (re-search-forward reg nil 'move))
- (cond ((let ((state (save-excursion
- (parse-partial-sexp (point-min) (point)))))
- (or (nth 3 state) (nth 4 state))) ; Inside string or comment
- ())
- ((match-end 1)
- (setq nest (1+ nest))
- (if (save-excursion
- (goto-char (match-beginning 0))
- (looking-at "\\<record\\>"))
- (setq func (1+ func))))
- ((match-end 2)
- (setq nest (1- nest))
- (if (= nest 0)
- (setq func (1- func))))
- ((match-end 3)
- (setq func (1+ func))))))
- (forward-line 1))
-
-(defun pascal-downcase-keywords ()
- "Downcase all Pascal keywords in the buffer."
- (interactive)
- (pascal-change-keywords 'downcase-word))
-
-(defun pascal-upcase-keywords ()
- "Upcase all Pascal keywords in the buffer."
- (interactive)
- (pascal-change-keywords 'upcase-word))
-
-(defun pascal-capitalize-keywords ()
- "Capitalize all Pascal keywords in the buffer."
- (interactive)
- (pascal-change-keywords 'capitalize-word))
-
-;; Change the keywords according to argument.
-(defun pascal-change-keywords (change-word)
- (save-excursion
- (let ((keyword-re (concat "\\<\\("
- (mapconcat 'identity pascal-keywords "\\|")
- "\\)\\>")))
- (goto-char (point-min))
- (while (re-search-forward keyword-re nil t)
- (funcall change-word -1)))))
-
-
-
-;;;
-;;; Other functions
-;;;
-(defun pascal-set-auto-comments ()
- "Insert `{ case }' or `{ NAME }' on this line if appropriate.
-Insert `{ case }' if there is an `end' on the line which
-ends a case block. Insert `{ NAME }' if there is an `end'
-on the line which ends a function or procedure named NAME."
- (save-excursion
- (forward-line -1)
- (skip-chars-forward " \t")
- (if (and (looking-at "\\<end;")
- (not (save-excursion
- (end-of-line)
- (search-backward "{" (pascal-get-beg-of-line) t))))
- (let ((type (car (pascal-calculate-indent))))
- (if (eq type 'declaration)
- ()
- (if (eq type 'case)
- ;; This is a case block
- (progn
- (end-of-line)
- (delete-horizontal-space)
- (insert " { case }"))
- (let ((nest 1))
- ;; Check if this is the end of a function
- (save-excursion
- (while (not (or (looking-at pascal-defun-re) (bobp)))
- (backward-sexp 1)
- (cond ((looking-at pascal-beg-block-re)
- (setq nest (1- nest)))
- ((looking-at pascal-end-block-re)
- (setq nest (1+ nest)))))
- (if (bobp)
- (setq nest 1)))
- (if (zerop nest)
- (progn
- (end-of-line)
- (delete-horizontal-space)
- (insert " { ")
- (let (b e)
- (save-excursion
- (setq b (progn (pascal-beg-of-defun)
- (skip-chars-forward "^ \t")
- (skip-chars-forward " \t")
- (point))
- e (progn (skip-chars-forward "a-zA-Z0-9_")
- (point))))
- (insert-buffer-substring (current-buffer) b e))
- (insert " }"))))))))))
-
-
-
-;;;
-;;; Indentation
-;;;
-(defconst pascal-indent-alist
- '((block . (+ ind pascal-indent-level))
- (case . (+ ind pascal-case-indent))
- (declaration . (+ ind pascal-indent-level))
- (paramlist . (pascal-indent-paramlist t))
- (comment . (pascal-indent-comment t))
- (defun . ind) (contexp . ind)
- (unknown . 0) (string . 0)))
-
-(defun pascal-indent-command ()
- "Indent for special part of code."
- (let* ((indent-str (pascal-calculate-indent))
- (type (car indent-str))
- (ind (car (cdr indent-str))))
- (cond ((eq type 'paramlist)
- (pascal-indent-paramlist)
- (pascal-indent-paramlist))
- ((eq type 'declaration)
- (pascal-indent-declaration))
- ((and (eq type 'case) (not (looking-at "^[ \t]*$")))
- (pascal-indent-case)))
- (if (looking-at "[ \t]+$")
- (skip-chars-forward " \t"))))
-
-(defun pascal-indent-line ()
- "Indent current line as a Pascal statement."
- (let* ((indent-str (pascal-calculate-indent))
- (type (car indent-str))
- (ind (car (cdr indent-str))))
- (if (looking-at "^[0-9a-zA-Z]+[ \t]*:[^=]")
- (search-forward ":" nil t))
- (delete-horizontal-space)
- ;; Some thing should not be indented
- (if (or (and (eq type 'declaration) (looking-at pascal-declaration-re))
- (looking-at pascal-defun-re))
- ()
- ;; Other things should have no extra indent
- (if (looking-at pascal-noindent-re)
- (indent-to ind)
- ;; But most lines are treated this way:
- (indent-to (eval (cdr (assoc type pascal-indent-alist))))
- ))))
-
-(defun pascal-calculate-indent ()
- "Calculate the indent of the current Pascal line.
-Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
- (save-excursion
- (let* ((oldpos (point))
- (state (save-excursion (parse-partial-sexp (point-min) (point))))
- (nest 0) (par 0) (complete nil)
- (elsed (looking-at "[ \t]*else\\>"))
- (type (catch 'nesting
- ;; Check if inside a string, comment or parenthesis
- (cond ((nth 3 state) (throw 'nesting 'string))
- ((nth 4 state) (throw 'nesting 'comment))
- ((> (car state) 0)
- (goto-char (scan-lists (point) -1 (car state)))
- (setq par (1+ (current-column)))))
- ;; Loop until correct indent is found
- (while t
- (backward-sexp 1)
- (cond (;--Nest block outwards
- (looking-at pascal-beg-block-re)
- (if (= nest 0)
- (cond ((looking-at "case\\>")
- (throw 'nesting 'case))
- ((looking-at "record\\>")
- (throw 'nesting 'declaration))
- (t (throw 'nesting 'block)))
- (setq nest (1- nest))))
- (;--Nest block inwards
- (looking-at pascal-end-block-re)
- (if (and (looking-at "end\\s ")
- elsed (not complete))
- (throw 'nesting 'block))
- (setq complete t
- nest (1+ nest)))
- (;--Defun (or parameter list)
- (looking-at pascal-defun-re)
- (if (= 0 par)
- (throw 'nesting 'defun)
- (setq par 0)
- (let ((n 0))
- (while (re-search-forward
- "\\(\\<record\\>\\)\\|\\<end\\>"
- oldpos t)
- (if (match-end 1)
- (setq n (1+ n)) (setq n (1- n))))
- (if (> n 0)
- (throw 'nesting 'declaration)
- (throw 'nesting 'paramlist)))))
- (;--Declaration part
- (looking-at pascal-declaration-re)
- (if (save-excursion
- (goto-char oldpos)
- (forward-line -1)
- (looking-at "^[ \t]*$"))
- (throw 'nesting 'unknown)
- (throw 'nesting 'declaration)))
- (;--If, else or while statement
- (and (not complete)
- (looking-at pascal-sub-block-re))
- (throw 'nesting 'block))
- (;--Found complete statement
- (save-excursion (forward-sexp 1)
- (= (following-char) ?\;))
- (setq complete t))
- (;--No known statements
- (bobp)
- (throw 'nesting 'unknown))
- )))))
- ;; Return type of block and indent level.
- (if (> par 0) ; Unclosed Parenthesis
- (list 'contexp par)
- (list type (pascal-indent-level))))))
-
-(defun pascal-indent-level ()
- "Return the indent-level the current statement has.
-Do not count labels, case-statements or records."
- (save-excursion
- (beginning-of-line)
- (if (looking-at "[ \t]*[0-9a-zA-Z]+[ \t]*:[^=]")
- (search-forward ":" nil t)
- (if (looking-at ".*=[ \t]*record\\>")
- (search-forward "=" nil t)))
- (skip-chars-forward " \t")
- (current-column)))
-
-(defun pascal-indent-comment (&optional arg)
- "Indent current line as comment.
-If optional arg is non-nil, just return the
-column number the line should be indented to."
- (let* ((stcol (save-excursion
- (re-search-backward "(\\*\\|{" nil t)
- (1+ (current-column)))))
- (if arg stcol
- (delete-horizontal-space)
- (indent-to stcol))))
-
-(defun pascal-indent-case ()
- "Indent within case statements."
- (skip-chars-forward ": \t")
- (let ((end (prog2
- (end-of-line)
- (point-marker)
- (re-search-backward "\\<case\\>" nil t)))
- (beg (point))
- (ind 0))
- ;; Get right indent
- (while (< (point) (marker-position end))
- (if (re-search-forward
- "^[ \t]*[^ \t,:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:"
- (marker-position end) 'move)
- (forward-char -1))
- (delete-horizontal-space)
- (if (> (current-column) ind)
- (setq ind (current-column)))
- (beginning-of-line 2))
- (goto-char beg)
- ;; Indent all case statements
- (while (< (point) (marker-position end))
- (if (re-search-forward
- "^[ \t]*[^ \t,:]+[ \t]*\\(,[ \t]*[^ \t,:]+[ \t]*\\)*:"
- (marker-position end) 'move)
- (forward-char -1))
- (indent-to (1+ ind))
- (if (/= (following-char) ?:)
- ()
- (forward-char 1)
- (delete-horizontal-space)
- (insert " ")))))
-
-(defun pascal-indent-paramlist (&optional arg)
- "Indent current line in parameterlist.
-If optional arg is non-nil, just return the
-indent of the current line in parameterlist."
- (save-excursion
- (let* ((oldpos (point))
- (stpos (progn (goto-char (scan-lists (point) -1 1)) (point)))
- (stcol (1+ (current-column)))
- (edpos (progn (pascal-declaration-end)
- (search-backward ")" (pascal-get-beg-of-line) t)
- (point)))
- (usevar (re-search-backward "\\<var\\>" stpos t)))
- (if arg (progn
- ;; If arg, just return indent
- (goto-char oldpos)
- (beginning-of-line)
- (if (or (not usevar) (looking-at "[ \t]*var\\>"))
- stcol (+ 4 stcol)))
- (goto-char stpos)
- (forward-char 1)
- (delete-horizontal-space)
- (if (and usevar (not (looking-at "var\\>")))
- (indent-to (+ 4 stcol)))
- (pascal-indent-declaration nil stpos edpos)))))
-
-(defun pascal-indent-declaration (&optional arg start end)
- "Indent current lines as declaration, lining up the `:'s or `='s."
- (let ((pos (point-marker)))
- (if (and (not (or arg start)) (not (pascal-declaration-beg)))
- ()
- (let ((lineup (if (or (looking-at "\\<var\\>\\|\\<record\\>") arg start)
- ":" "="))
- (stpos (if start start
- (forward-word 2) (backward-word 1) (point)))
- (edpos (set-marker (make-marker)
- (if end end
- (max (progn (pascal-declaration-end)
- (point))
- pos))))
- ind)
-
- (goto-char stpos)
- ;; Indent lines in record block
- (if arg
- (while (<= (point) (marker-position edpos))
- (beginning-of-line)
- (delete-horizontal-space)
- (if (looking-at "end\\>")
- (indent-to arg)
- (indent-to (+ arg pascal-indent-level)))
- (forward-line 1)))
-
- ;; Do lineup
- (setq ind (pascal-get-lineup-indent stpos edpos lineup))
- (goto-char stpos)
- (while (<= (point) (marker-position edpos))
- (if (search-forward lineup (pascal-get-end-of-line) 'move)
- (forward-char -1))
- (delete-horizontal-space)
- (indent-to ind)
- (if (not (looking-at lineup))
- (forward-line 1) ; No more indent if there is no : or =
- (forward-char 1)
- (delete-horizontal-space)
- (insert " ")
- ;; Indent record block
- (if (looking-at "record\\>")
- (pascal-indent-declaration (current-column)))
- (forward-line 1)))))
-
- ;; If arg - move point
- (if arg (forward-line -1)
- (goto-char (marker-position pos)))))
-
-; "Return the indent level that will line up several lines within the region
-;from b to e nicely. The lineup string is str."
-(defun pascal-get-lineup-indent (b e str)
- (save-excursion
- (let ((ind 0)
- (reg (concat str "\\|\\(\\<record\\>\\)"))
- nest)
- (goto-char b)
- ;; Get rightmost position
- (while (< (point) e)
- (setq nest 1)
- (if (re-search-forward reg (min e (pascal-get-end-of-line 2)) 'move)
- ;; Skip record blocks
- (if (match-beginning 1)
- (pascal-declaration-end)
- (progn
- (goto-char (match-beginning 0))
- (skip-chars-backward " \t")
- (if (> (current-column) ind)
- (setq ind (current-column)))
- (end-of-line)))))
- ;; In case no lineup was found
- (if (> ind 0)
- (1+ ind)
- ;; No lineup-string found
- (goto-char b)
- (end-of-line)
- (skip-chars-backward " \t")
- (1+ (current-column))))))
-
-
-
-;;;
-;;; Completion
-;;;
-(defun pascal-string-diff (str1 str2)
- "Return index of first letter where STR1 and STR2 differs."
- (catch 'done
- (let ((diff 0))
- (while t
- (if (or (> (1+ diff) (length str1))
- (> (1+ diff) (length str2)))
- (throw 'done diff))
- (or (equal (aref str1 diff) (aref str2 diff))
- (throw 'done diff))
- (setq diff (1+ diff))))))
-
-;; Calculate all possible completions for functions if argument is `function',
-;; completions for procedures if argument is `procedure' or both functions and
-;; procedures otherwise.
-
-(defun pascal-func-completion (type)
- ;; Build regular expression for function/procedure names
- (if (string= str "")
- (setq str "[a-zA-Z_]"))
- (let ((str (concat (cond ((eq type 'procedure) "\\<\\(procedure\\)\\s +")
- ((eq type 'function) "\\<\\(function\\)\\s +")
- (t "\\<\\(function\\|procedure\\)\\s +"))
- "\\<\\(" str "[a-zA-Z0-9_.]*\\)\\>"))
- match)
-
- (if (not (looking-at "\\<\\(function\\|procedure\\)\\>"))
- (re-search-backward "\\<\\(function\\|procedure\\)\\>" nil t))
- (forward-char 1)
-
- ;; Search through all reachable functions
- (while (pascal-beg-of-defun)
- (if (re-search-forward str (pascal-get-end-of-line) t)
- (progn (setq match (buffer-substring (match-beginning 2)
- (match-end 2)))
- (if (or (null predicate)
- (funcall prdicate match))
- (setq all (cons match all)))))
- (goto-char (match-beginning 0)))))
-
-(defun pascal-get-completion-decl ()
- ;; Macro for searching through current declaration (var, type or const)
- ;; for matches of `str' and adding the occurence tp `all'
- (let ((end (save-excursion (pascal-declaration-end)
- (point)))
- match)
- ;; Traverse lines
- (while (< (point) end)
- (if (re-search-forward "[:=]" (pascal-get-end-of-line) t)
- ;; Traverse current line
- (while (and (re-search-backward
- (concat "\\((\\|\\<\\(var\\|type\\|const\\)\\>\\)\\|"
- pascal-symbol-re)
- (pascal-get-beg-of-line) t)
- (not (match-end 1)))
- (setq match (buffer-substring (match-beginning 0) (match-end 0)))
- (if (string-match (concat "\\<" str) match)
- (if (or (null predicate)
- (funcall predicate match))
- (setq all (cons match all))))))
- (if (re-search-forward "\\<record\\>" (pascal-get-end-of-line) t)
- (pascal-declaration-end)
- (forward-line 1)))))
-
-(defun pascal-type-completion ()
- "Calculate all possible completions for types."
- (let ((start (point))
- goon)
- ;; Search for all reachable type declarations
- (while (or (pascal-beg-of-defun)
- (setq goon (not goon)))
- (save-excursion
- (if (and (< start (prog1 (save-excursion (pascal-end-of-defun)
- (point))
- (forward-char 1)))
- (re-search-forward
- "\\<type\\>\\|\\<\\(begin\\|function\\|proceudre\\)\\>"
- start t)
- (not (match-end 1)))
- ;; Check current type declaration
- (pascal-get-completion-decl))))))
-
-(defun pascal-var-completion ()
- "Calculate all possible completions for variables (or constants)."
- (let ((start (point))
- goon twice)
- ;; Search for all reachable var declarations
- (while (or (pascal-beg-of-defun)
- (setq goon (not goon)))
- (save-excursion
- (if (> start (prog1 (save-excursion (pascal-end-of-defun)
- (point))))
- () ; Declarations not reacable
- (if (search-forward "(" (pascal-get-end-of-line) t)
- ;; Check parameterlist
- (pascal-get-completion-decl))
- (setq twice 2)
- (while (>= (setq twice (1- twice)) 0)
- (cond ((and (re-search-forward
- (concat "\\<\\(var\\|const\\)\\>\\|"
- "\\<\\(begin\\|function\\|procedure\\)\\>")
- start t)
- (not (match-end 2)))
- ;; Check var/const declarations
- (pascal-get-completion-decl))
- ((match-end 2)
- (setq twice 0)))))))))
-
-
-(defun pascal-keyword-completion (keyword-list)
- "Give list of all possible completions of keywords in KEYWORD-LIST."
- (mapcar '(lambda (s)
- (if (string-match (concat "\\<" str) s)
- (if (or (null predicate)
- (funcall predicate s))
- (setq all (cons s all)))))
- keyword-list))
-
-;; Function passed to completing-read, try-completion or
-;; all-completions to get completion on STR. If predicate is non-nil,
-;; it must be a function to be called for every match to check if this
-;; should really be a match. If flag is t, the function returns a list
-;; of all possible completions. If it is nil it returns a string, the
-;; longest possible completion, or t if STR is an exact match. If flag
-;; is 'lambda, the function returns t if STR is an exact match, nil
-;; otherwise.
-
-(defun pascal-completion (str predicate flag)
- (save-excursion
- (let ((all nil))
- ;; Set buffer to use for searching labels. This should be set
- ;; within functins which use pascal-completions
- (set-buffer buffer-to-use)
-
- ;; Determine what should be completed
- (let ((state (car (pascal-calculate-indent))))
- (cond (;--Within a declaration or parameterlist
- (or (eq state 'declaration) (eq state 'paramlist)
- (and (eq state 'defun)
- (save-excursion
- (re-search-backward ")[ \t]*:" (pascal-get-beg-of-line) t))))
- (if (or (eq state 'paramlist) (eq state 'defun))
- (pascal-beg-of-defun))
- (pascal-type-completion)
- (pascal-keyword-completion pascal-type-keywords))
- (;--Starting a new statement
- (and (not (eq state 'contexp))
- (save-excursion
- (skip-chars-backward "a-zA-Z0-9_.")
- (backward-sexp 1)
- (or (looking-at pascal-nosemi-re)
- (progn
- (forward-sexp 1)
- (looking-at "\\s *\\(;\\|:[^=]\\)")))))
- (save-excursion (pascal-var-completion))
- (pascal-func-completion 'procedure)
- (pascal-keyword-completion pascal-start-keywords))
- (t;--Anywhere else
- (save-excursion (pascal-var-completion))
- (pascal-func-completion 'function)
- (pascal-keyword-completion pascal-separator-keywords))))
-
- ;; Now we have built a list of all matches. Give response to caller
- (pascal-completion-response))))
-
-(defun pascal-completion-response ()
- (cond ((or (equal flag 'lambda) (null flag))
- ;; This was not called by all-completions
- (if (null all)
- ;; Return nil if there was no matching label
- nil
- ;; Get longest string common in the labels
- (let* ((elm (cdr all))
- (match (car all))
- (min (length match))
- exact tmp)
- (if (string= match str)
- ;; Return t if first match was an exact match
- (setq match t)
- (while (not (null elm))
- ;; Find longest common string
- (if (< (setq tmp (pascal-string-diff match (car elm))) min)
- (progn
- (setq min tmp)
- (setq match (substring match 0 min))))
- ;; Terminate with match=t if this is an exact match
- (if (string= (car elm) str)
- (progn
- (setq match t)
- (setq elm nil))
- (setq elm (cdr elm)))))
- ;; If this is a test just for exact match, return nil ot t
- (if (and (equal flag 'lambda) (not (equal match 't)))
- nil
- match))))
- ;; If flag is t, this was called by all-completions. Return
- ;; list of all possible completions
- (flag
- all)))
-
-(defvar pascal-last-word-numb 0)
-(defvar pascal-last-word-shown nil)
-(defvar pascal-last-completions nil)
-
-(defun pascal-complete-word ()
- "Complete word at current point.
-\(See also `pascal-toggle-completions', `pascal-type-keywords',
-`pascal-start-keywords' and `pascal-separator-keywords'.)"
- (interactive)
- (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
- (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
- (str (buffer-substring b e))
- ;; The following variable is used in pascal-completion
- (buffer-to-use (current-buffer))
- (allcomp (if (and pascal-toggle-completions
- (string= pascal-last-word-shown str))
- pascal-last-completions
- (all-completions str 'pascal-completion)))
- (match (if pascal-toggle-completions
- "" (try-completion
- str (mapcar '(lambda (elm) (cons elm 0)) allcomp)))))
- ;; Delete old string
- (delete-region b e)
-
- ;; Toggle-completions inserts whole labels
- (if pascal-toggle-completions
- (progn
- ;; Update entry number in list
- (setq pascal-last-completions allcomp
- pascal-last-word-numb
- (if (>= pascal-last-word-numb (1- (length allcomp)))
- 0
- (1+ pascal-last-word-numb)))
- (setq pascal-last-word-shown (elt allcomp pascal-last-word-numb))
- ;; Display next match or same string if no match was found
- (if (not (null allcomp))
- (insert "" pascal-last-word-shown)
- (insert "" str)
- (message "(No match)")))
- ;; The other form of completion does not necessarly do that.
-
- ;; Insert match if found, or the original string if no match
- (if (or (null match) (equal match 't))
- (progn (insert "" str)
- (message "(No match)"))
- (insert "" match))
- ;; Give message about current status of completion
- (cond ((equal match 't)
- (if (not (null (cdr allcomp)))
- (message "(Complete but not unique)")
- (message "(Sole completion)")))
- ;; Display buffer if the current completion didn't help
- ;; on completing the label.
- ((and (not (null (cdr allcomp))) (= (length str) (length match)))
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list allcomp))
- ;; Wait for a keypress. Then delete *Completion* window
- (momentary-string-display "" (point))
- (delete-window (get-buffer-window (get-buffer "*Completions*")))
- )))))
-
-(defun pascal-show-completions ()
- "Show all possible completions at current point."
- (interactive)
- (let* ((b (save-excursion (skip-chars-backward "a-zA-Z0-9_") (point)))
- (e (save-excursion (skip-chars-forward "a-zA-Z0-9_") (point)))
- (str (buffer-substring b e))
- ;; The following variable is used in pascal-completion
- (buffer-to-use (current-buffer))
- (allcomp (if (and pascal-toggle-completions
- (string= pascal-last-word-shown str))
- pascal-last-completions
- (all-completions str 'pascal-completion))))
- ;; Show possible completions in a temporary buffer.
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list allcomp))
- ;; Wait for a keypress. Then delete *Completion* window
- (momentary-string-display "" (point))
- (delete-window (get-buffer-window (get-buffer "*Completions*")))))
-
-
-(defun pascal-get-default-symbol ()
- "Return symbol around current point as a string."
- (save-excursion
- (buffer-substring (progn
- (skip-chars-backward " \t")
- (skip-chars-backward "a-zA-Z0-9_")
- (point))
- (progn
- (skip-chars-forward "a-zA-Z0-9_")
- (point)))))
-
-(defun pascal-build-defun-re (str &optional arg)
- "Return function/procedure starting with STR as regular expression.
-With optional second arg non-nil, STR is the complete name of the instruction."
- (if arg
- (concat "^\\(function\\|procedure\\)[ \t]+\\(" str "\\)\\>")
- (concat "^\\(function\\|procedure\\)[ \t]+\\(" str "[a-zA-Z0-9_]*\\)\\>")))
-
-;; Function passed to completing-read, try-completion or
-;; all-completions to get completion on any function name. If
-;; predicate is non-nil, it must be a function to be called for every
-;; match to check if this should really be a match. If flag is t, the
-;; function returns a list of all possible completions. If it is nil
-;; it returns a string, the longest possible completion, or t if STR
-;; is an exact match. If flag is 'lambda, the function returns t if
-;; STR is an exact match, nil otherwise.
-
-(defun pascal-comp-defun (str predicate flag)
- (save-excursion
- (let ((all nil)
- match)
-
- ;; Set buffer to use for searching labels. This should be set
- ;; within functins which use pascal-completions
- (set-buffer buffer-to-use)
-
- (let ((str str))
- ;; Build regular expression for functions
- (if (string= str "")
- (setq str (pascal-build-defun-re "[a-zA-Z_]"))
- (setq str (pascal-build-defun-re str)))
- (goto-char (point-min))
-
- ;; Build a list of all possible completions
- (while (re-search-forward str nil t)
- (setq match (buffer-substring (match-beginning 2) (match-end 2)))
- (if (or (null predicate)
- (funcall predicate match))
- (setq all (cons match all)))))
-
- ;; Now we have built a list of all matches. Give response to caller
- (pascal-completion-response))))
-
-(defun pascal-goto-defun ()
- "Move to specified Pascal function/procedure.
-The default is a name found in the buffer around point."
- (interactive)
- (let* ((default (pascal-get-default-symbol))
- ;; The following variable is used in pascal-comp-function
- (buffer-to-use (current-buffer))
- (default (if (pascal-comp-defun default nil 'lambda)
- default ""))
- (label (if (not (string= default ""))
- ;; Do completion with default
- (completing-read (concat "Label: (default " default ") ")
- 'pascal-comp-defun nil t "")
- ;; There is no default value. Complete without it
- (completing-read "Label: "
- 'pascal-comp-defun nil t ""))))
- ;; If there was no response on prompt, use default value
- (if (string= label "")
- (setq label default))
- ;; Goto right place in buffer if label is not an empty string
- (or (string= label "")
- (progn
- (goto-char (point-min))
- (re-search-forward (pascal-build-defun-re label t))
- (beginning-of-line)))))
-
-
-
-;;;
-;;; Pascal-outline-mode
-;;;
-(defvar pascal-outline-map nil "Keymap used in Pascal Outline mode.")
-
-(if pascal-outline-map
- nil
- (if (boundp 'set-keymap-name)
- (set-keymap-name pascal-outline-map 'pascal-outline-map))
- (if (not (boundp 'set-keymap-parent))
- (setq pascal-outline-map (copy-keymap pascal-mode-map))
- (setq pascal-outline-map (make-sparse-keymap))
- (set-keymap-parent pascal-outline-map pascal-mode-map))
- (define-key pascal-outline-map "\e\C-a" 'pascal-outline-prev-defun)
- (define-key pascal-outline-map "\e\C-e" 'pascal-outline-next-defun)
- (define-key pascal-outline-map "\C-cg" 'pascal-outline-goto-defun)
- (define-key pascal-outline-map "\C-c\C-s" 'pascal-show-all)
- (define-key pascal-outline-map "\C-c\C-h" 'pascal-hide-other-defuns))
-
-(defvar pascal-outline-mode nil "Non-nil while using Pascal Outline mode.")
-(make-variable-buffer-local 'pascal-outline-mode)
-(set-default 'pascal-outline-mode nil)
-(if (not (assoc 'pascal-outline-mode minor-mode-alist))
- (setq minor-mode-alist (append minor-mode-alist
- (list '(pascal-outline-mode " Outl")))))
-
-(defun pascal-outline (&optional arg)
- "Outline-line minor mode for Pascal mode.
-When in Pascal Outline mode, portions
-of the text being edited may be made invisible. \\<pascal-outline-map>
-
-Pascal Outline mode provides some additional commands.
-
-\\[pascal-outline-prev-defun]\
-\t- Move to previous function/procedure, hiding everything else.
-\\[pascal-outline-next-defun]\
-\t- Move to next function/procedure, hiding everything else.
-\\[pascal-outline-goto-defun]\
-\t- Goto function/procedure prompted for in minibuffer,
-\t hide all other functions.
-\\[pascal-show-all]\t- Show the whole buffer.
-\\[pascal-hide-other-defuns]\
-\t- Hide everything but the current function (function under the cursor).
-\\[pascal-outline]\t- Leave pascal-outline-mode."
- (interactive "P")
- (setq pascal-outline-mode
- (if (null arg) (not pascal-outline-mode) t))
- (if (boundp 'redraw-mode-line)
- (redraw-mode-line))
- (if pascal-outline-mode
- (progn
- (setq selective-display t)
- (use-local-map pascal-outline-map))
- (progn
- (setq selective-display nil)
- (pascal-show-all)
- (use-local-map pascal-mode-map))))
-
-(defun pascal-outline-change (b e flag)
- (let ((modp (buffer-modified-p)))
- (unwind-protect
- (subst-char-in-region b e (if (= flag ?\n) ?\^M ?\n) flag)
- (set-buffer-modified-p modp))))
-
-(defun pascal-show-all ()
- "Show all of the text in the buffer."
- (interactive)
- (pascal-outline-change (point-min) (point-max) ?\n))
-
-(defun pascal-hide-other-defuns ()
- "Show only the current defun."
- (interactive)
- (save-excursion
- (let ((beg (progn (if (not (looking-at "\\(function\\|procedure\\)\\>"))
- (pascal-beg-of-defun))
- (point)))
- (end (progn (pascal-end-of-defun)
- (backward-sexp 1)
- (search-forward "\n\\|\^M" nil t)
- (point)))
- (opoint (point-min)))
- (goto-char (point-min))
-
- ;; Hide all functions before current function
- (while (re-search-forward "^\\(function\\|procedure\\)\\>" beg 'move)
- (pascal-outline-change opoint (1- (match-beginning 0)) ?\^M)
- (setq opoint (point))
- ;; Functions may be nested
- (if (> (progn (pascal-end-of-defun) (point)) beg)
- (goto-char opoint)))
- (if (> beg opoint)
- (pascal-outline-change opoint (1- beg) ?\^M))
-
- ;; Show current function
- (pascal-outline-change beg end ?\n)
- ;; Hide nested functions
- (forward-char 1)
- (while (re-search-forward "^\\(function\\|procedure\\)\\>" end 'move)
- (setq opoint (point))
- (pascal-end-of-defun)
- (pascal-outline-change opoint (point) ?\^M))
-
- (goto-char end)
- (setq opoint end)
-
- ;; Hide all function after current function
- (while (re-search-forward "^\\(function\\|procedure\\)\\>" nil 'move)
- (pascal-outline-change opoint (1- (match-beginning 0)) ?\^M)
- (setq opoint (point))
- (pascal-end-of-defun))
- (pascal-outline-change opoint (point-max) ?\^M)
-
- ;; Hide main program
- (if (< (progn (forward-line -1) (point)) end)
- (progn
- (goto-char beg)
- (pascal-end-of-defun)
- (backward-sexp 1)
- (pascal-outline-change (point) (point-max) ?\^M))))))
-
-(defun pascal-outline-next-defun ()
- "Move to next function/procedure, hiding all others."
- (interactive)
- (pascal-end-of-defun)
- (pascal-hide-other-defuns))
-
-(defun pascal-outline-prev-defun ()
- "Move to previous function/procedure, hiding all others."
- (interactive)
- (pascal-beg-of-defun)
- (pascal-hide-other-defuns))
-
-(defun pascal-outline-goto-defun ()
- "Move to specified function/procedure, hiding all others."
- (interactive)
- (pascal-goto-defun)
- (pascal-hide-other-defuns))
-
-;;; pascal.el ends here
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
deleted file mode 100644
index ac2c260ad0b..00000000000
--- a/lisp/progmodes/perl-mode.el
+++ /dev/null
@@ -1,641 +0,0 @@
-;;; perl-mode.el --- Perl code editing commands for GNU Emacs
-
-;; Copyright (C) 1990 Free Software Foundation, Inc.
-
-;; Author: William F. Mann
-;; Adapted-By: ESR
-;; Keywords: languages
-
-;; Adapted from C code editing commands 'c-mode.el', Copyright 1987 by the
-;; Free Software Foundation, under terms of its General Public License.
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; To enter perl-mode automatically, add (autoload 'perl-mode "perl-mode")
-;; to your .emacs file and change the first line of your perl script to:
-;; #!/usr/bin/perl -- # -*-Perl-*-
-;; With argments to perl:
-;; #!/usr/bin/perl -P- # -*-Perl-*-
-;; To handle files included with do 'filename.pl';, add something like
-;; (setq auto-mode-alist (append (list (cons "\\.pl$" 'perl-mode))
-;; auto-mode-alist))
-;; to your .emacs file; otherwise the .pl suffix defaults to prolog-mode.
-
-;; This code is based on the 18.53 version c-mode.el, with extensive
-;; rewriting. Most of the features of c-mode survived intact.
-
-;; I added a new feature which adds functionality to TAB; it is controlled
-;; by the variable perl-tab-to-comment. With it enabled, TAB does the
-;; first thing it can from the following list: change the indentation;
-;; move past leading white space; delete an empty comment; reindent a
-;; comment; move to end of line; create an empty comment; tell you that
-;; the line ends in a quoted string, or has a # which should be a \#.
-
-;; If your machine is slow, you may want to remove some of the bindings
-;; to electric-perl-terminator. I changed the indenting defaults to be
-;; what Larry Wall uses in perl/lib, but left in all the options.
-
-;; I also tuned a few things: comments and labels starting in column
-;; zero are left there by indent-perl-exp; perl-beginning-of-function
-;; goes back to the first open brace/paren in column zero, the open brace
-;; in 'sub ... {', or the equal sign in 'format ... ='; indent-perl-exp
-;; (meta-^q) indents from the current line through the close of the next
-;; brace/paren, so you don't need to start exactly at a brace or paren.
-
-;; It may be good style to put a set of redundant braces around your
-;; main program. This will let you reindent it with meta-^q.
-
-;; Known problems (these are all caused by limitations in the Emacs Lisp
-;; parsing routine (parse-partial-sexp), which was not designed for such
-;; a rich language; writing a more suitable parser would be a big job):
-;; 1) Regular expression delimiters do not act as quotes, so special
-;; characters such as `'"#:;[](){} may need to be backslashed
-;; in regular expressions and in both parts of s/// and tr///.
-;; 2) The globbing syntax <pattern> is not recognized, so special
-;; characters in the pattern string must be backslashed.
-;; 3) The q, qq, and << quoting operators are not recognized; see below.
-;; 4) \ (backslash) always quotes the next character, so '\' is
-;; treated as the start of a string. Use "\\" as a work-around.
-;; 5) To make variables such a $' and $#array work, perl-mode treats
-;; $ just like backslash, so '$' is the same as problem 5.
-;; 6) Unfortunately, treating $ like \ makes ${var} be treated as an
-;; unmatched }. See below.
-;; 7) When ' (quote) is used as a package name separator, perl-mode
-;; doesn't understand, and thinks it is seeing a quoted string.
-
-;; Here are some ugly tricks to bypass some of these problems: the perl
-;; expression /`/ (that's a back-tick) usually evaluates harmlessly,
-;; but will trick perl-mode into starting a quoted string, which
-;; can be ended with another /`/. Assuming you have no embedded
-;; back-ticks, this can used to help solve problem 3:
-;;
-;; /`/; $ugly = q?"'$?; /`/;
-;;
-;; To solve problem 6, add a /{/; before each use of ${var}:
-;; /{/; while (<${glob_me}>) ...
-;;
-;; Problem 7 is even worse, but this 'fix' does work :-(
-;; $DB'stop#'
-;; [$DB'line#'
-;; ] =~ s/;9$//;
-
-;;; Code:
-
-(defvar perl-mode-abbrev-table nil
- "Abbrev table in use in perl-mode buffers.")
-(define-abbrev-table 'perl-mode-abbrev-table ())
-
-(defvar perl-mode-map ()
- "Keymap used in Perl mode.")
-(if perl-mode-map
- ()
- (setq perl-mode-map (make-sparse-keymap))
- (define-key perl-mode-map "{" 'electric-perl-terminator)
- (define-key perl-mode-map "}" 'electric-perl-terminator)
- (define-key perl-mode-map ";" 'electric-perl-terminator)
- (define-key perl-mode-map ":" 'electric-perl-terminator)
- (define-key perl-mode-map "\e\C-a" 'perl-beginning-of-function)
- (define-key perl-mode-map "\e\C-e" 'perl-end-of-function)
- (define-key perl-mode-map "\e\C-h" 'mark-perl-function)
- (define-key perl-mode-map "\e\C-q" 'indent-perl-exp)
- (define-key perl-mode-map "\177" 'backward-delete-char-untabify)
- (define-key perl-mode-map "\t" 'perl-indent-command))
-
-(autoload 'c-macro-expand "cmacexp"
- "Display the result of expanding all C macros occurring in the region.
-The expansion is entirely correct because it uses the C preprocessor."
- t)
-
-(defvar perl-mode-syntax-table nil
- "Syntax table in use in perl-mode buffers.")
-
-(if perl-mode-syntax-table
- ()
- (setq perl-mode-syntax-table (make-syntax-table (standard-syntax-table)))
- (modify-syntax-entry ?\n ">" perl-mode-syntax-table)
- (modify-syntax-entry ?# "<" perl-mode-syntax-table)
- (modify-syntax-entry ?$ "/" perl-mode-syntax-table)
- (modify-syntax-entry ?% "." perl-mode-syntax-table)
- (modify-syntax-entry ?& "." perl-mode-syntax-table)
- (modify-syntax-entry ?\' "\"" perl-mode-syntax-table)
- (modify-syntax-entry ?* "." perl-mode-syntax-table)
- (modify-syntax-entry ?+ "." perl-mode-syntax-table)
- (modify-syntax-entry ?- "." perl-mode-syntax-table)
- (modify-syntax-entry ?/ "." perl-mode-syntax-table)
- (modify-syntax-entry ?< "." perl-mode-syntax-table)
- (modify-syntax-entry ?= "." perl-mode-syntax-table)
- (modify-syntax-entry ?> "." perl-mode-syntax-table)
- (modify-syntax-entry ?\\ "\\" perl-mode-syntax-table)
- (modify-syntax-entry ?` "\"" perl-mode-syntax-table)
- (modify-syntax-entry ?| "." perl-mode-syntax-table)
-)
-
-(defvar perl-indent-level 4
- "*Indentation of Perl statements with respect to containing block.")
-(defvar perl-continued-statement-offset 4
- "*Extra indent for lines not starting new statements.")
-(defvar perl-continued-brace-offset -4
- "*Extra indent for substatements that start with open-braces.
-This is in addition to `perl-continued-statement-offset'.")
-(defvar perl-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context.")
-(defvar perl-brace-imaginary-offset 0
- "*Imagined indentation of an open brace that actually follows a statement.")
-(defvar perl-label-offset -2
- "*Offset of Perl label lines relative to usual indentation.")
-
-(defvar perl-tab-always-indent t
- "*Non-nil means TAB in Perl mode always indents the current line.
-Otherwise it inserts a tab character if you type it past the first
-nonwhite character on the line.")
-
-(defvar perl-tab-to-comment t
- "*Non-nil means TAB moves to eol or makes a comment in some cases.
-For lines which don't need indenting, TAB either indents an
-existing comment, moves to end-of-line, or if at end-of-line already,
-create a new comment.")
-
-(defvar perl-nochange ";?#\\|\f\\|\\s(\\|\\(\\w\\|\\s_\\)+:"
- "*Lines starting with this regular expression are not auto-indented.")
-
-;;;###autoload
-(defun perl-mode ()
- "Major mode for editing Perl code.
-Expression and list commands understand all Perl brackets.
-Tab indents for Perl code.
-Comments are delimited with # ... \\n.
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-\\{perl-mode-map}
-Variables controlling indentation style:
- perl-tab-always-indent
- Non-nil means TAB in Perl mode should always indent the current line,
- regardless of where in the line point is when the TAB command is used.
- perl-tab-to-comment
- Non-nil means that for lines which don't need indenting, TAB will
- either delete an empty comment, indent an existing comment, move
- to end-of-line, or if at end-of-line already, create a new comment.
- perl-nochange
- Lines starting with this regular expression are not auto-indented.
- perl-indent-level
- Indentation of Perl statements within surrounding block.
- The surrounding block's indentation is the indentation
- of the line on which the open-brace appears.
- perl-continued-statement-offset
- Extra indentation given to a substatement, such as the
- then-clause of an if or body of a while.
- perl-continued-brace-offset
- Extra indentation given to a brace that starts a substatement.
- This is in addition to `perl-continued-statement-offset'.
- perl-brace-offset
- Extra indentation for line if it starts with an open brace.
- perl-brace-imaginary-offset
- An open brace following other text is treated as if it were
- this far to the right of the start of its line.
- perl-label-offset
- Extra indentation for line that is a label.
-
-Various indentation styles: K&R BSD BLK GNU LW
- perl-indent-level 5 8 0 2 4
- perl-continued-statement-offset 5 8 4 2 4
- perl-continued-brace-offset 0 0 0 0 -4
- perl-brace-offset -5 -8 0 0 0
- perl-brace-imaginary-offset 0 0 4 0 0
- perl-label-offset -5 -8 -2 -2 -2
-
-Turning on Perl mode runs the normal hook `perl-mode-hook'."
- (interactive)
- (kill-all-local-variables)
- (use-local-map perl-mode-map)
- (setq major-mode 'perl-mode)
- (setq mode-name "Perl")
- (setq local-abbrev-table perl-mode-abbrev-table)
- (set-syntax-table perl-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'perl-indent-line)
- (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 "")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *")
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'perl-comment-indent)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (run-hooks 'perl-mode-hook))
-
-;; This is used by indent-for-comment
-;; to decide how much to indent a comment in Perl code
-;; based on its context.
-(defun perl-comment-indent ()
- (if (and (bolp) (not (eolp)))
- 0 ;Existing comment at bol stays there.
- (save-excursion
- (skip-chars-backward " \t")
- (max (1+ (current-column)) ;Else indent at comment column
- comment-column)))) ; except leave at least one space.
-
-(defun electric-perl-terminator (arg)
- "Insert character and adjust indentation.
-If at end-of-line, and not in a comment or a quote, correct the's indentation."
- (interactive "P")
- (let ((insertpos (point)))
- (and (not arg) ; decide whether to indent
- (eolp)
- (save-excursion
- (beginning-of-line)
- (and (not ; eliminate comments quickly
- (re-search-forward comment-start-skip insertpos t))
- (or (/= last-command-char ?:)
- ;; Colon is special only after a label ....
- (looking-at "\\s-*\\(\\w\\|\\s_\\)+$"))
- (let ((pps (parse-partial-sexp
- (perl-beginning-of-function) insertpos)))
- (not (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))
- (progn ; must insert, indent, delete
- (insert-char last-command-char 1)
- (perl-indent-line)
- (delete-char -1))))
- (self-insert-command (prefix-numeric-value arg)))
-
-;; not used anymore, but may be useful someday:
-;;(defun perl-inside-parens-p ()
-;; (condition-case ()
-;; (save-excursion
-;; (save-restriction
-;; (narrow-to-region (point)
-;; (perl-beginning-of-function))
-;; (goto-char (point-max))
-;; (= (char-after (or (scan-lists (point) -1 1) (point-min))) ?\()))
-;; (error nil)))
-
-(defun perl-indent-command (&optional arg)
- "Indent current line as Perl code, or optionally, insert a tab character.
-
-With an argument, indent the current line, regardless of other options.
-
-If `perl-tab-always-indent' is nil and point is not in the indentation
-area at the beginning of the line, simply insert a tab.
-
-Otherwise, indent the current line. If point was within the indentation
-area it is moved to the end of the indentation area. If the line was
-already indented properly and point was not within the indentation area,
-and if `perl-tab-to-comment' is non-nil (the default), then do the first
-possible action from the following list:
-
- 1) delete an empty comment
- 2) move forward to start of comment, indenting if necessary
- 3) move forward to end of line
- 4) create an empty comment
- 5) move backward to start of comment, indenting if necessary."
- (interactive "P")
- (if arg ; If arg, just indent this line
- (perl-indent-line "\f")
- (if (and (not perl-tab-always-indent)
- (<= (current-column) (current-indentation)))
- (insert-tab)
- (let (bof lsexp delta (oldpnt (point)))
- (beginning-of-line)
- (setq lsexp (point))
- (setq bof (perl-beginning-of-function))
- (goto-char oldpnt)
- (setq delta (perl-indent-line "\f\\|;?#" bof))
- (and perl-tab-to-comment
- (= oldpnt (point)) ; done if point moved
- (if (listp delta) ; if line starts in a quoted string
- (setq lsexp (or (nth 2 delta) bof))
- (= delta 0)) ; done if indenting occurred
- (let (eol state)
- (end-of-line)
- (setq eol (point))
- (if (= (char-after bof) ?=)
- (if (= oldpnt eol)
- (message "In a format statement"))
- (setq state (parse-partial-sexp lsexp eol))
- (if (nth 3 state)
- (if (= oldpnt eol) ; already at eol in a string
- (message "In a string which starts with a %c."
- (nth 3 state)))
- (if (not (nth 4 state))
- (if (= oldpnt eol) ; no comment, create one?
- (indent-for-comment))
- (beginning-of-line)
- (if (re-search-forward comment-start-skip eol 'move)
- (if (eolp)
- (progn ; kill existing comment
- (goto-char (match-beginning 0))
- (skip-chars-backward " \t")
- (kill-region (point) eol))
- (if (or (< oldpnt (point)) (= oldpnt eol))
- (indent-for-comment) ; indent existing comment
- (end-of-line)))
- (if (/= oldpnt eol)
- (end-of-line)
- (message "Use backslash to quote # characters.")
- (ding t))))))))))))
-
-(defun perl-indent-line (&optional nochange parse-start)
- "Indent current line as Perl code.
-Return the amount the indentation
-changed by, or (parse-state) if line starts in a quoted string."
- (let ((case-fold-search nil)
- (pos (- (point-max) (point)))
- (bof (or parse-start (save-excursion (perl-beginning-of-function))))
- beg indent shift-amt)
- (beginning-of-line)
- (setq beg (point))
- (setq shift-amt
- (cond ((= (char-after bof) ?=) 0)
- ((listp (setq indent (calculate-perl-indent bof))) indent)
- ((looking-at (or nochange perl-nochange)) 0)
- (t
- (skip-chars-forward " \t\f")
- (cond ((looking-at "\\(\\w\\|\\s_\\)+:")
- (setq indent (max 1 (+ indent perl-label-offset))))
- ((= (following-char) ?})
- (setq indent (- indent perl-indent-level)))
- ((= (following-char) ?{)
- (setq indent (+ indent perl-brace-offset))))
- (- indent (current-column)))))
- (skip-chars-forward " \t\f")
- (if (and (numberp shift-amt) (/= 0 shift-amt))
- (progn (delete-region beg (point))
- (indent-to indent)))
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- shift-amt))
-
-(defun calculate-perl-indent (&optional parse-start)
- "Return appropriate indentation for current line as Perl code.
-In usual case returns an integer: the column to indent to.
-Returns (parse-state) if line starts inside a string."
- (save-excursion
- (beginning-of-line)
- (let ((indent-point (point))
- (case-fold-search nil)
- (colon-line-end 0)
- state containing-sexp)
- (if parse-start ;used to avoid searching
- (goto-char parse-start)
- (perl-beginning-of-function))
- (while (< (point) indent-point) ;repeat until right sexp
- (setq parse-start (point))
- (setq state (parse-partial-sexp (point) indent-point 0))
-; state = (depth_in_parens innermost_containing_list last_complete_sexp
-; string_terminator_or_nil inside_commentp following_quotep
-; minimum_paren-depth_this_scan)
-; Parsing stops if depth in parentheses becomes equal to third arg.
- (setq containing-sexp (nth 1 state)))
- (cond ((nth 3 state) state) ; In a quoted string?
- ((null containing-sexp) ; Line is at top level.
- (skip-chars-forward " \t\f")
- (if (= (following-char) ?{)
- 0 ; move to beginning of line if it starts a function body
- ;; indent a little if this is a continuation line
- (perl-backward-to-noncomment)
- (if (or (bobp)
- (memq (preceding-char) '(?\; ?\})))
- 0 perl-continued-statement-offset)))
- ((/= (char-after containing-sexp) ?{)
- ;; line is expression, not statement:
- ;; indent to just after the surrounding open.
- (goto-char (1+ containing-sexp))
- (current-column))
- (t
- ;; Statement level. Is it a continuation or a new statement?
- ;; Find previous non-comment character.
- (perl-backward-to-noncomment)
- ;; Back up over label lines, since they don't
- ;; affect whether our line is a continuation.
- (while (or (eq (preceding-char) ?\,)
- (and (eq (preceding-char) ?:)
- (memq (char-syntax (char-after (- (point) 2)))
- '(?w ?_))))
- (if (eq (preceding-char) ?\,)
- (perl-backward-to-start-of-continued-exp containing-sexp))
- (beginning-of-line)
- (perl-backward-to-noncomment))
- ;; Now we get the answer.
- (if (not (memq (preceding-char) '(?\; ?\} ?\{)))
- ;; This line is continuation of preceding line's statement;
- ;; indent perl-continued-statement-offset more than the
- ;; previous line of the statement.
- (progn
- (perl-backward-to-start-of-continued-exp containing-sexp)
- (+ perl-continued-statement-offset (current-column)
- (if (save-excursion (goto-char indent-point)
- (looking-at "[ \t]*{"))
- perl-continued-brace-offset 0)))
- ;; This line starts a new statement.
- ;; Position at last unclosed open.
- (goto-char containing-sexp)
- (or
- ;; If open paren is in col 0, close brace is special
- (and (bolp)
- (save-excursion (goto-char indent-point)
- (looking-at "[ \t]*}"))
- perl-indent-level)
- ;; Is line first statement after an open-brace?
- ;; If no, find that first statement and indent like it.
- (save-excursion
- (forward-char 1)
- ;; Skip over comments and labels following openbrace.
- (while (progn
- (skip-chars-forward " \t\f\n")
- (cond ((looking-at ";?#")
- (forward-line 1) t)
- ((looking-at "\\(\\w\\|\\s_\\)+:")
- (save-excursion
- (end-of-line)
- (setq colon-line-end (point)))
- (search-forward ":")))))
- ;; The first following code counts
- ;; if it is before the line we want to indent.
- (and (< (point) indent-point)
- (if (> colon-line-end (point))
- (- (current-indentation) perl-label-offset)
- (current-column))))
- ;; If no previous statement,
- ;; indent it relative to line brace is on.
- ;; For open paren in column zero, don't let statement
- ;; start there too. If perl-indent-level is zero,
- ;; use perl-brace-offset + perl-continued-statement-offset
- ;; For open-braces not the first thing in a line,
- ;; add in perl-brace-imaginary-offset.
- (+ (if (and (bolp) (zerop perl-indent-level))
- (+ perl-brace-offset perl-continued-statement-offset)
- perl-indent-level)
- ;; Move back over whitespace before the openbrace.
- ;; If openbrace is not first nonwhite thing on the line,
- ;; add the perl-brace-imaginary-offset.
- (progn (skip-chars-backward " \t")
- (if (bolp) 0 perl-brace-imaginary-offset))
- ;; If the openbrace is preceded by a parenthesized exp,
- ;; move to the beginning of that;
- ;; possibly a different line
- (progn
- (if (eq (preceding-char) ?\))
- (forward-sexp -1))
- ;; Get initial indentation of the line we are on.
- (current-indentation))))))))))
-
-(defun perl-backward-to-noncomment ()
- "Move point backward to after the first non-white-space, skipping comments."
- (interactive)
- (let (opoint stop)
- (while (not stop)
- (setq opoint (point))
- (beginning-of-line)
- (if (re-search-forward comment-start-skip opoint 'move 1)
- (progn (goto-char (match-end 1))
- (skip-chars-forward ";")))
- (skip-chars-backward " \t\f")
- (setq stop (or (bobp)
- (not (bolp))
- (forward-char -1))))))
-
-(defun perl-backward-to-start-of-continued-exp (lim)
- (if (= (preceding-char) ?\))
- (forward-sexp -1))
- (beginning-of-line)
- (if (<= (point) lim)
- (goto-char (1+ lim)))
- (skip-chars-forward " \t\f"))
-
-;; note: this may be slower than the c-mode version, but I can understand it.
-(defun indent-perl-exp ()
- "Indent each line of the Perl grouping following point."
- (interactive)
- (let* ((case-fold-search nil)
- (oldpnt (point-marker))
- (bof-mark (save-excursion
- (end-of-line 2)
- (perl-beginning-of-function)
- (point-marker)))
- eol last-mark lsexp-mark delta)
- (if (= (char-after (marker-position bof-mark)) ?=)
- (message "Can't indent a format statement")
- (message "Indenting Perl expression...")
- (save-excursion (end-of-line) (setq eol (point)))
- (save-excursion ; locate matching close paren
- (while (and (not (eobp)) (<= (point) eol))
- (parse-partial-sexp (point) (point-max) 0))
- (setq last-mark (point-marker)))
- (setq lsexp-mark bof-mark)
- (beginning-of-line)
- (while (< (point) (marker-position last-mark))
- (setq delta (perl-indent-line nil (marker-position bof-mark)))
- (if (numberp delta) ; unquoted start-of-line?
- (progn
- (if (eolp)
- (delete-horizontal-space))
- (setq lsexp-mark (point-marker))))
- (end-of-line)
- (setq eol (point))
- (if (nth 4 (parse-partial-sexp (marker-position lsexp-mark) eol))
- (progn ; line ends in a comment
- (beginning-of-line)
- (if (or (not (looking-at "\\s-*;?#"))
- (listp delta)
- (and (/= 0 delta)
- (= (- (current-indentation) delta) comment-column)))
- (if (re-search-forward comment-start-skip eol t)
- (indent-for-comment))))) ; indent existing comment
- (forward-line 1))
- (goto-char (marker-position oldpnt))
- (message "Indenting Perl expression...done"))))
-
-(defun perl-beginning-of-function (&optional arg)
- "Move backward to next beginning-of-function, or as far as possible.
-With argument, repeat that many times; negative args move forward.
-Returns new value of point in all cases."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0) (forward-char 1))
- (and (/= arg 0)
- (re-search-backward "^\\s(\\|^\\s-*sub\\b[^{]+{\\|^\\s-*format\\b[^=]*=\\|^\\."
- nil 'move arg)
- (goto-char (1- (match-end 0))))
- (point))
-
-;; note: this routine is adapted directly from emacs lisp.el, end-of-defun;
-;; no bugs have been removed :-)
-(defun perl-end-of-function (&optional arg)
- "Move forward to next end-of-function.
-The end of a function is found by moving forward from the beginning of one.
-With argument, repeat that many times; negative args move backward."
- (interactive "p")
- (or arg (setq arg 1))
- (let ((first t))
- (while (and (> arg 0) (< (point) (point-max)))
- (let ((pos (point)) npos)
- (while (progn
- (if (and first
- (progn
- (forward-char 1)
- (perl-beginning-of-function 1)
- (not (bobp))))
- nil
- (or (bobp) (forward-char -1))
- (perl-beginning-of-function -1))
- (setq first nil)
- (forward-list 1)
- (skip-chars-forward " \t")
- (if (looking-at "[#\n]")
- (forward-line 1))
- (<= (point) pos))))
- (setq arg (1- arg)))
- (while (< arg 0)
- (let ((pos (point)))
- (perl-beginning-of-function 1)
- (forward-sexp 1)
- (forward-line 1)
- (if (>= (point) pos)
- (if (progn (perl-beginning-of-function 2) (not (bobp)))
- (progn
- (forward-list 1)
- (skip-chars-forward " \t")
- (if (looking-at "[#\n]")
- (forward-line 1)))
- (goto-char (point-min)))))
- (setq arg (1+ arg)))))
-
-(defun mark-perl-function ()
- "Put mark at end of Perl function, point at beginning."
- (interactive)
- (push-mark (point))
- (perl-end-of-function)
- (push-mark (point))
- (perl-beginning-of-function)
- (backward-paragraph))
-
-;;;;;;;; That's all, folks! ;;;;;;;;;
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
deleted file mode 100644
index 52b65113073..00000000000
--- a/lisp/progmodes/prolog.el
+++ /dev/null
@@ -1,271 +0,0 @@
-;;; prolog.el --- major mode for editing and running Prolog under Emacs
-
-;; Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; This package provides a major mode for editing Prolog. It knows
-;; about Prolog syntax and comments, and can send regions to an inferior
-;; Prolog interpreter process.
-
-;;; Code:
-
-(defvar prolog-mode-syntax-table nil)
-(defvar prolog-mode-abbrev-table nil)
-(defvar prolog-mode-map nil)
-
-(defvar prolog-program-name "prolog"
- "*Program name for invoking an inferior Prolog with `run-prolog'.")
-
-(defvar prolog-consult-string "reconsult(user).\n"
- "*(Re)Consult mode (for C-Prolog and Quintus Prolog). ")
-
-(defvar prolog-compile-string "compile(user).\n"
- "*Compile mode (for Quintus Prolog).")
-
-(defvar prolog-eof-string "end_of_file.\n"
- "*String that represents end of file for prolog.
-nil means send actual operating system end of file.")
-
-(defvar prolog-indent-width 4)
-
-(if prolog-mode-syntax-table
- ()
- (let ((table (make-syntax-table)))
- (modify-syntax-entry ?_ "w" table)
- (modify-syntax-entry ?\\ "\\" table)
- (modify-syntax-entry ?/ "." table)
- (modify-syntax-entry ?* "." table)
- (modify-syntax-entry ?+ "." table)
- (modify-syntax-entry ?- "." table)
- (modify-syntax-entry ?= "." table)
- (modify-syntax-entry ?% "<" table)
- (modify-syntax-entry ?< "." table)
- (modify-syntax-entry ?> "." table)
- (modify-syntax-entry ?\' "\"" table)
- (setq prolog-mode-syntax-table table)))
-
-(define-abbrev-table 'prolog-mode-abbrev-table ())
-
-(defun prolog-mode-variables ()
- (set-syntax-table prolog-mode-syntax-table)
- (setq local-abbrev-table prolog-mode-abbrev-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^%%\\|^$\\|" page-delimiter)) ;'%%..'
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'prolog-indent-line)
- (make-local-variable 'comment-start)
- (setq comment-start "%")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "%+ *")
- (make-local-variable 'comment-column)
- (setq comment-column 48)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'prolog-comment-indent))
-
-(defun prolog-mode-commands (map)
- (define-key map "\t" 'prolog-indent-line)
- (define-key map "\e\C-x" 'prolog-consult-region))
-
-(if prolog-mode-map
- nil
- (setq prolog-mode-map (make-sparse-keymap))
- (prolog-mode-commands prolog-mode-map))
-
-;;;###autoload
-(defun prolog-mode ()
- "Major mode for editing Prolog code for Prologs.
-Blank lines and `%%...' separate paragraphs. `%'s start comments.
-Commands:
-\\{prolog-mode-map}
-Entry to this mode calls the value of `prolog-mode-hook'
-if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (use-local-map prolog-mode-map)
- (setq major-mode 'prolog-mode)
- (setq mode-name "Prolog")
- (prolog-mode-variables)
- (run-hooks 'prolog-mode-hook))
-
-(defun prolog-indent-line (&optional whole-exp)
- "Indent current line as Prolog code.
-With argument, indent any additional lines of the same clause
-rigidly along with this one (not yet)."
- (interactive "p")
- (let ((indent (prolog-indent-level))
- (pos (- (point-max) (point))) beg)
- (beginning-of-line)
- (setq beg (point))
- (skip-chars-forward " \t")
- (if (zerop (- indent (current-column)))
- nil
- (delete-region beg (point))
- (indent-to indent))
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- ))
-
-(defun prolog-indent-level ()
- "Compute prolog indentation level."
- (save-excursion
- (beginning-of-line)
- (skip-chars-forward " \t")
- (cond
- ((looking-at "%%%") 0) ;Large comment starts
- ((looking-at "%[^%]") comment-column) ;Small comment starts
- ((bobp) 0) ;Beginning of buffer
- (t
- (let ((empty t) ind more less)
- (if (looking-at ")")
- (setq less t) ;Find close
- (setq less nil))
- ;; See previous indentation
- (while empty
- (forward-line -1)
- (beginning-of-line)
- (if (bobp)
- (setq empty nil)
- (skip-chars-forward " \t")
- (if (not (or (looking-at "%[^%]") (looking-at "\n")))
- (setq empty nil))))
- (if (bobp)
- (setq ind 0) ;Beginning of buffer
- (setq ind (current-column))) ;Beginning of clause
- ;; See its beginning
- (if (looking-at "%%[^%]")
- ind
- ;; Real prolog code
- (if (looking-at "(")
- (setq more t) ;Find open
- (setq more nil))
- ;; See its tail
- (end-of-prolog-clause)
- (or (bobp) (forward-char -1))
- (cond ((looking-at "[,(;>]")
- (if (and more (looking-at "[^,]"))
- (+ ind prolog-indent-width) ;More indentation
- (max tab-width ind))) ;Same indentation
- ((looking-at "-") tab-width) ;TAB
- ((or less (looking-at "[^.]"))
- (max (- ind prolog-indent-width) 0)) ;Less indentation
- (t 0)) ;No indentation
- )))
- )))
-
-(defun end-of-prolog-clause ()
- "Go to end of clause in this line."
- (beginning-of-line 1)
- (let* ((eolpos (save-excursion (end-of-line) (point))))
- (if (re-search-forward comment-start-skip eolpos 'move)
- (goto-char (match-beginning 0)))
- (skip-chars-backward " \t")))
-
-(defun prolog-comment-indent ()
- "Compute prolog comment indentation."
- (cond ((looking-at "%%%") 0)
- ((looking-at "%%") (prolog-indent-level))
- (t
- (save-excursion
- (skip-chars-backward " \t")
- ;; Insert one space at least, except at left margin.
- (max (+ (current-column) (if (bolp) 0 1))
- comment-column)))
- ))
-
-
-;;;
-;;; Inferior prolog mode
-;;;
-(defvar inferior-prolog-mode-map nil)
-
-(defun inferior-prolog-mode ()
- "Major mode for interacting with an inferior Prolog process.
-
-The following commands are available:
-\\{inferior-prolog-mode-map}
-
-Entry to this mode calls the value of `prolog-mode-hook' with no arguments,
-if that value is non-nil. Likewise with the value of `comint-mode-hook'.
-`prolog-mode-hook' is called after `comint-mode-hook'.
-
-You can send text to the inferior Prolog from other buffers
-using the commands `send-region', `send-string' and \\[prolog-consult-region].
-
-Commands:
-Tab indents for Prolog; with argument, shifts rest
- of expression rigidly with the current line.
-Paragraphs are separated only by blank lines and '%%'.
-'%'s start comments.
-
-Return at end of buffer sends line as input.
-Return not at end copies rest of line to end and sends it.
-\\[comint-kill-input] and \\[backward-kill-word] are kill commands, imitating normal Unix input editing.
-\\[comint-interrupt-subjob] interrupts the shell or its current subjob if any.
-\\[comint-stop-subjob] stops. \\[comint-quit-subjob] sends quit signal."
- (interactive)
- (require 'comint)
- (comint-mode)
- (setq major-mode 'inferior-prolog-mode
- mode-name "Inferior Prolog"
- comint-prompt-regexp "^| [ ?][- ] *")
- (prolog-mode-variables)
- (if inferior-prolog-mode-map nil
- (setq inferior-prolog-mode-map (copy-keymap comint-mode-map))
- (prolog-mode-commands inferior-prolog-mode-map))
- (use-local-map inferior-prolog-mode-map)
- (run-hooks 'prolog-mode-hook))
-
-;;;###autoload
-(defun run-prolog ()
- "Run an inferior Prolog process, input and output via buffer *prolog*."
- (interactive)
- (require 'comint)
- (switch-to-buffer (make-comint "prolog" prolog-program-name))
- (inferior-prolog-mode))
-
-(defun prolog-consult-region (compile beg end)
- "Send the region to the Prolog process made by \"M-x run-prolog\".
-If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
- (interactive "P\nr")
- (save-excursion
- (if compile
- (send-string "prolog" prolog-compile-string)
- (send-string "prolog" prolog-consult-string))
- (send-region "prolog" beg end)
- (send-string "prolog" "\n") ;May be unnecessary
- (if prolog-eof-string
- (send-string "prolog" prolog-eof-string)
- (process-send-eof "prolog")))) ;Send eof to prolog process.
-
-(defun prolog-consult-region-and-go (compile beg end)
- "Send the region to the inferior Prolog, and switch to *prolog* buffer.
-If COMPILE (prefix arg) is not nil, use compile mode rather than consult mode."
- (interactive "P\nr")
- (prolog-consult-region compile beg end)
- (switch-to-buffer "*prolog*"))
-
-;;; prolog.el ends here
diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
deleted file mode 100644
index caf74e3b3b9..00000000000
--- a/lisp/progmodes/scheme.el
+++ /dev/null
@@ -1,507 +0,0 @@
-;;; scheme.el --- Scheme mode, and its idiosyncratic commands.
-
-;; Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-;; Author: Bill Rozas <jinz@prep.ai.mit.edu>
-;; Keywords: languages, lisp
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; Adapted from Lisp mode by Bill Rozas, jinx@prep.
-;; Initially a query replace of Lisp mode, except for the indentation
-;; of special forms. Probably the code should be merged at some point
-;; so that there is sharing between both libraries.
-
-;;; Code:
-
-(defvar scheme-mode-syntax-table nil "")
-(if (not scheme-mode-syntax-table)
- (let ((i 0))
- (setq scheme-mode-syntax-table (make-syntax-table))
- (set-syntax-table scheme-mode-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 ? " ")
-
- ;; These characters are delimiters but otherwise undefined.
- ;; Brackets and braces balance for editing convenience.
- (modify-syntax-entry ?[ "(] ")
- (modify-syntax-entry ?] ")[ ")
- (modify-syntax-entry ?{ "(} ")
- (modify-syntax-entry ?} "){ ")
- (modify-syntax-entry ?\| " 23")
-
- ;; Other atom delimiters
- (modify-syntax-entry ?\( "() ")
- (modify-syntax-entry ?\) ")( ")
- (modify-syntax-entry ?\; "< ")
- (modify-syntax-entry ?\" "\" ")
- (modify-syntax-entry ?' " p")
- (modify-syntax-entry ?` " p")
-
- ;; Special characters
- (modify-syntax-entry ?, "_ p")
- (modify-syntax-entry ?@ "_ p")
- (modify-syntax-entry ?# "_ p14")
- (modify-syntax-entry ?\\ "\\ ")))
-
-(defvar scheme-mode-abbrev-table nil "")
-(define-abbrev-table 'scheme-mode-abbrev-table ())
-
-(defun scheme-mode-variables ()
- (set-syntax-table scheme-mode-syntax-table)
- (setq local-abbrev-table scheme-mode-abbrev-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'scheme-indent-line)
- (make-local-variable 'comment-start)
- (setq comment-start ";")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip ";+[ \t]*")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'scheme-comment-indent)
- (setq mode-line-process '("" scheme-mode-line-process)))
-
-(defvar scheme-mode-line-process "")
-
-(defun scheme-mode-commands (map)
- (define-key map "\t" 'scheme-indent-line)
- (define-key map "\177" 'backward-delete-char-untabify)
- (define-key map "\e\C-q" 'scheme-indent-sexp))
-
-(defvar scheme-mode-map nil)
-(if (not scheme-mode-map)
- (progn
- (setq scheme-mode-map (make-sparse-keymap))
- (scheme-mode-commands scheme-mode-map)))
-
-;;;###autoload
-(defun scheme-mode ()
- "Major mode for editing Scheme code.
-Editing commands are similar to those of lisp-mode.
-
-In addition, if an inferior Scheme process is running, some additional
-commands will be defined, for evaluating expressions and controlling
-the interpreter, and the state of the process will be displayed in the
-modeline of all Scheme buffers. The names of commands that interact
-with the Scheme process start with \"xscheme-\". For more information
-see the documentation for xscheme-interaction-mode.
-
-Commands:
-Delete converts tabs to spaces as it moves back.
-Blank lines separate paragraphs. Semicolons start comments.
-\\{scheme-mode-map}
-Entry to this mode calls the value of scheme-mode-hook
-if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (scheme-mode-initialize)
- (scheme-mode-variables)
- (run-hooks 'scheme-mode-hook))
-
-(defun scheme-mode-initialize ()
- (use-local-map scheme-mode-map)
- (setq major-mode 'scheme-mode)
- (setq mode-name "Scheme"))
-
-(defvar scheme-mit-dialect t
- "If non-nil, scheme mode is specialized for MIT Scheme.
-Set this to nil if you normally use another dialect.")
-
-(defun scheme-comment-indent (&optional pos)
- (save-excursion
- (if pos (goto-char pos))
- (cond ((looking-at ";;;") (current-column))
- ((looking-at ";;")
- (let ((tem (calculate-scheme-indent)))
- (if (listp tem) (car tem) tem)))
- (t
- (skip-chars-backward " \t")
- (max (if (bolp) 0 (1+ (current-column)))
- comment-column)))))
-
-(defvar scheme-indent-offset nil "")
-(defvar scheme-indent-function 'scheme-indent-function "")
-
-(defun scheme-indent-line (&optional whole-exp)
- "Indent current line as Scheme code.
-With argument, indent any additional lines of the same expression
-rigidly along with this one."
- (interactive "P")
- (let ((indent (calculate-scheme-indent)) shift-amt beg end
- (pos (- (point-max) (point))))
- (beginning-of-line)
- (setq beg (point))
- (skip-chars-forward " \t")
- (if (looking-at "[ \t]*;;;")
- ;; Don't alter indentation of a ;;; comment line.
- nil
- (if (listp indent) (setq indent (car indent)))
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- nil
- (delete-region beg (point))
- (indent-to indent))
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- ;; If desired, shift remaining lines of expression the same amount.
- (and whole-exp (not (zerop shift-amt))
- (save-excursion
- (goto-char beg)
- (forward-sexp 1)
- (setq end (point))
- (goto-char beg)
- (forward-line 1)
- (setq beg (point))
- (> end beg))
- (indent-code-rigidly beg end shift-amt)))))
-
-(defun calculate-scheme-indent (&optional parse-start)
- "Return appropriate indentation for current line as scheme code.
-In usual case returns an integer: the column to indent to.
-Can instead return a list, whose car is the column to indent to.
-This means that following lines at the same level of indentation
-should not necessarily be indented the same way.
-The second element of the list is the buffer position
-of the start of the containing expression."
- (save-excursion
- (beginning-of-line)
- (let ((indent-point (point)) state paren-depth desired-indent (retry t)
- last-sexp containing-sexp first-sexp-list-p)
- (if parse-start
- (goto-char parse-start)
- (beginning-of-defun))
- ;; Find outermost containing sexp
- (while (< (point) indent-point)
- (setq state (parse-partial-sexp (point) indent-point 0)))
- ;; Find innermost containing sexp
- (while (and retry (setq paren-depth (car state)) (> paren-depth 0))
- (setq retry nil)
- (setq last-sexp (nth 2 state))
- (setq containing-sexp (car (cdr state)))
- ;; Position following last unclosed open.
- (goto-char (1+ containing-sexp))
- ;; Is there a complete sexp since then?
- (if (and last-sexp (> last-sexp (point)))
- ;; Yes, but is there a containing sexp after that?
- (let ((peek (parse-partial-sexp last-sexp indent-point 0)))
- (if (setq retry (car (cdr peek))) (setq state peek))))
- (if (not retry)
- ;; Innermost containing sexp found
- (progn
- (goto-char (1+ containing-sexp))
- (if (not last-sexp)
- ;; indent-point immediately follows open paren.
- ;; Don't call hook.
- (setq desired-indent (current-column))
- ;; Move to first sexp after containing open paren
- (parse-partial-sexp (point) last-sexp 0 t)
- (setq first-sexp-list-p (looking-at "\\s("))
- (cond
- ((> (save-excursion (forward-line 1) (point))
- last-sexp)
- ;; Last sexp is on same line as containing sexp.
- ;; It's almost certainly a function call.
- (parse-partial-sexp (point) last-sexp 0 t)
- (if (/= (point) last-sexp)
- ;; Indent beneath first argument or, if only one sexp
- ;; on line, indent beneath that.
- (progn (forward-sexp 1)
- (parse-partial-sexp (point) last-sexp 0 t)))
- (backward-prefix-chars))
- (t
- ;; Indent beneath first sexp on same line as last-sexp.
- ;; Again, it's almost certainly a function call.
- (goto-char last-sexp)
- (beginning-of-line)
- (parse-partial-sexp (point) last-sexp 0 t)
- (backward-prefix-chars)))))))
- ;; If looking at a list, don't call hook.
- (if first-sexp-list-p
- (setq desired-indent (current-column)))
- ;; Point is at the point to indent under unless we are inside a string.
- ;; Call indentation hook except when overridden by scheme-indent-offset
- ;; or if the desired indentation has already been computed.
- (cond ((car (nthcdr 3 state))
- ;; Inside a string, don't change indentation.
- (goto-char indent-point)
- (skip-chars-forward " \t")
- (setq desired-indent (current-column)))
- ((and (integerp scheme-indent-offset) containing-sexp)
- ;; Indent by constant offset
- (goto-char containing-sexp)
- (setq desired-indent (+ scheme-indent-offset (current-column))))
- ((not (or desired-indent
- (and (boundp 'scheme-indent-function)
- scheme-indent-function
- (not retry)
- (setq desired-indent
- (funcall scheme-indent-function
- indent-point state)))))
- ;; Use default indentation if not computed yet
- (setq desired-indent (current-column))))
- desired-indent)))
-
-(defun scheme-indent-function (indent-point state)
- (let ((normal-indent (current-column)))
- (save-excursion
- (goto-char (1+ (car (cdr state))))
- (re-search-forward "\\sw\\|\\s_")
- (if (/= (point) (car (cdr state)))
- (let ((function (buffer-substring (progn (forward-char -1) (point))
- (progn (forward-sexp 1) (point))))
- method)
- ;; Who cares about this, really?
- ;(if (not (string-match "\\\\\\||" function)))
- (setq function (downcase function))
- (setq method (get (intern-soft function) 'scheme-indent-function))
- (cond ((integerp method)
- (scheme-indent-specform method state indent-point))
- (method
- (funcall method state indent-point))
- ((and (> (length function) 3)
- (string-equal (substring function 0 3) "def"))
- (scheme-indent-defform state indent-point))))))))
-
-(defvar scheme-body-indent 2 "")
-
-(defun scheme-indent-specform (count state indent-point)
- (let ((containing-form-start (car (cdr state))) (i count)
- body-indent containing-form-column)
- ;; Move to the start of containing form, calculate indentation
- ;; to use for non-distinguished forms (> count), and move past the
- ;; function symbol. scheme-indent-function guarantees that there is at
- ;; least one word or symbol character following open paren of containing
- ;; form.
- (goto-char containing-form-start)
- (setq containing-form-column (current-column))
- (setq body-indent (+ scheme-body-indent containing-form-column))
- (forward-char 1)
- (forward-sexp 1)
- ;; Now find the start of the last form.
- (parse-partial-sexp (point) indent-point 1 t)
- (while (and (< (point) indent-point)
- (condition-case nil
- (progn
- (setq count (1- count))
- (forward-sexp 1)
- (parse-partial-sexp (point) indent-point 1 t))
- (error nil))))
- ;; Point is sitting on first character of last (or count) sexp.
- (cond ((> count 0)
- ;; A distinguished form. Use double scheme-body-indent.
- (list (+ containing-form-column (* 2 scheme-body-indent))
- containing-form-start))
- ;; A non-distinguished form. Use body-indent if there are no
- ;; distinguished forms and this is the first undistinguished
- ;; form, or if this is the first undistinguished form and
- ;; the preceding distinguished form has indentation at least
- ;; as great as body-indent.
- ((and (= count 0)
- (or (= i 0)
- (<= body-indent normal-indent)))
- body-indent)
- (t
- normal-indent))))
-
-(defun scheme-indent-defform (state indent-point)
- (goto-char (car (cdr state)))
- (forward-line 1)
- (if (> (point) (car (cdr (cdr state))))
- (progn
- (goto-char (car (cdr state)))
- (+ scheme-body-indent (current-column)))))
-
-;;; Let is different in Scheme
-
-(defun would-be-symbol (string)
- (not (string-equal (substring string 0 1) "(")))
-
-(defun next-sexp-as-string ()
- ;; Assumes that protected by a save-excursion
- (forward-sexp 1)
- (let ((the-end (point)))
- (backward-sexp 1)
- (buffer-substring (point) the-end)))
-
-;; This is correct but too slow.
-;; The one below works almost always.
-;;(defun scheme-let-indent (state indent-point)
-;; (if (would-be-symbol (next-sexp-as-string))
-;; (scheme-indent-specform 2 state indent-point)
-;; (scheme-indent-specform 1 state indent-point)))
-
-(defun scheme-let-indent (state indent-point)
- (skip-chars-forward " \t")
- (if (looking-at "[-a-zA-Z0-9+*/?!@$%^&_:~]")
- (scheme-indent-specform 2 state indent-point)
- (scheme-indent-specform 1 state indent-point)))
-
-;; (put 'begin 'scheme-indent-function 0), say, causes begin to be indented
-;; like defun if the first form is placed on the next line, otherwise
-;; it is indented like any other form (i.e. forms line up under first).
-
-(put 'begin 'scheme-indent-function 0)
-(put 'case 'scheme-indent-function 1)
-(put 'delay 'scheme-indent-function 0)
-(put 'do 'scheme-indent-function 2)
-(put 'lambda 'scheme-indent-function 1)
-(put 'let 'scheme-indent-function 'scheme-let-indent)
-(put 'let* 'scheme-indent-function 1)
-(put 'letrec 'scheme-indent-function 1)
-(put 'sequence 'scheme-indent-function 0)
-
-(put 'call-with-input-file 'scheme-indent-function 1)
-(put 'with-input-from-file 'scheme-indent-function 1)
-(put 'with-input-from-port 'scheme-indent-function 1)
-(put 'call-with-output-file 'scheme-indent-function 1)
-(put 'with-output-to-file 'scheme-indent-function 1)
-(put 'with-output-to-port 'scheme-indent-function 1)
-
-;;;; MIT Scheme specific indentation.
-
-(if scheme-mit-dialect
- (progn
- (put 'fluid-let 'scheme-indent-function 1)
- (put 'in-package 'scheme-indent-function 1)
- (put 'let-syntax 'scheme-indent-function 1)
- (put 'local-declare 'scheme-indent-function 1)
- (put 'macro 'scheme-indent-function 1)
- (put 'make-environment 'scheme-indent-function 0)
- (put 'named-lambda 'scheme-indent-function 1)
- (put 'using-syntax 'scheme-indent-function 1)
-
- (put 'with-input-from-string 'scheme-indent-function 1)
- (put 'with-output-to-string 'scheme-indent-function 0)
- (put 'with-values 'scheme-indent-function 1)
-
- (put 'syntax-table-define 'scheme-indent-function 2)
- (put 'list-transform-positive 'scheme-indent-function 1)
- (put 'list-transform-negative 'scheme-indent-function 1)
- (put 'list-search-positive 'scheme-indent-function 1)
- (put 'list-search-negative 'scheme-indent-function 1)
-
- (put 'access-components 'scheme-indent-function 1)
- (put 'assignment-components 'scheme-indent-function 1)
- (put 'combination-components 'scheme-indent-function 1)
- (put 'comment-components 'scheme-indent-function 1)
- (put 'conditional-components 'scheme-indent-function 1)
- (put 'disjunction-components 'scheme-indent-function 1)
- (put 'declaration-components 'scheme-indent-function 1)
- (put 'definition-components 'scheme-indent-function 1)
- (put 'delay-components 'scheme-indent-function 1)
- (put 'in-package-components 'scheme-indent-function 1)
- (put 'lambda-components 'scheme-indent-function 1)
- (put 'lambda-components* 'scheme-indent-function 1)
- (put 'lambda-components** 'scheme-indent-function 1)
- (put 'open-block-components 'scheme-indent-function 1)
- (put 'pathname-components 'scheme-indent-function 1)
- (put 'procedure-components 'scheme-indent-function 1)
- (put 'sequence-components 'scheme-indent-function 1)
- (put 'unassigned\?-components 'scheme-indent-function 1)
- (put 'unbound\?-components 'scheme-indent-function 1)
- (put 'variable-components 'scheme-indent-function 1)))
-
-(defun scheme-indent-sexp ()
- "Indent each line of the list starting just after point."
- (interactive)
- (let ((indent-stack (list nil)) (next-depth 0) bol
- outer-loop-done inner-loop-done state this-indent)
- (save-excursion (forward-sexp 1))
- (save-excursion
- (setq outer-loop-done nil)
- (while (not outer-loop-done)
- (setq last-depth next-depth
- innerloop-done nil)
- (while (and (not innerloop-done)
- (not (setq outer-loop-done (eobp))))
- (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
- nil nil state))
- (setq next-depth (car state))
- (if (car (nthcdr 4 state))
- (progn (indent-for-comment)
- (end-of-line)
- (setcar (nthcdr 4 state) nil)))
- (if (car (nthcdr 3 state))
- (progn
- (forward-line 1)
- (setcar (nthcdr 5 state) nil))
- (setq innerloop-done t)))
- (if (setq outer-loop-done (<= next-depth 0))
- nil
- (while (> last-depth next-depth)
- (setq indent-stack (cdr indent-stack)
- last-depth (1- last-depth)))
- (while (< last-depth next-depth)
- (setq indent-stack (cons nil indent-stack)
- last-depth (1+ last-depth)))
- (forward-line 1)
- (setq bol (point))
- (skip-chars-forward " \t")
- (if (or (eobp) (looking-at "[;\n]"))
- nil
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- (setq this-indent (car indent-stack))
- (let ((val (calculate-scheme-indent
- (if (car indent-stack) (- (car indent-stack))))))
- (if (integerp val)
- (setcar indent-stack
- (setq this-indent val))
- (setcar indent-stack (- (car (cdr val))))
- (setq this-indent (car val)))))
- (if (/= (current-column) this-indent)
- (progn (delete-region bol (point))
- (indent-to this-indent)))))))))
-
-(provide 'scheme)
-
-;;; scheme.el ends here
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
deleted file mode 100644
index b0fd04d4a13..00000000000
--- a/lisp/progmodes/sh-script.el
+++ /dev/null
@@ -1,895 +0,0 @@
-;;; sh-script.el --- shell-script editing commands for Emacs
-;; Copyright (C) 1993 Free Software Foundation, Inc.
-
-;; Author: Daniel Pfeiffer, fax (+49 69) 75 88 529, c/o <bonhoure@cict.fr>
-;; Maintainer: FSF
-;; Keywords: shell programming
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; Major mode for editing shell scripts. Currently sh, ksh, bash and csh,
-;; tcsh are supported. Structured statements can be inserted with one
-;; command.
-
-;;; Code:
-
-;; page 1: variables and settings
-;; page 2: mode-command and utility functions
-;; page 3: statement syntax-commands for various shells
-;; page 4: various other commands
-
-
-;;;###autoload
-(setq auto-mode-alist
- ;; matches files
- ;; - who's path contains /bin/, but not directories
- (cons '("/bin/" . sh-or-other-mode)
- ;; - that have a suffix .sh or .shar (shell archive)
- ;; - that contain ressources for the various shells
- ;; - startup files for X11
- (cons '("\\.sh$\\|\\.shar$\\|/\\.\\(profile\\|bash_profile\\|login\\|bash_login\\|logout\\|bash_logout\\|bashrc\\|t?cshrc\\|xinitrc\\|startxrc\\|xsession\\)$" . sh-mode)
- auto-mode-alist)))
-
-
-(defvar sh-mode-syntax-table
- (let ((table (copy-syntax-table)))
- (modify-syntax-entry ?\# "<" table)
- (modify-syntax-entry ?\^l ">#" table)
- (modify-syntax-entry ?\n ">#" table)
- (modify-syntax-entry ?\" "\"\"" table)
- (modify-syntax-entry ?\' "\"'" table)
- (modify-syntax-entry ?\` "$`" table)
- (modify-syntax-entry ?$ "_" table)
- (modify-syntax-entry ?! "_" table)
- (modify-syntax-entry ?% "_" table)
- (modify-syntax-entry ?: "_" table)
- (modify-syntax-entry ?. "_" table)
- (modify-syntax-entry ?^ "_" table)
- (modify-syntax-entry ?~ "_" table)
- table)
- "Syntax table in use in Shell-Script mode.")
-
-
-
-(defvar sh-use-prefix nil
- "If non-nil when loading, `$' and `<' will be C-c $ and C-c < .")
-
-(defvar sh-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c(" 'sh-function)
- (define-key map "\C-c\C-w" 'sh-while)
- (define-key map "\C-c\C-u" 'sh-until)
- (define-key map "\C-c\C-s" 'sh-select)
- (define-key map "\C-c\C-l" 'sh-indexed-loop)
- (define-key map "\C-c\C-i" 'sh-if)
- (define-key map "\C-c\C-f" 'sh-for)
- (define-key map "\C-c\C-c" 'sh-case)
-
- (define-key map (if sh-use-prefix "\C-c$" "$")
- 'sh-query-for-variable)
- (define-key map "=" 'sh-assignment)
- (define-key map "\C-c+" 'sh-add)
- (define-key map (if sh-use-prefix "\C-c<" "<")
- 'sh-maybe-here-document)
- (define-key map "(" 'pair-insert-maybe)
- (define-key map "{" 'pair-insert-maybe)
- (define-key map "[" 'pair-insert-maybe)
- (define-key map "'" 'pair-insert-maybe)
- (define-key map "`" 'pair-insert-maybe)
- (define-key map "\"" 'pair-insert-maybe)
-
- (define-key map "\t" 'sh-indent-line)
- (substitute-key-definition 'complete-tag 'comint-dynamic-complete-filename
- map (current-global-map))
- (substitute-key-definition 'newline-and-indent 'sh-newline-and-indent
- map (current-global-map))
- ;; Now that tabs work properly, this might be unwanted.
- (substitute-key-definition 'delete-backward-char
- 'backward-delete-char-untabify
- map (current-global-map))
- (define-key map "\C-c:" 'sh-set-shell)
- (substitute-key-definition 'beginning-of-defun
- 'sh-beginning-of-compound-command
- map (current-global-map))
- (substitute-key-definition 'backward-sentence 'sh-beginning-of-command
- map (current-global-map))
- (substitute-key-definition 'forward-sentence 'sh-end-of-command
- map (current-global-map))
- (substitute-key-definition 'manual-entry 'sh-manual-entry
- map (current-global-map))
- (define-key map [menu-bar insert]
- (cons "Insert" (make-sparse-keymap "Insert")))
- (define-key map [menu-bar insert sh-while]
- '("While loop" . sh-while))
- (define-key map [menu-bar insert sh-until]
- '("Until loop" . sh-until))
- (define-key map [menu-bar insert sh-select]
- '("Select statement" . sh-select))
- (define-key map [menu-bar insert sh-indexed-loop]
- '("Indexed loop" . sh-indexed-loop))
- (define-key map [menu-bar insert sh-if]
- '("If statement" . sh-if))
- (define-key map [menu-bar insert sh-for]
- '("For loop" . sh-for))
- (define-key map [menu-bar insert sh-case]
- '("Case statement" . sh-case))
- map)
- "Keymap used in Shell-Script mode.")
-
-
-
-(defvar sh-find-file-modifies t
- "*What to do when newly found file has no magic number:
- nil do nothing
- t insert magic number
- other insert magic number, but mark as unmodified.")
-
-
-(defvar sh-query-for-magic t
- "*If non-nil, ask user before changing or inserting magic number.")
-
-
-(defvar sh-magicless-file-regexp "/\\.[^/]+$"
- "*On files with this kind of name no magic is inserted or changed.")
-
-
-;; someone who understands /etc/magic better than me should beef this up
-;; this currently covers only SCO Unix and Sinix executables
-;; the elegant way would be to read /etc/magic
-(defvar magic-number-alist '(("L\^a\^h\\|\^?ELF" . hexl-mode)
- ("#!.*perl" . perl-mode))
- "A regexp to match the magic number of a found file.
-Currently this is only used by function `sh-or-other-mode'.")
-
-
-(defvar sh-executable ".* is \\([^ \t]*\\)\n"
- "*Regexp to match the output of sh builtin `type' command on your machine.
-The regexp must match the whole output, and must contain a \\(something\\)
-construct which matches the actual executable.")
-
-
-
-(defvar sh-chmod-argument "755"
- "*After saving, if the file is not executable, set this mode.
-The mode can be absolute \"511\" or relative \"u+x\". Do nothing if this is nil.")
-
-
-(defvar sh-shell-path (or (getenv "SHELL") "/bin/sh")
- "*The executable of the shell being programmed.")
-
-(defvar sh-shell-argument nil
- "*A single argument for the magic number, or nil.")
-
-(defvar sh-shell nil
- "The shell being programmed. This is set by \\[sh-set-shell].")
-
-(defvar sh-shell-is-csh nil
- "The shell being programmed. This is set by \\[sh-set-shell].")
-
-(defvar sh-tab-width 4
- "The default value for `tab-width' in Shell-Script mode.
-This is the width of tab stops after the indentation of the preceeding line.")
-
-(defvar sh-remember-variable-min 3
- "*Don't remember variables less than this length for completing reads.")
-
-
-(defvar sh-beginning-of-command
- "\\([;({`|&]\\|^\\)[ \t]*\\([/~:a-zA-Z0-9]\\)"
- "*Regexp to determine the beginning of a shell command.
-The actual command starts at the beginning of the second \\(grouping\\).")
-
-(defvar sh-end-of-command
- "\\([/~:a-zA-Z0-9]\\)[ \t]*\\([;#)}`|&]\\|$\\)"
- "*Regexp to determine the end of a shell command.
-The actual command ends at the end of the first \\(grouping\\).")
-
-
-
-(defvar sh-assignment-space '(csh tcsh)
- "List of shells that allow spaces around the assignment =.")
-
-(defvar sh-here-document-word "+"
- "Word to delimit here documents.")
-
-
-;process-environment
-(defvar sh-variables
- '(("addsuffix" tcsh) ("allow_null_glob_expansion" bash)
- ("ampm" tcsh) ("argv" csh tcsh)
- ("autocorrect" tcsh) ("autoexpand" tcsh)
- ("autolist" tcsh) ("autologout" tcsh)
- ("auto_resume" bash) ("BASH" bash)
- ("BASH_VERSION" bash) ("cdable_vars" bash)
- ("cdpath" csh tcsh) ("CDPATH" sh ksh bash)
- ("chase_symlinks" tcsh) ("child" csh tcsh)
- ("COLUMNS" ksh tcsh) ("correct" tcsh)
- ("dextract" tcsh) ("echo" csh tcsh)
- ("edit" tcsh) ("EDITOR")
- ("el" tcsh) ("ENV" ksh bash)
- ("ERRNO" ksh) ("EUID" bash)
- ("FCEDIT" ksh bash) ("FIGNORE" bash)
- ("fignore" tcsh) ("FPATH" ksh)
- ("gid" tcsh) ("glob_dot_filenames" bash)
- ("histchars" bash csh tcsh) ("HISTFILE" ksh bash)
- ("HISTFILESIZE" bash) ("histlit" tcsh)
- ("history" csh tcsh) ("history_control" bash)
- ("HISTSIZE" bash) ("home" csh tcsh)
- ("HOME") ("HOST" tcsh)
- ("hostname_completion_file" bash) ("HOSTTYPE" bash tcsh)
- ("HPATH" tcsh) ("HUSHLOGIN")
- ("IFS" sh ksh bash) ("ignoreeof" bash csh tcsh)
- ("IGNOREEOF" bash) ("ignore_symlinks" tcsh)
- ("LANG") ("LC_COLLATE")
- ("LC_CTYPE") ("LC_MESSAGES")
- ("LC_MONETARY") ("LC_NUMERIC")
- ("LC_TIME") ("LINENO" ksh bash)
- ("LINES" ksh tcsh) ("listjobs" tcsh)
- ("listlinks" tcsh) ("listmax" tcsh)
- ("LOGNAME") ("mail" csh tcsh)
- ("MAIL") ("MAILCHECK")
- ("MAILPATH") ("MAIL_WARNING" bash)
- ("matchbeep" tcsh) ("nobeep" tcsh)
- ("noclobber" bash csh tcsh) ("noglob" csh tcsh)
- ("nolinks" bash) ("nonomatch" csh tcsh)
- ("NOREBIND" tcsh) ("notify" bash)
- ("no_exit_on_failed_exec" bash) ("NO_PROMPT_VARS" bash)
- ("oid" tcsh) ("OLDPWD" ksh bash)
- ("OPTARG" sh ksh bash) ("OPTERR" bash)
- ("OPTIND" sh ksh bash) ("PAGER")
- ("path" csh tcsh) ("PATH")
- ("PPID" ksh bash) ("printexitvalue" tcsh)
- ("prompt" csh tcsh) ("prompt2" tcsh)
- ("prompt3" tcsh) ("PROMPT_COMMAND" bash)
- ("PS1" sh ksh bash) ("PS2" sh ksh bash)
- ("PS3" ksh) ("PS4" ksh bash)
- ("pushdsilent" tcsh) ("pushdtohome" tcsh)
- ("pushd_silent" bash) ("PWD" ksh bash)
- ("RANDOM" ksh bash) ("recexact" tcsh)
- ("recognize_only_executables" tcsh) ("REPLY" ksh bash)
- ("rmstar" tcsh) ("savehist" tcsh)
- ("SECONDS" ksh bash) ("shell" csh tcsh)
- ("SHELL") ("SHLVL" bash tcsh)
- ("showdots" tcsh) ("sl" tcsh)
- ("status" csh tcsh) ("SYSTYPE" tcsh)
- ("tcsh" tcsh) ("term" tcsh)
- ("TERM") ("TERMCAP")
- ("time" csh tcsh) ("TMOUT" ksh bash)
- ("tperiod" tcsh) ("tty" tcsh)
- ("UID" bash) ("uid" tcsh)
- ("verbose" csh tcsh) ("version" tcsh)
- ("visiblebell" tcsh) ("VISUAL")
- ("watch" tcsh) ("who" tcsh)
- ("wordchars" tcsh))
- "Alist of all environment and shell variables used for completing read.
-Variables only understood by some shells are associated to a list of those.")
-
-
-
-(defvar sh-font-lock-keywords
- '(("[ \t]\\(#.*\\)" 1 font-lock-comment-face)
- ("\"[^`]*\"\\|'.*'\\|\\\\[^\nntc]" . font-lock-string-face))
- "*Rules for highlighting shell scripts.
-This variable is included into the various variables
-`sh-SHELL-font-lock-keywords'. If no such variable exists for some shell,
-this one is used.")
-
-
-(defvar sh-sh-font-lock-keywords
- (append sh-font-lock-keywords
- '(("\\(^\\|[^-._a-z0-9]\\)\\(case\\|do\\|done\\|elif\\|else\\|esac\\|fi\\|for\\|if\\|in\\|then\\|until\\|while\\)\\($\\|[^-._a-z0-9]\\)" 2 font-lock-keyword-face t)))
- "*Rules for highlighting Bourne shell scripts.")
-
-(defvar sh-ksh-font-lock-keywords
- (append sh-sh-font-lock-keywords
- '(("\\(^\\|[^-._a-z0-9]\\)\\(function\\|select\\)\\($\\|[^-._a-z0-9]\\)" 2 font-lock-keyword-face t)))
- "*Rules for highlighting Korn shell scripts.")
-
-(defvar sh-bash-font-lock-keywords
- (append sh-sh-font-lock-keywords
- '(("\\(^\\|[^-._a-z0-9]\\)\\(function\\)\\($\\|[^-._a-z0-9]\\)" 2 font-lock-keyword-face t)))
- "*Rules for highlighting Bourne again shell scripts.")
-
-
-(defvar sh-csh-font-lock-keywords
- (append sh-font-lock-keywords
- '(("\\(^\\|[^-._a-z0-9]\\)\\(breaksw\\|case\\|default\\|else\\|end\\|endif\\|foreach\\|if\\|switch\\|then\\|while\\)\\($\\|[^-._a-z0-9]\\)" 2 font-lock-keyword-face t)))
- "*Rules for highlighting C shell scripts.")
-
-(defvar sh-tcsh-font-lock-keywords sh-csh-font-lock-keywords
- "*Rules for highlighting Toronto C shell scripts.")
-
-
-
-;; mode-command and utility functions
-
-;;;###autoload
-(defun sh-or-other-mode ()
- "Decide whether this is a compiled executable or a script.
-Usually the file-names of scripts and binaries cannot be automatically
-distinguished, so the presence of an executable's magic number is used."
- (funcall (or (let ((l magic-number-alist))
- (while (and l
- (not (looking-at (car (car l)))))
- (setq l (cdr l)))
- (cdr (car l)))
- 'sh-mode)))
-
-
-;;;###autoload
-(defun sh-mode ()
- "Major mode for editing shell scripts.
-This mode works for many shells, since they all have roughly the same syntax,
-as far as commands, arguments, variables, pipes, comments etc. are concerned.
-Unless the file's magic number indicates the shell, your usual shell is
-assumed. Since filenames rarely give a clue, they are not further analyzed.
-
-The syntax of the statements varies with the shell being used. The syntax of
-statements can be modified by putting a property on the command or new ones
-defined with `define-sh-skeleton'. For example
-
- (put 'sh-until 'ksh '(() \"until \" _ \\n > \"do\" \\n \"done\"))
-or
- (put 'sh-if 'smush '(\"What? \" \"If ya got ( \" str \" ) ya betta { \" _ \" }\"))
-
-where `sh-until' or `sh-if' have been or will be defined by `define-sh-skeleton'.
-
-The following commands are available, based on the current shell's syntax:
-
-\\[sh-case] case statement
-\\[sh-for] for loop
-\\[sh-function] function definition
-\\[sh-if] if statement
-\\[sh-indexed-loop] indexed loop from 1 to n
-\\[sh-select] select statement
-\\[sh-until] until loop
-\\[sh-while] while loop
-
-\\[backward-delete-char-untabify] Delete backward one position, even if it was a tab.
-\\[sh-newline-and-indent] Delete unquoted space and indent new line same as this one.
-\\[sh-end-of-command] Go to end of successive commands.
-\\[sh-beginning-of-command] Go to beginning of successive commands.
-\\[sh-set-shell] Set this buffer's shell, and maybe its magic number.
-\\[sh-manual-entry] Display the Unix manual entry for the current command or shell.
-
-\\[sh-query-for-variable] Unless quoted with \\, query for a variable with completions offered.
-\\[sh-maybe-here-document] Without prefix, following an unquoted < inserts here document.
-{, (, [, ', \", `
- Unless quoted with \\, insert the pairs {}, (), [], or '', \"\", ``."
- (interactive)
- (kill-all-local-variables)
- (set-syntax-table sh-mode-syntax-table)
- (use-local-map sh-mode-map)
- (make-local-variable 'indent-line-function)
- (make-local-variable 'comment-start)
- (make-local-variable 'comment-start-skip)
- (make-local-variable 'after-save-hook)
- (make-local-variable 'require-final-newline)
- (make-local-variable 'sh-shell-path)
- (make-local-variable 'sh-shell)
- (make-local-variable 'sh-shell-is-csh)
- (make-local-variable 'pair-alist)
- (make-local-variable 'pair-filter)
- (make-local-variable 'font-lock-keywords)
- (make-local-variable 'font-lock-keywords-case-fold-search)
- (make-local-variable 'sh-variables)
- (setq major-mode 'sh-mode
- mode-name "Shell-script"
- ;; Why can't Emacs have one standard function with some parameters?
- ;; Only few modes actually analyse the previous line's contents
- indent-line-function 'sh-indent-line
- comment-start "# "
- after-save-hook 'sh-chmod
- tab-width sh-tab-width
- ;; C shells do
- require-final-newline t
- font-lock-keywords-case-fold-search nil
- pair-alist '((?` _ ?`))
- pair-filter 'sh-quoted-p)
- ; parse or insert magic number for exec()
- (goto-char (point-min))
- (sh-set-shell
- (if (looking-at "#![\t ]*\\([^\t\n ]+\\)")
- (buffer-substring (match-beginning 1) (match-end 1))
- sh-shell-path))
- ;; find-file is set by `normal-mode' when called by `after-find-file'
- (and (boundp 'find-file) find-file
- (or (eq sh-find-file-modifies t)
- (set-buffer-modified-p nil)))
- (run-hooks 'sh-mode-hook))
-;;;###autoload
-(defalias 'shell-script-mode 'sh-mode)
-
-
-
-(defmacro define-sh-skeleton (command documentation &rest definitions)
- "Define COMMAND with [DOCSTRING] to insert statements as in DEFINITION ...
-Prior definitions (e.g. from ~/.emacs) are maintained.
-Each definition is built up as (SHELL PROMPT ELEMENT ...). Alternately
-a synonym definition can be (SHELL . PREVIOUSLY-DEFINED-SHELL).
-
-For the meaning of (PROMPT ELEMENT ...) see `skeleton-insert'.
-Each DEFINITION is actually stored as
- (put COMMAND SHELL (PROMPT ELEMENT ...)),
-which you can also do yourself."
- (or (stringp documentation)
- (setq definitions (cons documentation definitions)
- documentation ""))
- ;; The compiled version doesn't.
- (require 'backquote)
- (`(progn
- (let ((definitions '(, definitions)))
- (while definitions
- ;; skeleton need not be loaded to define these
- (or (and (not (if (boundp 'skeleton-debug) skeleton-debug))
- (get '(, command) (car (car definitions))))
- (put '(, command) (car (car definitions))
- (if (symbolp (cdr (car definitions)))
- (get '(, command) (cdr (car definitions)))
- (cdr (car definitions)))))
- (setq definitions (cdr definitions))))
- (put '(, command) 'menu-enable '(get '(, command) sh-shell))
- (defun (, command) ()
- (, documentation)
- (interactive)
- (skeleton-insert
- (or (get '(, command) sh-shell)
- (error "%s statement syntax not defined for shell %s."
- '(, command) sh-shell)))))))
-
-
-
-(defun sh-indent-line ()
- "Indent as far as preceding line, then by steps of `tab-width'.
-If previous line starts with a comment, it's considered empty."
- (interactive)
- (let ((previous (save-excursion
- (line-move -1)
- (back-to-indentation)
- (if (looking-at comment-start-skip)
- 0
- (current-column)))))
- (save-excursion
- (indent-to (if (eq this-command 'newline-and-indent)
- previous
- (if (< (current-column)
- (progn (back-to-indentation)
- (current-column)))
- (if (eolp) previous 0)
- (if (eolp)
- (max previous (* (1+ (/ (current-column) tab-width))
- tab-width))
- (* (1+ (/ (current-column) tab-width)) tab-width))))))
- (if (< (current-column) (current-indentation))
- (skip-chars-forward " \t"))))
-
-
-(defun sh-remember-variable (var)
- "Make VARIABLE available for future completing reads in this buffer."
- (or (< (length var) sh-remember-variable-min)
- (assoc var sh-variables)
- (setq sh-variables (cons (list var) sh-variables)))
- var)
-
-
-;; Augment the standard variables by those found in the environment.
-(if (boundp 'process-environment)(let ((l process-environment))
- (while l
- (sh-remember-variable (substring (car l)
- 0 (string-match "=" (car l))))
- (setq l (cdr l)))))
-
-
-
-(defun sh-quoted-p ()
- "Is point preceded by an odd number of backslashes?"
- (eq 1 (% (- (point) (save-excursion
- (skip-chars-backward "\\\\")
- (point)))
- 2)))
-
-
-
-(defun sh-executable (command)
- "If COMMAND is an executable in $PATH its full name is returned. Else nil."
- (let ((point (point))
- (buffer-modified-p (buffer-modified-p))
- buffer-read-only after-change-function)
- (call-process "sh" nil t nil "-c" (concat "type " command))
- (setq point (prog1 (point)
- (goto-char point)))
- (prog1
- (and (looking-at sh-executable)
- (eq point (match-end 0))
- (buffer-substring (match-beginning 1) (match-end 1)))
- (delete-region (point) point)
- (set-buffer-modified-p buffer-modified-p))))
-
-
-
-(defun sh-chmod ()
- "This gets called after saving a file to assure that it be executable.
-You can set the absolute or relative mode with `sh-chmod-argument'."
- (if sh-chmod-argument
- (or (file-executable-p buffer-file-name)
- (shell-command (concat "chmod " sh-chmod-argument
- " " buffer-file-name)))))
-
-;; statement syntax-commands for various shells
-
-;; You are welcome to add the syntax or even completely new statements as
-;; appropriate for your favorite shell.
-
-(define-sh-skeleton sh-case
- "Insert a case/switch statement in the current shell's syntax."
- (sh "expression: "
- "case " str " in" \n
- > (read-string "pattern: ") ?\) \n
- > _ \n
- ";;" \n
- ( "other pattern, %s: "
- < str ?\) \n
- > \n
- ";;" \n)
- < "*)" \n
- > \n
- resume:
- < < "esac")
- (ksh . sh)
- (bash . sh)
- (csh "expression: "
- "switch( " str " )" \n
- > "case " (read-string "pattern: ") ?: \n
- > _ \n
- "breaksw" \n
- ( "other pattern, %s: "
- < "case " str ?: \n
- > \n
- "breaksw" \n)
- < "default:" \n
- > \n
- resume:
- < < "endsw")
- (tcsh . csh))
-
-
-
-(define-sh-skeleton sh-for
- "Insert a for loop in the current shell's syntax."
- (sh "Index variable: "
- "for " str " in " _ "; do" \n
- > ?$ (sh-remember-variable str) \n
- < "done")
- (ksh . sh)
- (bash . sh)
- (csh "Index variable: "
- "foreach " str " ( " _ " )" \n
- > ?$ (sh-remember-variable str) \n
- < "end")
- (tcsh . csh))
-
-
-
-(define-sh-skeleton sh-indexed-loop
- "Insert an indexed loop from 1 to n in the current shell's syntax."
- (sh "Index variable: "
- str "=1" \n
- "while [ $" str " -le "
- (read-string "upper limit: ")
- " ]; do" \n
- > _ ?$ str \n
- str ?= (sh-add (sh-remember-variable str) 1) \n
- < "done")
- (ksh . sh)
- (bash . sh)
- (csh "Index variable: "
- "@ " str " = 1" \n
- "while( $" str " <= "
- (read-string "upper limit: ")
- " )" \n
- > _ ?$ (sh-remember-variable str) \n
- "@ " str "++" \n
- < "end")
- (tcsh . csh))
-
-
-
-(defun sh-add (var delta)
- "Insert an addition of VAR and prefix DELTA for Bourne type shells."
- (interactive
- (list (sh-remember-variable
- (completing-read "Variable: " sh-variables
- (lambda (element)
- (or (not (cdr element))
- (memq sh-shell (cdr element))))))
- (prefix-numeric-value current-prefix-arg)))
- (setq delta (concat (if (< delta 0) " - " " + ")
- (abs delta)))
- (skeleton-insert
- (assq sh-shell
- '((sh "`expr $" var delta "`")
- (ksh "$(( $" var delta " ))")
- (bash "$[ $" var delta " ]")))
- t))
-
-
-
-(define-sh-skeleton sh-function
- "Insert a function definition in the current shell's syntax."
- (sh ()
- "() {" \n
- > _ \n
- < "}")
- (ksh "name: "
- "function " str " {" \n
- > _ \n
- < "}")
- (bash "name: "
- "function " str "() {" \n
- > _ \n
- < "}"))
-
-
-
-(define-sh-skeleton sh-if
- "Insert an if statement in the current shell's syntax."
- (sh "condition: "
- "if [ " str " ]; then" \n
- > _ \n
- ( "other condition, %s: "
- < "elif [ " str " ]; then" \n
- > \n)
- < "else" \n
- > \n
- resume:
- < "fi")
- (ksh . sh)
- (bash . sh)
- (csh "condition: "
- "if( " str " ) then" \n
- > _ \n
- ( "other condition, %s: "
- < "else if ( " str " ) then" \n
- > \n)
- < "else" \n
- > \n
- resume:
- < "endif")
- (tcsh . csh))
-
-
-
-(define-sh-skeleton sh-select
- "Insert a select statement in the current shell's syntax."
- (ksh "Index variable: "
- "select " str " in " _ "; do" \n
- > ?$ str \n
- < "done"))
-(put 'sh-select 'menu-enable '(get 'sh-select sh-shell))
-
-
-
-(define-sh-skeleton sh-until
- "Insert an until loop in the current shell's syntax."
- (sh "condition: "
- "until [ " str " ]; do" \n
- > _ \n
- < "done")
- (ksh . sh)
- (bash . sh))
-(put 'sh-until 'menu-enable '(get 'sh-until sh-shell))
-
-
-(define-sh-skeleton sh-while
- "Insert a while loop in the current shell's syntax."
- (sh "condition: "
- "while [ " str " ]; do" \n
- > _ \n
- < "done")
- (ksh . sh)
- (bash . sh)
- (csh "condition: "
- "while( " str " )" \n
- > _ \n
- < "end")
- (tcsh . csh))
-
-
-
-(defun sh-query-for-variable (arg)
- "Unless quoted with `\\', query for variable-name with completions.
-Prefix arg 0 means don't insert `$' before the variable.
-Prefix arg 2 or more means only do self-insert that many times.
- If { is pressed as the first character, it will surround the variable name."
- (interactive "*p")
- (or (prog1 (or (> arg 1)
- (sh-quoted-p))
- (self-insert-command arg))
- (let (completion-ignore-case
- (minibuffer-local-completion-map
- (or (get 'sh-query-for-variable 'keymap)
- (put 'sh-query-for-variable 'keymap
- (copy-keymap minibuffer-local-completion-map))))
- (buffer (current-buffer)))
- ;; local function that depends on `arg' and `buffer'
- (define-key minibuffer-local-completion-map "{"
- (lambda () (interactive)
- (if (or arg (> (point) 1))
- (beep)
- (save-window-excursion
- (setq arg t)
- (switch-to-buffer-other-window buffer)
- (insert "{}")))))
- (insert
- (prog1
- (sh-remember-variable
- (completing-read "Variable: " sh-variables
- (lambda (element)
- (or (not (cdr element))
- (memq sh-shell (cdr element))))))
- (if (eq t arg) (forward-char 1))))
- (if (eq t arg) (forward-char 1)))))
-
-
-
-(defun sh-assignment (arg)
- "Insert self. Remember previous identifier for future completing read."
- (interactive "p")
- (if (eq arg 1)
- (sh-remember-variable
- (save-excursion
- (buffer-substring
- (progn
- (if (memq sh-shell sh-assignment-space)
- (skip-chars-backward " \t"))
- (point))
- (progn
- (skip-chars-backward "a-zA-Z0-9_")
- (point))))))
- (self-insert-command arg))
-
-
-
-(defun sh-maybe-here-document (arg)
- "Inserts self. Without prefix, following unquoted `<' inserts here document.
-The document is bounded by `sh-here-document-word'."
- (interactive "*P")
- (self-insert-command (prefix-numeric-value arg))
- (or arg
- (not (eq (char-after (- (point) 2)) last-command-char))
- (save-excursion
- (goto-char (- (point) 2))
- (sh-quoted-p))
- (progn
- (insert sh-here-document-word)
- (or (looking-at "[ \t\n]") (insert ? ))
- (end-of-line 1)
- (newline)
- (save-excursion (insert ?\n sh-here-document-word)))))
-
-
-;; various other commands
-
-(autoload 'comint-dynamic-complete-filename "comint"
- "Dynamically complete the filename at point." t)
-
-
-
-(defun sh-newline-and-indent (&optional arg)
- "Strip unquoted whitespace, insert newline, and indent like current line.
-Unquoted whitespace is stripped from the current line's end, unless a
-prefix ARG is given."
- (interactive "*P")
- (let ((previous (current-indentation))
- (end-of-line (point)))
- (if arg ()
- (skip-chars-backward " \t")
- (and (< (point) end-of-line)
- (sh-quoted-p)
- (forward-char 1))
- (delete-region (point) end-of-line))
- (newline)
- (indent-to previous)))
-
-
-
-(defun sh-set-shell (shell)
- "Set this buffer's shell to SHELL (a string).
-Calls the value of `sh-set-shell-hook' if set."
- (interactive "sName or path of shell: ")
- (save-excursion
- (goto-char (point-min))
- (setq sh-shell-path (if (file-name-absolute-p shell)
- shell
- (or (sh-executable shell)
- (error "Cannot find %s." shell)))
- sh-shell (intern (file-name-nondirectory sh-shell-path))
- sh-shell-is-csh (memq sh-shell '(csh tcsh))
- font-lock-keywords
- (intern-soft (format "sh-%s-font-lock-keywords" sh-shell))
- font-lock-keywords (if (and font-lock-keywords
- (boundp font-lock-keywords))
- (symbol-value font-lock-keywords)
- sh-font-lock-keywords)
- comment-start-skip (if sh-shell-is-csh
- "\\(^\\|[^$]\\|\\$[^{]\\)#+[\t ]*"
- "\\(^\\|[^$]\\|\\$[^{]\\)\\B#+[\t ]*")
- mode-line-process (format ": %s" sh-shell)
- shell (concat sh-shell-path
- (and sh-shell-argument " ")
- sh-shell-argument))
- (and (not buffer-read-only)
- (not (if buffer-file-name
- (string-match sh-magicless-file-regexp buffer-file-name)))
- ;; find-file is set by `normal-mode' when called by `after-find-file'
- (if (and (boundp 'find-file) find-file) sh-find-file-modifies t)
- (if (looking-at "#!")
- (and (skip-chars-forward "#! \t")
- (not (string= shell
- (buffer-substring (point)
- (save-excursion (end-of-line)
- (point)))))
- (if sh-query-for-magic
- (y-or-n-p (concat "Replace magic number by ``#! "
- shell "''? "))
- (message "Magic number ``%s'' replaced."
- (buffer-substring (point-min) (point))))
- (not (delete-region (point) (progn (end-of-line) (point))))
- (insert shell))
- (insert "#! " shell ?\n))))
- (run-hooks 'sh-set-shell-hook))
-
-
-
-(defun sh-beginning-of-command ()
- "Move point to successive beginnings of commands."
- (interactive)
- (if (re-search-backward sh-beginning-of-command nil t)
- (goto-char (match-beginning 2))))
-
-
-
-(defun sh-end-of-command ()
- "Move point to successive ends of commands."
- (interactive)
- (if (re-search-forward sh-end-of-command nil t)
- (goto-char (match-end 1))))
-
-
-
-(defun sh-manual-entry (arg)
- "Display the Unix manual entry for the current command or shell.
-Universal argument ARG, is passed to `Man-getpage-in-background'."
- (interactive "P")
- (let ((command (save-excursion
- (sh-beginning-of-command)
- (sh-executable
- (buffer-substring (point)
- (progn (forward-sexp) (point)))))))
- (setq command (read-input (concat "Manual entry (default "
- (symbol-name sh-shell)
- "): ")
- (if command
- (file-name-nondirectory command))))
- (manual-entry (if (string= command "")
- (symbol-name sh-shell)
- command)
- arg)))
-
-;; sh-script.el ends here
diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el
deleted file mode 100644
index 82c5b87401a..00000000000
--- a/lisp/progmodes/simula.el
+++ /dev/null
@@ -1,1291 +0,0 @@
-;;; simula.el --- SIMULA 87 code editing commands for Emacs
-
-;; Copyright (C) 1992 Free Software Foundation, Inc.
-
-;; Author: Hans Henrik Eriksen <hhe@ifi.uio.no>
-;; Maintainer: simula-mode@ifi.uio.no
-;; Version: 0.992
-;; Adapted-By: ESR
-;; Keywords: languages
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;;; Commentary:
-
-;; A major mode for editing the Simula language. It knows about Simula
-;; syntax and standard indentation commands. It also provides convenient
-;; abbrevs for Simula keywords.
-;;
-;; Hans Henrik Eriksen (the author) may be reached at:
-;; Institutt for informatikk,
-;; Universitetet i Oslo
-
-;;; Code:
-
-(provide 'simula-mode)
-
-(defconst simula-tab-always-indent nil
- "*Non-nil means TAB in SIMULA mode should always reindent the current line.
-Otherwise TAB indents only when point is within
-the run of whitespace at the beginning of the line.")
-
-(defconst simula-indent-level 3
- "*Indentation of SIMULA statements with respect to containing block.")
-
-(defconst simula-substatement-offset 3
- "*Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.")
-
-(defconst simula-continued-statement-offset 3
- "*Extra indentation for lines not starting a statement or substatement.
-If value is a list, each line in a multipleline continued statement
-will have the car of the list extra indentation with respect to
-the previous line of the statement.")
-
-(defconst simula-label-offset -4711
- "*Offset of SIMULA label lines relative to usual indentation.")
-
-(defconst simula-if-indent '(0 . 0)
- "*Extra indentation of THEN and ELSE with respect to the starting IF.
-Value is a cons cell, the car is extra THEN indentation and the cdr
-extra ELSE indentation. IF after ELSE is indented as the starting IF.")
-
-(defconst simula-inspect-indent '(0 . 0)
- "*Extra indentation of WHEN and OTHERWISE with respect to the INSPECT.
-Value is a cons cell, the car is extra WHEN indentation
-and the cdr extra OTHERWISE indentation.")
-
-(defconst simula-electric-indent nil
- "*Non-nil means `simula-indent-line' function may reindent previous line.")
-
-(defconst simula-abbrev-keyword 'upcase
- "*Specify how to convert case for SIMULA keywords.
-Value is one of the symbols `upcase', `downcase', `capitalize',
-(as in) `abbrev-table' or nil if they should not be changed.")
-
-(defconst simula-abbrev-stdproc 'abbrev-table
- "*Specify how to convert case for standard SIMULA procedure and class names.
-Value is one of the symbols `upcase', `downcase', `capitalize',
-(as in) `abbrev-table', or nil if they should not be changed.")
-
-(defvar simula-abbrev-file nil
- "*File with extra abbrev definitions for use in SIMULA mode.
-These are used together with the standard abbrev definitions for SIMULA.
-Please note that the standard definitions are required
-for SIMULA mode to function correctly.")
-
-(defvar simula-mode-syntax-table nil
- "Syntax table in SIMULA mode buffers.")
-
-(if simula-mode-syntax-table
- ()
- (setq simula-mode-syntax-table (copy-syntax-table (standard-syntax-table)))
- (modify-syntax-entry ?! "<" simula-mode-syntax-table)
- (modify-syntax-entry ?$ "." simula-mode-syntax-table)
- (modify-syntax-entry ?% "." simula-mode-syntax-table)
- (modify-syntax-entry ?' "\"" simula-mode-syntax-table)
- (modify-syntax-entry ?\( "()" simula-mode-syntax-table)
- (modify-syntax-entry ?\) ")(" simula-mode-syntax-table)
- (modify-syntax-entry ?\; ">" simula-mode-syntax-table)
- (modify-syntax-entry ?\[ "." simula-mode-syntax-table)
- (modify-syntax-entry ?\\ "." simula-mode-syntax-table)
- (modify-syntax-entry ?\] "." simula-mode-syntax-table)
- (modify-syntax-entry ?_ "w" simula-mode-syntax-table)
- (modify-syntax-entry ?\| "." simula-mode-syntax-table)
- (modify-syntax-entry ?\{ "." simula-mode-syntax-table)
- (modify-syntax-entry ?\} "." simula-mode-syntax-table))
-
-(defvar simula-mode-map ()
- "Keymap used in SIMULA mode.")
-
-(if simula-mode-map
- ()
- (setq simula-mode-map (make-sparse-keymap))
- (define-key simula-mode-map "\C-c\C-u" 'simula-backward-up-level)
- (define-key simula-mode-map "\C-c\C-p" 'simula-previous-statement)
- (define-key simula-mode-map "\C-c\C-d" 'simula-forward-down-level)
- (define-key simula-mode-map "\C-c\C-n" 'simula-next-statement)
- ;(define-key simula-mode-map "\C-c\C-g" 'simula-goto-definition)
- ;(define-key simula-mode-map "\C-c\C-h" 'simula-standard-help)
- (define-key simula-mode-map "\177" 'backward-delete-char-untabify)
- (define-key simula-mode-map ":" 'simula-electric-label)
- (define-key simula-mode-map "\t" 'simula-indent-command))
-
-(defvar simula-mode-abbrev-table nil
- "Abbrev table in SIMULA mode buffers")
-
-
-(defun simula-mode ()
- "Major mode for editing SIMULA code.
-\\{simula-mode-map}
-Variables controlling indentation style:
- simula-tab-always-indent
- Non-nil means TAB in SIMULA mode should always reindent the current line,
- regardless of where in the line point is when the TAB command is used.
- simula-indent-level
- Indentation of SIMULA statements with respect to containing block.
- simula-substatement-offset
- Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.
- simula-continued-statement-offset 3
- Extra indentation for lines not starting a statement or substatement,
- e.g. a nested FOR-loop. If value is a list, each line in a multiple-
- line continued statement will have the car of the list extra indentation
- with respect to the previous line of the statement.
- simula-label-offset -4711
- Offset of SIMULA label lines relative to usual indentation.
- simula-if-indent '(0 . 0)
- Extra indentation of THEN and ELSE with respect to the starting IF.
- Value is a cons cell, the car is extra THEN indentation and the cdr
- extra ELSE indentation. IF after ELSE is indented as the starting IF.
- simula-inspect-indent '(0 . 0)
- Extra indentation of WHEN and OTHERWISE with respect to the
- corresponding INSPECT. Value is a cons cell, the car is
- extra WHEN indentation and the cdr extra OTHERWISE indentation.
- simula-electric-indent nil
- If this variable is non-nil, `simula-indent-line'
- will check the previous line to see if it has to be reindented.
- simula-abbrev-keyword 'upcase
- Determine how SIMULA keywords will be expanded. Value is one of
- the symbols `upcase', `downcase', `capitalize', (as in) `abbrev-table',
- or nil if they should not be changed.
- simula-abbrev-stdproc 'abbrev-table
- Determine how standard SIMULA procedure and class names will be
- expanded. Value is one of the symbols `upcase', `downcase', `capitalize',
- (as in) `abbrev-table', or nil if they should not be changed.
-
-Turning on SIMULA mode calls the value of the variable simula-mode-hook
-with no arguments, if that value is non-nil
-
-Warning: simula-mode-hook should not read in an abbrev file without calling
-the function simula-install-standard-abbrevs afterwards, preferably not
-at all."
- (interactive)
- (kill-all-local-variables)
- (use-local-map simula-mode-map)
- (setq major-mode 'simula-mode)
- (setq mode-name "SIMULA")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'end-comment-column)
- (setq end-comment-column 75)
- (set-syntax-table simula-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start "^[ \t]*$\\|\\f")
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'simula-indent-line)
- (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 " ;")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "!+ *")
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments nil)
- (make-local-variable 'comment-multi-line)
- (setq comment-multi-line t)
- (if simula-mode-abbrev-table
- ()
- (if simula-abbrev-file
- (read-abbrev-file simula-abbrev-file)
- (define-abbrev-table 'simula-mode-abbrev-table ()))
- (let (abbrevs-changed)
- (simula-install-standard-abbrevs)))
- (setq local-abbrev-table simula-mode-abbrev-table)
- (abbrev-mode 1)
- (run-hooks 'simula-mode-hook))
-
-
-
-(defun simula-indent-line ()
- "Indent this line as SIMULA code.
-If `simula-electric-indent' is non-nil, indent previous line if necessary."
- (let ((origin (- (point-max) (point)))
- (indent (simula-calculate-indent))
- (case-fold-search t))
- (unwind-protect
- (progn
- ;;
- ;; manually expand abbrev on last line, if any
- ;;
- (end-of-line 0)
- (expand-abbrev)
- ;; now maybe we should reindent that line
- (if simula-electric-indent
- (progn
- (beginning-of-line)
- (skip-chars-forward " \t\f")
- (if (and
- (looking-at
- "\\(end\\|if\\|then\\|else\\|when\\|otherwise\\)\\>")
- (not (simula-context)))
- ;; yes - reindent
- (let ((post-indent (simula-calculate-indent)))
- (if (eq (current-indentation) post-indent)
- ()
- (delete-horizontal-space)
- (indent-to post-indent)))))))
- (goto-char (- (point-max) origin))
- (if (eq (current-indentation) indent)
- (back-to-indentation)
- (delete-horizontal-space)
- (indent-to indent)))))
-
-
-(defun simula-indent-command (&optional whole-exp)
- "Indent current line as SIMULA code, or insert TAB character.
-If `simula-tab-always-indent' is non-nil, always indent current line.
-Otherwise, indent only if point is before any non-whitespace
-character on the line.
-
-A numeric argument, regardless of its value, means indent rigidly
-all the lines of the SIMULA statement after point so that this line
-becomes properly indented.
-The relative indentation among the lines of the statement are preserved."
- (interactive "P")
- (let ((case-fold-search t))
- (if (or whole-exp simula-tab-always-indent
- (save-excursion
- (skip-chars-backward " \t\f")
- (bolp)))
- ;; reindent current line
- (let ((indent (save-excursion
- (beginning-of-line)
- (simula-calculate-indent)))
- (current (current-indentation))
- (origin (- (point-max) (point)))
- (bol (save-excursion
- (skip-chars-backward " \t\f")
- (bolp)))
- beg end)
- (unwind-protect
- (if (eq current indent)
- (if (save-excursion
- (skip-chars-backward " \t\f")
- (bolp))
- (back-to-indentation))
- (beginning-of-line)
- (delete-horizontal-space)
- (indent-to indent))
- (if (not bol)
- (goto-char (- (point-max) origin))))
- (setq origin (point))
- (if whole-exp
- (save-excursion
- (beginning-of-line 2)
- (setq beg (point))
- (goto-char origin)
- (simula-next-statement 1)
- (setq end (point))
- (if (and (> end beg) (not (eq indent current)))
- (indent-code-rigidly beg end (- indent current) "%")))))
- (insert-tab))))
-
-
-(defun simula-context ()
- "Returns value according to syntactic SIMULA context of point.
- 0 point inside COMMENT comment
- 1 point on SIMULA-compiler directive line
- 2 point inside END comment
- 3 point inside string
- 4 point inside character constant
- nil otherwise."
- ;; first, find out if this is a compiler directive line
- (if (save-excursion
- (beginning-of-line)
- (eq (following-char) ?%))
- ;; YES - return 1
- 1
- (save-excursion
- ;; The current line is NOT a compiler directive line.
- ;; Now, the strategy is to search backward to find a semicolon
- ;; that is NOT inside a string. The point after semicolon MUST be
- ;; outside a comment, since semicolons are comment-ending and
- ;; comments are non-recursive. We take advantage of the fact
- ;; that strings MUST end on the same line as they started, so
- ;; that we can easily decide whether we are inside a string or not.
- (let (return-value (origin (point)))
- (skip-chars-backward "^;" (point-min))
- ;; found semicolon or beginning of buffer
- (let (loopvalue (saved-point origin))
- (while (and (not (bobp))
- (if (progn
- (beginning-of-line)
- ;; compiler directive line? If so, cont searching..
- (eq (following-char) ?%))
- t
- (while (< (point) saved-point)
- (skip-chars-forward "^;\"'")
- (forward-char 1)
- (cond
- ((eq (preceding-char) ?\;)
- (setq saved-point (point)))
- ((eq (preceding-char) ?\")
- (skip-chars-forward "^\";")
- (if (eq (following-char) ?\;)
- (setq saved-point (point) loopvalue t)
- (forward-char 1)))
- (t
- (if (eq (following-char) ?')
- (forward-char 1))
- (skip-chars-forward "^';")
- (if (eq (following-char) ?\;)
- (setq saved-point (point) loopvalue t)
- (forward-char 1)))))
- loopvalue))
- (backward-char 1)
- (skip-chars-backward "^;")
- (setq saved-point (point) loopvalue nil)))
- ;; Now we are CERTAIN that we are outside comments and strings.
- ;; The job now is to search forward again towards the origin
- ;; skipping directives, comments and strings correctly,
- ;; so that we know what context we are in when we find the origin.
- (while (and
- (< (point) origin)
- (re-search-forward
- "\\<end\\>\\|!\\|\"\\|'\\|^%\\|\\<comment\\>" origin 'move))
- (cond
- ((memq (preceding-char) '(?d ?D))
- (setq return-value 2)
- (while (and (memq (preceding-char) '(?d ?D)) (not return-value))
- (while (and (re-search-forward
- ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\|^%"
- origin 'move)
- (eq (preceding-char) ?%))
- (beginning-of-line 2)))
- (if (looking-at "[ \t\n\f]*\\(;\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\)")
- (setq return-value nil)))
- ((memq (preceding-char) '(?! ?t ?T))
- ; skip comment
- (setq return-value 0)
- (skip-chars-forward "^%;" origin)
- (while (and return-value (< (point) origin))
- (if (eq (following-char) ?\;)
- (setq return-value nil)
- (if (bolp)
- (beginning-of-line 2) ; skip directive inside comment
- (forward-char 1)) ; or single '%'
- (skip-chars-forward "^%;" origin))))
- ((eq (preceding-char) ?\")
- (if (not (search-forward "\"" origin 'move))
- (setq return-value 3)))
- ((eq (preceding-char) ?\')
- (if (or (eq (point) origin) (eobp))
- (setq return-value 4)
- (forward-char 1)
- (if (not (search-forward "'" origin 'move))
- (setq return-value 4))))
- ;; compiler directive line - skip
- (t (beginning-of-line 2))))
- return-value)
- )))
-
-
-(defun simula-electric-label ()
- "If this is a label that starts the line, reindent the line."
- (interactive)
- (expand-abbrev)
- (insert ?:)
- (let ((origin (- (point-max) (point)))
- (case-fold-search t)
- ;; don't mix a label with an assignment operator := :-
- ;; therefore look at next typed character...
- (next-char (setq unread-command-events (list (read-event))))
- (com-char last-command-char))
- (unwind-protect
- ;; Problem: find out if character just read is a command char
- ;; that would insert something after ':' making it a label.
- ;; At least \n, \r (and maybe \t) falls into this category.
- ;; This is a real crock, it depends on traditional keymap
- ;; bindings, that is, printing characters doing self-insert,
- ;; and no other command sequence inserting '-' or '='.
- ;; simula-electric-label can be easily fooled...
- (if (and (not (memq next-char '(?= ?-)))
- (or (memq next-char '(?\n ?\r))
- (and (eq next-char ?\t)
- simula-tab-always-indent)
- (not (memq (following-char) '(?= ?-))))
- (not (simula-context))
- ;; label?
- (progn
- (backward-char 1)
- (skip-chars-backward " \t\f")
- (skip-chars-backward "a-zA-Z0-9_")
- (if (looking-at "virtual\\>")
- nil
- (skip-chars-backward " \t\f")
- (bolp))))
- (let ((amount (simula-calculate-indent)))
- (delete-horizontal-space)
- (indent-to amount)))
- (goto-char (- (point-max) origin)))))
-
-
-(defun simula-backward-up-level (count)
- "Move backward up COUNT block levels.
-If COUNT is negative, move forward up block level instead."
- (interactive "p")
- (let ((origin (point))
- (case-fold-search t))
- (condition-case ()
- (if (> count 0)
- (while (> count 0)
- (re-search-backward "\\<begin\\>\\|\\<end\\>")
- (if (not (simula-context))
- (setq count (if (memq (following-char) '(?b ?B))
- (1- count)
- (1+ count)))))
- (while (< count 0)
- (re-search-forward "\\<begin\\>\\|\\<end\\>")
- (backward-word 1)
- (if (not (simula-context))
- (setq count (if (memq (following-char) '(?e ?E))
- (1+ count)
- (1- count))))
- (backward-word -1)))
- ;; If block level not found, jump back to origin and signal an error
- (error (progn
- (goto-char origin)
- (error "No higher block level")))
- (quit (progn
- (goto-char origin)
- (signal 'quit nil))))))
-
-
-(defun simula-forward-down-level (count)
- "Move forward down COUNT block levels.
-If COUNT is negative, move backward down block level instead."
- (interactive "p")
- ;; When we search for a deeper block level, we must never
- ;; get out of the block where we started -> count >= start-count
- (let ((start-count count)
- (origin (point))
- (case-fold-search t))
- (condition-case ()
- (if (< count 0)
- (while (< count 0)
- (re-search-backward "\\<begin\\>\\|\\<end\\>")
- (if (not (simula-context))
- (setq count (if (memq (following-char) '(?e ?E))
- (1+ count)
- (1- count))))
- (if (< count start-count) (signal 'error nil)))
- (while (> count 0)
- (re-search-forward "\\<begin\\>\\|\\<end\\>")
- (backward-word 1)
- (if (not (simula-context))
- (setq count (if (memq (following-char) '(?b ?B))
- (1- count)
- (1+ count))))
- (backward-word -1)
- ;; deeper level has to be found within starting block
- (if (> count start-count) (signal 'error nil))))
- ;; If block level not found, jump back to origin and signal an error
- (error (progn
- (goto-char origin)
- (error "No containing block level")))
- (quit (progn
- (goto-char origin)
- (signal 'quit nil))))))
-
-
-(defun simula-previous-statement (count)
- "Move backward COUNT statements.
-If COUNT is negative, move forward instead."
- (interactive "p")
- (if (< count 0)
- (simula-next-statement (- count))
- (let (status
- (case-fold-search t)
- (origin (point)))
- (condition-case ()
- (progn
- (simula-skip-comment-backward)
- (if (memq (preceding-char) '(?n ?N))
- (progn
- (backward-word 1)
- (if (not (looking-at "\\<begin\\>"))
- (backward-word -1)))
- (if (eq (preceding-char) ?\;)
- (backward-char 1)))
- (while (and (natnump (setq count (1- count)))
- (setq status (simula-search-backward
- ";\\|\\<begin\\>" nil 'move))))
- (if status
- (progn
- (if (eq (following-char) ?\;)
- (forward-char 1)
- (backward-word -1))))
- (simula-skip-comment-forward))
- (error (progn (goto-char origin)
- (error "Incomplete statement (too many ENDs)")))
- (quit (progn (goto-char origin) (signal 'quit nil)))))))
-
-
-(defun simula-next-statement (count)
- "Move forward COUNT statements.
-If COUNT is negative, move backward instead."
- (interactive "p")
- (if (< count 0)
- (simula-previous-statement (- count))
- (let (status
- (case-fold-search t)
- (origin (point)))
- (condition-case ()
- (progn
- (simula-skip-comment-forward)
- (if (looking-at "\\<end\\>") (forward-word 1))
- (while (and (natnump (setq count (1- count)))
- (setq status (simula-search-forward
- ";\\|\\<end\\>" (point-max) 'move))))
- (if (and status (/= (preceding-char) ?\;))
- (progn
- (backward-word 1)
- (simula-skip-comment-backward))))
- (error (progn (goto-char origin)
- (error "Incomplete statement (too few ENDs)")))
- (quit (progn (goto-char origin) (signal 'quit nil)))))))
-
-
-(defun simula-skip-comment-backward ()
- "Search towards bob to find first char that is outside a comment."
- (interactive)
- (catch 'simula-out
- (let (context)
- (while t
- (skip-chars-backward " \t\n\f")
- (if (eq (preceding-char) ?\;)
- (save-excursion
- (backward-char 1)
- (setq context (simula-context)))
- (setq context (simula-context)))
- (cond
- ((memq context '(nil 3 4))
- ;; check to see if we found a label
- (if (and (eq (preceding-char) ?:)
- (not (memq (following-char) '(?- ?=)))
- (save-excursion
- (skip-chars-backward ": \t\fa-zA-Z0-9_")
- (not (looking-at "virtual\\>"))))
- (skip-chars-backward ": \t\fa-zA-Z0-9_")
- (throw 'simula-out nil)))
- ((eq context 0)
- ;; since we are inside a comment, it must start somewhere!
- (while (and (re-search-backward "!\\|\\<comment\\>")
- (memq (simula-context) '(0 1)))))
- ((eq context 1)
- (end-of-line 0)
- (if (bobp)
- (throw 'simula-out nil)))
- ((eq context 2)
- ;; an END-comment must belong to an END
- (re-search-backward "\\<end\\>")
- (forward-word 1)
- (throw 'simula-out nil))
- ;; should be impossible to get here..
- )))))
-
-
-(defun simula-skip-comment-forward ()
- "Search towards eob to find first char that is outside a comment."
- ;; this function assumes we start with point .outside a comment
- (interactive)
- (catch 'simula-out
- (while t
- (skip-chars-forward " \t\n\f")
- (cond
- ((looking-at "!\\|\\<comment\\>")
- (search-forward ";" nil 'move))
- ((and (bolp) (eq (following-char) ?%))
- (beginning-of-line 2))
- ((and (looking-at "[a-z0-9_]*[ \t\f]*:[^-=]")
- (not (looking-at "virtual\\>")))
- (skip-chars-forward "a-zA-Z0-9_ \t\f:"))
- (t
- (throw 'simula-out t))))))
-
-
-(defun simula-forward-up-level ()
- (let ((continue-loop t)
- (origin (point))
- (case-fold-search t)
- return-value
- temp)
- (while continue-loop
- (if (re-search-backward "\\<begin\\>\\|\\<end\\>" (point-min) 'move)
- (setq temp (simula-context)
- return-value (and (memq (preceding-char) '(?d ?D))
- (memq temp '(nil 2)))
- continue-loop (and (not return-value)
- (simula-forward-up-level)))
- (setq continue-loop nil)))
- (if return-value
- t
- (goto-char origin)
- nil)))
-
-
-(defun simula-calculate-indent ()
- (save-excursion
- (let ((where (simula-context))
- (origin (point))
- (indent 0)
- continued
- start-line
- temp
- found-end
- prev-cont)
- (cond
- ((eq where 0)
- ;;
- ;; Comment.
- ;; If comment started on previous non-blank line, indent to the
- ;; column where the comment started, else indent as that line.
- ;;
- (skip-chars-backward " \t\n\f")
- (while (and (not (bolp)) (eq (simula-context) 0))
- (re-search-backward "^\\|!\\|\\<comment\\>"))
- (skip-chars-forward " \t\n\f")
- (prog1
- (current-column)
- (goto-char origin)))
- ;;
- ;; Detect missing string delimiters
- ;;
- ((eq where 3)
- (error "Inside string"))
- ((eq where 4)
- (error "Inside character constant"))
- ;;
- ;; check to see if inside ()'s
- ;;
- ((setq temp (simula-inside-parens))
- temp)
- ;;
- ;; Calculate non-comment indentation
- (t
- ;; first, find out if this line starts with something that needs
- ;; special indentation (END/IF/THEN/ELSE/WHEN/OTHERWISE or label)
- ;;
- (skip-chars-forward " \t\f")
- (cond
- ;;
- ;; END
- ;;
- ((looking-at "end\\>")
- (setq indent (- simula-indent-level)
- found-end t))
- ;;
- ;; IF/THEN/ELSE
- ;;
- ((looking-at "if\\>\\|then\\>\\|else\\>")
- ;; search for the *starting* IF
- (cond
- ((memq (following-char) '(?T ?t))
- (setq indent (car simula-if-indent)))
- ((memq (following-char) '(?E ?e))
- (setq indent (cdr simula-if-indent)))
- (t
- (forward-word 1)
- (setq indent 0)))
- (simula-find-if))
- ;;
- ;; WHEN/OTHERWISE
- ;;
- ((looking-at "when\\>\\|otherwise\\>")
- ;; search for corresponding INSPECT
- (if (memq (following-char) '(?W ?w))
- (setq indent (car simula-inspect-indent))
- (setq indent (cdr simula-inspect-indent)))
- (simula-find-inspect))
- ;;
- ;; label:
- ;;
- ((and (not (looking-at "virtual\\>"))
- (looking-at "[a-z0-9_]*[ \t\f]*:[^-=]"))
- (setq indent simula-label-offset)))
- ;; find line with non-comment text
- (simula-skip-comment-backward)
- (if (and found-end
- (not (eq (preceding-char) ?\;))
- (if (memq (preceding-char) '(?N ?n))
- (save-excursion
- (backward-word 1)
- (not (looking-at "begin\\>")))
- t))
- (progn
- (simula-previous-statement 1)
- (simula-skip-comment-backward)))
- (setq start-line
- (save-excursion (beginning-of-line) (point))
- ;; - perhaps this is a continued statement
- continued
- (save-excursion
- (and (not (bobp))
- ;; (not found-end)
- (if (eq (char-syntax (preceding-char)) ?w)
- (progn
- (backward-word 1)
- (not (looking-at
- "begin\\|then\\|else\\|when\\|otherwise\\|do"
- )))
- (not (memq (preceding-char) '(?: ?\;)))))))
- ;;
- ;; MAIN calculation loop - count BEGIN/DO etc.
- ;;
- (while (not (bolp))
- (if (re-search-backward
- ";\\|\\<\\(begin\\|end\\|if\\|else\\|then\\|when\\|otherwise\\|do\\)\\>"
- start-line 'move)
- (if (simula-context)
- ();; found something in a comment/string - ignore
- (setq temp (following-char))
- (cond
- ((eq temp ?\;)
- (simula-previous-statement 1))
- ((looking-at "begin\\>")
- (setq indent (+ indent simula-indent-level)))
- ((looking-at "end\\>")
- (forward-word 1)
- (simula-previous-statement 1))
- ((looking-at "do\\>")
- (setq indent (+ indent simula-substatement-offset))
- (simula-find-do-match))
- ((looking-at "\\(if\\|then\\|else\\)\\>")
- (if (memq temp '(?I ?i))
- (forward-word 1)
- (setq indent (+ indent
- simula-substatement-offset
- (if (memq temp '(?T ?t))
- (car simula-if-indent)
- (cdr simula-if-indent)))))
- (simula-find-if))
- ((looking-at "\\<when\\>\\|\\<otherwise\\>")
- (setq indent (+ indent
- simula-substatement-offset
- (if (memq temp '(?W ?w))
- (car simula-if-indent)
- (cdr simula-if-indent))))
- (simula-find-inspect)))
- ;; found the start of a [sub]statement
- ;; add indentation for continued statement
- (if continued
- (setq indent
- (+ indent
- (if (listp simula-continued-statement-offset)
- (car simula-continued-statement-offset)
- simula-continued-statement-offset))))
- (setq start-line
- (save-excursion (beginning-of-line) (point))
- continued nil))
- ;; search failed .. point is at beginning of line
- ;; determine if we should continue searching
- ;; (at or before comment or label)
- ;; temp = t means finished
- (setq temp
- (and (not (simula-context))
- (save-excursion
- (skip-chars-forward " \t\f")
- (or (looking-at "virtual")
- (not
- (looking-at
- "!\\|comment\\>\\|[a-z0-9_]*[ \t\f]*:[^-=]")))))
- prev-cont continued)
- ;; if we are finished, find current line's indentation
- (if temp
- (setq indent (+ indent (current-indentation))))
- ;; find next line with non-comment SIMULA text
- ;; maybe indent extra if statement continues
- (simula-skip-comment-backward)
- (setq continued
- (and (not (bobp))
- (if (eq (char-syntax (preceding-char)) ?w)
- (save-excursion
- (backward-word 1)
- (not (looking-at
- "begin\\|then\\|else\\|when\\|otherwise\\|do")))
- (not (memq (preceding-char) '(?: ?\;))))))
- ;; if we the state of the continued-variable
- ;; changed, add indentation for continued statement
- (if (or (and prev-cont (not continued))
- (and continued
- (listp simula-continued-statement-offset)))
- (setq indent
- (+ indent
- (if (listp simula-continued-statement-offset)
- (car simula-continued-statement-offset)
- simula-continued-statement-offset))))
- ;; while ends if point is at beginning of line at loop test
- (if (not temp)
- (setq start-line (save-excursion (beginning-of-line) (point)))
- (beginning-of-line))))
- ;;
- ;; return indentation
- ;;
- indent)))))
-
-
-(defun simula-find-if ()
- "Find starting IF of a IF-THEN[-ELSE[-IF-THEN...]] statement."
- (catch 'simula-out
- (while t
- (if (and (simula-search-backward "\\<if\\>\\|;\\|\\<begin\\>"nil t)
- (memq (following-char) '(?I ?i)))
- (save-excursion
- ;;
- ;; find out if this IF was really the start of the IF statement
- ;;
- (simula-skip-comment-backward)
- (if (and (eq (char-syntax (preceding-char)) ?w)
- (progn
- (backward-word 1)
- (looking-at "else\\>")))
- ()
- (throw 'simula-out t)))
- (if (not (looking-at "\\<if\\>"))
- (error "Missing IF or misplaced BEGIN or ';' (can't find IF)")
- ;;
- ;; we were at the starting IF in the first place..
- ;;
- (throw 'simula-out t))))))
-
-
-(defun simula-find-inspect ()
- "Find INSPECT matching WHEN or OTHERWISE."
- (catch 'simula-out
- (let ((level 0))
- ;;
- ;; INSPECTs can be nested, have to find the corresponding one
- ;;
- (while t
- (if (and (simula-search-backward "\\<inspect\\>\\|\\<otherwise\\>\\|;"
- nil t)
- (/= (following-char) ?\;))
- (if (memq (following-char) '(?O ?o))
- (setq level (1+ level))
- (if (zerop level)
- (throw 'simula-out t)
- (setq level (1- level))))
- (error "Missing INSPECT or misplaced ';' (can't find INSPECT)"))))))
-
-
-(defun simula-find-do-match ()
- "Find keyword matching DO: FOR, WHILE, INSPECT or WHEN"
- (while (and (re-search-backward
- "\\<\\(do\\|for\\|while\\|inspect\\|when\\|end\\|begin\\)\\>\\|;"
- nil 'move)
- (simula-context)))
- (if (and (looking-at "\\<\\(for\\|while\\|inspect\\|when\\)\\>")
- (not (simula-context)))
- () ;; found match
- (error "No matching FOR, WHILE or INSPECT for DO, or misplaced ';'")))
-
-
-(defun simula-inside-parens ()
- "Return position after `(' on line if inside parentheses, nil otherwise."
- (save-excursion
- (let ((parlevel 0))
- (catch 'simula-out
- (while t
- (if (re-search-backward "(\\|)\\|;" nil t)
- (if (eq (simula-context) nil)
- ;; found something - check it out
- (cond
- ((eq (following-char) ?\;)
- (if (zerop parlevel)
- (throw 'simula-out nil)
- (error "Parenthesis mismatch or misplaced ';'")))
- ((eq (following-char) ?\()
- (if (zerop parlevel)
- (throw 'simula-out (1+ (current-column)))
- (setq parlevel (1- parlevel))))
- (t (setq parlevel (1+ parlevel))))
- );; nothing - inside comment or string
- ;; search failed
- (throw 'simula-out nil)))))))
-
-
-(defun simula-goto-definition ()
- "Goto point of definition of variable, procedure or class."
- (interactive))
-
-
-(defun simula-expand-stdproc ()
- (if (or (not simula-abbrev-stdproc) (simula-context))
- (unexpand-abbrev)
- (cond
- ((eq simula-abbrev-stdproc 'upcase) (upcase-word -1))
- ((eq simula-abbrev-stdproc 'downcase) (downcase-word -1))
- ((eq simula-abbrev-stdproc 'capitalize) (capitalize-word -1)))))
-
-
-(defun simula-expand-keyword ()
- (if (or (not simula-abbrev-keyword) (simula-context))
- (unexpand-abbrev)
- (cond
- ((eq simula-abbrev-keyword 'upcase) (upcase-word -1))
- ((eq simula-abbrev-keyword 'downcase) (downcase-word -1))
- ((eq simula-abbrev-keyword 'capitalize) (capitalize-word -1)))))
-
-
-(defun simula-electric-keyword ()
- "Expand SIMULA keyword. If it starts the line, reindent."
- ;; redisplay
- (let ((show-char (eq this-command 'self-insert-command)))
- ;; If the abbrev expansion results in reindentation, the user may have
- ;; to wait some time before the character he typed is displayed
- ;; (the char causing the expansion is inserted AFTER the hook function
- ;; is called). This is annoying in case of normal characters.
- ;; However, if the user pressed a key bound to newline, it is better
- ;; to have the line inserted after the begin-end match.
- (if show-char
- (progn
- (insert-char last-command-char 1)
- (sit-for 0)
- (backward-char 1)))
- (if (let ((where (simula-context))
- (case-fold-search t))
- (if where
- (if (and (eq where 2) (eq (char-syntax (preceding-char)) ?w))
- (save-excursion
- (backward-word 1)
- (not (looking-at "end\\>"))))))
- (unexpand-abbrev)
- (cond
- ((not simula-abbrev-keyword) (unexpand-abbrev))
- ((eq simula-abbrev-keyword 'upcase) (upcase-word -1))
- ((eq simula-abbrev-keyword 'downcase) (downcase-word -1))
- ((eq simula-abbrev-keyword 'capitalize) (capitalize-word -1)))
- (let ((pos (- (point-max) (point)))
- (case-fold-search t)
- null)
- (condition-case null
- (progn
- ;; check if the expanded word is on the beginning of the line.
- (if (and (eq (char-syntax (preceding-char)) ?w)
- (progn
- (backward-word 1)
- (if (looking-at "end\\>")
- (save-excursion
- (simula-backward-up-level 1)
- (if (pos-visible-in-window-p)
- (sit-for 1)
- (message
- (concat "Matches "
- (buffer-substring
- (point)
- (+ (point) (window-width))))))))
- (skip-chars-backward " \t\f")
- (bolp)))
- (let ((indent (simula-calculate-indent)))
- (if (eq indent (current-indentation))
- ()
- (delete-horizontal-space)
- (indent-to indent)))
- (skip-chars-forward " \t\f"))
- ;; check for END - blow whistles and ring bells
-
- (goto-char (- (point-max) pos))
- (if show-char
- (delete-char 1)))
- (quit (goto-char (- (point-max) pos))))))))
-
-
-(defun simula-search-backward (string &optional limit move)
- (setq string (concat string "\\|\\<end\\>"))
- (let (level)
- (catch 'simula-out
- (while (re-search-backward string limit move)
- (if (simula-context)
- ()
- (if (looking-at "\\<end\\>")
- (progn
- (setq level 0)
- (while (natnump level)
- (re-search-backward "\\<begin\\>\\|\\<end\\>")
- (if (simula-context)
- ()
- (setq level (if (memq (following-char) '(?b ?B))
- (1- level)
- (1+ level))))))
- (throw 'simula-out t)))))))
-
-
-(defun simula-search-forward (string &optional limit move)
- (setq string (concat string "\\|\\<begin\\>"))
- (let (level)
- (catch 'exit
- (while (re-search-forward string limit move)
- (goto-char (match-beginning 0))
- (if (simula-context)
- (goto-char (1- (match-end 0)))
- (if (looking-at "\\<begin\\>")
- (progn
- (goto-char (1- (match-end 0)))
- (setq level 0)
- (while (natnump level)
- (re-search-forward "\\<begin\\>\\|\\<end\\>")
- (backward-word 1)
- (if (not (simula-context))
- (setq level (if (memq (following-char) '(?e ?E))
- (1- level)
- (1+ level))))
- (backward-word -1)))
- (goto-char (1- (match-end 0)))
- (throw 'exit t)))))))
-
-
-(defun simula-install-standard-abbrevs ()
- "Define Simula keywords, procedures and classes in local abbrev table."
- ;; procedure and class names are as of the SIMULA 87 standard.
- (interactive)
- (mapcar (function (lambda (args)
- (apply 'define-abbrev simula-mode-abbrev-table args)))
- '(("abs" "Abs" simula-expand-stdproc)
- ("accum" "Accum" simula-expand-stdproc)
- ("activate" "ACTIVATE" simula-expand-keyword)
- ("addepsilon" "AddEpsilon" simula-expand-stdproc)
- ("after" "AFTER" simula-expand-keyword)
- ("and" "AND" simula-expand-keyword)
- ("arccos" "ArcCos" simula-expand-stdproc)
- ("arcsin" "ArcSin" simula-expand-stdproc)
- ("arctan" "ArcTan" simula-expand-stdproc)
- ("arctan2" "ArcTan2" simula-expand-stdproc)
- ("array" "ARRAY" simula-expand-keyword)
- ("at" "AT" simula-expand-keyword)
- ("before" "BEFORE" simula-expand-keyword)
- ("begin" "BEGIN" simula-expand-keyword)
- ("blanks" "Blanks" simula-expand-stdproc)
- ("boolean" "BOOLEAN" simula-expand-keyword)
- ("breakoutimage" "BreakOutImage" simula-expand-stdproc)
- ("bytefile" "ByteFile" simula-expand-stdproc)
- ("call" "Call" simula-expand-stdproc)
- ("cancel" "Cancel" simula-expand-stdproc)
- ("cardinal" "Cardinal" simula-expand-stdproc)
- ("char" "Char" simula-expand-stdproc)
- ("character" "CHARACTER" simula-expand-keyword)
- ("checkpoint" "CheckPoint" simula-expand-stdproc)
- ("class" "CLASS" simula-expand-keyword)
- ("clear" "Clear" simula-expand-stdproc)
- ("clocktime" "ClockTime" simula-expand-stdproc)
- ("close" "Close" simula-expand-stdproc)
- ("comment" "COMMENT" simula-expand-keyword)
- ("constant" "Constant" simula-expand-stdproc)
- ("copy" "Copy" simula-expand-stdproc)
- ("cos" "Cos" simula-expand-stdproc)
- ("cosh" "CosH" simula-expand-stdproc)
- ("cotan" "CoTan" simula-expand-stdproc)
- ("cputime" "CpuTime" simula-expand-stdproc)
- ("current" "Current" simula-expand-stdproc)
- ("datetime" "DateTime" simula-expand-stdproc)
- ("decimalmark" "DecimalMark" simula-expand-stdproc)
- ("delay" "DELAY" simula-expand-keyword)
- ("deleteimage" "DeleteImage" simula-expand-stdproc)
- ("detach" "Detach" simula-expand-stdproc)
- ("digit" "Digit" simula-expand-stdproc)
- ("directbytefile" "DirectByteFile" simula-expand-stdproc)
- ("directfile" "DirectFile" simula-expand-stdproc)
- ("discrete" "Discrete" simula-expand-stdproc)
- ("do" "DO" simula-expand-keyword)
- ("downcase" "Downcase" simula-expand-stdproc)
- ("draw" "Draw" simula-expand-stdproc)
- ("eject" "Eject" simula-expand-stdproc)
- ("else" "ELSE" simula-electric-keyword)
- ("empty" "Empty" simula-expand-stdproc)
- ("end" "END" simula-electric-keyword)
- ("endfile" "Endfile" simula-expand-stdproc)
- ("entier" "Entier" simula-expand-stdproc)
- ("eq" "EQ" simula-expand-keyword)
- ("eqv" "EQV" simula-expand-keyword)
- ("erlang" "Erlang" simula-expand-stdproc)
- ("error" "Error" simula-expand-stdproc)
- ("evtime" "EvTime" simula-expand-stdproc)
- ("exp" "Exp" simula-expand-stdproc)
- ("external" "EXTERNAL" simula-expand-keyword)
- ("false" "FALSE" simula-expand-keyword)
- ("field" "Field" simula-expand-stdproc)
- ("file" "File" simula-expand-stdproc)
- ("first" "First" simula-expand-stdproc)
- ("follow" "Follow" simula-expand-stdproc)
- ("for" "FOR" simula-expand-keyword)
- ("ge" "GE" simula-expand-keyword)
- ("getchar" "GetChar" simula-expand-stdproc)
- ("getfrac" "GetFrac" simula-expand-stdproc)
- ("getint" "GetInt" simula-expand-stdproc)
- ("getreal" "GetReal" simula-expand-stdproc)
- ("go" "GO" simula-expand-keyword)
- ("goto" "GOTO" simula-expand-keyword)
- ("gt" "GT" simula-expand-keyword)
- ("head" "Head" simula-expand-stdproc)
- ("hidden" "HIDDEN" simula-expand-keyword)
- ("histd" "HistD" simula-expand-stdproc)
- ("histo" "Histo" simula-expand-stdproc)
- ("hold" "Hold" simula-expand-stdproc)
- ("idle" "Idle" simula-expand-stdproc)
- ("if" "IF" simula-expand-keyword)
- ("image" "Image" simula-expand-stdproc)
- ("imagefile" "ImageFile" simula-expand-stdproc)
- ("imp" "IMP" simula-expand-keyword)
- ("in" "IN" simula-expand-keyword)
- ("inbyte" "InByte" simula-expand-stdproc)
- ("inbytefile" "InByteFile" simula-expand-stdproc)
- ("inchar" "InChar" simula-expand-stdproc)
- ("infile" "InFile" simula-expand-stdproc)
- ("infrac" "InFrac" simula-expand-stdproc)
- ("inimage" "InImage" simula-expand-stdproc)
- ("inint" "InInt" simula-expand-stdproc)
- ("inner" "INNER" simula-expand-keyword)
- ("inreal" "InReal" simula-expand-stdproc)
- ("inrecord" "InRecord" simula-expand-stdproc)
- ("inspect" "INSPECT" simula-expand-keyword)
- ("integer" "INTEGER" simula-expand-keyword)
- ("intext" "InText" simula-expand-stdproc)
- ("into" "Into" simula-expand-stdproc)
- ("is" "IS" simula-expand-keyword)
- ("isochar" "ISOChar" simula-expand-stdproc)
- ("isopen" "IsOpen" simula-expand-stdproc)
- ("isorank" "ISORank" simula-expand-stdproc)
- ("label" "LABEL" simula-expand-keyword)
- ("last" "Last" simula-expand-stdproc)
- ("lastitem" "LastItem" simula-expand-stdproc)
- ("lastloc" "LastLoc" simula-expand-stdproc)
- ("le" "LE" simula-expand-keyword)
- ("length" "Length" simula-expand-stdproc)
- ("letter" "Letter" simula-expand-stdproc)
- ("line" "Line" simula-expand-stdproc)
- ("linear" "Linear" simula-expand-stdproc)
- ("linesperpage" "LinesPerPage" simula-expand-stdproc)
- ("link" "Link" simula-expand-stdproc)
- ("linkage" "Linkage" simula-expand-stdproc)
- ("ln" "Ln" simula-expand-stdproc)
- ("locate" "Locate" simula-expand-stdproc)
- ("location" "Location" simula-expand-stdproc)
- ("lock" "Lock" simula-expand-stdproc)
- ("locked" "Locked" simula-expand-stdproc)
- ("log10" "Log10" simula-expand-stdproc)
- ("long" "LONG" simula-expand-keyword)
- ("lowcase" "LowCase" simula-expand-stdproc)
- ("lowerbound" "LowerBound" simula-expand-stdproc)
- ("lowten" "LowTen" simula-expand-stdproc)
- ("lt" "LT" simula-expand-keyword)
- ("main" "Main" simula-expand-stdproc)
- ("max" "Max" simula-expand-stdproc)
- ("maxint" "MaxInt" simula-expand-stdproc)
- ("maxlongreal" "MaxLongReal" simula-expand-stdproc)
- ("maxloc" "MaxLoc" simula-expand-stdproc)
- ("maxrank" "MaxRank" simula-expand-stdproc)
- ("maxreal" "MaxReal" simula-expand-stdproc)
- ("min" "Min" simula-expand-stdproc)
- ("minint" "MinInt" simula-expand-stdproc)
- ("minlongreal" "MinLongReal" simula-expand-stdproc)
- ("minrank" "MinRank" simula-expand-stdproc)
- ("minreal" "MinReal" simula-expand-stdproc)
- ("mod" "Mod" simula-expand-stdproc)
- ("more" "More" simula-expand-stdproc)
- ("name" "NAME" simula-expand-keyword)
- ("ne" "NE" simula-expand-keyword)
- ("negexp" "NegExp" simula-expand-stdproc)
- ("new" "NEW" simula-expand-keyword)
- ("nextev" "NextEv" simula-expand-stdproc)
- ("none" "NONE" simula-expand-keyword)
- ("normal" "Normal" simula-expand-stdproc)
- ("not" "NOT" simula-expand-keyword)
- ("notext" "NOTEXT" simula-expand-keyword)
- ("open" "Open" simula-expand-stdproc)
- ("or" "OR" simula-expand-keyword)
- ("otherwise" "OTHERWISE" simula-electric-keyword)
- ("out" "Out" simula-expand-stdproc)
- ("outbyte" "OutByte" simula-expand-stdproc)
- ("outbytefile" "OutByteFile" simula-expand-stdproc)
- ("outchar" "OutChar" simula-expand-stdproc)
- ("outfile" "OutFile" simula-expand-stdproc)
- ("outfix" "OutFix" simula-expand-stdproc)
- ("outfrac" "OutFrac" simula-expand-stdproc)
- ("outimage" "OutImage" simula-expand-stdproc)
- ("outint" "OutInt" simula-expand-stdproc)
- ("outreal" "OutReal" simula-expand-stdproc)
- ("outrecord" "OutRecord" simula-expand-stdproc)
- ("outtext" "OutText" simula-expand-stdproc)
- ("page" "Page" simula-expand-stdproc)
- ("passivate" "Passivate" simula-expand-stdproc)
- ("poisson" "Poisson" simula-expand-stdproc)
- ("pos" "Pos" simula-expand-stdproc)
- ("precede" "Precede" simula-expand-stdproc)
- ("pred" "Pred" simula-expand-stdproc)
- ("prev" "Prev" simula-expand-stdproc)
- ("printfile" "PrintFile" simula-expand-stdproc)
- ("prior" "PRIOR" simula-expand-keyword)
- ("procedure" "PROCEDURE" simula-expand-keyword)
- ("process" "Process" simula-expand-stdproc)
- ("protected" "PROTECTED" simula-expand-keyword)
- ("putchar" "PutChar" simula-expand-stdproc)
- ("putfix" "PutFix" simula-expand-stdproc)
- ("putfrac" "PutFrac" simula-expand-stdproc)
- ("putint" "PutInt" simula-expand-stdproc)
- ("putreal" "PutReal" simula-expand-stdproc)
- ("qua" "QUA" simula-expand-keyword)
- ("randint" "RandInt" simula-expand-stdproc)
- ("rank" "Rank" simula-expand-stdproc)
- ("reactivate" "REACTIVATE" simula-expand-keyword)
- ("real" "REAL" simula-expand-keyword)
- ("ref" "REF" simula-expand-keyword)
- ("resume" "Resume" simula-expand-stdproc)
- ("setaccess" "SetAccess" simula-expand-stdproc)
- ("setpos" "SetPos" simula-expand-stdproc)
- ("short" "SHORT" simula-expand-keyword)
- ("sign" "Sign" simula-expand-stdproc)
- ("simset" "SimSet" simula-expand-stdproc)
- ("simulaid" "SimulaId" simula-expand-stdproc)
- ("simulation" "Simulation" simula-expand-stdproc)
- ("sin" "Sin" simula-expand-stdproc)
- ("sinh" "SinH" simula-expand-stdproc)
- ("sourceline" "SourceLine" simula-expand-stdproc)
- ("spacing" "Spacing" simula-expand-stdproc)
- ("sqrt" "Sqrt" simula-expand-stdproc)
- ("start" "Start" simula-expand-stdproc)
- ("step" "STEP" simula-expand-keyword)
- ("strip" "Strip" simula-expand-stdproc)
- ("sub" "Sub" simula-expand-stdproc)
- ("subepsilon" "SubEpsilon" simula-expand-stdproc)
- ("suc" "Suc" simula-expand-stdproc)
- ("switch" "SWITCH" simula-expand-keyword)
- ("sysin" "SysIn" simula-expand-stdproc)
- ("sysout" "SysOut" simula-expand-stdproc)
- ("tan" "Tan" simula-expand-stdproc)
- ("tanh" "TanH" simula-expand-stdproc)
- ("terminate_program" "Terminate_Program" simula-expand-stdproc)
- ("terminated" "Terminated" simula-expand-stdproc)
- ("text" "TEXT" simula-expand-keyword)
- ("then" "THEN" simula-electric-keyword)
- ("this" "THIS" simula-expand-keyword)
- ("time" "Time" simula-expand-stdproc)
- ("to" "TO" simula-expand-keyword)
- ("true" "TRUE" simula-expand-keyword)
- ("uniform" "Uniform" simula-expand-stdproc)
- ("unlock" "Unlock" simula-expand-stdproc)
- ("until" "UNTIL" simula-expand-keyword)
- ("upcase" "Upcase" simula-expand-stdproc)
- ("upperbound" "UpperBound" simula-expand-stdproc)
- ("value" "VALUE" simula-expand-keyword)
- ("virtual" "VIRTUAL" simula-expand-keyword)
- ("wait" "Wait" simula-expand-stdproc)
- ("when" "WHEN" simula-electric-keyword)
- ("while" "WHILE" simula-expand-keyword))))
-
-;;; simula.el ends here
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
deleted file mode 100644
index 02466483e19..00000000000
--- a/lisp/progmodes/tcl.el
+++ /dev/null
@@ -1,1816 +0,0 @@
-;; tcl.el --- Tcl code editing commands for Emacs
-
-;; Copyright (C) 1994 Free Software Foundation, Inc.
-
-;; Maintainer: Tom Tromey <tromey@busco.lanl.gov>
-;; Author: Tom Tromey <tromey@busco.lanl.gov>
-;; Chris Lindblad <cjl@lcs.mit.edu>
-;; Keywords: languages tcl modes
-;; Version: $Revision: 1.4 $
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 1, or (at your option)
-;; any later version.
-
-;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
-;; HOW TO INSTALL:
-;; Put the following forms in your .emacs to enable autoloading of Tcl
-;; mode, and auto-recognition of ".tcl" files.
-;;
-;; (autoload 'tcl-mode "tcl" "Tcl mode." t)
-;; (autoload 'inferior-tcl "tcl" "Run inferior Tcl process." t)
-;; (setq auto-mode-alist (append '(("\\.tcl$" . tcl-mode)) auto-mode-alist))
-;;
-;; If you plan to use the interface to the TclX help files, you must
-;; set the variable tcl-help-directory to point to the topmost
-;; directory containing the TclX help files. Eg:
-;;
-;; (setq tcl-help-directory "/usr/local/lib/tclx/help")
-;;
-;; Also you will want to add the following to your .emacs:
-;;
-;; (autoload 'tcl-help-on-word "tcl" "Help on Tcl commands" t)
-;;
-;; FYI a *very* useful thing to do is nroff all the Tk man pages and
-;; put them in a subdir of the help system.
-;;
-
-;;; Commentary:
-
-;; LCD Archive Entry:
-;; tcl|Tom Tromey|tromey@busco.lanl.gov|
-;; Major mode for editing Tcl|
-;; $Date: 1994/04/07 00:23:36 $|$Revision: 1.4 $|~/modes/tcl.el.Z|
-
-;; CUSTOMIZATION NOTES:
-;; * tcl-proc-list can be used to customize a list of things that
-;; "define" other things. Eg in my project I put "defvar" in this
-;; list.
-;; * tcl-typeword-list is similar, but uses font-lock-type-face.
-;; * tcl-keyword-list is a list of keywords. I've generally used this
-;; for flow-control words. Eg I add "unwind_protect" to this list.
-;; * tcl-type-alist can be used to minimally customize indentation
-;; according to context.
-
-;; Change log:
-;; 18-Mar-1994 Tom Tromey Fourth beta release.
-;; Added {un,}comment-region to menu. Idea from
-;; Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
-;; 17-Mar-1994 Tom Tromey
-;; Fixed tcl-restart-with-file. Bug fix attempt in
-;; tcl-internal-end-of-defun.
-;; 16-Mar-1994 Tom Tromey Third beta release
-;; Added support code for menu (from Tcl mode written by
-;; schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid)).
-;; 12-Mar-1994 Tom Tromey
-;; Better documentation for inferior-tcl-buffer. Wrote
-;; tcl-restart-with-file. Wrote Lucid Emacs menu (but no
-;; code to install it).
-;; 12-Mar-1994 Tom Tromey
-;; Wrote tcl-guess-application. Another stab at making
-;; tcl-omit-ws-regexp work.
-;; 10-Mar-1994 Tom Tromey Second beta release
-;; Last Modified: Thu Mar 10 01:24:25 1994 (Tom Tromey)
-;; Wrote perl-mode style line indentation command.
-;; Wrote more documentation. Added tcl-continued-indent-level.
-;; Integrated help code.
-;; 8-Mar-1994 Tom Tromey
-;; Last Modified: Tue Mar 8 11:58:44 1994 (Tom Tromey)
-;; Bug fixes.
-;; 6-Mar-1994 Tom Tromey
-;; Last Modified: Sun Mar 6 18:55:41 1994 (Tom Tromey)
-;; Updated auto-newline support.
-;; 6-Mar-1994 Tom Tromey Beta release
-;; Last Modified: Sat Mar 5 17:24:32 1994 (Tom Tromey)
-;; Wrote tcl-hashify-buffer. Other minor bug fixes.
-;; 5-Mar-1994 Tom Tromey
-;; Last Modified: Sat Mar 5 16:11:20 1994 (Tom Tromey)
-;; Wrote electric-hash code.
-;; 3-Mar-1994 Tom Tromey
-;; Last Modified: Thu Mar 3 02:53:40 1994 (Tom Tromey)
-;; Added code to handle auto-fill in comments.
-;; Added imenu support code.
-;; Cleaned up code.
-;; Better font-lock support.
-;; 28-Feb-1994 Tom Tromey
-;; Last Modified: Mon Feb 28 14:08:05 1994 (Tom Tromey)
-;; Made tcl-figure-type more easily configurable.
-;; 28-Feb-1994 Tom Tromey
-;; Last Modified: Mon Feb 28 01:02:58 1994 (Tom Tromey)
-;; Wrote inferior-tcl mode.
-;; 16-Feb-1994 Tom Tromey
-;; Last Modified: Wed Feb 16 17:05:19 1994 (Tom Tromey)
-;; Added support for font-lock-mode.
-;; 29-Oct-1993 Tom Tromey
-;; Last Modified: Sun Oct 24 17:39:14 1993 (Tom Tromey)
-;; Patches from Guido Bosch to make things work with Lucid Emacs.
-;; 22-Oct-1993 Tom Tromey
-;; Last Modified: Fri Oct 22 15:26:46 1993 (Tom Tromey)
-;; Made many characters have "_" syntax class; suggested by Guido
-;; Bosch <Guido.Bosch@loria.fr>. Note that this includes the "$"
-;; character, which might be a change you'd notice.
-;; 21-Oct-1993 Tom Tromey
-;; Last Modified: Thu Oct 21 20:28:40 1993 (Tom Tromey)
-;; More fixes for tcl-omit-ws-regexp.
-;; 20-Oct-1993 Tom Tromey
-;; Started keeping history. Fixed tcl-{beginning,end}-of-defun.
-;; Added some code to make things work with Emacs 18.
-
-;; THANKS TO:
-;; Guido Bosch <Guido.Bosch@loria.fr>
-;; pgs1002@esc.cam.ac.uk (Dr P.G. Sjoerdsma)
-;; Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
-;; Matt Newman <men@charney.colorado.edu>
-;; rwhitby@research.canon.oz.au (Rod Whitby)
-;; h9118101@hkuxa.hku.hk (Yip Chi Lap [Beta])
-;; Pertti Tapio Kasanen <ptk@delta.hut.fi>
-;; schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid)
-
-;; KNOWN BUGS:
-;; * indent-region should skip blank lines. (It does in v19, so I'm
-;; not motivated to fix it here).
-;; * In Tcl "#" is not always a comment character. This can confuse
-;; tcl.el in certain circumstances. For now the only workaround is
-;; to enclose offending hash characters in quotes or precede it with
-;; a backslash. Note that using braces won't work -- quotes change
-;; the syntax class of characters between them, while braces do not.
-;; The electric-# mode helps alleviate this problem somewhat.
-;; * indent-tcl-exp is untested.
-;; * Doesn't work under Emacs 18 yet.
-;; * There's been a report that font-lock does strange things under
-;; Lucid Emacs 19.6. For instance in "proc foobar", the space
-;; before "foobar" is highlighted.
-
-;; TODO:
-;; * make add-log-tcl-defun smarter. should notice if we are in the
-;; middle of a defun, or between defuns. should notice if point is
-;; on first line of defun (or maybe even in comments before defun).
-;; * Allow continuation lines to be indented under the first argument
-;; of the preceeding line, like this:
-;; [list something \
-;; something-else]
-;; * There is a request that indentation work like this:
-;; button .fred -label Fred \
-;; -command {puts fred}
-;; * Should have tcl-complete-symbol that queries the inferior process.
-;; * Should have describe-symbol that works by sending the magic
-;; command to a tclX process.
-;; * Need C-x C-e binding (tcl-eval-last-exp).
-;; * Write indent-region function that is faster than indenting each
-;; line individually.
-;; * tcl-figure-type should stop at "beginning of line" (only ws
-;; before point, and no "\" on previous line). (see tcl-real-command-p).
-;; * Fix beginning-of-defun. I believe this will be fully possible in
-;; FSF Emacs 19.23
-;; * overrides some comint keybindings; fix.
-;; * Trailing \ will eat blank lines. Should deal with this.
-;; (this would help catch some potential bugs).
-;; * Inferior should display in half the screen, not the whole screen.
-
-
-
-;;; Code:
-
-(require 'comint)
-
-;;
-;; User variables.
-;;
-
-(defvar tcl-indent-level 4
- "*Indentation of Tcl statements with respect to containing block.")
-
-(defvar tcl-continued-indent-level 4
- "*Indentation of continuation line relative to first line of command.")
-
-(defvar tcl-auto-newline nil
- "*Non-nil means automatically newline before and after braces
-inserted in Tcl code.")
-
-(defvar tcl-tab-always-indent t
- "*Control effect of TAB key.
-If t (the default), always indent current line.
-If nil and point is not in the indentation area at the beginning of
-the line, a TAB is inserted.
-Other values cause the first possible action from the following list
-to take place:
-
- 1. Move from beginning of line to correct indentation.
- 2. Delete an empty comment.
- 3. Move forward to start of comment, indenting if necessary.
- 4. Move forward to end of line, indenting if necessary.
- 5. Create an empty comment.
- 6. Move backward to start of comment, indenting if necessary.")
-
-(defvar tcl-use-hairy-comment-detector t
- "*If not `nil', the the more complicated, but slower, comment
-detecting function is used. This variable is only used in GNU Emacs
-19 (the fast function is always used elsewhere).")
-
-(defvar tcl-electric-hash-style 'smart
- "*Style of electric hash insertion to use.
-Possible values are 'backslash, meaning that `\\' quoting should be
-done; `quote, meaning that `\"' quoting should be done; 'smart,
-meaning that the choice between 'backslash and 'quote should be
-made depending on the number of hashes inserted; or nil, meaning that
-no quoting should be done. Any other value for this variable is
-taken to mean 'smart. The default is 'smart.")
-
-(defvar tcl-help-directory nil
- "*Name of topmost directory containing TclX help files")
-
-(defvar tcl-use-smart-word-finder t
- "*If not nil, use a better way of finding the current word when
-looking up help on a Tcl command.")
-
-(defvar tcl-application "wish"
- "*Name of Tcl application to run in inferior Tcl mode.")
-
-(defvar tcl-command-switches nil
- "*Switches to supply to `tcl-application'.")
-
-(defvar tcl-prompt-regexp "^\\(% \\|\\)"
- "*If not nil, a regexp that will match the prompt in the inferior process.
-If nil, the prompt is the name of the application with \">\" appended.
-
-The default is \"^\\(% \\|\\)\", which will match the default primary
-and secondary prompts for tclsh and wish.")
-
-(defvar inferior-tcl-source-command "source %s\n"
- "*Format-string for building a Tcl command to load a file.
-This format string should use `%s' to substitute a file name
-and should result in a Tcl expression that will command the
-inferior Tcl to load that file. The filename will be appropriately
-quoted for Tcl.")
-
-;;
-;; Keymaps, abbrevs, syntax tables.
-;;
-
-(defvar tcl-mode-abbrev-table nil
- "Abbrev table in use in Tcl-mode buffers.")
-(if tcl-mode-abbrev-table
- ()
- (define-abbrev-table 'tcl-mode-abbrev-table ()))
-
-;; I sure wish Emacs had a package that made it easy to extract this
-;; sort of information.
-(defconst tcl-using-emacs-19 (string-match "19\\." emacs-version)
- "Nil unless using Emacs 19 (Lucid or FSF).")
-
-;; FIXME this will break on Emacs 19.100.
-(defconst tcl-using-emacs-19.23
- (string-match "19\\.\\(2[3-9]\\|[3-9][0-9]\\)" emacs-version)
- "Nil unless using Emacs 19.23 or later.")
-
-(defconst tcl-using-lemacs-19 (string-match "Lucid" emacs-version)
- "Nil unless using Lucid Emacs).")
-
-(defvar tcl-mode-map ()
- "Keymap used in Tcl mode.")
-(if tcl-mode-map
- ()
- (setq tcl-mode-map (make-sparse-keymap))
- (define-key tcl-mode-map "{" 'tcl-electric-char)
- (define-key tcl-mode-map "}" 'tcl-electric-brace)
- (define-key tcl-mode-map "[" 'tcl-electric-char)
- (define-key tcl-mode-map "]" 'tcl-electric-char)
- (define-key tcl-mode-map ";" 'tcl-electric-char)
- (define-key tcl-mode-map "#" 'tcl-electric-hash)
- ;; FIXME.
- (define-key tcl-mode-map "\e\C-a" 'tcl-beginning-of-defun)
- ;; FIXME.
- (define-key tcl-mode-map "\e\C-e" 'tcl-end-of-defun)
- ;; FIXME.
- (define-key tcl-mode-map "\e\C-h" 'mark-tcl-function)
- (define-key tcl-mode-map "\e\C-q" 'indent-tcl-exp)
- (define-key tcl-mode-map "\177" 'backward-delete-char-untabify)
- (define-key tcl-mode-map "\t" 'tcl-indent-command)
- (define-key tcl-mode-map "\M-\C-x" 'tcl-eval-defun)
- (and (fboundp 'comment-region)
- (define-key tcl-mode-map "\C-c\C-c" 'comment-region))
- (define-key tcl-mode-map "\C-c\C-d" 'tcl-help-on-word)
- (define-key tcl-mode-map "\C-c\C-e" 'tcl-eval-defun)
- (define-key tcl-mode-map "\C-c\C-l" 'tcl-load-file)
- (define-key tcl-mode-map "\C-c\C-p" 'inferior-tcl)
- (define-key tcl-mode-map "\C-c\C-r" 'tcl-eval-region)
- (define-key tcl-mode-map "\C-c\C-z" 'switch-to-tcl))
-
-(defvar tcl-mode-syntax-table nil
- "Syntax table in use in Tcl-mode buffers.")
-(if tcl-mode-syntax-table
- ()
- (setq tcl-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?% "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?@ "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?& "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?* "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?+ "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?- "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?. "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?: "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?! "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?$ "_" tcl-mode-syntax-table) ; FIXME use "'"?
- (modify-syntax-entry ?/ "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?~ "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?< "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?= "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?> "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?| "_" tcl-mode-syntax-table)
- (modify-syntax-entry ?\( "()" tcl-mode-syntax-table)
- (modify-syntax-entry ?\) ")(" tcl-mode-syntax-table)
- (modify-syntax-entry ?\; "." tcl-mode-syntax-table)
- (modify-syntax-entry ?\n "> " tcl-mode-syntax-table)
- (modify-syntax-entry ?\f "> " tcl-mode-syntax-table)
- (modify-syntax-entry ?# "< " tcl-mode-syntax-table))
-
-(defvar inferior-tcl-mode-map nil
- "Keymap used in Inferior Tcl mode.")
-(if inferior-tcl-mode-map
- ()
- ;; FIXME Use keymap inheritance here? FIXME we override comint
- ;; keybindings here. Maybe someone has a better set?
- (setq inferior-tcl-mode-map (copy-keymap comint-mode-map))
- (define-key inferior-tcl-mode-map "\e\C-a" 'tcl-beginning-of-defun)
- (define-key inferior-tcl-mode-map "\e\C-e" 'tcl-end-of-defun)
- (define-key inferior-tcl-mode-map "\177" 'backward-delete-char-untabify)
- (define-key inferior-tcl-mode-map "\M-\C-x" 'tcl-eval-defun)
- (define-key inferior-tcl-mode-map "\C-c\C-d" 'tcl-help-on-word)
- (define-key inferior-tcl-mode-map "\C-c\C-e" 'tcl-eval-defun)
- (define-key inferior-tcl-mode-map "\C-c\C-l" 'tcl-load-file)
- (define-key inferior-tcl-mode-map "\C-c\C-p" 'inferior-tcl)
- (define-key inferior-tcl-mode-map "\C-c\C-r" 'tcl-eval-region)
- (define-key inferior-tcl-mode-map "\C-c\C-z" 'switch-to-tcl))
-
-;; Lucid Emacs menu.
-(defvar tcl-lucid-menu
- '("Tcl"
- ["Beginning of function" tcl-beginning-of-defun t]
- ["End of function" tcl-end-of-defun t]
- ["Mark function" mark-tcl-function t]
- ["Indent region" indent-region t]
- ["Comment region" comment-region t]
- ["Uncomment region" tcl-uncomment-region t]
- "----"
- ["Show Tcl process buffer" inferior-tcl t]
- ["Send function to Tcl process" tcl-eval-defun t]
- ["Send region to Tcl process" tcl-eval-region t]
- ["Send file to Tcl process" tcl-load-file t]
- ["Restart Tcl process with file" tcl-restart-with-file t]
- "----"
- ["Tcl help" tcl-help-on-word t]))
-
-(defvar inferior-tcl-buffer nil
- "*The current inferior-tcl process buffer.
-
-MULTIPLE PROCESS SUPPORT
-===========================================================================
-To run multiple Tcl processes, you start the first up with
-\\[inferior-tcl]. It will be in a buffer named `*inferior-tcl*'.
-Rename this buffer with \\[rename-buffer]. You may now start up a new
-process with another \\[inferior-tcl]. It will be in a new buffer,
-named `*inferior-tcl*'. You can switch between the different process
-buffers with \\[switch-to-buffer].
-
-Commands that send text from source buffers to Tcl processes -- like
-`tcl-eval-defun' or `tcl-load-file' -- have to choose a process to
-send to, when you have more than one Tcl process around. This is
-determined by the global variable `inferior-tcl-buffer'. Suppose you
-have three inferior Lisps running:
- Buffer Process
- foo inferior-tcl
- bar inferior-tcl<2>
- *inferior-tcl* inferior-tcl<3>
-If you do a \\[tcl-eval-defun] command on some Lisp source code, what
-process do you send it to?
-
-- If you're in a process buffer (foo, bar, or *inferior-tcl*),
- you send it to that process.
-- If you're in some other buffer (e.g., a source file), you
- send it to the process attached to buffer `inferior-tcl-buffer'.
-This process selection is performed by function `inferior-tcl-proc'.
-
-Whenever \\[inferior-tcl] fires up a new process, it resets
-`inferior-tcl-buffer' to be the new process's buffer. If you only run
-one process, this does the right thing. If you run multiple
-processes, you can change `inferior-tcl-buffer' to another process
-buffer with \\[set-variable].")
-
-;;
-;; Hooks and other customization.
-;;
-
-(defvar tcl-mode-hook nil
- "Hook run on entry to Tcl mode.
-
-Several functions exist which are useful to run from your
-`tcl-mode-hook' (see each function's documentation for more
-information):
-
- tcl-install-menubar
- Puts a \"Tcl\" menu on the menubar. Doesn't work in Emacs 18.
- tcl-guess-application
- Guesses a default setting for `tcl-application' based on any
- \"#!\" line at the top of the file.
- tcl-hashify-buffer
- Quotes all \"#\" characters that don't correspond to actual
- Tcl comments. (Useful when editing code not originally created
- with this mode).
- tcl-auto-fill-mode
- Auto-filling of Tcl comments.
-
-Emacs 19 users can add functions to the hook with `add-hook':
-
- (add-hook 'tcl-mode-hook 'tcl-guess-application)
-
-Emacs 18 users must use `setq':
-
- (setq tcl-mode-hook (cons 'tcl-guess-application tcl-mode-hook))")
-
-
-(defvar inferior-tcl-mode-hook nil
- "Hook for customizing Inferior Tcl mode.")
-
-(defvar tcl-proc-list
- '("proc")
- "List of commands whose first argument defines something.
-This exists because some people (eg, me) use \"defvar\" et al.
-Call `tcl-set-proc-regexp' and `tcl-set-font-lock-keywords'
-after changing this list.")
-
-(defvar tcl-proc-regexp nil
- "Regexp to use when matching proc headers.")
-
-(defvar tcl-typeword-list
- '("global" "upvar")
- "List of Tcl keywords deonting \"type\". Used only for highlighting.
-Call `tcl-set-font-lock-keywords' after changing this list.")
-
-;; Generally I've picked control operators to be keywords.
-(defvar tcl-keyword-list
- '("if" "then" "else" "elseif" "for" "foreach" "break" "continue" "while"
- "eval" "case" "in" "switch" "default" "exit" "error" "proc" "return"
- "uplevel" "loop" "for_array_keys" "for_recursive_glob" "for_file")
- "List of Tcl keywords. Used only for highlighting.
-Default list includes some TclX keywords.
-Call `tcl-set-font-lock-keywords' after changing this list.")
-
-(defvar tcl-font-lock-keywords nil
- "Keywords to highlight for Tcl. See variable `font-lock-keywords'.
-This variable is generally set from `tcl-proc-regexp',
-`tcl-typeword-list', and `tcl-keyword-list' by the function
-`tcl-set-font-lock-keywords'.")
-
-;; FIXME need some way to recognize variables because array refs look
-;; like 2 sexps.
-(defvar tcl-type-alist
- '(
- ("expr" tcl-expr)
- ("catch" tcl-commands)
- ("if" tcl-expr "then" tcl-commands)
- ("elseif" tcl-expr "then" tcl-commands)
- ("elseif" tcl-expr tcl-commands)
- ("if" tcl-expr tcl-commands)
- ("while" tcl-expr tcl-commands)
- ("for" tcl-commands tcl-expr tcl-commands tcl-commands)
- ("foreach" nil nil tcl-commands)
- ("for_file" nil nil tcl-commands)
- ("for_array_keys" nil nil tcl-commands)
- ("for_recursive_glob" nil nil nil tcl-commands)
- ;; Loop handling is not perfect, because the third argument can be
- ;; either a command or an expr, and there is no real way to look
- ;; forward.
- ("loop" nil tcl-expr tcl-expr tcl-commands)
- ("loop" nil tcl-expr tcl-commands)
- )
- "Alist that controls indentation.
-\(Actually, this really only controls what happens on continuation lines).
-Each entry looks like `(KEYWORD TYPE ...)'.
-Each type entry describes a sexp after the keyword, and can be one of:
-* nil, meaning that this sexp has no particular type.
-* tcl-expr, meaning that this sexp is an arithmetic expression.
-* tcl-commands, meaning that this sexp holds Tcl commands.
-* a string, which must exactly match the string at the corresponding
- position for a match to be made.
-
-For example, the entry for the \"loop\" command is:
-
- (\"loop\" nil tcl-expr tcl-commands)
-
-This means that the \"loop\" command has three arguments. The first
-argument is ignored (for indentation purposes). The second argument
-is a Tcl expression, and the last argument is Tcl commands.")
-
-(defvar tcl-explain-indentation nil
- "If not `nil', debugging message will be printed during indentation.")
-
-
-
-;;
-;; Work around differences between various versions of Emacs.
-;;
-
-;; We use this because Lemacs 19.9 has what we need.
-(defconst tcl-pps-has-arg-6
- (or tcl-using-emacs-19
- (and tcl-using-lemacs-19
- (condition-case nil
- (progn
- (parse-partial-sexp (point) (point) nil nil nil t)
- t)
- (error nil))))
- "t if using an emacs which supports sixth (\"commentstop\") argument
-to parse-partial-sexp.")
-
-;; Its pretty bogus to have to do this, but there is no easier way to
-;; say "match not syntax-1 and not syntax-2". Too bad you can't put
-;; \s in [...]. This sickness is used in Emacs 19 to match a defun
-;; starter. (It is used for this in v18 as well).
-;;(defconst tcl-omit-ws-regexp
-;; (concat "^\\(\\s"
-;; (mapconcat 'char-to-string "w_.()\"\\$'/" "\\|\\s")
-;; "\\)\\S(*")
-;; "Regular expression that matches everything except space, comment
-;;starter, and comment ender syntax codes.")
-
-;; FIXME? Instead of using the hairy regexp above, we just use a
-;; simple one.
-;;(defconst tcl-omit-ws-regexp "^[^] \t\n#}]\\S(*"
-;; "Regular expression used in locating function definitions.")
-
-;; Here's another stab. I think this one actually works. Now the
-;; problem seems to be that there is a bug in Emacs 19.22 where
-;; end-of-defun doesn't really use the brace matching the one that
-;; trails defun-prompt-regexp.
-(defconst tcl-omit-ws-regexp "^[^ \t\n#}][^\n}]+}*[ \t]+")
-
-(defun tcl-internal-beginning-of-defun (&optional arg)
- "Move backward to next beginning-of-defun.
-With argument, do this that many times.
-Returns t unless search stops due to end of buffer."
- (interactive "p")
- (if (or (null arg) (= arg 0))
- (setq arg 1))
- (let (success)
- (while (progn
- (setq arg (1- arg))
- (and (>= arg 0)
- (setq success
- (re-search-backward tcl-omit-ws-regexp nil 'move 1))))
- (while (and (looking-at "[]#}]")
- (setq success
- (re-search-backward tcl-omit-ws-regexp nil 'move 1)))))
- (beginning-of-line)
- (not (null success))))
-
-(defun tcl-internal-end-of-defun (&optional arg)
- "Move forward to next end of defun.
-An end of a defun is found by moving forward from the beginning of one."
- (interactive "p")
- (if (or (null arg) (= arg 0)) (setq arg 1))
- (let ((start (point)))
- ;; Was forward-char. I think this works a little better.
- (forward-line)
- (tcl-beginning-of-defun)
- (while (> arg 0)
- (while (and (re-search-forward tcl-omit-ws-regexp nil 'move 1)
- (progn (beginning-of-line) t)
- (looking-at "[]#}]")
- (progn (forward-line) t)))
- (let ((next-line (save-excursion
- (forward-line)
- (point))))
- (while (< (point) next-line)
- (forward-sexp)))
- (forward-line)
- (if (> (point) start) (setq arg (1- arg))))))
-
-;; In Emacs 19, we can use begining-of-defun as long as we set up a
-;; certain regexp. In Emacs 18, we need our own function.
-(fset 'tcl-beginning-of-defun
- (if tcl-using-emacs-19
- 'beginning-of-defun
- 'tcl-internal-beginning-of-defun))
-
-;; Only FSF Emacs 19 works correctly using end-of-defun. Emacs 18 and
-;; Lucid need our own function.
-(fset 'tcl-end-of-defun
- (if (and tcl-using-emacs-19 (not tcl-using-lemacs-19))
- 'end-of-defun
- 'tcl-internal-end-of-defun))
-
-
-
-;;
-;; Some helper functions.
-;;
-
-(defun tcl-set-proc-regexp ()
- "Set `tcl-proc-regexp' from variable `tcl-proc-list'."
- (setq tcl-proc-regexp (concat "^\\("
- (mapconcat 'identity tcl-proc-list "\\|")
- "\\)[ \t]+")))
-
-(defun tcl-set-font-lock-keywords ()
- "Set `tcl-font-lock-keywords'.
-Uses variables `tcl-proc-regexp' and `tcl-keyword-list'."
- (setq tcl-font-lock-keywords
- (list
- ;; Names of functions (and other "defining things").
- (list (concat tcl-proc-regexp "\\([^ \t\n]+\\)")
- 2 'font-lock-function-name-face)
-
- ;; Names of type-defining things.
- (list (concat "\\(\\s-\\|^\\)\\("
- ;; FIXME Use 'regexp-quote?
- (mapconcat 'identity tcl-typeword-list "\\|")
- "\\)\\(\\s-\\|$\\)")
- 2 'font-lock-type-face)
-
- ;; Keywords. Only recognized if surrounded by whitespace.
- ;; FIXME consider using "not word or symbol", not
- ;; "whitespace".
- (cons (concat "\\(\\s-\\|^\\)\\("
- ;; FIXME Use regexp-quote?
- (mapconcat 'identity tcl-keyword-list "\\|")
- "\\)\\(\\s-\\|$\\)")
- 2)
- )))
-
-(if tcl-proc-regexp
- ()
- (tcl-set-proc-regexp))
-
-(if tcl-font-lock-keywords
- ()
- (tcl-set-font-lock-keywords))
-
-
-
-;;
-;; The mode itself.
-;;
-
-(defun tcl-mode ()
- "Major mode for editing Tcl code.
-Expression and list commands understand all Tcl brackets.
-Tab indents for Tcl code.
-Paragraphs are separated by blank lines only.
-Delete converts tabs to spaces as it moves back.
-
-Variables controlling indentation style:
- tcl-indent-level
- Indentation of Tcl statements within surrounding block.
- tcl-continued-indent-level
- Indentation of continuation line relative to first line of command.
-
-Variables controlling user interaction with mode (see variable
-documentation for details):
- tcl-tab-always-indent
- Controls action of TAB key.
- tcl-auto-newline
- Non-nil means automatically newline before and after braces, brackets,
- and semicolons inserted in Tcl code.
- tcl-electric-hash-style
- Controls action of `#' key.
- tcl-use-hairy-comment-detector
- If t, use more complicated, but slower, comment detector.
- This variable is only used in GNU Emacs 19.
-
-Turning on Tcl mode calls the value of the variable `tcl-mode-hook'
-with no args, if that value is non-nil. Read the documentation for
-`tcl-mode-hook' to see what kinds of interesting hook functions
-already exist.
-
-Commands:
-\\{tcl-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (use-local-map tcl-mode-map)
- (setq major-mode 'tcl-mode)
- (setq mode-name "Tcl")
- (setq local-abbrev-table tcl-mode-abbrev-table)
- (set-syntax-table tcl-mode-syntax-table)
- (make-local-variable 'paragraph-start)
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (make-local-variable 'paragraph-separate)
- (setq paragraph-separate paragraph-start)
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'tcl-indent-line)
- ;; Tcl doesn't require a final newline.
- ;; (make-local-variable 'require-final-newline)
- ;; (setq require-final-newline t)
- (make-local-variable 'comment-start)
- (setq comment-start "# ")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "#+ *")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-end)
- (setq comment-end "")
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords tcl-font-lock-keywords)
- (setq imenu-create-index-function 'tcl-imenu-create-index-function)
- (make-local-variable 'parse-sexp-ignore-comments)
- (if tcl-using-emacs-19
- (progn
- ;; This can only be set to t in Emacs 19 and Lucid Emacs.
- ;; Emacs 18 and Epoch lose.
- (setq parse-sexp-ignore-comments t)
- ;; Lucid Emacs has defun-prompt-regexp, but I don't believe
- ;; that it works for end-of-defun -- only for
- ;; beginning-of-defun.
- (make-local-variable 'defun-prompt-regexp)
- (setq defun-prompt-regexp tcl-omit-ws-regexp)
- ;; The following doesn't work in Lucid Emacs 19.6, but maybe
- ;; it will appear in later versions.
- (make-local-variable 'add-log-current-defun-function)
- (setq add-log-current-defun-function 'add-log-tcl-defun))
- (setq parse-sexp-ignore-comments nil))
- (run-hooks 'tcl-mode-hook))
-
-
-
-;; This is used for braces, brackets, and semi (except for closing
-;; braces, which are handled specially).
-(defun tcl-electric-char (arg)
- "Insert character and correct line's indentation."
- (interactive "p")
- ;; Indent line first; this looks better if parens blink.
- (tcl-indent-line)
- (self-insert-command arg)
- (if (and tcl-auto-newline (= last-command-char ?\;))
- (progn
- (newline)
- (tcl-indent-line))))
-
-;; This is used for closing braces. If tcl-auto-newline is set, can
-;; insert a newline both before and after the brace, depending on
-;; context. FIXME should this be configurable? Does anyone use this?
-(defun tcl-electric-brace (arg)
- "Insert character and correct line's indentation."
- (interactive "p")
- ;; If auto-newlining and there is stuff on the same line, insert a
- ;; newline first.
- (if tcl-auto-newline
- (progn
- (if (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- ()
- (tcl-indent-line)
- (newline))
- ;; In auto-newline case, must insert a newline after each
- ;; brace. So an explicit loop is needed.
- (while (> arg 0)
- (insert last-command-char)
- (tcl-indent-line)
- (newline)
- (setq arg (1- arg))))
- (self-insert-command arg))
- (tcl-indent-line))
-
-
-
-(defun tcl-indent-command (&optional arg)
- "Indent current line as Tcl code, or in some cases insert a tab character.
-If tcl-tab-always-indent is t (the default), always indent current line.
-If tcl-tab-always-indent is nil and point is not in the indentation
-area at the beginning of the line, a TAB is inserted.
-Other values of tcl-tab-always-indent cause the first possible action
-from the following list to take place:
-
- 1. Move from beginning of line to correct indentation.
- 2. Delete an empty comment.
- 3. Move forward to start of comment, indenting if necessary.
- 4. Move forward to end of line, indenting if necessary.
- 5. Create an empty comment.
- 6. Move backward to start of comment, indenting if necessary."
- (interactive "p")
- (cond
- ((not tcl-tab-always-indent)
- ;; Indent if in identation area, otherwise insert TAB.
- (if (<= (current-column) (current-indentation))
- (tcl-indent-line)
- (self-insert-command arg)))
- ((eq tcl-tab-always-indent t)
- ;; Always indent.
- (tcl-indent-line))
- (t
- ;; "Perl-mode" style TAB command.
- (let* ((ipoint (point))
- (eolpoint (progn
- (end-of-line)
- (point)))
- (comment-p (tcl-in-comment)))
- (cond
- ((= ipoint (save-excursion
- (beginning-of-line)
- (point)))
- (beginning-of-line)
- (tcl-indent-line)
- ;; If indenting didn't leave us in column 0, go to the
- ;; indentation. Otherwise leave point at end of line. This
- ;; is a hack.
- (if (= (point) (save-excursion
- (beginning-of-line)
- (point)))
- (end-of-line)
- (back-to-indentation)))
- ((and comment-p (looking-at "[ \t]*$"))
- ;; Empty comment, so delete it. We also delete any ";"
- ;; characters at the end of the line. I think this is
- ;; friendlier, but I don't know how other people will feel.
- (backward-char)
- (skip-chars-backward " \t;")
- (delete-region (point) eolpoint))
- ((and comment-p (< ipoint (point)))
- ;; Before comment, so skip to it.
- (tcl-indent-line)
- (indent-for-comment))
- ((/= ipoint eolpoint)
- ;; Go to end of line (since we're not there yet).
- (goto-char eolpoint)
- (tcl-indent-line))
- ((not comment-p)
- ;; Create an empty comment (since there isn't one on this
- ;; line). If line is not blank, make sure we insert a ";"
- ;; first.
- (beginning-of-line)
- (if (/= (point) eolpoint)
- (progn
- (goto-char eolpoint)
- (or (tcl-real-command-p)
- (insert ";"))))
- (tcl-indent-line)
- (indent-for-comment))
- (t
- ;; Go to start of comment. We don't leave point where it is
- ;; because we want to skip comment-start-skip.
- (tcl-indent-line)
- (indent-for-comment)))))))
-
-(defun tcl-indent-line ()
- "Indent current line as Tcl code.
-Return the amount the indentation changed by."
- (let ((indent (calculate-tcl-indent nil))
- beg shift-amt
- (case-fold-search nil)
- (pos (- (point-max) (point))))
- (beginning-of-line)
- (setq beg (point))
- (cond ((eq indent nil)
- (setq indent (current-indentation)))
- (t
- (skip-chars-forward " \t")
- (if (listp indent) (setq indent (car indent)))
- (cond ((= (following-char) ?})
- (setq indent (- indent tcl-indent-level)))
- ((= (following-char) ?\])
- (setq indent (- indent 1))))))
- (skip-chars-forward " \t")
- (setq shift-amt (- indent (current-column)))
- (if (zerop shift-amt)
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- (delete-region beg (point))
- (indent-to indent)
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos))))
- shift-amt))
-
-(defun tcl-figure-type ()
- "Determine type of sexp at point.
-This is either 'tcl-expr, 'tcl-commands, or nil. Puts point at start
-of sexp that indicates types.
-
-See documentation for variable `tcl-type-alist' for more information."
- (let ((count 0)
- result
- word-stack)
- (while (and (< count 5)
- (not result))
- (condition-case nil
- (progn
- ;; FIXME should use "tcl-backward-sexp", which would skip
- ;; over entire variables, etc.
- (backward-sexp)
- (if (looking-at "[a-zA-Z_]+")
- (let ((list tcl-type-alist)
- entry)
- (setq word-stack (cons (current-word) word-stack))
- (while (and list (not result))
- (setq entry (car list))
- (setq list (cdr list))
- (let ((index 0))
- (while (and entry (<= index count))
- ;; Abort loop if string does not match word on
- ;; stack.
- (and (stringp (car entry))
- (not (string= (car entry)
- (nth index word-stack)))
- (setq entry nil))
- (setq entry (cdr entry))
- (setq index (1+ index)))
- (and (> index count)
- (not (stringp (car entry)))
- (setq result (car entry)))
- )))
- (setq word-stack (cons nil word-stack))))
- (error nil))
- (setq count (1+ count)))
- (and tcl-explain-indentation
- (message "Indentation type %s" result))
- result))
-
-(defun calculate-tcl-indent (&optional parse-start)
- "Return appropriate indentation for current line as Tcl code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment."
- (save-excursion
- (beginning-of-line)
- (let* ((indent-point (point))
- (case-fold-search nil)
- (continued-line
- (save-excursion
- (if (bobp)
- nil
- (backward-char)
- (= ?\\ (preceding-char)))))
- (continued-indent-value (if continued-line
- tcl-continued-indent-level
- 0))
- state
- containing-sexp
- found-next-line)
- (if parse-start
- (goto-char parse-start)
- (tcl-beginning-of-defun))
- (while (< (point) indent-point)
- (setq parse-start (point))
- (setq state (parse-partial-sexp (point) indent-point 0))
- (setq containing-sexp (car (cdr state))))
- (cond ((or (nth 3 state) (nth 4 state))
- ;; Inside comment or string. Return nil or t if should
- ;; not change this line
- (nth 4 state))
- ((null containing-sexp)
- ;; Line is at top level.
- continued-indent-value)
- (t
- ;; Set expr-p if we are looking at the expression part of
- ;; an "if", "expr", etc statement. Set commands-p if we
- ;; are looking at the body part of an if, while, etc
- ;; statement. FIXME Should check for "for" loops here.
- (goto-char containing-sexp)
- (let* ((sexpr-type (tcl-figure-type))
- (expr-p (eq sexpr-type 'tcl-expr))
- (commands-p (eq sexpr-type 'tcl-commands))
- (expr-start (point)))
- ;; Find the first statement in the block and indent
- ;; like it. The first statement in the block might be
- ;; on the same line, so what we do is skip all
- ;; "virtually blank" lines, looking for a non-blank
- ;; one. A line is virtually blank if it only contains
- ;; a comment and whitespace. FIXME continued comments
- ;; aren't supported. They are a wart on Tcl anyway.
- ;; We do it this funky way because we want to know if
- ;; we've found a statement on some line _after_ the
- ;; line holding the sexp opener.
- (goto-char containing-sexp)
- (forward-char)
- (if (and (< (point) indent-point)
- (looking-at "[ \t]*\\(#.*\\)?$"))
- (progn
- (forward-line)
- (while (and (< (point) indent-point)
- (looking-at "[ \t]*\\(#.*\\)?$"))
- (setq found-next-line t)
- (forward-line))))
- (if (or continued-line
- (/= (char-after containing-sexp) ?{)
- expr-p)
- (progn
- ;; Line is continuation line, or the sexp opener
- ;; is not a curly brace, or we are are looking at
- ;; an `expr' expression (which must be split
- ;; specially). So indentation is column of first
- ;; good spot after sexp opener (with some added
- ;; in the continued-line case). If there is no
- ;; nonempty line before the indentation point, we
- ;; use the column of the character after the sexp
- ;; opener.
- (if (>= (point) indent-point)
- (progn
- (goto-char containing-sexp)
- (forward-char))
- (skip-chars-forward " \t"))
- (+ (current-column) continued-indent-value))
- ;; After a curly brace, and not a continuation line.
- ;; So take indentation from first good line after
- ;; start of block, unless that line is on the same
- ;; line as the opening brace. In this case use the
- ;; indentation of the opening brace's line, plus
- ;; another indent step. If we are in the body part
- ;; of an "if" or "while" then the indentation is
- ;; taken from the line holding the start of the
- ;; statement.
- (if (and (< (point) indent-point)
- found-next-line)
- (current-indentation)
- (if commands-p
- (goto-char expr-start)
- (goto-char containing-sexp))
- (+ (current-indentation) tcl-indent-level)))))))))
-
-
-
-(defun mark-tcl-function ()
- "Put mark at end of Tcl function, point at beginning."
- (interactive)
- (push-mark (point))
- (tcl-end-of-defun)
- (if tcl-using-emacs-19
- (push-mark (point) nil t)
- (push-mark (point)))
- (tcl-beginning-of-defun)
- (backward-paragraph))
-
-
-
-(defun indent-tcl-exp ()
- "Indent each line of the Tcl grouping following point."
- (interactive)
- (let ((indent-stack (list nil))
- (contain-stack (list (point)))
- (case-fold-search nil)
- outer-loop-done inner-loop-done state ostate
- this-indent last-sexp continued-line
- (next-depth 0)
- last-depth)
- (save-excursion
- (forward-sexp 1))
- (save-excursion
- (setq outer-loop-done nil)
- (while (and (not (eobp)) (not outer-loop-done))
- (setq last-depth next-depth)
- ;; Compute how depth changes over this line
- ;; plus enough other lines to get to one that
- ;; does not end inside a comment or string.
- ;; Meanwhile, do appropriate indentation on comment lines.
- (setq inner-loop-done nil)
- (while (and (not inner-loop-done)
- (not (and (eobp) (setq outer-loop-done t))))
- (setq ostate state)
- (setq state (parse-partial-sexp (point) (progn (end-of-line) (point))
- nil nil state))
- (setq next-depth (car state))
- (if (and (car (cdr (cdr state)))
- (>= (car (cdr (cdr state))) 0))
- (setq last-sexp (car (cdr (cdr state)))))
- (if (or (nth 4 ostate))
- (tcl-indent-line))
- (if (or (nth 3 state))
- (forward-line 1)
- (setq inner-loop-done t)))
- (if (<= next-depth 0)
- (setq outer-loop-done t))
- (if outer-loop-done
- nil
- ;; If this line had ..))) (((.. in it, pop out of the levels
- ;; that ended anywhere in this line, even if the final depth
- ;; doesn't indicate that they ended.
- (while (> last-depth (nth 6 state))
- (setq indent-stack (cdr indent-stack)
- contain-stack (cdr contain-stack)
- last-depth (1- last-depth)))
- (if (/= last-depth next-depth)
- (setq last-sexp nil))
- ;; Add levels for any parens that were started in this line.
- (while (< last-depth next-depth)
- (setq indent-stack (cons nil indent-stack)
- contain-stack (cons nil contain-stack)
- last-depth (1+ last-depth)))
- (if (null (car contain-stack))
- (setcar contain-stack
- (or (car (cdr state))
- (save-excursion
- (forward-sexp -1)
- (point)))))
- (forward-line 1)
- (setq continued-line
- (save-excursion
- (backward-char)
- (= (preceding-char) ?\\)))
- (skip-chars-forward " \t")
- (if (eolp)
- nil
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- ;; Line is on an existing nesting level.
- (setq this-indent (car indent-stack))
- ;; Just started a new nesting level.
- ;; Compute the standard indent for this level.
- (let ((val (calculate-tcl-indent
- (if (car indent-stack)
- (- (car indent-stack))))))
- (setcar indent-stack
- (setq this-indent val))
- (setq continued-line nil)))
- (cond ((not (numberp this-indent)))
- ((= (following-char) ?})
- (setq this-indent (- this-indent tcl-indent-level)))
- ((= (following-char) ?\])
- (setq this-indent (- this-indent 1))))
- ;; Put chosen indentation into effect.
- (or (null this-indent)
- (= (current-column)
- (if continued-line
- (+ this-indent tcl-indent-level)
- this-indent))
- (progn
- (delete-region (point) (progn (beginning-of-line) (point)))
- (indent-to
- (if continued-line
- (+ this-indent tcl-indent-level)
- this-indent)))))))))
- )
-
-
-
-;;
-;; Interfaces to other packages.
-;;
-
-(defun tcl-imenu-create-index-function ()
- "Generate alist of indices for imenu."
- (let ((re (concat tcl-proc-regexp "\\([^ \t\n{]+\\)"))
- alist)
- (imenu-progress-message 0)
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (imenu-progress-message nil)
- ;; Position on start of proc name, not beginning of line.
- (setq alist (cons
- (cons (buffer-substring (match-beginning 2) (match-end 2))
- (match-beginning 2))
- alist)))
- (imenu-progress-message 100)
- (nreverse alist)))
-
-;; FIXME Definition of function is very ad-hoc. Should use
-;; tcl-beginning-of-defun. Also has incestuous knowledge about the
-;; format of tcl-proc-regexp.
-(defun add-log-tcl-defun ()
- "Return name of Tcl function point is in, or nil."
- (save-excursion
- (if (re-search-backward
- (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
- (buffer-substring (match-beginning 2)
- (match-end 2)))))
-
-
-
-;;
-;; Helper functions for inferior Tcl mode.
-;;
-
-;; This exists to let us delete the prompt when commands are sent
-;; directly to the inferior Tcl. See gud.el for an explanation of how
-;; it all works (I took it from there). This stuff doesn't really
-;; work as well as I'd like it to. But I don't believe there is
-;; anything useful that can be done.
-(defvar inferior-tcl-delete-prompt-marker nil)
-
-(defun tcl-filter (proc string)
- (let ((inhibit-quit t))
- (save-excursion
- (set-buffer (process-buffer proc))
- (goto-char (process-mark proc))
- ;; Delete prompt if requested.
- (if (marker-buffer inferior-tcl-delete-prompt-marker)
- (progn
- (delete-region (point) inferior-tcl-delete-prompt-marker)
- (set-marker inferior-tcl-delete-prompt-marker nil)))))
- (comint-output-filter proc string))
-
-(defun tcl-send-string (proc string)
- (save-excursion
- (set-buffer (process-buffer proc))
- (goto-char (process-mark proc))
- (beginning-of-line)
- (if (looking-at comint-prompt-regexp)
- (set-marker inferior-tcl-delete-prompt-marker (point))))
- (comint-send-string proc string))
-
-(defun tcl-send-region (proc start end)
- (save-excursion
- (set-buffer (process-buffer proc))
- (goto-char (process-mark proc))
- (beginning-of-line)
- (if (looking-at comint-prompt-regexp)
- (set-marker inferior-tcl-delete-prompt-marker (point))))
- (comint-send-region proc start end))
-
-(defun switch-to-tcl (eob-p)
- "Switch to inferior Tcl process buffer.
-With argument, positions cursor at end of buffer."
- (interactive "P")
- (if (get-buffer inferior-tcl-buffer)
- (pop-to-buffer inferior-tcl-buffer)
- (error "No current inferior Tcl buffer"))
- (cond (eob-p
- (push-mark)
- (goto-char (point-max)))))
-
-(defun inferior-tcl-proc ()
- "Return current inferior Tcl process.
-See variable `inferior-tcl-buffer'."
- (let ((proc (get-buffer-process (if (eq major-mode 'inferior-tcl-mode)
- (current-buffer)
- inferior-tcl-buffer))))
- (or proc
- (error "No Tcl process; see variable `inferior-tcl-buffer'"))))
-
-(defun tcl-eval-region (start end &optional and-go)
- "Send the current region to the inferior Tcl process.
-Prefix argument means switch to the Tcl buffer afterwards."
- (interactive "r\nP")
- (let ((proc (inferior-tcl-proc)))
- (tcl-send-region proc start end)
- (tcl-send-string proc "\n")
- (if and-go (switch-to-tcl t))))
-
-(defun tcl-eval-defun (&optional and-go)
- "Send the current defun to the inferior Tcl process.
-Prefix argument means switch to the Tcl buffer afterwards."
- (interactive "P")
- (save-excursion
- (tcl-end-of-defun)
- (let ((end (point)))
- (tcl-beginning-of-defun)
- (tcl-eval-region (point) end)))
- (if and-go (switch-to-tcl t)))
-
-
-
-;;
-;; Inferior Tcl mode itself.
-;;
-
-(defun inferior-tcl-mode ()
- "Major mode for interacting with Tcl interpreter.
-
-A Tcl process can be started with M-x inferior-tcl.
-
-Entry to this mode runs the hooks comint-mode-hook and
-inferior-tcl-mode-hook, in that order.
-
-You can send text to the inferior Tcl process from other buffers
-containing Tcl source.
-
-Variables controlling Inferior Tcl mode:
- tcl-application
- Name of program to run.
- tcl-command-switches
- Command line arguments to `tcl-application'.
- tcl-prompt-regexp
- Matches prompt.
- inferior-tcl-source-command
- Command to use to read Tcl file in running application.
- inferior-tcl-buffer
- The current inferior Tcl process buffer. See variable
- documentation for details on multiple-process support.
-
-The following commands are available:
-\\{inferior-tcl-mode-map}"
- (interactive)
- (comint-mode)
- (setq comint-prompt-regexp (or tcl-prompt-regexp
- (concat "^"
- (regexp-quote tcl-application)
- ">")))
- (setq major-mode 'inferior-tcl-mode)
- (setq mode-name "Inferior Tcl")
- (setq mode-line-process '(": %s"))
- (use-local-map inferior-tcl-mode-map)
- (setq local-abbrev-table tcl-mode-abbrev-table)
- (set-syntax-table tcl-mode-syntax-table)
- (if tcl-using-emacs-19
- (progn
- (make-local-variable 'defun-prompt-regexp)
- (setq defun-prompt-regexp tcl-omit-ws-regexp)))
- (make-local-variable 'inferior-tcl-delete-prompt-marker)
- (setq inferior-tcl-delete-prompt-marker (make-marker))
- (set-process-filter (get-buffer-process (current-buffer)) 'tcl-filter)
- (run-hooks 'inferior-tcl-mode-hook))
-
-(defun inferior-tcl (cmd)
- "Run inferior Tcl process.
-Prefix arg means enter program name interactively.
-See documentation for function `inferior-tcl-mode' for more information."
- (interactive
- (list (if current-prefix-arg
- (read-string "Run Tcl: " tcl-application)
- tcl-application)))
- (if (not (comint-check-proc "*inferior-tcl*"))
- (progn
- (set-buffer (apply (function make-comint) "inferior-tcl" cmd nil
- tcl-command-switches))
- (inferior-tcl-mode)))
- (make-local-variable 'tcl-application)
- (setq tcl-application cmd)
- (setq inferior-tcl-buffer "*inferior-tcl*")
- (switch-to-buffer "*inferior-tcl*"))
-
-(and (fboundp 'defalias)
- (defalias 'run-tcl 'inferior-tcl))
-
-
-
-;;
-;; Auto-fill support.
-;;
-
-(defun tcl-real-command-p ()
- "Return nil if point is not at the beginning of a command.
-A command is the first word on an otherwise empty line, or the
-first word following a semicolon, opening brace, or opening bracket."
- (save-excursion
- (skip-chars-backward " \t")
- (cond
- ((bobp) t)
- ((bolp)
- (backward-char)
- ;; Note -- continued comments are not supported here. I
- ;; consider those to be a wart on the language.
- (not (eq ?\\ (preceding-char))))
- (t
- (memq (preceding-char) '(?\; ?{ ?\[))))))
-
-;; FIXME doesn't actually return t. See last case.
-(defun tcl-real-comment-p ()
- "Return t if point is just after the `#' beginning a real comment.
-Does not check to see if previous char is actually `#'.
-A real comment is either at the beginning of the buffer,
-preceeded only by whitespace on the line, or has a preceeding
-semicolon, opening brace, or opening bracket on the same line."
- (save-excursion
- (backward-char)
- (tcl-real-command-p)))
-
-(defun tcl-hairy-scan-for-comment (state end always-stop)
- "Determine if point is in a comment.
-Returns a list of the form `(FLAG . STATE)'. STATE can be used
-as input to future invocations. FLAG is nil if not in comment,
-t otherwise. If in comment, leaves point at beginning of comment.
-Only works in Emacs 19. See also `tcl-simple-scan-for-comment', a
-simpler version that is often right, and works in Emacs 18."
- (let ((bol (save-excursion
- (goto-char end)
- (beginning-of-line)
- (point)))
- real-comment
- last-cstart)
- (while (and (not last-cstart) (< (point) end))
- (setq real-comment nil) ;In case we've looped around and it is
- ;set.
- (setq state (parse-partial-sexp (point) end nil nil state t))
- (if (nth 4 state)
- (progn
- ;; If ALWAYS-STOP is set, stop even if we don't have a
- ;; real comment, or if the comment isn't on the same line
- ;; as the end.
- (if always-stop (setq last-cstart (point)))
- ;; If we have a real comment, then set the comment
- ;; starting point if we are on the same line as the ending
- ;; location.
- (setq real-comment (tcl-real-comment-p))
- (if real-comment
- (progn
- (and (> (point) bol) (setq last-cstart (point)))
- ;; NOTE Emacs 19 has a misfeature whereby calling
- ;; parse-partial-sexp with COMMENTSTOP set and with
- ;; an initial list that says point is in a comment
- ;; will cause an immediate return. So we must skip
- ;; over the comment ourselves.
- (beginning-of-line 2)))
- ;; Frob the state to make it look like we aren't in a
- ;; comment.
- (setcar (nthcdr 4 state) nil))))
- (and last-cstart
- (goto-char last-cstart))
- (cons real-comment state)))
-
-(defun tcl-hairy-in-comment ()
- "Return t if point is in a comment, and leave point at beginning
-of comment."
- (let ((save (point)))
- (tcl-beginning-of-defun)
- (car (tcl-hairy-scan-for-comment nil save nil))))
-
-(defun tcl-simple-in-comment ()
- "Return t if point is in comment, and leave point at beginning
-of comment. This is faster that `tcl-hairy-in-comment', but is
-correct less often."
- (let ((save (point))
- comment)
- (beginning-of-line)
- (while (and (< (point) save) (not comment))
- (search-forward "#" save 'move)
- (setq comment (tcl-real-comment-p)))
- comment))
-
-(defun tcl-in-comment ()
- "Return t if point is in comment, and leave point at beginning
-of comment."
- (if (and tcl-pps-has-arg-6
- tcl-use-hairy-comment-detector)
- (tcl-hairy-in-comment)
- (tcl-simple-in-comment)))
-
-(defun tcl-do-auto-fill ()
- "Auto-fill function for Tcl mode. Only auto-fills in a comment."
- (let (in-comment
- col)
- (save-excursion
- (setq in-comment (tcl-in-comment))
- (if in-comment
- (setq col (1- (current-column)))))
- (if in-comment
- (progn
- (do-auto-fill)
- (save-excursion
- (back-to-indentation)
- (delete-region (point) (save-excursion
- (beginning-of-line)
- (point)))
- (indent-to-column col))))))
-
-
-
-;;
-;; Help-related code.
-;;
-
-(defvar tcl-help-saved-dir nil
- "Saved help directory. If `tcl-help-directory' changes, this allows
-tcl-help-on-word to update the alist")
-
-(defvar tcl-help-alist nil
- "Alist with command names as keys and filenames as values.")
-
-(defun tcl-help-snarf-commands (dir)
- "Build alist of commands and filenames. There is probably a much
-better implementation of this, but I'm too tired to think of it right
-now."
- (let ((files (directory-files dir t)))
- (while files
- (if (and (file-directory-p (car files))
- (not
- (let ((fpart (file-name-nondirectory (car files))))
- (or (equal fpart ".")
- (equal fpart "..")))))
- (let ((matches (directory-files (car files) t)))
- (while matches
- (or (file-directory-p (car matches))
- (setq tcl-help-alist
- (cons
- (cons (file-name-nondirectory (car matches))
- (car matches))
- tcl-help-alist)))
- (setq matches (cdr matches)))))
- (setq files (cdr files)))))
-
-(defun tcl-reread-help-files ()
- "Set up to re-read files, and then do it."
- (interactive)
- (message "Building Tcl help file index...")
- (setq tcl-help-saved-dir tcl-help-directory)
- (setq tcl-help-alist nil)
- (tcl-help-snarf-commands tcl-help-directory)
- (message "Building Tcl help file index...done"))
-
-(defun tcl-current-word (flag)
- "Return current command word, or nil.
-If FLAG is nil, just uses `current-word'.
-Otherwise scans backward for most likely Tcl command word."
- (if (and flag (eq major-mode 'tcl-mode))
- (condition-case nil
- (save-excursion
- ;; Look backward for first word actually in alist.
- (if (bobp)
- ()
- (while (and (not (bobp))
- (not (tcl-real-command-p)))
- (backward-sexp)))
- (if (assoc (current-word) tcl-help-alist)
- (current-word)))
- (error nil))
- (current-word)))
-
-(defun tcl-help-on-word (command &optional arg)
- "Get help on Tcl command. Default is word at point.
-Prefix argument means invert sense of `tcl-use-smart-word-finder'."
- (interactive
- (list
- (progn
- (if (not (string= tcl-help-directory tcl-help-saved-dir))
- (tcl-reread-help-files))
- (let ((word (tcl-current-word
- (if current-prefix-arg
- (not tcl-use-smart-word-finder)
- tcl-use-smart-word-finder))))
- (completing-read
- (if (or (null word) (string= word ""))
- "Help on Tcl command: "
- (format "Help on Tcl command (default %s): " word))
- tcl-help-alist nil t)))
- current-prefix-arg))
- (if (not (string= tcl-help-directory tcl-help-saved-dir))
- (tcl-reread-help-files))
- (if (string= command "")
- (setq command (tcl-current-word
- (if arg
- (not tcl-use-smart-word-finder)
- tcl-use-smart-word-finder))))
- (let* ((help (get-buffer-create "*Tcl help*"))
- (cell (assoc command tcl-help-alist))
- (file (and cell (cdr cell))))
- (set-buffer help)
- (delete-region (point-min) (point-max))
- (if file
- (progn
- (insert "*** " command "\n\n")
- (insert-file-contents file))
- (if (string= command "")
- (insert "Magical Pig!")
- (insert "Tcl command " command " not in help\n")))
- (set-buffer-modified-p nil)
- (goto-char (point-min))
- (display-buffer help)))
-
-
-
-;;
-;; Other interactive stuff.
-;;
-
-(defvar tcl-previous-dir/file nil
- "Record last directory and file used in loading.
-This holds a cons cell of the form `(DIRECTORY . FILE)'
-describing the last `tcl-load-file' command.")
-
-(defun tcl-load-file (file &optional and-go)
- "Load a Tcl file into the inferior Tcl process.
-Prefix argument means switch to the Tcl buffer afterwards."
- (interactive
- (list
- ;; car because comint-get-source returns a list holding the
- ;; filename.
- (car (comint-get-source "Load Tcl file: " tcl-previous-dir/file
- '(tcl-mode) t))
- current-prefix-arg))
- (comint-check-source file)
- (setq tcl-previous-dir/file (cons (file-name-directory file)
- (file-name-nondirectory file)))
- (tcl-send-string (inferior-tcl-proc)
- (format inferior-tcl-source-command (tcl-quote file)))
- (if and-go (switch-to-tcl t)))
-
-;; Maybe this should work just like tcl-load-file. But I think what
-;; I've implemented will turn out to be more useful.
-(defun tcl-restart-with-file (file &optional and-go)
- "Restart inferior Tcl with file.
-If an inferior Tcl process exists, it is killed first.
-Prefix argument means switch to the Tcl buffer afterwards."
- (interactive
- (list
- (car (comint-get-source "Restart with Tcl file: "
- (or (and
- (eq major-mode 'tcl-mode)
- (buffer-file-name))
- tcl-previous-dir/file)
- '(tcl-mode) t))
- current-prefix-arg))
- (let* ((buf (if (eq major-mode 'inferior-tcl-mode)
- (current-buffer)
- inferior-tcl-buffer))
- (proc (and buf (get-process buf))))
- (cond
- ((not (and buf (get-buffer buf)))
- ;; I think this will be ok.
- (inferior-tcl tcl-application)
- (tcl-load-file file and-go))
- ((or
- (not (comint-check-proc buf))
- (yes-or-no-p
- "A Tcl process is running, are you sure you want to reset it? "))
- (save-excursion
- (comint-check-source file)
- (setq tcl-previous-dir/file (cons (file-name-directory file)
- (file-name-nondirectory file)))
- (comint-exec (get-buffer-create buf)
- (if proc
- (process-name proc)
- "inferior-tcl")
- tcl-application file tcl-command-switches)
- (if and-go (switch-to-tcl t)))))))
-
-;; FIXME I imagine you can do this under Emacs 18. I just don't know
-;; how.
-(defun tcl-auto-fill-mode (&optional arg)
- "Like `auto-fill-mode', but controls filling of Tcl comments."
- (interactive "P")
- (and (not tcl-using-emacs-19)
- (error "You must use Emacs 19 to get this feature."))
- ;; Following code taken from "auto-fill-mode" (simple.el).
- (prog1
- (setq auto-fill-function
- (if (if (null arg)
- (not auto-fill-function)
- (> (prefix-numeric-value arg) 0))
- 'tcl-do-auto-fill
- nil))
- ;; Update mode line. FIXME I'd use force-mode-line-update, but I
- ;; don't know if it exists in v18.
- (set-buffer-modified-p (buffer-modified-p))))
-
-(defun tcl-electric-hash (&optional count)
- "Insert a `#' and quote if it does not start a real comment.
-Prefix arg is number of `#'s to insert.
-See variable `tcl-electric-hash-style' for description of quoting
-styles."
- (interactive "p")
- (or count (setq count 1))
- (if (> count 0)
- (let ((type
- (if (eq tcl-electric-hash-style 'smart)
- (if (> count 3) ; FIXME what is "smart"?
- 'quote
- 'backslash)
- tcl-electric-hash-style))
- comment)
- (if type
- (progn
- (save-excursion
- (insert "#")
- (setq comment (tcl-in-comment)))
- (delete-char 1)
- (and tcl-explain-indentation (message "comment: %s" comment))
- (cond
- ((eq type 'quote)
- (if (not comment)
- (insert "\"")))
- ((eq type 'backslash)
- ;; The following will set count to 0, so the
- ;; insert-char can still be run.
- (if (not comment)
- (while (> count 0)
- (insert "\\#")
- (setq count (1- count)))))
- (t nil))))
- (insert-char ?# count))))
-
-(defun tcl-hashify-buffer ()
- "Quote all `#'s in current buffer that aren't Tcl comments."
- (interactive)
- (save-excursion
- (goto-char (point-min))
- (if (and tcl-pps-has-arg-6 tcl-use-hairy-comment-detector)
- (let (state
- result)
- (while (< (point) (point-max))
- (setq result (tcl-hairy-scan-for-comment state (point-max) t))
- (if (car result)
- (beginning-of-line 2)
- (backward-char)
- (if (eq ?# (following-char))
- (insert "\\"))
- (forward-char))
- (setq state (cdr result))))
- (while (and (< (point) (point-max))
- (search-forward "#" nil 'move))
- (if (tcl-real-comment-p)
- (beginning-of-line 2)
- ;; There's really no good way for the simple converter to
- ;; work. So we just quote # if it isn't already quoted.
- ;; Bogus, but it works.
- (backward-char)
- (if (not (eq ?\\ (preceding-char)))
- (insert "\\"))
- (forward-char))))))
-
-;; The following was inspired by the Tcl editing mode written by
-;; Gregor Schmid <schmid@fb3-s7.math.TU-Berlin.DE>. His version also
-;; attempts to snarf the command line options from the command line,
-;; but I didn't think that would really be that helpful (doesn't seem
-;; like it owould be right enough. His version also looks for the
-;; "#!/bin/csh ... exec" hack, but that seemed even less useful.
-(defun tcl-guess-application ()
- "Attempt to guess Tcl application by looking at first line.
-The first line is assumed to look like \"#!.../program ...\"."
- (save-excursion
- (goto-char (point-min))
- (if (looking-at "#![^ \t]*/\\([^ \t/]+\\)\\([ \t]\\|$\\)")
- (progn
- (make-local-variable 'tcl-application)
- (setq tcl-application (buffer-substring (match-beginning 1)
- (match-end 1)))))))
-
-;; This only exists to put on the menubar. I couldn't figure out any
-;; other way to do it. FIXME should take "number of #-marks"
-;; argument.
-(defun tcl-uncomment-region (beg end)
- "Uncomment region."
- (interactive "r")
- (comment-region beg end -1))
-
-
-
-;;
-;; Lucid menu support.
-;; Taken from schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid),
-;; who wrote a different Tcl mode.
-;; We also have simple support for menus in FSF. We do this by
-;; loading the Lucid menu emulation code.
-;;
-
-;; Put this into your tcl-mode-hook.
-(defun tcl-install-menubar ()
- (and tcl-using-emacs-19
- (not tcl-using-lemacs-19)
- (if tcl-using-emacs-19.23
- (require 'lmenu)
- ;; CAVEATS:
- ;; * lmenu.el provides 'menubar, which is bogus.
- ;; * lmenu.el causes menubars to be turned on everywhere.
- ;; Doubly bogus!
- ;; Both of these problems are fixed in Emacs 19.23. People
- ;; using an Emacs before that just suffer.
- (require 'menubar "lmenu")))
- (if (not (assoc "Tcl" current-menubar))
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-menu nil "Tcl" (cdr tcl-lucid-menu))))
- ;; You might want to do something like the below. I have it
- ;; commented out because it overrides existing bindings.
- ;; For Lucid:
- ;; (define-key tcl-mode-map 'button3 'tcl-popup-menu)
- ;; For FSF:
- ;; (define-key tcl-mode-map [down-mouse-3] 'tcl-popup-menu)
- )
-
-(defun tcl-popup-menu (e)
- (interactive "e")
- (and tcl-using-emacs-19
- (not tcl-using-lemacs-19)
- (if tcl-using-emacs-19.23
- (require 'lmenu)
- ;; CAVEATS:
- ;; * lmenu.el provides 'menubar, which is bogus.
- ;; * lmenu.el causes menubars to be turned on everywhere.
- ;; Doubly bogus!
- ;; Both of these problems are fixed in Emacs 19.23. People
- ;; using an Emacs before that just suffer.
- (require 'menubar "lmenu"))) ;; This is annoying
- ;;(mouse-set-point e)
- ;; IMHO popup-menu should be autoloaded. Oh well.
- (popup-menu tcl-lucid-menu))
-
-
-
-;;
-;; Quoting and unquoting functions.
-;;
-
-;; This quoting is sufficient to protect eg a filename from any sort
-;; of expansion or splitting. Tcl quoting sure sucks.
-(defun tcl-quote (string)
- "Quote STRING according to Tcl rules."
- (mapconcat (function (lambda (char)
- (if (memq char '(?[ ?] ?{ ?} ?\\ ?\" ?$ ? ?\;))
- (concat "\\" (char-to-string char))
- (char-to-string char))))
- string ""))
-
-
-
-(provide 'tcl)
-
-;;; tcl.el ends here