summaryrefslogtreecommitdiff
path: root/lisp/progmodes
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/ada-mode.el3741
-rw-r--r--lisp/progmodes/asm-mode.el231
-rw-r--r--lisp/progmodes/awk-mode.el153
-rw-r--r--lisp/progmodes/c-mode.el1650
-rw-r--r--lisp/progmodes/cmacexp.el371
-rw-r--r--lisp/progmodes/compile.el1583
-rw-r--r--lisp/progmodes/cplus-md.el1061
-rw-r--r--lisp/progmodes/cpp.el782
-rw-r--r--lisp/progmodes/etags.el1606
-rw-r--r--lisp/progmodes/executable.el235
-rw-r--r--lisp/progmodes/f90.el1697
-rw-r--r--lisp/progmodes/fortran.el1589
-rw-r--r--lisp/progmodes/hideif.el1048
-rw-r--r--lisp/progmodes/hideshow.el492
-rw-r--r--lisp/progmodes/icon.el556
-rw-r--r--lisp/progmodes/inf-lisp.el642
-rw-r--r--lisp/progmodes/m4-mode.el152
-rw-r--r--lisp/progmodes/make-mode.el1396
-rw-r--r--lisp/progmodes/modula2.el454
-rw-r--r--lisp/progmodes/pascal.el1560
-rw-r--r--lisp/progmodes/perl-mode.el732
-rw-r--r--lisp/progmodes/prolog.el273
-rw-r--r--lisp/progmodes/scheme.el515
-rw-r--r--lisp/progmodes/sh-script.el1388
-rw-r--r--lisp/progmodes/simula.el1773
-rw-r--r--lisp/progmodes/tcl.el2227
26 files changed, 0 insertions, 27907 deletions
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el
deleted file mode 100644
index cf74a914ea2..00000000000
--- a/lisp/progmodes/ada-mode.el
+++ /dev/null
@@ -1,3741 +0,0 @@
-;;; ada-mode.el --- An Emacs major-mode for editing Ada source.
-;;; Copyright (C) 1994, 1995 Free Software Foundation, Inc.
-
-;;; Authors: Markus Heritsch <Markus.Heritsch@studbox.uni-stuttgart.de>
-;;; Rolf Ebert <ebert@inf.enst.fr>
-
-;;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; This mode is a complete rewrite of a major mode for editing Ada 83
-;;; and Ada 95 source code under Emacs-19. It contains completely new
-;;; indenting code and support for code browsing (see ada-xref).
-
-
-;;; USAGE
-;;; =====
-;;; Emacs should enter ada-mode when you load an ada source (*.ad[abs]).
-;;;
-;;; When you have entered ada-mode, you may get more info by pressing
-;;; C-h m. You may also get online help describing various functions by:
-;;; C-h d <Name of function you want described>
-
-
-;;; HISTORY
-;;; =======
-;;; The first Ada mode for GNU Emacs was written by V. Broman in
-;;; 1985. He based his work on the already existing Modula-2 mode.
-;;; This was distributed as ada.el in versions of Emacs prior to 19.29.
-;;;
-;;; Lynn Slater wrote an extensive Ada mode in 1989. It consisted of
-;;; several files with support for dired commands and other nice
-;;; things. It is currently available from the PAL
-;;; (wuarchive.wustl.edu:/languages/ada) as ada-mode-1.06a.tar.Z.
-;;;
-;;; The probably very first Ada mode (called electric-ada.el) was
-;;; written by Steven D. Litvintchouk and Steven M. Rosen for the
-;;; Gosling Emacs. L. Slater based his development on ada.el and
-;;; electric-ada.el.
-;;;
-;;; The current Ada mode is a complete rewrite by M. Heritsch and
-;;; R. Ebert. Some ideas from the ada-mode mailing list have been
-;;; added. Some of the functionality of L. Slater's mode has not
-;;; (yet) been recoded in this new mode. Perhaps you prefer sticking
-;;; to his version.
-
-
-;;; KNOWN BUGS
-;;; ==========
-;;;
-;;; In the presence of comments and/or incorrect syntax
-;;; ada-format-paramlist produces weird results.
-;;; -------------------
-;;; Indenting of some tasking constructs is still buggy.
-;;; -------------------
-;;; package Test is
-;;; -- If I hit return on the "type" line it will indent the next line
-;;; -- in another 3 space instead of heading out to the "(". If I hit
-;;; -- tab or return it reindents the line correctly but does not initially.
-;;; type Wait_Return is (Read_Success, Read_Timeout, Wait_Timeout,
-;;; Nothing_To_Wait_For_In_Wait_List);
-;;; -------------------
-
-
-
-;;; CREDITS
-;;; =======
-;;;
-;;; Many thanks to
-;;; Philippe Waroquiers (PW) <philippe@cfmu.eurocontrol.be> in particular,
-;;; woodruff@stc.llnl.gov (John Woodruff)
-;;; jj@ddci.dk (Jesper Joergensen)
-;;; gse@ocsystems.com (Scott Evans)
-;;; comar@LANG8.CS.NYU.EDU (Cyrille Comar)
-;;; and others for their valuable hints.
-
-;;;--------------------
-;;; USER OPTIONS
-;;;--------------------
-
-;; ---- configure indentation
-
-(defvar ada-indent 3
- "*Defines the size of Ada indentation.")
-
-(defvar ada-broken-indent 2
- "*# of columns to indent the continuation of a broken line.")
-
-(defvar ada-label-indent -4
- "*# of columns to indent a label.")
-
-(defvar ada-stmt-end-indent 0
- "*# of columns to indent a statement end keyword in a separate line.
-Examples are 'is', 'loop', 'record', ...")
-
-(defvar ada-when-indent 3
- "*Defines the indentation for 'when' relative to 'exception' or 'case'.")
-
-(defvar ada-indent-record-rel-type 3
- "*Defines the indentation for 'record' relative to 'type' or 'use'.")
-
-(defvar ada-indent-comment-as-code t
- "*If non-nil, comment-lines get indented as Ada code.")
-
-(defvar ada-indent-is-separate t
- "*If non-nil, 'is separate' or 'is abstract' on a single line are indented.")
-
-(defvar ada-indent-to-open-paren t
- "*If non-nil, indent according to the innermost open parenthesis.")
-
-(defvar ada-search-paren-char-count-limit 3000
- "*Search that many characters for an open parenthesis.")
-
-
-;; ---- other user options
-
-(defvar ada-tab-policy 'indent-auto
- "*Control behaviour of the TAB key.
-Must be one of `indent-rigidly', `indent-auto', `gei', `indent-af'
-or `always-tab'.
-
-`indent-rigidly' : always adds ada-indent blanks at the beginning of the line.
-`indent-auto' : use indentation functions in this file.
-`gei' : use David Kågedal's Generic Indentation Engine.
-`indent-af' : use Gary E. Barnes' ada-format.el
-`always-tab' : do indent-relative.")
-
-(defvar ada-move-to-declaration nil
- "*If non-nil, `ada-move-to-start' moves point to the subprog declaration,
-not to 'begin'.")
-
-(defvar ada-spec-suffix ".ads"
- "*Suffix of Ada specification files.")
-
-(defvar ada-body-suffix ".adb"
- "*Suffix of Ada body files.")
-
-(defvar ada-language-version 'ada95
- "*Do we program in `ada83' or `ada95'?")
-
-(defvar ada-case-keyword 'downcase-word
- "*Function to call to adjust the case of Ada keywords.
-It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
-`capitalize-word'.")
-
-(defvar ada-case-identifier 'ada-loose-case-word
- "*Function to call to adjust the case of an Ada identifier.
-It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
-`capitalize-word'.")
-
-(defvar ada-case-attribute 'capitalize-word
- "*Function to call to adjust the case of Ada attributes.
-It may be `downcase-word', `upcase-word', `ada-loose-case-word' or
-`capitalize-word'.")
-
-(defvar ada-auto-case t
- "*Non-nil automatically changes case of preceding word while typing.
-Casing is done according to `ada-case-keyword', `ada-case-identifier'
-and `ada-cacse-attribute'.")
-
-(defvar ada-clean-buffer-before-saving nil
- "*If non-nil, `remove-trailing-spaces' and `untabify' buffer before saving.")
-
-(defvar ada-mode-hook nil
- "*List of functions to call when Ada Mode is invoked.
-This is a good place to add Ada environment specific bindings.")
-
-(defvar ada-external-pretty-print-program "aimap"
- "*External pretty printer to call from within Ada Mode.")
-
-(defvar ada-tmp-directory "/tmp/"
- "*Directory to store the temporary file for the Ada pretty printer.")
-
-(defvar ada-fill-comment-prefix "-- "
- "*This is inserted in the first columns when filling a comment paragraph.")
-
-(defvar ada-fill-comment-postfix " --"
- "*This is inserted at the end of each line when filling a comment paragraph.
-with `ada-fill-comment-paragraph-postfix'.")
-
-(defvar ada-krunch-args "0"
- "*Argument of gnatk8, a string containing the max number of characters.
-Set to 0, if you don't use crunched filenames.")
-
-;;; ---- end of user configurable variables
-
-
-(defvar ada-mode-abbrev-table nil
- "Abbrev table used in Ada mode.")
-(define-abbrev-table 'ada-mode-abbrev-table ())
-
-(defvar ada-mode-map ()
- "Local keymap used for Ada Mode.")
-
-(defvar ada-mode-syntax-table nil
- "Syntax table to be used for editing Ada source code.")
-
-(defvar ada-mode-symbol-syntax-table nil
- "Syntax table for Ada, where `_' is a word constituent.")
-
-(defconst ada-83-keywords
- "\\<\\(abort\\|abs\\|accept\\|access\\|all\\|and\\|array\\|\
-at\\|begin\\|body\\|case\\|constant\\|declare\\|delay\\|delta\\|\
-digits\\|do\\|else\\|elsif\\|end\\|entry\\|exception\\|exit\\|for\\|\
-function\\|generic\\|goto\\|if\\|in\\|is\\|limited\\|loop\\|mod\\|\
-new\\|not\\|null\\|of\\|or\\|others\\|out\\|package\\|pragma\\|\
-private\\|procedure\\|raise\\|range\\|record\\|rem\\|renames\\|\
-return\\|reverse\\|select\\|separate\\|subtype\\|task\\|terminate\\|\
-then\\|type\\|use\\|when\\|while\\|with\\|xor\\)\\>"
-; "\\<\\(a\\(b\\(ort\\|s\\)\\|cce\\(pt\\|ss\\)\\|ll\\|nd\\|rray\\|t\\)\\|\
-;b\\(egin\\|ody\\)\\|c\\(ase\\|onstant\\)\\|\
-;d\\(e\\(clare\\|l\\(ay\\|ta\\)\\)\\|igits\\|o\\)\\|\
-;e\\(ls\\(e\\|if\\)\\|n\\(d\\|try\\)\\|x\\(ception\\|it\\)\\)\\|\
-;f\\(or\\|unction\\)\\|g\\(eneric\\|oto\\)\\|i[fns]\\|l\\(imited\\|oop\\)\\|\
-;mod\\|n\\(ew\\|ot\\|ull\\)\\|o\\([fr]\\|thers\\|ut\\)\\|\
-;p\\(ackage\\|r\\(agma\\|ivate\\|ocedure\\)\\)\\|\
-;r\\(a\\(ise\\|nge\\)\\|e\\(cord\\|m\\|names\\|turn\\|verse\\)\\)\\|\
-;s\\(e\\(lect\\|parate\\)\\|ubtype\\)\\|use\\|
-;t\\(ask\\|erminate\\|hen\\|ype\\)\\|w\\(h\\(en\\|ile\\)\\|ith\\)\\|xor\\)\\>"
- "regular expression for looking at Ada83 keywords.")
-
-(defconst ada-95-keywords
- "\\<\\(abort\\|abs\\|abstract\\|accept\\|access\\|aliased\\|\
-all\\|and\\|array\\|at\\|begin\\|body\\|case\\|constant\\|declare\\|\
-delay\\|delta\\|digits\\|do\\|else\\|elsif\\|end\\|entry\\|\
-exception\\|exit\\|for\\|function\\|generic\\|goto\\|if\\|in\\|\
-is\\|limited\\|loop\\|mod\\|new\\|not\\|null\\|of\\|or\\|others\\|\
-out\\|package\\|pragma\\|private\\|procedure\\|protected\\|raise\\|\
-range\\|record\\|rem\\|renames\\|requeue\\|return\\|reverse\\|\
-select\\|separate\\|subtype\\|tagged\\|task\\|terminate\\|then\\|\
-type\\|until\\|use\\|when\\|while\\|with\\|xor\\)\\>"
- "regular expression for looking at Ada95 keywords.")
-
-(defvar ada-keywords ada-95-keywords
- "Regular expression for looking at Ada keywords.")
-
-(defvar ada-ret-binding nil
- "Variable to save key binding of RET when casing is activated.")
-
-(defvar ada-lfd-binding nil
- "Variable to save key binding of LFD when casing is activated.")
-
-;;; ---- Regexps to find procedures/functions/packages
-
-(defconst ada-ident-re
- "[a-zA-Z0-9_\\.]+"
- "Regexp matching Ada (qualified) identifiers.")
-
-(defvar ada-procedure-start-regexp
- "^[ \t]*\\(procedure\\|function\\|task\\)[ \t\n]+\\([a-zA-Z0-9_\\.]+\\)"
- "Regexp used to find Ada procedures/functions.")
-
-(defvar ada-package-start-regexp
- "^[ \t]*\\(package\\)"
- "Regexp used to find Ada packages")
-
-
-;;; ---- regexps for indentation functions
-
-(defvar ada-block-start-re
- "\\<\\(begin\\|select\\|declare\\|private\\|or\\|generic\\|\
-exception\\|loop\\|else\\|\
-\\(\\(limited\\|abstract\\|tagged\\)[ \t]+\\)*record\\)\\>"
- "Regexp for keywords starting Ada blocks.")
-
-(defvar ada-end-stmt-re
- "\\(;\\|=>\\|^[ \t]*separate[ \t]+([a-zA-Z0-9_\\.]+)\\|\
-\\<\\(begin\\|else\\|record\\|loop\\|select\\|do\\|\
-declare\\|generic\\|private\\)\\>\\|\
-^[ \t]*\\(package\\|procedure\\|function\\)[ \ta-zA-Z0-9_\\.]+is\\|\
-^[ \t]*exception\\>\\)"
- "Regexp of possible ends for a non-broken statement.
-A new statement starts after these.")
-
-(defvar ada-loop-start-re
- "\\<\\(for\\|while\\|loop\\)\\>"
- "Regexp for the start of a loop.")
-
-(defvar ada-subprog-start-re
- "\\<\\(procedure\\|protected\\|package\\|function\\|\
-task\\|accept\\|entry\\)\\>"
- "Regexp for the start of a subprogram.")
-
-
-;; Written by Christian Egli <Christian.Egli@hcsd.hac.com>
-;;
-(defvar ada-imenu-generic-expression
- '((nil "^\\s-*\\(procedure\\|function\\)\\s-+\\([A-Za-z0-9_]+\\)" 2)
- ("Type Defs" "^\\s-*\\(sub\\)?type\\s-+\\([A-Za-z0-9_]+\\)" 2))
-
- "Imenu generic expression for Ada mode. See `imenu-generic-expression'.")
-
-;;;-------------
-;;; functions
-;;;-------------
-
-(defun ada-xemacs ()
- (or (string-match "Lucid" emacs-version)
- (string-match "XEmacs" emacs-version)))
-
-(defun ada-create-syntax-table ()
- "Create the syntax table for Ada Mode."
- ;; There are two different syntax-tables. The standard one declares
- ;; `_' as a symbol constituent, in the second one, it is a word
- ;; constituent. For some search and replacing routines we
- ;; temporarily switch between the two.
- (setq ada-mode-syntax-table (make-syntax-table))
- (set-syntax-table ada-mode-syntax-table)
-
- ;; define string brackets (% is alternative string bracket)
- (modify-syntax-entry ?% "\"" ada-mode-syntax-table)
- (modify-syntax-entry ?\" "\"" ada-mode-syntax-table)
-
- (modify-syntax-entry ?\# "$" ada-mode-syntax-table)
-
- (modify-syntax-entry ?: "." ada-mode-syntax-table)
- (modify-syntax-entry ?\; "." ada-mode-syntax-table)
- (modify-syntax-entry ?& "." ada-mode-syntax-table)
- (modify-syntax-entry ?\| "." ada-mode-syntax-table)
- (modify-syntax-entry ?+ "." ada-mode-syntax-table)
- (modify-syntax-entry ?* "." ada-mode-syntax-table)
- (modify-syntax-entry ?/ "." ada-mode-syntax-table)
- (modify-syntax-entry ?= "." ada-mode-syntax-table)
- (modify-syntax-entry ?< "." ada-mode-syntax-table)
- (modify-syntax-entry ?> "." ada-mode-syntax-table)
- (modify-syntax-entry ?$ "." ada-mode-syntax-table)
- (modify-syntax-entry ?\[ "." ada-mode-syntax-table)
- (modify-syntax-entry ?\] "." ada-mode-syntax-table)
- (modify-syntax-entry ?\{ "." ada-mode-syntax-table)
- (modify-syntax-entry ?\} "." ada-mode-syntax-table)
- (modify-syntax-entry ?. "." ada-mode-syntax-table)
- (modify-syntax-entry ?\\ "." ada-mode-syntax-table)
- (modify-syntax-entry ?\' "." ada-mode-syntax-table)
-
- ;; a single hyphen is punctuation, but a double hyphen starts a comment
- (modify-syntax-entry ?- ". 12" ada-mode-syntax-table)
-
- ;; and \f and \n end a comment
- (modify-syntax-entry ?\f "> " ada-mode-syntax-table)
- (modify-syntax-entry ?\n "> " ada-mode-syntax-table)
-
- ;; define what belongs in ada symbols
- (modify-syntax-entry ?_ "_" ada-mode-syntax-table)
-
- ;; define parentheses to match
- (modify-syntax-entry ?\( "()" ada-mode-syntax-table)
- (modify-syntax-entry ?\) ")(" ada-mode-syntax-table)
-
- (setq ada-mode-symbol-syntax-table (copy-syntax-table ada-mode-syntax-table))
- (modify-syntax-entry ?_ "w" ada-mode-symbol-syntax-table)
- )
-
-
-;;;###autoload
-(defun ada-mode ()
- "Ada Mode is the major mode for editing Ada code.
-
-Bindings are as follows: (Note: 'LFD' is control-j.)
-
- Indent line '\\[ada-tab]'
- Indent line, insert newline and indent the new line. '\\[newline-and-indent]'
-
- Re-format the parameter-list point is in '\\[ada-format-paramlist]'
- Indent all lines in region '\\[ada-indent-region]'
- Call external pretty printer program '\\[ada-call-pretty-printer]'
-
- Adjust case of identifiers and keywords in region '\\[ada-adjust-case-region]'
- Adjust case of identifiers and keywords in buffer '\\[ada-adjust-case-buffer]'
-
- Call EXTERNAL pretty printer (if you have one) '\\[ada-call-pretty-printer]'
-
- Fill comment paragraph '\\[ada-fill-comment-paragraph]'
- Fill comment paragraph and justify each line '\\[ada-fill-comment-paragraph-justify]'
- Fill comment paragraph, justify and append postfix '\\[ada-fill-comment-paragraph-postfix]'
-
- Next func/proc/task '\\[ada-next-procedure]' Previous func/proc/task '\\[ada-previous-procedure]'
- Next package '\\[ada-next-package]' Previous package '\\[ada-previous-package]'
-
- Goto matching start of current 'end ...;' '\\[ada-move-to-start]'
- Goto end of current block '\\[ada-move-to-end]'
-
-Comments are handled using standard GNU Emacs conventions, including:
- Start a comment '\\[indent-for-comment]'
- Comment region '\\[comment-region]'
- Uncomment region '\\[ada-uncomment-region]'
- Continue comment on next line '\\[indent-new-comment-line]'
-
-If you use imenu.el:
- Display index-menu of functions & procedures '\\[imenu]'
-
-If you use find-file.el:
- Switch to other file (Body <-> Spec) '\\[ff-find-other-file]'
- or '\\[ff-mouse-find-other-file]
- Switch to other file in other window '\\[ada-ff-other-window]'
- or '\\[ff-mouse-find-other-file-other-window]
- If you use this function in a spec and no body is available, it gets created
- with body stubs.
-
-If you use ada-xref.el:
- Goto declaration: '\\[ada-point-and-xref]' on the identifier
- or '\\[ada-goto-declaration]' with point on the identifier
- Complete identifier: '\\[ada-complete-identifier]'
- Execute Gnatf: '\\[ada-gnatf-current]'"
-
- (interactive)
- (kill-all-local-variables)
-
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
-
- (make-local-variable 'comment-start)
- (setq comment-start "-- ")
-
- ;; comment end must be set because it may hold a wrong value if
- ;; this buffer had been in another mode before. RE
- (make-local-variable 'comment-end)
- (setq comment-end "")
-
- (make-local-variable 'comment-start-skip) ;; used by autofill
- (setq comment-start-skip "--+[ \t]*")
-
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'ada-indent-current-function)
-
- (make-local-variable 'fill-column)
- (setq fill-column 75)
-
- (make-local-variable 'comment-column)
- (setq comment-column 40)
-
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
-
- (make-local-variable 'case-fold-search)
- (setq case-fold-search t)
-
- (make-local-variable 'fill-paragraph-function)
- (setq fill-paragraph-function 'ada-fill-comment-paragraph)
-
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression ada-imenu-generic-expression)
-
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '((ada-font-lock-keywords
- ada-font-lock-keywords-1
- ada-font-lock-keywords-2)
- nil t
- ((?\_ . "w"))
- beginning-of-line))
-
- (setq major-mode 'ada-mode)
- (setq mode-name "Ada")
-
- (setq blink-matching-paren t)
-
- (use-local-map ada-mode-map)
-
- (if ada-mode-syntax-table
- (set-syntax-table ada-mode-syntax-table)
- (ada-create-syntax-table))
-
- (if ada-clean-buffer-before-saving
- (progn
- ;; remove all spaces at the end of lines in the whole buffer.
- (add-hook 'local-write-file-hooks 'ada-remove-trailing-spaces)
- ;; convert all tabs to the correct number of spaces.
- (add-hook 'local-write-file-hooks 'ada-untabify-buffer)))
-
-
- ;; add menu 'Ada' to the menu bar
- (ada-add-ada-menu)
-
- (run-hooks 'ada-mode-hook)
-
- ;; the following has to be done after running the ada-mode-hook
- ;; because users might want to set the values of these variable
- ;; inside the hook (MH)
-
- (cond ((eq ada-language-version 'ada83)
- (setq ada-keywords ada-83-keywords))
- ((eq ada-language-version 'ada95)
- (setq ada-keywords ada-95-keywords)))
-
- (if ada-auto-case
- (ada-activate-keys-for-case)))
-
-
-;;;--------------------------
-;;; Fill Comment Paragraph
-;;;--------------------------
-
-(defun ada-fill-comment-paragraph-justify ()
- "Fills current comment paragraph and justifies each line as well."
- (interactive)
- (ada-fill-comment-paragraph t))
-
-
-(defun ada-fill-comment-paragraph-postfix ()
- "Fills current comment paragraph and justifies each line as well.
-Prompts for a postfix to be appended to each line."
- (interactive)
- (ada-fill-comment-paragraph t t))
-
-
-(defun ada-fill-comment-paragraph (&optional justify postfix)
- "Fills the current comment paragraph.
-If JUSTIFY is non-nil, each line is justified as well.
-If POSTFIX and JUSTIFY are non-nil, `ada-fill-comment-postfix' is appended
-to each filled and justified line.
-If `ada-indent-comment-as-code' is non-nil, the paragraph is idented."
- (interactive "P")
- (let ((opos (point-marker))
- (begin nil)
- (end nil)
- (end-2 nil)
- (indent nil)
- (ada-fill-comment-old-postfix "")
- (fill-prefix nil))
-
- ;; check if inside comment
- (if (not (ada-in-comment-p))
- (error "not inside comment"))
-
- ;; prompt for postfix if wanted
- (if (and justify
- postfix)
- (setq ada-fill-comment-postfix
- (read-from-minibuffer "enter new postfix string: "
- ada-fill-comment-postfix)))
-
- ;; prompt for old postfix to remove if necessary
- (if (and justify
- postfix)
- (setq ada-fill-comment-old-postfix
- (read-from-minibuffer "enter already existing postfix string: "
- ada-fill-comment-postfix)))
-
- ;;
- ;; find limits of paragraph
- ;;
- (message "filling comment paragraph ...")
- (save-excursion
- (back-to-indentation)
- ;; find end of paragraph
- (while (and (looking-at "--.*$")
- (not (looking-at "--[ \t]*$")))
- (forward-line 1)
- (back-to-indentation))
- (beginning-of-line)
- (setq end (point-marker))
- (goto-char opos)
- ;; find begin of paragraph
- (back-to-indentation)
- (while (and (looking-at "--.*$")
- (not (looking-at "--[ \t]*$")))
- (forward-line -1)
- (back-to-indentation))
- (forward-line 1)
- ;; get indentation to calculate width for filling
- (ada-indent-current)
- (back-to-indentation)
- (setq indent (current-column))
- (setq begin (point-marker)))
-
- ;; delete old postfix if necessary
- (if (and justify
- postfix)
- (save-excursion
- (goto-char begin)
- (while (re-search-forward (concat ada-fill-comment-old-postfix
- "\n")
- end t)
- (replace-match "\n"))))
-
- ;; delete leading whitespace and uncomment
- (save-excursion
- (goto-char begin)
- (beginning-of-line)
- (while (re-search-forward "^[ \t]*--[ \t]*" end t)
- (replace-match "")))
-
- ;; calculate fill width
- (setq fill-column (- fill-column indent
- (length ada-fill-comment-prefix)
- (if postfix
- (length ada-fill-comment-postfix)
- 0)))
- ;; fill paragraph
- (fill-region begin (1- end) justify)
- (setq fill-column (+ fill-column indent
- (length ada-fill-comment-prefix)
- (if postfix
- (length ada-fill-comment-postfix)
- 0)))
- ;; find end of second last line
- (save-excursion
- (goto-char end)
- (forward-line -2)
- (end-of-line)
- (setq end-2 (point-marker)))
-
- ;; re-comment and re-indent region
- (save-excursion
- (goto-char begin)
- (indent-to indent)
- (insert ada-fill-comment-prefix)
- (while (re-search-forward "\n" (1- end-2) t)
- (replace-match (concat "\n" ada-fill-comment-prefix))
- (beginning-of-line)
- (indent-to indent)))
-
- ;; append postfix if wanted
- (if (and justify
- postfix
- ada-fill-comment-postfix)
- (progn
- ;; append postfix up to there
- (save-excursion
- (goto-char begin)
- (while (re-search-forward "\n" (1- end-2) t)
- (replace-match (concat ada-fill-comment-postfix "\n")))
-
- ;; fill last line and append postfix
- (end-of-line)
- (insert-char ?
- (- fill-column
- (current-column)
- (length ada-fill-comment-postfix)))
- (insert ada-fill-comment-postfix))))
-
- ;; delete the extra line that gets inserted somehow(??)
- (save-excursion
- (goto-char (1- end))
- (end-of-line)
- (delete-char 1))
-
- (message "filling comment paragraph ... done")
- (goto-char opos))
- t)
-
-
-;;;--------------------------------;;;
-;;; Call External Pretty Printer ;;;
-;;;--------------------------------;;;
-
-(defun ada-call-pretty-printer ()
- "Calls the external Pretty Printer.
-The name is specified in `ada-external-pretty-print-program'. Saves the
-current buffer in a directory specified by `ada-tmp-directory',
-starts the pretty printer as external process on that file and then
-reloads the beautified program in the buffer and cleans up
-`ada-tmp-directory'."
- (interactive)
- (let ((filename-with-path buffer-file-name)
- (curbuf (current-buffer))
- (orgpos (point))
- (mesgbuf nil) ;; for byte-compiling
- (file-path (file-name-directory buffer-file-name))
- (filename-without-path (file-name-nondirectory buffer-file-name))
- (tmp-file-with-directory
- (concat ada-tmp-directory
- (file-name-nondirectory buffer-file-name))))
- ;;
- ;; save buffer in temporary file
- ;;
- (message "saving current buffer to temporary file ...")
- (write-file tmp-file-with-directory)
- (auto-save-mode nil)
- (message "saving current buffer to temporary file ... done")
- ;;
- ;; call external pretty printer program
- ;;
-
- (message "running external pretty printer ...")
- ;; create a temporary buffer for messages of pretty printer
- (setq mesgbuf (get-buffer-create "Pretty Printer Messages"))
- ;; execute pretty printer on temporary file
- (call-process ada-external-pretty-print-program
- nil mesgbuf t
- tmp-file-with-directory)
- ;; display messages if there are some
- (if (buffer-modified-p mesgbuf)
- ;; show the message buffer
- (display-buffer mesgbuf t)
- ;; kill the message buffer
- (kill-buffer mesgbuf))
- (message "running external pretty printer ... done")
- ;;
- ;; kill current buffer and load pretty printer output
- ;; or restore old buffer
- ;;
- (if (y-or-n-p
- "Really replace current buffer with pretty printer output ? ")
- (progn
- (set-buffer-modified-p nil)
- (kill-buffer curbuf)
- (find-file tmp-file-with-directory))
- (message "old buffer contents restored"))
- ;;
- ;; delete temporary file and restore information of current buffer
- ;;
- (delete-file tmp-file-with-directory)
- (set-visited-file-name filename-with-path)
- (auto-save-mode t)
- (goto-char orgpos)))
-
-
-;;;---------------
-;;; auto-casing
-;;;---------------
-
-;; from Philippe Waroquiers <philippe@cfmu.eurocontrol.be>
-;; modifiedby RE and MH
-
-(defun ada-after-keyword-p ()
- ;; returns t if cursor is after a keyword.
- (save-excursion
- (forward-word -1)
- (and (save-excursion
- (or
- (= (point) (point-min))
- (backward-char 1))
- (not (looking-at "_"))) ; (MH)
- (looking-at (concat ada-keywords "[^_]")))))
-
-(defun ada-after-char-p ()
- ;; returns t if after ada character "'". This is interpreted as being
- ;; in a character constant.
- (save-excursion
- (if (> (point) 2)
- (progn
- (forward-char -2)
- (looking-at "'"))
- nil)))
-
-
-(defun ada-adjust-case (&optional force-identifier)
- "Adjust the case of the word before the just typed character.
-Respect options `ada-case-keyword', `ada-case-identifier', and
-`ada-case-attribute'.
-If FORCE-IDENTIFIER is non-nil then also adjust keyword as identifier." ; (MH)
- (forward-char -1)
- (if (and (> (point) 1) (not (or (ada-in-string-p)
- (ada-in-comment-p)
- (ada-after-char-p))))
- (if (eq (char-syntax (char-after (1- (point)))) ?w)
- (if (save-excursion
- (forward-word -1)
- (or (= (point) (point-min))
- (backward-char 1))
- (looking-at "'"))
- (funcall ada-case-attribute -1)
- (if (and
- (not force-identifier) ; (MH)
- (ada-after-keyword-p))
- (funcall ada-case-keyword -1)
- (funcall ada-case-identifier -1)))))
- (forward-char 1))
-
-
-(defun ada-adjust-case-interactive (arg)
- (interactive "P")
- (let ((lastk last-command-char))
- (cond ((or (eq lastk ?\n)
- (eq lastk ?\r))
- ;; horrible kludge
- (insert " ")
- (ada-adjust-case)
- ;; horrible dekludge
- (delete-backward-char 1)
- ;; some special keys and their bindings
- (cond
- ((eq lastk ?\n)
- (funcall ada-lfd-binding))
- ((eq lastk ?\r)
- (funcall ada-ret-binding))))
- ((eq lastk ?\C-i) (ada-tab))
- ((self-insert-command (prefix-numeric-value arg))))
- ;; if there is a keyword in front of the underscore
- ;; then it should be part of an identifier (MH)
- (if (eq lastk ?_)
- (ada-adjust-case t)
- (ada-adjust-case))))
-
-
-(defun ada-activate-keys-for-case ()
- ;; save original keybindings to allow swapping ret/lfd
- ;; when casing is activated
- ;; the 'or ...' is there to be sure that the value will not
- ;; be changed again when Ada Mode is called more than once (MH)
- (or ada-ret-binding
- (setq ada-ret-binding (key-binding "\C-M")))
- (or ada-lfd-binding
- (setq ada-lfd-binding (key-binding "\C-j")))
- ;; call case modifying function after certain keys.
- (mapcar (function (lambda(key) (define-key
- ada-mode-map
- (char-to-string key)
- 'ada-adjust-case-interactive)))
- '( ?` ?~ ?! ?@ ?# ?$ ?% ?^ ?& ?* ?( ?) ?- ?= ?+ ?[ ?{ ?] ?}
- ?_ ?\\ ?| ?\; ?: ?' ?\" ?< ?, ?. ?> ?? ?/ ?\n 32 ?\r )))
-;; deleted ?\t from above list
-
-;;
-;; added by MH
-;;
-(defun ada-loose-case-word (&optional arg)
- "Capitalizes the first letter and the letters following `_'.
-ARG is ignored, it's there to fit the standard casing functions' style."
- (let ((pos (point))
- (first t))
- (skip-chars-backward "a-zA-Z0-9_")
- (while (or first
- (search-forward "_" pos t))
- (and first
- (setq first nil))
- (insert-char (upcase (following-char)) 1)
- (delete-char 1))
- (goto-char pos)))
-
-
-;;
-;; added by MH
-;;
-(defun ada-adjust-case-region (from to)
- "Adjusts the case of all words in the region.
-Attention: This function might take very long for big regions !"
- (interactive "*r")
- (let ((begin nil)
- (end nil)
- (keywordp nil)
- (reldiff nil))
- (unwind-protect
- (save-excursion
- (set-syntax-table ada-mode-symbol-syntax-table)
- (goto-char to)
- ;;
- ;; loop: look for all identifiers and keywords
- ;;
- (while (re-search-backward
- "[^a-zA-Z0-9_]\\([a-zA-Z0-9_]+\\)[^a-zA-Z0-9_]"
- from
- t)
- ;;
- ;; print status message
- ;;
- (setq reldiff (- (point) from))
- (message "adjusting case ... %5d characters left"
- (- (point) from))
- (forward-char 1)
- (or
- ;; do nothing if it is a string or comment
- (ada-in-string-or-comment-p)
- (progn
- ;;
- ;; get the identifier or keyword
- ;;
- (setq begin (point))
- (setq keywordp (looking-at (concat ada-keywords "[^_]")))
- (skip-chars-forward "a-zA-Z0-9_")
- ;;
- ;; casing according to user-option
- ;;
- (if keywordp
- (funcall ada-case-keyword -1)
- (funcall ada-case-identifier -1))
- (goto-char begin))))
- (message "adjusting case ... done"))
- (set-syntax-table ada-mode-syntax-table))))
-
-
-;;
-;; added by MH
-;;
-(defun ada-adjust-case-buffer ()
- "Adjusts the case of all words in the whole buffer.
-ATTENTION: This function might take very long for big buffers !"
- (interactive "*")
- (ada-adjust-case-region (point-min) (point-max)))
-
-
-;;;------------------------;;;
-;;; Format Parameter Lists ;;;
-;;;------------------------;;;
-
-(defun ada-format-paramlist ()
- "Reformats a parameter list.
-ATTENTION: 1) Comments inside the list are killed !
- 2) If the syntax is not correct (especially, if there are
- semicolons missing), it can get totally confused !
-In such a case, use `undo', correct the syntax and try again."
-
- (interactive)
- (let ((begin nil)
- (end nil)
- (delend nil)
- (paramlist nil))
- (unwind-protect
- (progn
- (set-syntax-table ada-mode-symbol-syntax-table)
-
- ;; check if really inside parameter list
- (or (ada-in-paramlist-p)
- (error "not in parameter list"))
- ;;
- ;; find start of current parameter-list
- ;;
- (ada-search-ignore-string-comment
- (concat ada-subprog-start-re "\\|\\<body\\>" ) t nil)
- (ada-search-ignore-string-comment "(" nil nil t)
- (backward-char 1)
- (setq begin (point))
-
- ;;
- ;; find end of parameter-list
- ;;
- (forward-sexp 1)
- (setq delend (point))
- (delete-char -1)
-
- ;;
- ;; find end of last parameter-declaration
- ;;
- (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
- (forward-char 1)
- (setq end (point))
-
- ;;
- ;; build a list of all elements of the parameter-list
- ;;
- (setq paramlist (ada-scan-paramlist (1+ begin) end))
-
- ;;
- ;; delete the original parameter-list
- ;;
- (delete-region begin (1- delend))
-
- ;;
- ;; insert the new parameter-list
- ;;
- (goto-char begin)
- (ada-insert-paramlist paramlist))
-
- ;;
- ;; restore syntax-table
- ;;
- (set-syntax-table ada-mode-syntax-table)
- )))
-
-
-(defun ada-scan-paramlist (begin end)
- ;; Scans a parameter-list between BEGIN and END and returns a list
- ;; of its contents.
- ;; The list has the following format:
- ;;
- ;; Name of Param in? out? access? Name of Type Default-Exp or nil
- ;;
- ;; ( ('Name_Param_1' t nil t Type_Param_1 ':= expression')
- ;; ('Name_Param_2' nil nil t Type_Param_2 nil) )
-
- (let ((paramlist (list))
- (param (list))
- (notend t)
- (apos nil)
- (epos nil)
- (semipos nil)
- (match-cons nil))
-
- (goto-char begin)
- ;;
- ;; loop until end of last parameter
- ;;
- (while notend
-
- ;;
- ;; find first character of parameter-declaration
- ;;
- (ada-goto-next-non-ws)
- (setq apos (point))
-
- ;;
- ;; find last character of parameter-declaration
- ;;
- (if (setq match-cons
- (ada-search-ignore-string-comment "[ \t\n]*;" nil end t))
- (progn
- (setq epos (car match-cons))
- (setq semipos (cdr match-cons)))
- (setq epos end))
-
- ;;
- ;; read name(s) of parameter(s)
- ;;
- (goto-char apos)
- (looking-at "\\([a-zA-Z0-9_, \t\n]*[a-zA-Z0-9_]\\)[ \t\n]*:[^=]")
-
- (setq param (list (buffer-substring (match-beginning 1)
- (match-end 1))))
- (ada-search-ignore-string-comment ":" nil epos t)
-
- ;;
- ;; look for 'in'
- ;;
- (setq apos (point))
- (setq param
- (append param
- (list
- (consp
- (ada-search-ignore-string-comment "\\<in\\>"
- nil
- epos
- t)))))
-
- ;;
- ;; look for 'out'
- ;;
- (goto-char apos)
- (setq param
- (append param
- (list
- (consp
- (ada-search-ignore-string-comment "\\<out\\>"
- nil
- epos
- t)))))
-
- ;;
- ;; look for 'access'
- ;;
- (goto-char apos)
- (setq param
- (append param
- (list
- (consp
- (ada-search-ignore-string-comment "\\<access\\>"
- nil
- epos
- t)))))
-
- ;;
- ;; skip 'in'/'out'/'access'
- ;;
- (goto-char apos)
- (ada-goto-next-non-ws)
- (while (looking-at "\\<\\(in\\|out\\|access\\)\\>")
- (forward-word 1)
- (ada-goto-next-non-ws))
-
- ;;
- ;; read type of parameter
- ;;
- (looking-at "\\<[a-zA-Z0-9_\\.]+\\>")
- (setq param
- (append param
- (list
- (buffer-substring (match-beginning 0)
- (match-end 0)))))
-
- ;;
- ;; read default-expression, if there is one
- ;;
- (goto-char (setq apos (match-end 0)))
- (setq param
- (append param
- (list
- (if (setq match-cons
- (ada-search-ignore-string-comment ":="
- nil
- epos
- t))
- (buffer-substring (car match-cons)
- epos)
- nil))))
- ;;
- ;; add this parameter-declaration to the list
- ;;
- (setq paramlist (append paramlist (list param)))
-
- ;;
- ;; check if it was the last parameter
- ;;
- (if (eq epos end)
- (setq notend nil)
- (goto-char semipos))
-
- ) ; end of loop
-
- (reverse paramlist)))
-
-
-(defun ada-insert-paramlist (paramlist)
- ;; Inserts a formatted PARAMLIST in the buffer.
- ;; See doc of `ada-scan-paramlist' for the format.
- (let ((i (length paramlist))
- (parlen 0)
- (typlen 0)
- (temp 0)
- (inp nil)
- (outp nil)
- (accessp nil)
- (column nil)
- (orgpoint 0)
- (firstcol nil))
-
- ;;
- ;; loop until last parameter
- ;;
- (while (not (zerop i))
- (setq i (1- i))
-
- ;;
- ;; get max length of parameter-name
- ;;
- (setq parlen
- (if (<= parlen (setq temp
- (length (nth 0 (nth i paramlist)))))
- temp
- parlen))
-
- ;;
- ;; get max length of type-name
- ;;
- (setq typlen
- (if (<= typlen (setq temp
- (length (nth 4 (nth i paramlist)))))
- temp
- typlen))
-
- ;;
- ;; is there any 'in' ?
- ;;
- (setq inp
- (or inp
- (nth 1 (nth i paramlist))))
-
- ;;
- ;; is there any 'out' ?
- ;;
- (setq outp
- (or outp
- (nth 2 (nth i paramlist))))
-
- ;;
- ;; is there any 'access' ?
- ;;
- (setq accessp
- (or accessp
- (nth 3 (nth i paramlist))))) ; end of loop
-
- ;;
- ;; does paramlist already start on a separate line ?
- ;;
- (if (save-excursion
- (re-search-backward "^.\\|[^ \t]" nil t)
- (looking-at "^."))
- ;; yes => re-indent it
- (ada-indent-current)
- ;;
- ;; no => insert newline and indent it
- ;;
- (progn
- (ada-indent-current)
- (newline)
- (delete-horizontal-space)
- (setq orgpoint (point))
- (setq column (save-excursion
- (funcall (ada-indent-function) orgpoint)))
- (indent-to column)
- ))
-
- (insert "(")
-
- (setq firstcol (current-column))
- (setq i (length paramlist))
-
- ;;
- ;; loop until last parameter
- ;;
- (while (not (zerop i))
- (setq i (1- i))
- (setq column firstcol)
-
- ;;
- ;; insert parameter-name, space and colon
- ;;
- (insert (nth 0 (nth i paramlist)))
- (indent-to (+ column parlen 1))
- (insert ": ")
- (setq column (current-column))
-
- ;;
- ;; insert 'in' or space
- ;;
- (if (nth 1 (nth i paramlist))
- (insert "in ")
- (if (and
- (or inp
- accessp)
- (not (nth 3 (nth i paramlist))))
- (insert " ")))
-
- ;;
- ;; insert 'out' or space
- ;;
- (if (nth 2 (nth i paramlist))
- (insert "out ")
- (if (and
- (or outp
- accessp)
- (not (nth 3 (nth i paramlist))))
- (insert " ")))
-
- ;;
- ;; insert 'access'
- ;;
- (if (nth 3 (nth i paramlist))
- (insert "access "))
-
- (setq column (current-column))
-
- ;;
- ;; insert type-name and, if necessary, space and default-expression
- ;;
- (insert (nth 4 (nth i paramlist)))
- (if (nth 5 (nth i paramlist))
- (progn
- (indent-to (+ column typlen 1))
- (insert (nth 5 (nth i paramlist)))))
-
- ;;
- ;; check if it was the last parameter
- ;;
- (if (not (zerop i))
- ;; no => insert ';' and newline and indent
- (progn
- (insert ";")
- (newline)
- (indent-to firstcol))
- ;; yes
- (insert ")"))
-
- ) ; end of loop
-
- ;;
- ;; if anything follows, except semicolon:
- ;; put it in a new line and indent it
- ;;
- (if (not (looking-at "[ \t]*[;\n]"))
- (ada-indent-newline-indent))
-
- ))
-
-
-;;;----------------------------;;;
-;;; Move To Matching Start/End ;;;
-;;;----------------------------;;;
-
-(defun ada-move-to-start ()
- "Moves point to the matching start of the current Ada structure."
- (interactive)
- (let ((pos (point)))
- (unwind-protect
- (progn
- (set-syntax-table ada-mode-symbol-syntax-table)
-
- (message "searching for block start ...")
- (save-excursion
- ;;
- ;; do nothing if in string or comment or not on 'end ...;'
- ;; or if an error occurs during processing
- ;;
- (or
- (ada-in-string-or-comment-p)
- (and (progn
- (or (looking-at "[ \t]*\\<end\\>")
- (backward-word 1))
- (or (looking-at "[ \t]*\\<end\\>")
- (backward-word 1))
- (or (looking-at "[ \t]*\\<end\\>")
- (error "not on end ...;")))
- (ada-goto-matching-start 1)
- (setq pos (point))
-
- ;;
- ;; on 'begin' => go on, according to user option
- ;;
- ada-move-to-declaration
- (looking-at "\\<begin\\>")
- (ada-goto-matching-decl-start)
- (setq pos (point))))
-
- ) ; end of save-excursion
-
- ;; now really move to the found position
- (goto-char pos)
- (message "searching for block start ... done"))
-
- ;;
- ;; restore syntax-table
- ;;
- (set-syntax-table ada-mode-syntax-table))))
-
-
-(defun ada-move-to-end ()
- "Moves point to the matching end of the current block around point.
-Moves to 'begin' if in a declarative part."
- (interactive)
- (let ((pos (point))
- (decstart nil)
- (packdecl nil))
- (unwind-protect
- (progn
- (set-syntax-table ada-mode-symbol-syntax-table)
-
- (message "searching for block end ...")
- (save-excursion
-
- (forward-char 1)
- (cond
- ;; directly on 'begin'
- ((save-excursion
- (ada-goto-previous-word)
- (looking-at "\\<begin\\>"))
- (ada-goto-matching-end 1))
- ;; on first line of defun declaration
- ((save-excursion
- (and (ada-goto-stmt-start)
- (looking-at "\\<function\\>\\|\\<procedure\\>" )))
- (ada-search-ignore-string-comment "\\<begin\\>"))
- ;; on first line of task declaration
- ((save-excursion
- (and (ada-goto-stmt-start)
- (looking-at "\\<task\\>" )
- (forward-word 1)
- (ada-search-ignore-string-comment "[^ \n\t]")
- (not (backward-char 1))
- (looking-at "\\<body\\>")))
- (ada-search-ignore-string-comment "\\<begin\\>"))
- ;; accept block start
- ((save-excursion
- (and (ada-goto-stmt-start)
- (looking-at "\\<accept\\>" )))
- (ada-goto-matching-end 0))
- ;; package start
- ((save-excursion
- (and (ada-goto-matching-decl-start t)
- (looking-at "\\<package\\>")))
- (ada-goto-matching-end 1))
- ;; inside a 'begin' ... 'end' block
- ((save-excursion
- (ada-goto-matching-decl-start t))
- (ada-search-ignore-string-comment "\\<begin\\>"))
- ;; (hopefully ;-) everything else
- (t
- (ada-goto-matching-end 1)))
- (setq pos (point))
-
- ) ; end of save-excursion
-
- ;; now really move to the found position
- (goto-char pos)
- (message "searching for block end ... done"))
-
- ;;
- ;; restore syntax-table
- ;;
- (set-syntax-table ada-mode-syntax-table))))
-
-
-;;;-----------------------------;;;
-;;; Functions For Indentation ;;;
-;;;-----------------------------;;;
-
-;; ---- main functions for indentation
-
-(defun ada-indent-region (beg end)
- "Indents the region using `ada-indent-current' on each line."
- (interactive "*r")
- (goto-char beg)
- (let ((block-done 0)
- (lines-remaining (count-lines beg end))
- (msg (format "indenting %4d lines %%4d lines remaining ..."
- (count-lines beg end)))
- (endmark (copy-marker end)))
- ;; catch errors while indenting
- (condition-case err
- (while (< (point) endmark)
- (if (> block-done 9)
- (progn (message msg lines-remaining)
- (setq block-done 0)))
- (if (looking-at "^$") nil
- (ada-indent-current))
- (forward-line 1)
- (setq block-done (1+ block-done))
- (setq lines-remaining (1- lines-remaining)))
- ;; show line number where the error occurred
- (error
- (error "line %d: %s" (1+ (count-lines (point-min) (point))) err)))
- (message "indenting ... done")))
-
-
-(defun ada-indent-newline-indent ()
- "Indents the current line, inserts a newline and then indents the new line."
- (interactive "*")
- (let ((column)
- (orgpoint))
-
- (ada-indent-current)
- (newline)
- (delete-horizontal-space)
- (setq orgpoint (point))
-
- (unwind-protect
- (progn
- (set-syntax-table ada-mode-symbol-syntax-table)
-
- (setq column (save-excursion
- (funcall (ada-indent-function) orgpoint))))
-
- ;;
- ;; restore syntax-table
- ;;
- (set-syntax-table ada-mode-syntax-table))
-
- (indent-to column)
-
- ;; The following is needed to ensure that indentation will still be
- ;; correct if something follows behind point when typing LFD
- ;; For example: Imagine point to be there (*) when LFD is typed:
- ;; while cond loop
- ;; null; *end loop;
- ;; Result without the following statement would be:
- ;; while cond loop
- ;; null;
- ;; *end loop;
- ;; You would then have to type TAB to correct it.
- ;; If that doesn't bother you, you can comment out the following
- ;; statement to speed up indentation a LITTLE bit.
-
- (if (not (looking-at "[ \t]*$"))
- (ada-indent-current))
- ))
-
-
-(defun ada-indent-current ()
- "Indents current line as Ada code.
-This works by two steps:
- 1) It moves point to the end of the previous code line.
- Then it calls the function to calculate the indentation for the
- following line as if a newline would be inserted there.
- The calculated column # is saved and the old position of point
- is restored.
- 2) Then another function is called to calculate the indentation for
- the current line, based on the previously calculated column #."
-
- (interactive)
-
- (unwind-protect
- (progn
- (set-syntax-table ada-mode-symbol-syntax-table)
-
- (let ((line-end)
- (orgpoint (point-marker))
- (cur-indent)
- (prev-indent)
- (prevline t))
-
- ;;
- ;; first step
- ;;
- (save-excursion
- (if (ada-goto-prev-nonblank-line t)
- ;;
- ;; we are not in the first accessible line in the buffer
- ;;
- (progn
- ;;(end-of-line)
- ;;(forward-char 1)
- ;; we are already at the BOL
- (forward-line 1)
- (setq line-end (point))
- (setq prev-indent
- (save-excursion
- (funcall (ada-indent-function) line-end))))
- (progn ; first line of buffer -> set indent
- (beginning-of-line) ; to 0
- (delete-horizontal-space)
- (setq prevline nil))))
-
- (if prevline
- ;;
- ;; we are not in the first accessible line in the buffer
- ;;
- (progn
- ;;
- ;; second step
- ;;
- (back-to-indentation)
- (setq cur-indent (ada-get-current-indent prev-indent))
- ;; only reindent if indentation is different then the current
- (if (= (current-column) cur-indent)
- nil
- (delete-horizontal-space)
- (indent-to cur-indent))
- ;;
- ;; restore position of point
- ;;
- (goto-char orgpoint)
- (if (< (current-column) (current-indentation))
- (back-to-indentation))))))
-
- ;;
- ;; restore syntax-table
- ;;
- (set-syntax-table ada-mode-syntax-table)))
-
-
-(defun ada-get-current-indent (prev-indent)
- ;; Returns the column # to indent the current line to.
- ;; PREV-INDENT is the indentation resulting from the previous lines.
- (let ((column nil)
- (pos nil)
- (match-cons nil))
-
- (cond
- ;;
- ;; in open parenthesis, but not in parameter-list
- ;;
- ((and
- ada-indent-to-open-paren
- (not (ada-in-paramlist-p))
- (setq column (ada-in-open-paren-p)))
- ;; check if we have something like this (Table_Component_Type =>
- ;; Source_File_Record,)
- (save-excursion
- (if (and (ada-search-ignore-string-comment "[^ \t]" t nil)
- (looking-at "\n")
- (ada-search-ignore-string-comment "[^ \t\n]" t nil)
- (looking-at ">"))
- (setq column (+ ada-broken-indent column))))
- column)
-
- ;;
- ;; end
- ;;
- ((looking-at "\\<end\\>")
- (save-excursion
- (ada-goto-matching-start 1)
-
- ;;
- ;; found 'loop' => skip back to 'while' or 'for'
- ;; if 'loop' is not on a separate line
- ;;
- (if (and
- (looking-at "\\<loop\\>")
- (save-excursion
- (back-to-indentation)
- (not (looking-at "\\<loop\\>"))))
- (if (save-excursion
- (and
- (setq match-cons
- (ada-search-ignore-string-comment
- ada-loop-start-re t nil))
- (not (looking-at "\\<loop\\>"))))
- (goto-char (car match-cons))))
-
- (current-indentation)))
- ;;
- ;; exception
- ;;
- ((looking-at "\\<exception\\>")
- (save-excursion
- (ada-goto-matching-start 1)
- (current-indentation)))
- ;;
- ;; when
- ;;
- ((looking-at "\\<when\\>")
- (save-excursion
- (ada-goto-matching-start 1)
- (+ (current-indentation) ada-when-indent)))
- ;;
- ;; else
- ;;
- ((looking-at "\\<else\\>")
- (if (save-excursion
- (ada-goto-previous-word)
- (looking-at "\\<or\\>"))
- prev-indent
- (save-excursion
- (ada-goto-matching-start 1 nil t)
- (current-indentation))))
- ;;
- ;; elsif
- ;;
- ((looking-at "\\<elsif\\>")
- (save-excursion
- (ada-goto-matching-start 1 nil t)
- (current-indentation)))
- ;;
- ;; then
- ;;
- ((looking-at "\\<then\\>")
- (if (save-excursion
- (ada-goto-previous-word)
- (looking-at "\\<and\\>"))
- prev-indent
- (save-excursion
- (ada-search-ignore-string-comment "\\<elsif\\>\\|\\<if\\>" t nil)
- (+ (current-indentation) ada-stmt-end-indent))))
- ;;
- ;; loop
- ;;
- ((looking-at "\\<loop\\>")
- (setq pos (point))
- (save-excursion
- (goto-char (match-end 0))
- (ada-goto-stmt-start)
- (if (looking-at "\\<loop\\>\\|\\<if\\>")
- prev-indent
- (progn
- (if (not (looking-at ada-loop-start-re))
- (ada-search-ignore-string-comment ada-loop-start-re
- nil pos))
- (if (looking-at "\\<loop\\>")
- prev-indent
- (+ (current-indentation) ada-stmt-end-indent))))))
- ;;
- ;; begin
- ;;
- ((looking-at "\\<begin\\>")
- (save-excursion
- (if (ada-goto-matching-decl-start t)
- (current-indentation)
- (progn
- (message "no matching declaration start")
- prev-indent))))
- ;;
- ;; is
- ;;
- ((looking-at "\\<is\\>")
- (if (and
- ada-indent-is-separate
- (save-excursion
- (goto-char (match-end 0))
- (ada-goto-next-non-ws (save-excursion
- (end-of-line)
- (point)))
- (looking-at "\\<abstract\\>\\|\\<separate\\>")))
- (save-excursion
- (ada-goto-stmt-start)
- (+ (current-indentation) ada-indent))
- (save-excursion
- (ada-goto-stmt-start)
- (+ (current-indentation) ada-stmt-end-indent))))
- ;;
- ;; record
- ;;
- ((looking-at "\\<record\\>")
- (save-excursion
- (ada-search-ignore-string-comment
- "\\<\\(type\\|use\\)\\>" t nil)
- (if (looking-at "\\<use\\>")
- (ada-search-ignore-string-comment "\\<for\\>" t nil))
- (+ (current-indentation) ada-indent-record-rel-type)))
- ;;
- ;; or as statement-start
- ;;
- ((ada-looking-at-semi-or)
- (save-excursion
- (ada-goto-matching-start 1)
- (current-indentation)))
- ;;
- ;; private as statement-start
- ;;
- ((ada-looking-at-semi-private)
- (save-excursion
- (ada-goto-matching-decl-start)
- (current-indentation)))
- ;;
- ;; new/abstract/separate
- ;;
- ((looking-at "\\<\\(new\\|abstract\\|separate\\)\\>")
- (- prev-indent ada-indent (- ada-broken-indent)))
- ;;
- ;; return
- ;;
- ((looking-at "\\<return\\>")
- (save-excursion
- (forward-sexp -1)
- (if (and (looking-at "(")
- (save-excursion
- (backward-sexp 2)
- (looking-at "\\<function\\>")))
- (1+ (current-column))
- prev-indent)))
- ;;
- ;; do
- ;;
- ((looking-at "\\<do\\>")
- (save-excursion
- (ada-goto-stmt-start)
- (+ (current-indentation) ada-stmt-end-indent)))
- ;;
- ;; package/function/procedure
- ;;
- ((and (looking-at "\\<\\(package\\|function\\|procedure\\)\\>")
- (save-excursion
- (forward-char 1)
- (ada-goto-stmt-start)
- (looking-at "\\<\\(package\\|function\\|procedure\\)\\>")))
- (save-excursion
- ;; look for 'generic'
- (if (and (ada-goto-matching-decl-start t)
- (looking-at "generic"))
- (current-column)
- prev-indent)))
- ;;
- ;; label
- ;;
- ((looking-at "\\<[a-zA-Z0-9_]+[ \t\n]*:[^=]")
- (if (ada-in-decl-p)
- prev-indent
- (+ prev-indent ada-label-indent)))
- ;;
- ;; identifier and other noindent-statements
- ;;
- ((looking-at "\\<[a-zA-Z0-9_]+[ \t\n]*")
- prev-indent)
- ;;
- ;; beginning of a parameter list
- ;;
- ((looking-at "(")
- prev-indent)
- ;;
- ;; end of a parameter list
- ;;
- ((looking-at ")")
- (save-excursion
- (forward-char 1)
- (backward-sexp 1)
- (current-column)))
- ;;
- ;; comment
- ;;
- ((looking-at "--")
- (if ada-indent-comment-as-code
- prev-indent
- (current-indentation)))
- ;;
- ;; unknown syntax - maybe this should signal an error ?
- ;;
- (t
- prev-indent))))
-
-
-(defun ada-indent-function (&optional nomove)
- ;; Returns the function to calculate the indentation for the current
- ;; line according to the previous statement, ignoring the contents
- ;; of the current line after point. Moves point to the beginning of
- ;; the current statement, if NOMOVE is nil.
-
- (let ((orgpoint (point))
- (func nil)
- (stmt-start nil))
- ;;
- ;; inside a parameter-list
- ;;
- (if (ada-in-paramlist-p)
- (setq func 'ada-get-indent-paramlist)
- (progn
- ;;
- ;; move to beginning of current statement
- ;;
- (if (not nomove)
- (setq stmt-start (ada-goto-stmt-start)))
- ;;
- ;; no beginning found => don't change indentation
- ;;
- (if (and
- (eq orgpoint (point))
- (not nomove))
- (setq func 'ada-get-indent-nochange)
-
- (cond
- ;;
- ((and
- ada-indent-to-open-paren
- (ada-in-open-paren-p))
- (setq func 'ada-get-indent-open-paren))
- ;;
- ((looking-at "\\<end\\>")
- (setq func 'ada-get-indent-end))
- ;;
- ((looking-at ada-loop-start-re)
- (setq func 'ada-get-indent-loop))
- ;;
- ((looking-at ada-subprog-start-re)
- (setq func 'ada-get-indent-subprog))
- ;;
- ((looking-at "\\<package\\>")
- (setq func 'ada-get-indent-subprog)) ; maybe it needs a
- ; special function
- ; sometimes ?
- ;;
- ((looking-at ada-block-start-re)
- (setq func 'ada-get-indent-block-start))
- ;;
- ((looking-at "\\<type\\>")
- (setq func 'ada-get-indent-type))
- ;;
- ((looking-at "\\<\\(els\\)?if\\>")
- (setq func 'ada-get-indent-if))
- ;;
- ((looking-at "\\<case\\>")
- (setq func 'ada-get-indent-case))
- ;;
- ((looking-at "\\<when\\>")
- (setq func 'ada-get-indent-when))
- ;;
- ((looking-at "--")
- (setq func 'ada-get-indent-comment))
- ;;
- ((looking-at "[a-zA-Z0-9_]+[ \t\n]*:[^=]")
- (setq func 'ada-get-indent-label))
- ;;
- ((looking-at "\\<separate\\>")
- (setq func 'ada-get-indent-nochange))
- (t
- (setq func 'ada-get-indent-noindent))))))
-
- func))
-
-
-;; ---- functions to return indentation for special cases
-
-(defun ada-get-indent-open-paren (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be behind an open parenthesis not yet closed.
- (ada-in-open-paren-p))
-
-
-(defun ada-get-indent-nochange (orgpoint)
- ;; Returns the indentation (column #) of the current line.
- (save-excursion
- (forward-line -1)
- (current-indentation)))
-
-
-(defun ada-get-indent-paramlist (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be inside a parameter-list.
- (save-excursion
- (ada-search-ignore-string-comment "[^ \t\n]" t nil t)
- (cond
- ;;
- ;; in front of the first parameter
- ;;
- ((looking-at "(")
- (goto-char (match-end 0))
- (current-column))
- ;;
- ;; in front of another parameter
- ;;
- ((looking-at ";")
- (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
- (ada-goto-next-non-ws)
- (current-column))
- ;;
- ;; inside a parameter declaration
- ;;
- (t
- (goto-char (cdr (ada-search-ignore-string-comment "(\\|;" t nil t)))
- (ada-goto-next-non-ws)
- (+ (current-column) ada-broken-indent)))))
-
-
-(defun ada-get-indent-end (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of an end-statement.
- ;; Therefore it has to find the corresponding start. This can be a little
- ;; slow, if it has to search through big files with many nested blocks.
- ;; Signals an error if the corresponding block-start doesn't match.
- (let ((defun-name nil)
- (indent nil))
- ;;
- ;; is the line already terminated by ';' ?
- ;;
- (if (save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- ;;
- ;; yes, look what's following 'end'
- ;;
- (progn
- (forward-word 1)
- (ada-goto-next-non-ws)
- (cond
- ;;
- ;; loop/select/if/case/record/select
- ;;
- ((looking-at "\\<\\(loop\\|select\\|if\\|case\\|record\\)\\>")
- (save-excursion
- (ada-check-matching-start
- (buffer-substring (match-beginning 0)
- (match-end 0)))
- (if (looking-at "\\<\\(loop\\|record\\)\\>")
- (progn
- (forward-word 1)
- (ada-goto-stmt-start)))
- ;; a label ? => skip it
- (if (looking-at "[a-zA-Z0-9_]+[ \n\t]+:")
- (progn
- (goto-char (match-end 0))
- (ada-goto-next-non-ws)))
- ;; really looking-at the right thing ?
- (or (looking-at (concat "\\<\\("
- "loop\\|select\\|if\\|case\\|"
- "record\\|while\\|type\\)\\>"))
- (progn
- (ada-search-ignore-string-comment
- (concat "\\<\\("
- "loop\\|select\\|if\\|case\\|"
- "record\\|while\\|type\\)\\>")))
- (backward-word 1))
- (current-indentation)))
- ;;
- ;; a named block end
- ;;
- ((looking-at ada-ident-re)
- (setq defun-name (buffer-substring (match-beginning 0)
- (match-end 0)))
- (save-excursion
- (ada-goto-matching-start 0)
- (ada-check-defun-name defun-name)
- (current-indentation)))
- ;;
- ;; a block-end without name
- ;;
- ((looking-at ";")
- (save-excursion
- (ada-goto-matching-start 0)
- (if (looking-at "\\<begin\\>")
- (progn
- (setq indent (current-column))
- (if (ada-goto-matching-decl-start t)
- (current-indentation)
- indent)))))
- ;;
- ;; anything else - should maybe signal an error ?
- ;;
- (t
- (+ (current-indentation) ada-broken-indent))))
-
- (+ (current-indentation) ada-broken-indent))))
-
-
-(defun ada-get-indent-case (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of an case-statement.
- (let ((cur-indent (current-indentation))
- (match-cons nil)
- (opos (point)))
- (cond
- ;;
- ;; case..is..when..=>
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "[ \t\n]+=>" nil orgpoint)))
- (save-excursion
- (goto-char (car match-cons))
- (if (not (ada-search-ignore-string-comment "\\<when\\>" t opos))
- (error "missing 'when' between 'case' and '=>'"))
- (+ (current-indentation) ada-indent)))
- ;;
- ;; case..is..when
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "\\<when\\>" nil orgpoint)))
- (goto-char (cdr match-cons))
- (+ (current-indentation) ada-broken-indent))
- ;;
- ;; case..is
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "\\<is\\>" nil orgpoint)))
- (+ (current-indentation) ada-when-indent))
- ;;
- ;; incomplete case
- ;;
- (t
- (+ (current-indentation) ada-broken-indent)))))
-
-
-(defun ada-get-indent-when (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of an when-statement.
- (let ((cur-indent (current-indentation)))
- (if (ada-search-ignore-string-comment
- "[ \t\n]+=>" nil orgpoint)
- (+ cur-indent ada-indent)
- (+ cur-indent ada-broken-indent))))
-
-
-(defun ada-get-indent-if (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of an if-statement.
- (let ((cur-indent (current-indentation))
- (match-cons nil))
- ;;
- ;; if..then ?
- ;;
- (if (ada-search-but-not
- "\\<then\\>" "\\<and\\>[ \t\n]+\\<then\\>" nil orgpoint)
-
- (progn
- ;;
- ;; 'then' first in separate line ?
- ;; => indent according to 'then'
- ;;
- (if (save-excursion
- (back-to-indentation)
- (looking-at "\\<then\\>"))
- (setq cur-indent (current-indentation)))
- (forward-word 1)
- ;;
- ;; something follows 'then' ?
- ;;
- (if (setq match-cons
- (ada-search-ignore-string-comment
- "[^ \t\n]" nil orgpoint))
- (progn
- (goto-char (car match-cons))
- (+ ada-indent
- (- cur-indent (current-indentation))
- (funcall (ada-indent-function t) orgpoint)))
-
- (+ cur-indent ada-indent)))
-
- (+ cur-indent ada-broken-indent))))
-
-
-(defun ada-get-indent-block-start (orgpoint)
- ;; Returns the indentation (column #) for the new line after
- ;; ORGPOINT. Assumes point to be at the beginning of a block start
- ;; keyword.
- (let ((cur-indent (current-indentation))
- (pos nil))
- (cond
- ((save-excursion
- (forward-word 1)
- (setq pos (car (ada-search-ignore-string-comment
- "[^ \t\n]" nil orgpoint))))
- (goto-char pos)
- (save-excursion
- (funcall (ada-indent-function t) orgpoint)))
- ;;
- ;; nothing follows the block-start
- ;;
- (t
- (+ (current-indentation) ada-indent)))))
-
-
-(defun ada-get-indent-subprog (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of a subprog-/package-declaration.
- (let ((match-cons nil)
- (cur-indent (current-indentation))
- (foundis nil)
- (addind 0)
- (fstart (point)))
- ;;
- ;; is there an 'is' in front of point ?
- ;;
- (if (save-excursion
- (setq match-cons
- (ada-search-ignore-string-comment
- "\\<is\\>\\|\\<do\\>" nil orgpoint)))
- ;;
- ;; yes, then skip to its end
- ;;
- (progn
- (setq foundis t)
- (goto-char (cdr match-cons)))
- ;;
- ;; no, then goto next non-ws, if there is one in front of point
- ;;
- (progn
- (if (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint)
- (ada-goto-next-non-ws)
- (goto-char orgpoint))))
-
- (cond
- ;;
- ;; nothing follows 'is'
- ;;
- ((and
- foundis
- (save-excursion
- (not (ada-search-ignore-string-comment
- "[^ \t\n]" nil orgpoint t))))
- (+ cur-indent ada-indent))
- ;;
- ;; is abstract/separate/new ...
- ;;
- ((and
- foundis
- (save-excursion
- (setq match-cons
- (ada-search-ignore-string-comment
- "\\<\\(separate\\|new\\|abstract\\)\\>"
- nil orgpoint))))
- (goto-char (car match-cons))
- (ada-search-ignore-string-comment ada-subprog-start-re t)
- (ada-get-indent-noindent orgpoint))
- ;;
- ;; something follows 'is'
- ;;
- ((and
- foundis
- (save-excursion
- (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint))
- (ada-goto-next-non-ws)
- (funcall (ada-indent-function t) orgpoint)))
- ;;
- ;; no 'is' but ';'
- ;;
- ((save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- cur-indent)
- ;;
- ;; no 'is' or ';'
- ;;
- (t
- (+ cur-indent ada-broken-indent)))))
-
-
-(defun ada-get-indent-noindent (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of a 'noindent statement'.
- (if (save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- (current-indentation)
- (+ (current-indentation) ada-broken-indent)))
-
-
-(defun ada-get-indent-label (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of a label or variable declaration.
- ;; Checks the context to decide if it's a label or a variable declaration.
- ;; This check might be a bit slow.
- (let ((match-cons nil)
- (cur-indent (current-indentation)))
- (goto-char (cdr (ada-search-ignore-string-comment ":")))
- (cond
- ;;
- ;; loop label
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- ada-loop-start-re nil orgpoint)))
- (goto-char (car match-cons))
- (ada-get-indent-loop orgpoint))
- ;;
- ;; declare label
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "\\<declare\\>" nil orgpoint)))
- (save-excursion
- (goto-char (car match-cons))
- (+ (current-indentation) ada-indent)))
- ;;
- ;; complete statement following colon
- ;;
- ((save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- (if (ada-in-decl-p)
- cur-indent ; variable-declaration
- (- cur-indent ada-label-indent))) ; label
- ;;
- ;; broken statement
- ;;
- ((save-excursion
- (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint))
- (if (ada-in-decl-p)
- (+ cur-indent ada-broken-indent)
- (+ cur-indent ada-broken-indent (- ada-label-indent))))
- ;;
- ;; nothing follows colon
- ;;
- (t
- (if (ada-in-decl-p)
- (+ cur-indent ada-broken-indent) ; variable-declaration
- (- cur-indent ada-label-indent)))))) ; label
-
-
-(defun ada-get-indent-loop (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of a loop statement
- ;; or (unfortunately) also a for ... use statement.
- (let ((match-cons nil)
- (pos (point)))
- (cond
-
- ;;
- ;; statement complete
- ;;
- ((save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- (current-indentation))
- ;;
- ;; simple loop
- ;;
- ((looking-at "loop\\>")
- (ada-get-indent-block-start orgpoint))
-
- ;;
- ;; 'for'- loop (or also a for ... use statement)
- ;;
- ((looking-at "for\\>")
- (cond
- ;;
- ;; for ... use
- ;;
- ((save-excursion
- (and
- (goto-char (match-end 0))
- (ada-search-ignore-string-comment "[^ /n/t]" nil orgpoint)
- (not (backward-char 1))
- (not (zerop (skip-chars-forward "_a-zA-Z0-9'")))
- (ada-search-ignore-string-comment "[^ /n/t]" nil orgpoint)
- (not (backward-char 1))
- (looking-at "\\<use\\>")
- ;;
- ;; check if there is a 'record' before point
- ;;
- (progn
- (setq match-cons (ada-search-ignore-string-comment
- "\\<record\\>" nil orgpoint))
- t)))
- (if match-cons
- (goto-char (car match-cons)))
- (+ (current-indentation) ada-indent))
- ;;
- ;; for..loop
- ;;
- ((save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "\\<loop\\>" nil orgpoint)))
- (goto-char (car match-cons))
- ;;
- ;; indent according to 'loop', if it's first in the line;
- ;; otherwise to 'for'
- ;;
- (if (not (save-excursion
- (back-to-indentation)
- (looking-at "\\<loop\\>")))
- (goto-char pos))
- (+ (current-indentation) ada-indent))
- ;;
- ;; for-statement is broken
- ;;
- (t
- (+ (current-indentation) ada-broken-indent))))
-
- ;;
- ;; 'while'-loop
- ;;
- ((looking-at "while\\>")
- ;;
- ;; while..loop ?
- ;;
- (if (save-excursion
- (setq match-cons (ada-search-ignore-string-comment
- "\\<loop\\>" nil orgpoint)))
-
- (progn
- (goto-char (car match-cons))
- ;;
- ;; indent according to 'loop', if it's first in the line;
- ;; otherwise to 'while'.
- ;;
- (if (not (save-excursion
- (back-to-indentation)
- (looking-at "\\<loop\\>")))
- (goto-char pos))
- (+ (current-indentation) ada-indent))
-
- (+ (current-indentation) ada-broken-indent))))))
-
-
-(defun ada-get-indent-type (orgpoint)
- ;; Returns the indentation (column #) for the new line after ORGPOINT.
- ;; Assumes point to be at the beginning of a type statement.
- (let ((match-dat nil))
- (cond
- ;;
- ;; complete record declaration
- ;;
- ((save-excursion
- (and
- (setq match-dat (ada-search-ignore-string-comment "\\<end\\>"
- nil
- orgpoint))
- (ada-goto-next-non-ws)
- (looking-at "\\<record\\>")
- (forward-word 1)
- (ada-goto-next-non-ws)
- (looking-at ";")))
- (goto-char (car match-dat))
- (current-indentation))
- ;;
- ;; record type
- ;;
- ((save-excursion
- (setq match-dat (ada-search-ignore-string-comment "\\<record\\>"
- nil
- orgpoint)))
- (goto-char (car match-dat))
- (+ (current-indentation) ada-indent))
- ;;
- ;; complete type declaration
- ;;
- ((save-excursion
- (ada-search-ignore-string-comment ";" nil orgpoint))
- (current-indentation))
- ;;
- ;; "type ... is", but not "type ... is ...", which is broken
- ;;
- ((save-excursion
- (and
- (ada-search-ignore-string-comment "\\<is\\>" nil orgpoint)
- (not (ada-search-ignore-string-comment "[^ \t\n]" nil orgpoint))))
- (+ (current-indentation) ada-indent))
- ;;
- ;; broken statement
- ;;
- (t
- (+ (current-indentation) ada-broken-indent)))))
-
-
-;;; ---- support-functions for indentation
-
-;;; ---- searching and matching
-
-(defun ada-goto-stmt-start (&optional limit)
- ;; Moves point to the beginning of the statement that point is in or
- ;; after. Returns the new position of point. Beginnings are found
- ;; by searching for 'ada-end-stmt-re' and then moving to the
- ;; following non-ws that is not a comment. LIMIT is actually not
- ;; used by the indentation functions.
- (let ((match-dat nil)
- (orgpoint (point)))
-
- (setq match-dat (ada-search-prev-end-stmt limit))
- (if match-dat
- ;;
- ;; found a previous end-statement => check if anything follows
- ;;
- (progn
- (if (not
- (save-excursion
- (goto-char (cdr match-dat))
- (ada-search-ignore-string-comment
- "[^ \t\n]" nil orgpoint)))
- ;;
- ;; nothing follows => it's the end-statement directly in
- ;; front of point => search again
- ;;
- (setq match-dat (ada-search-prev-end-stmt limit)))
- ;;
- ;; if found the correct end-statement => goto next non-ws
- ;;
- (if match-dat
- (goto-char (cdr match-dat)))
- (ada-goto-next-non-ws))
-
- ;;
- ;; no previous end-statement => we are at the beginning of the
- ;; accessible part of the buffer
- ;;
- (progn
- (goto-char (point-min))
- ;;
- ;; skip to the very first statement, if there is one
- ;;
- (if (setq match-dat
- (ada-search-ignore-string-comment
- "[^ \t\n]" nil orgpoint))
- (goto-char (car match-dat))
- (goto-char orgpoint))))
-
-
- (point)))
-
-
-(defun ada-search-prev-end-stmt (&optional limit)
- ;; Moves point to previous end-statement. Returns a cons cell whose
- ;; car is the beginning and whose cdr the end of the match.
- ;; End-statements are defined by 'ada-end-stmt-re'. Checks for
- ;; certain keywords if they follow 'end', which means they are no
- ;; end-statement there.
- (interactive) ;; DEBUG
- (let ((match-dat nil)
- (pos nil)
- (found nil))
- ;;
- ;; search until found or beginning-of-buffer
- ;;
- (while
- (and
- (not found)
- (setq match-dat (ada-search-ignore-string-comment ada-end-stmt-re
- t
- limit)))
-
- (goto-char (car match-dat))
-
- (if (not (ada-in-open-paren-p))
- ;;
- ;; check if there is an 'end' in front of the match
- ;;
- (if (not (and
- (looking-at "\\<\\(record\\|loop\\|select\\)\\>")
- (save-excursion
- (ada-goto-previous-word)
- (looking-at "\\<end\\>"))))
- (setq found t)
-
- (forward-word -1)))) ; end of loop
-
- (if found
- match-dat
- nil)))
-
-
-(defun ada-goto-next-non-ws (&optional limit)
- ;; Skips whitespaces, newlines and comments to next non-ws
- ;; character. Signals an error if there is no more such character
- ;; and limit is nil.
- (let ((match-cons nil))
- (setq match-cons (ada-search-ignore-string-comment
- "[^ \t\n]" nil limit t))
- (if match-cons
- (goto-char (car match-cons))
- (if (not limit)
- (error "no more non-ws")
- nil))))
-
-
-(defun ada-goto-stmt-end (&optional limit)
- ;; Moves point to the end of the statement that point is in or
- ;; before. Returns the new position of point or nil if not found.
- (if (ada-search-ignore-string-comment ada-end-stmt-re nil limit)
- (point)
- nil))
-
-
-(defun ada-goto-previous-word ()
- ;; Moves point to the beginning of the previous word of Ada code.
- ;; Returns the new position of point or nil if not found.
- (let ((match-cons nil)
- (orgpoint (point)))
- (if (setq match-cons
- (ada-search-ignore-string-comment "[^ \t\n]" t nil t))
- ;;
- ;; move to the beginning of the word found
- ;;
- (progn
- (goto-char (cdr match-cons))
- (skip-chars-backward "_a-zA-Z0-9")
- (point))
- ;;
- ;; if not found, restore old position of point
- ;;
- (progn
- (goto-char orgpoint)
- 'nil))))
-
-
-(defun ada-check-matching-start (keyword)
- ;; Signals an error if matching block start is not KEYWORD.
- ;; Moves point to the matching block start.
- (ada-goto-matching-start 0)
- (if (not (looking-at (concat "\\<" keyword "\\>")))
- (error "matching start is not '%s'" keyword)))
-
-
-(defun ada-check-defun-name (defun-name)
- ;; Checks if the name of the matching defun really is DEFUN-NAME.
- ;; Assumes point to be already positioned by 'ada-goto-matching-start'.
- ;; Moves point to the beginning of the declaration.
-
- ;;
- ;; 'accept' or 'package' ?
- ;;
- (if (not (looking-at "\\<\\(accept\\|package\\|task\\|protected\\)\\>"))
- (ada-goto-matching-decl-start))
- ;;
- ;; 'begin' of 'procedure'/'function'/'task' or 'declare'
- ;;
- (save-excursion
- ;;
- ;; a named 'declare'-block ?
- ;;
- (if (looking-at "\\<declare\\>")
- (ada-goto-stmt-start)
- ;;
- ;; no, => 'procedure'/'function'/'task'/'protected'
- ;;
- (progn
- (forward-word 2)
- (backward-word 1)
- ;;
- ;; skip 'body' 'protected' 'type'
- ;;
- (if (looking-at "\\<\\(body\\|type\\)\\>")
- (forward-word 1))
- (forward-sexp 1)
- (backward-sexp 1)))
- ;;
- ;; should be looking-at the correct name
- ;;
- (if (not (looking-at (concat "\\<" defun-name "\\>")))
- (error "matching defun has different name: %s"
- (buffer-substring (point)
- (progn (forward-sexp 1) (point)))))))
-
-
-(defun ada-goto-matching-decl-start (&optional noerror nogeneric)
- ;; Moves point to the matching declaration start of the current 'begin'.
- ;; If NOERROR is non-nil, it only returns nil if no match was found.
- (interactive) ;; DEBUG
- (let ((nest-count 1)
- (pos nil)
- (first t)
- (flag nil))
- ;;
- ;; search backward for interesting keywords
- ;;
- (while (and
- (not (zerop nest-count))
- (ada-search-ignore-string-comment
- (concat "\\<\\("
- "is\\|separate\\|end\\|declare\\|new\\|begin\\|generic"
- "\\)\\>") t))
- ;;
- ;; calculate nest-depth
- ;;
- (cond
- ;;
- ((looking-at "end")
- (ada-goto-matching-start 1 noerror)
- (if (looking-at "begin")
- (setq nest-count (1+ nest-count))))
- ;;
- ((looking-at "declare\\|generic")
- (setq nest-count (1- nest-count))
- (setq first nil))
- ;;
- ((looking-at "is")
- ;; check if it is only a type definition, but not a protected
- ;; type definition, which should be handled like a procedure.
- (if (save-excursion
- (ada-goto-previous-word)
- (skip-chars-backward "a-zA-Z0-9_.'")
- (if (save-excursion
- (backward-char 1)
- (looking-at ")"))
- (progn
- (forward-char 1)
- (backward-sexp 1)
- (skip-chars-backward "a-zA-Z0-9_.'")
- ))
- (ada-goto-previous-word)
- (and
- (looking-at "\\<type\\>")
- (save-match-data
- (ada-goto-previous-word)
- (not (looking-at "\\<protected\\>"))))
- ); end of save-excursion
- (goto-char (match-beginning 0))
- (progn
- (setq nest-count (1- nest-count))
- (setq first nil))))
-
- ;;
- ((looking-at "new")
- (if (save-excursion
- (ada-goto-previous-word)
- (looking-at "is"))
- (goto-char (match-beginning 0))))
- ;;
- ((and first
- (looking-at "begin"))
- (setq nest-count 0)
- (setq flag t))
- ;;
- (t
- (setq nest-count (1+ nest-count))
- (setq first nil)))
-
- ) ;; end of loop
-
- ;; check if declaration-start is really found
- (if (not
- (and
- (zerop nest-count)
- (not flag)
- (progn
- (if (looking-at "is")
- (ada-search-ignore-string-comment
- ada-subprog-start-re t)
- (looking-at "declare\\|generic")))))
- (if noerror nil
- (error "no matching proc/func/task/declare/package/protected"))
- t)))
-
-
-(defun ada-goto-matching-start (&optional nest-level noerror gotothen)
- ;; Moves point to the beginning of a block-start. Which block
- ;; depends on the value of NEST-LEVEL, which defaults to zero. If
- ;; NOERROR is non-nil, it only returns nil if no matching start was
- ;; found. If GOTOTHEN is non-nil, point moves to the 'then'
- ;; following 'if'.
- (let ((nest-count (if nest-level nest-level 0))
- (found nil)
- (pos nil))
-
- ;;
- ;; search backward for interesting keywords
- ;;
- (while (and
- (not found)
- (ada-search-ignore-string-comment
- (concat "\\<\\("
- "end\\|loop\\|select\\|begin\\|case\\|do\\|"
- "if\\|task\\|package\\|record\\|protected\\)\\>")
- t))
-
- ;;
- ;; calculate nest-depth
- ;;
- (cond
- ;; found block end => increase nest depth
- ((looking-at "end")
- (setq nest-count (1+ nest-count)))
- ;; found loop/select/record/case/if => check if it starts or
- ;; ends a block
- ((looking-at "loop\\|select\\|record\\|case\\|if")
- (setq pos (point))
- (save-excursion
- ;;
- ;; check if keyword follows 'end'
- ;;
- (ada-goto-previous-word)
- (if (looking-at "\\<end\\>")
- ;; it ends a block => increase nest depth
- (progn
- (setq nest-count (1+ nest-count))
- (setq pos (point)))
- ;; it starts a block => decrease nest depth
- (setq nest-count (1- nest-count))))
- (goto-char pos))
- ;; found package start => check if it really is a block
- ((looking-at "package")
- (save-excursion
- (ada-search-ignore-string-comment "\\<is\\>")
- (ada-goto-next-non-ws)
- ;; ignore it if it is only a declaration with 'new'
- (if (not (looking-at "\\<new\\>"))
- (setq nest-count (1- nest-count)))))
- ;; found task start => check if it has a body
- ((looking-at "task")
- (save-excursion
- (forward-word 1)
- (ada-goto-next-non-ws)
- ;; ignore it if it has no body
- (if (not (looking-at "\\<body\\>"))
- (setq nest-count (1- nest-count)))))
- ;; all the other block starts
- (t
- (setq nest-count (1- nest-count)))) ; end of 'cond'
-
- ;; match is found, if nest-depth is zero
- ;;
- (setq found (zerop nest-count))) ; end of loop
-
- (if found
- ;;
- ;; match found => is there anything else to do ?
- ;;
- (progn
- (cond
- ;;
- ;; found 'if' => skip to 'then', if it's on a separate line
- ;; and GOTOTHEN is non-nil
- ;;
- ((and
- gotothen
- (looking-at "if")
- (save-excursion
- (ada-search-ignore-string-comment "\\<then\\>" nil nil)
- (back-to-indentation)
- (looking-at "\\<then\\>")))
- (goto-char (match-beginning 0)))
- ;;
- ;; found 'do' => skip back to 'accept'
- ;;
- ((looking-at "do")
- (if (not (ada-search-ignore-string-comment "\\<accept\\>" t nil))
- (error "missing 'accept' in front of 'do'"))))
- (point))
-
- (if noerror
- nil
- (error "no matching start")))))
-
-
-(defun ada-goto-matching-end (&optional nest-level noerror)
- ;; Moves point to the end of a block. Which block depends on the
- ;; value of NEST-LEVEL, which defaults to zero. If NOERROR is
- ;; non-nil, it only returns nil if found no matching start.
- (let ((nest-count (if nest-level nest-level 0))
- (found nil))
-
- ;;
- ;; search forward for interesting keywords
- ;;
- (while (and
- (not found)
- (ada-search-ignore-string-comment
- (concat "\\<\\(end\\|loop\\|select\\|begin\\|case\\|"
- "if\\|task\\|package\\|record\\|do\\)\\>")))
-
- ;;
- ;; calculate nest-depth
- ;;
- (backward-word 1)
- (cond
- ;; found block end => decrease nest depth
- ((looking-at "\\<end\\>")
- (setq nest-count (1- nest-count))
- ;; skip the following keyword
- (if (progn
- (skip-chars-forward "end")
- (ada-goto-next-non-ws)
- (looking-at "\\<\\(loop\\|select\\|record\\|case\\|if\\)\\>"))
- (forward-word 1)))
- ;; found package start => check if it really starts a block
- ((looking-at "\\<package\\>")
- (ada-search-ignore-string-comment "\\<is\\>")
- (ada-goto-next-non-ws)
- ;; ignore and skip it if it is only a 'new' package
- (if (not (looking-at "\\<new\\>"))
- (setq nest-count (1+ nest-count))
- (skip-chars-forward "new")))
- ;; all the other block starts
- (t
- (setq nest-count (1+ nest-count))
- (forward-word 1))) ; end of 'cond'
-
- ;; match is found, if nest-depth is zero
- ;;
- (setq found (zerop nest-count))) ; end of loop
-
- (if (not found)
- (if noerror
- nil
- (error "no matching end"))
- t)))
-
-
-(defun ada-forward-sexp-ignore-comment ()
- ;; Skips one sexp forward, ignoring comments.
- (while (looking-at "[ \t\n]*--")
- (skip-chars-forward "[ \t\n]")
- (end-of-line))
- (forward-sexp 1))
-
-
-(defun ada-search-ignore-string-comment
- (search-re &optional backward limit paramlists)
- ;; Regexp-Search for SEARCH-RE, ignoring comments, strings and
- ;; parameter lists, if PARAMLISTS is nil. Returns a cons cell of
- ;; begin and end of match data or nil, if not found.
- (let ((found nil)
- (begin nil)
- (end nil)
- (pos nil)
- (search-func
- (if backward 're-search-backward
- 're-search-forward)))
-
- ;;
- ;; search until found or end-of-buffer
- ;;
- (while (and (not found)
- (funcall search-func search-re limit 1))
- (setq begin (match-beginning 0))
- (setq end (match-end 0))
-
- (cond
- ;;
- ;; found in comment => skip it
- ;;
- ((ada-in-comment-p)
- (if backward
- (progn
- (re-search-backward "--" nil 1)
- (goto-char (match-beginning 0)))
- (progn
- (forward-line 1)
- (beginning-of-line))))
- ;;
- ;; found in string => skip it
- ;;
- ((ada-in-string-p)
- (if backward
- (progn
- (re-search-backward "\"" nil 1) ; "\"\\|#" don't treat #
- (goto-char (match-beginning 0))))
- (re-search-forward "\"" nil 1))
- ;;
- ;; found character constant => ignore it
- ;;
- ((save-excursion
- (setq pos (- (point) (if backward 1 2)))
- (and (char-after pos)
- (= (char-after pos) ?')
- (= (char-after (+ pos 2)) ?')))
- ())
- ;;
- ;; found a parameter-list but should ignore it => skip it
- ;;
- ((and (not paramlists)
- (ada-in-paramlist-p))
- (if backward
- (ada-search-ignore-string-comment "(" t nil t)))
- ;;
- ;; directly in front of a comment => skip it, if searching forward
- ;;
- ((save-excursion
- (goto-char begin)
- (looking-at "--"))
- (if (not backward)
- (progn
- (forward-line 1)
- (beginning-of-line))))
- ;;
- ;; found what we were looking for
- ;;
- (t
- (setq found t)))) ; end of loop
-
- (if found
- (cons begin end)
- nil)))
-
-
-(defun ada-search-but-not (search-re not-search-re &optional backward limit)
- ;; Searches SEARCH-RE, ignoring parts of NOT-SEARCH-RE, strings,
- ;; comments and parameter-lists.
- (let ((begin nil)
- (end nil)
- (begin-not nil)
- (begin-end nil)
- (end-not nil)
- (ret-cons nil)
- (found nil))
-
- ;;
- ;; search until found or end-of-buffer
- ;;
- (while (and
- (not found)
- (save-excursion
- (setq ret-cons
- (ada-search-ignore-string-comment search-re
- backward limit))
- (if (consp ret-cons)
- (progn
- (setq begin (car ret-cons))
- (setq end (cdr ret-cons))
- t)
- nil)))
-
- (if (or
- ;;
- ;; if no NO-SEARCH-RE was found
- ;;
- (not
- (save-excursion
- (setq ret-cons
- (ada-search-ignore-string-comment not-search-re
- backward nil))
- (if (consp ret-cons)
- (progn
- (setq begin-not (car ret-cons))
- (setq end-not (cdr ret-cons))
- t)
- nil)))
- ;;
- ;; or this NO-SEARCH-RE is not a part of the SEARCH-RE
- ;; found before.
- ;;
- (or
- (<= end-not begin)
- (>= begin-not end)))
-
- (setq found t)
-
- ;;
- ;; not found the correct match => skip this match
- ;;
- (goto-char (if backward
- begin
- end)))) ; end of loop
-
- (if found
- (progn
- (goto-char begin)
- (cons begin end))
- nil)))
-
-
-(defun ada-goto-prev-nonblank-line ( &optional ignore-comment)
- ;; Moves point to the beginning of previous non-blank line,
- ;; ignoring comments if IGNORE-COMMENT is non-nil.
- ;; It returns t if a matching line was found.
- (let ((notfound t)
- (newpoint nil))
-
- (save-excursion
- ;;
- ;; backward one line, if there is one
- ;;
- (if (zerop (forward-line -1))
- ;;
- ;; there is some kind of previous line
- ;;
- (progn
- (beginning-of-line)
- (setq newpoint (point))
-
- ;;
- ;; search until found or beginning-of-buffer
- ;;
- (while (and (setq notfound
- (or (looking-at "[ \t]*$")
- (and (looking-at "[ \t]*--")
- ignore-comment)))
- (not (ada-in-limit-line-p)))
- (forward-line -1)
- ;;(beginning-of-line)
- (setq newpoint (point))) ; end of loop
-
- )) ; end of if
-
- ) ; end of save-excursion
-
- (if notfound nil
- (progn
- (goto-char newpoint)
- t))))
-
-
-(defun ada-goto-next-nonblank-line ( &optional ignore-comment)
- ;; Moves point to next non-blank line,
- ;; ignoring comments if IGNORE-COMMENT is non-nil.
- ;; It returns t if a matching line was found.
- (let ((notfound t)
- (newpoint nil))
-
- (save-excursion
- ;;
- ;; forward one line
- ;;
- (if (zerop (forward-line 1))
- ;;
- ;; there is some kind of previous line
- ;;
- (progn
- (beginning-of-line)
- (setq newpoint (point))
-
- ;;
- ;; search until found or end-of-buffer
- ;;
- (while (and (setq notfound
- (or (looking-at "[ \t]*$")
- (and (looking-at "[ \t]*--")
- ignore-comment)))
- (not (ada-in-limit-line-p)))
- (forward-line 1)
- (beginning-of-line)
- (setq newpoint (point))) ; end of loop
-
- )) ; end of if
-
- ) ; end of save-excursion
-
- (if notfound nil
- (progn
- (goto-char newpoint)
- t))))
-
-
-;; ---- boolean functions for indentation
-
-(defun ada-in-decl-p ()
- ;; Returns t if point is inside a declarative part.
- ;; Assumes point to be at the end of a statement.
- (or
- (ada-in-paramlist-p)
- (save-excursion
- (ada-goto-matching-decl-start t))))
-
-
-(defun ada-looking-at-semi-or ()
- ;; Returns t if looking-at an 'or' following a semicolon.
- (save-excursion
- (and (looking-at "\\<or\\>")
- (progn
- (forward-word 1)
- (ada-goto-stmt-start)
- (looking-at "\\<or\\>")))))
-
-
-(defun ada-looking-at-semi-private ()
- ;; Returns t if looking-at an 'private' following a semicolon.
- (save-excursion
- (and (looking-at "\\<private\\>")
- (progn
- (forward-word 1)
- (ada-goto-stmt-start)
- (looking-at "\\<private\\>")))))
-
-
-;;; make a faster??? ada-in-limit-line-p not using count-lines
-(defun ada-in-limit-line-p ()
- ;; return t if point is in first or last accessible line.
- (or (save-excursion (beginning-of-line) (= (point-min) (point)))
- (save-excursion (end-of-line) (= (point-max) (point)))))
-
-
-(defun ada-in-comment-p ()
- ;; Returns t if inside a comment.
- ;; (save-excursion (and (re-search-backward "\\(--\\|\n\\)" nil 1)
- ;; (looking-at "-"))))
- (nth 4 (parse-partial-sexp
- (save-excursion (beginning-of-line) (point))
- (point))))
-
-
-
-(defun ada-in-string-p ()
- ;; Returns t if point is inside a string
- ;; (Taken from pascal-mode.el, modified by MH).
- (save-excursion
- (and
- (nth 3 (parse-partial-sexp
- (save-excursion
- (beginning-of-line)
- (point)) (point)))
- ;; check if 'string quote' is only a character constant
- (progn
- (re-search-backward "\"" nil t) ; # not a string delimiter anymore
- (not (= (char-after (1- (point))) ?'))))))
-
-
-(defun ada-in-string-or-comment-p ()
- ;; Returns t if point is inside a string or a comment.
- (or (ada-in-comment-p)
- (ada-in-string-p)))
-
-
-(defun ada-in-paramlist-p ()
- ;; Returns t if point is inside a parameter-list
- ;; following 'function'/'procedure'/'package'.
- (save-excursion
- (and
- (re-search-backward "(\\|)" nil t)
- ;; inside parentheses ?
- (looking-at "(")
- (backward-word 2)
- ;; right keyword before parenthesis ?
- (looking-at (concat "\\<\\("
- "procedure\\|function\\|body\\|package\\|"
- "task\\|entry\\|accept\\)\\>"))
- (re-search-forward ")\\|:" nil t)
- ;; at least one ':' inside the parentheses ?
- (not (backward-char 1))
- (looking-at ":"))))
-
-
-;; not really a boolean function ...
-(defun ada-in-open-paren-p ()
- ;; If point is somewhere behind an open parenthesis not yet closed,
- ;; it returns the column # of the first non-ws behind this open
- ;; parenthesis, otherwise nil."
-
- (let ((start (if (< (point) ada-search-paren-char-count-limit)
- 1
- (- (point) ada-search-paren-char-count-limit)))
- parse-result
- (col nil))
- (setq parse-result (parse-partial-sexp start (point)))
- (if (nth 1 parse-result)
- (save-excursion
- (goto-char (1+ (nth 1 parse-result)))
- (if (save-excursion
- (re-search-forward "[^ \t]" nil 1)
- (backward-char 1)
- (and
- (not (looking-at "\n"))
- (setq col (current-column))))
- col
- (current-column)))
- nil)))
-
-
-
-;;;----------------------;;;
-;;; Behaviour Of TAB Key ;;;
-;;;----------------------;;;
-
-(defun ada-tab ()
- "Do indenting or tabbing according to `ada-tab-policy'."
- (interactive)
- (cond ((eq ada-tab-policy 'indent-and-tab) (error "not implemented"))
- ;; ada-indent-and-tab
- ((eq ada-tab-policy 'indent-rigidly) (ada-tab-hard))
- ((eq ada-tab-policy 'indent-auto) (ada-indent-current))
- ((eq ada-tab-policy 'gei) (ada-tab-gei))
- ((eq ada-tab-policy 'indent-af) (af-indent-line)) ; GEB
- ((eq ada-tab-policy 'always-tab) (error "not implemented"))
- ))
-
-
-(defun ada-untab (arg)
- "Delete leading indenting according to `ada-tab-policy'."
- (interactive "P")
- (cond ((eq ada-tab-policy 'indent-rigidly) (ada-untab-hard))
- ((eq ada-tab-policy 'indent-af) (backward-delete-char-untabify ; GEB
- (prefix-numeric-value arg) ; GEB
- arg)) ; GEB
- ((eq ada-tab-policy 'indent-auto) (error "not implemented"))
- ((eq ada-tab-policy 'always-tab) (error "not implemented"))
- ))
-
-
-(defun ada-indent-current-function ()
- "Ada Mode version of the indent-line-function."
- (interactive "*")
- (let ((starting-point (point-marker)))
- (ada-beginning-of-line)
- (ada-tab)
- (if (< (point) starting-point)
- (goto-char starting-point))
- (set-marker starting-point nil)
- ))
-
-
-(defun ada-tab-hard ()
- "Indent current line to next tab stop."
- (interactive)
- (save-excursion
- (beginning-of-line)
- (insert-char ? ada-indent))
- (if (save-excursion (= (point) (progn (beginning-of-line) (point))))
- (forward-char ada-indent)))
-
-
-(defun ada-untab-hard ()
- "indent current line to previous tab stop."
- (interactive)
- (let ((bol (save-excursion (progn (beginning-of-line) (point))))
- (eol (save-excursion (progn (end-of-line) (point)))))
- (indent-rigidly bol eol (- 0 ada-indent))))
-
-
-
-;;;---------------;;;
-;;; Miscellaneous ;;;
-;;;---------------;;;
-
-(defun ada-remove-trailing-spaces ()
- "remove trailing spaces in the whole buffer."
- (interactive)
- (save-match-data
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (while (re-search-forward "[ \t]+$" (point-max) t)
- (replace-match "" nil nil))))))
-
-
-(defun ada-untabify-buffer ()
-;; change all tabs to spaces
- (save-excursion
- (untabify (point-min) (point-max))))
-
-
-(defun ada-uncomment-region (beg end)
- "delete `comment-start' at the beginning of a line in the region."
- (interactive "r")
- (comment-region beg end -1))
-
-
-;; define a function to support find-file.el if loaded
-(defun ada-ff-other-window ()
- "Find other file in other window using `ff-find-other-file'."
- (interactive)
- (and (fboundp 'ff-find-other-file)
- (ff-find-other-file t)))
-
-
-;;;-------------------------------;;;
-;;; Moving To Procedures/Packages ;;;
-;;;-------------------------------;;;
-
-(defun ada-next-procedure ()
- "Moves point to next procedure."
- (interactive)
- (end-of-line)
- (if (re-search-forward ada-procedure-start-regexp nil t)
- (goto-char (match-beginning 1))
- (error "No more functions/procedures/tasks")))
-
-(defun ada-previous-procedure ()
- "Moves point to previous procedure."
- (interactive)
- (beginning-of-line)
- (if (re-search-backward ada-procedure-start-regexp nil t)
- (goto-char (match-beginning 1))
- (error "No more functions/procedures/tasks")))
-
-(defun ada-next-package ()
- "Moves point to next package."
- (interactive)
- (end-of-line)
- (if (re-search-forward ada-package-start-regexp nil t)
- (goto-char (match-beginning 1))
- (error "No more packages")))
-
-(defun ada-previous-package ()
- "Moves point to previous package."
- (interactive)
- (beginning-of-line)
- (if (re-search-backward ada-package-start-regexp nil t)
- (goto-char (match-beginning 1))
- (error "No more packages")))
-
-
-;;;-----------------------
-;;; define keymap for Ada
-;;;-----------------------
-
-(if (not ada-mode-map)
- (progn
- (setq ada-mode-map (make-sparse-keymap))
-
- ;; Indentation and Formatting
- (define-key ada-mode-map "\C-j" 'ada-indent-newline-indent)
- (define-key ada-mode-map "\t" 'ada-tab)
- (define-key ada-mode-map "\C-c\C-l" 'ada-indent-region)
- (if (ada-xemacs)
- (define-key ada-mode-map '(shift tab) 'ada-untab)
- (define-key ada-mode-map [S-tab] 'ada-untab))
- (define-key ada-mode-map "\C-c\C-f" 'ada-format-paramlist)
- (define-key ada-mode-map "\C-c\C-p" 'ada-call-pretty-printer)
-;;; We don't want to make meta-characters case-specific.
-;;; (define-key ada-mode-map "\M-Q" 'ada-fill-comment-paragraph-justify)
- (define-key ada-mode-map "\M-\C-q" 'ada-fill-comment-paragraph-postfix)
-
- ;; Movement
-;;; It isn't good to redefine these. What should be done instead? -- rms.
-;;; (define-key ada-mode-map "\M-e" 'ada-next-package)
-;;; (define-key ada-mode-map "\M-a" 'ada-previous-package)
- (define-key ada-mode-map "\M-\C-e" 'ada-next-procedure)
- (define-key ada-mode-map "\M-\C-a" 'ada-previous-procedure)
- (define-key ada-mode-map "\C-c\C-a" 'ada-move-to-start)
- (define-key ada-mode-map "\C-c\C-e" 'ada-move-to-end)
-
- ;; Compilation
- (define-key ada-mode-map "\C-c\C-c" 'compile)
-
- ;; Casing
- (define-key ada-mode-map "\C-c\C-r" 'ada-adjust-case-region)
- (define-key ada-mode-map "\C-c\C-b" 'ada-adjust-case-buffer)
-
- (define-key ada-mode-map "\177" 'backward-delete-char-untabify)
-
- ;; Use predefined function of emacs19 for comments (RE)
- (define-key ada-mode-map "\C-c;" 'comment-region)
- (define-key ada-mode-map "\C-c:" 'ada-uncomment-region)
-
- ;; Change basic functionality
-
- ;; `substitute-key-definition' is not defined equally in GNU Emacs
- ;; and XEmacs, you cannot put in an optional 4th parameter in
- ;; XEmacs. I don't think it's necessary, so I leave it out for
- ;; GNU Emacs as well. If you encounter any problems with the
- ;; following three functions, please tell me. RE
- (mapcar (function (lambda (pair)
- (substitute-key-definition (car pair) (cdr pair)
- ada-mode-map)))
- '((beginning-of-line . ada-beginning-of-line)
- (end-of-line . ada-end-of-line)
- (forward-to-indentation . ada-forward-to-indentation)
- ))
- ;; else GNU Emacs
- ;;(mapcar (lambda (pair)
- ;; (substitute-key-definition (car pair) (cdr pair)
- ;; ada-mode-map global-map))
-
- ))
-
-
-;;;-------------------
-;;; define menu 'Ada'
-;;;-------------------
-
-(require 'easymenu)
-
-(defun ada-add-ada-menu ()
- "Adds the menu 'Ada' to the menu bar in Ada Mode."
- (easy-menu-define ada-mode-menu ada-mode-map "Menu keymap for Ada mode."
- '("Ada"
- ["Next Package" ada-next-package t]
- ["Previous Package" ada-previous-package t]
- ["Next Procedure" ada-next-procedure t]
- ["Previous Procedure" ada-previous-procedure t]
- ["Goto Start" ada-move-to-start t]
- ["Goto End" ada-move-to-end t]
- ["------------------" nil nil]
- ["Indent Current Line (TAB)"
- ada-indent-current-function t]
- ["Indent Lines in Region" ada-indent-region t]
- ["Format Parameter List" ada-format-paramlist t]
- ["Pretty Print Buffer" ada-call-pretty-printer t]
- ["------------" nil nil]
- ["Fill Comment Paragraph"
- ada-fill-comment-paragraph t]
- ["Justify Comment Paragraph"
- ada-fill-comment-paragraph-justify t]
- ["Postfix Comment Paragraph"
- ada-fill-comment-paragraph-postfix t]
- ["------------" nil nil]
- ["Adjust Case Region" ada-adjust-case-region t]
- ["Adjust Case Buffer" ada-adjust-case-buffer t]
- ["----------" nil nil]
- ["Comment Region" comment-region t]
- ["Uncomment Region" ada-uncomment-region t]
- ["----------------" nil nil]
- ["Compile" compile (fboundp 'compile)]
- ["Next Error" next-error (fboundp 'next-error)]
- ["---------------" nil nil]
- ["Index" imenu (fboundp 'imenu)]
- ["--------------" nil nil]
- ["Other File Other Window" ada-ff-other-window
- (fboundp 'ff-find-other-file)]
- ["Other File" ff-find-other-file
- (fboundp 'ff-find-other-file)]))
- (if (ada-xemacs) (progn
- (easy-menu-add ada-mode-menu)
- (setq mode-popup-menu (cons "Ada Mode" ada-mode-menu)))))
-
-
-
-;;;-------------------------------
-;;; Define Some Support Functions
-;;;-------------------------------
-
-(defun ada-beginning-of-line (&optional arg)
- (interactive "P")
- (cond
- ((eq ada-tab-policy 'indent-af) (af-beginning-of-line arg))
- (t (beginning-of-line arg))
- ))
-
-(defun ada-end-of-line (&optional arg)
- (interactive "P")
- (cond
- ((eq ada-tab-policy 'indent-af) (af-end-of-line arg))
- (t (end-of-line arg))
- ))
-
-(defun ada-current-column ()
- (cond
- ((eq ada-tab-policy 'indent-af) (af-current-column))
- (t (current-column))
- ))
-
-(defun ada-forward-to-indentation (&optional arg)
- (interactive "P")
- (cond
- ((eq ada-tab-policy 'indent-af) (af-forward-to-indentation arg))
- (t (forward-to-indentation arg))
- ))
-
-;;;---------------------------------------------------
-;;; support for find-file
-;;;---------------------------------------------------
-
-
-;;;###autoload
-(defun ada-make-filename-from-adaname (adaname)
- "Determine the filename of a package/procedure from its own Ada name."
- ;; this is done simply by calling gkrunch, when we work with GNAT. It
- ;; must be a more complex function in other compiler environments.
- (interactive "s")
-
- ;; things that should really be done by the external process
- ;; since gnat-2.0, gnatk8 can do these things. If you still use a
- ;; previous version, just uncomment the following lines.
- (let (krunch-buf)
- (setq krunch-buf (generate-new-buffer "*gkrunch*"))
- (save-excursion
- (set-buffer krunch-buf)
-; (insert (downcase adaname))
-; (goto-char (point-min))
-; (while (search-forward "." nil t)
-; (replace-match "-" nil t))
-; (setq adaname (buffer-substring (point-min)
-; (progn
-; (goto-char (point-min))
-; (end-of-line)
-; (point))))
-; ;; clean the buffer
-; (delete-region (point-min) (point-max))
- ;; send adaname to external process "gnatk8"
- (call-process "gnatk8" nil krunch-buf nil
- adaname ada-krunch-args)
- ;; fetch output of that process
- (setq adaname (buffer-substring
- (point-min)
- (progn
- (goto-char (point-min))
- (end-of-line)
- (point))))
- (kill-buffer krunch-buf)))
- (setq adaname adaname) ;; can I avoid this statement?
- )
-
-
-;;; functions for placing the cursor on the corresponding subprogram
-(defun ada-which-function-are-we-in ()
- "Determine whether we are on a function definition/declaration.
-If that is the case remember the name of that function."
-
- (setq ff-function-name nil)
-
- (save-excursion
- (if (re-search-backward ada-procedure-start-regexp nil t)
- (setq ff-function-name (buffer-substring (match-beginning 0)
- (match-end 0)))
- ; we didn't find a procedure start, perhaps there is a package
- (if (re-search-backward ada-package-start-regexp nil t)
- (setq ff-function-name (buffer-substring (match-beginning 0)
- (match-end 0)))
- ))))
-
-
-;;;---------------------------------------------------
-;;; support for imenu
-;;;---------------------------------------------------
-
-(defun imenu-create-ada-index (&optional regexp)
- "Create index alist for Ada files."
- (let ((index-alist '())
- prev-pos char)
- (goto-char (point-min))
- ;(imenu-progress-message prev-pos 0)
- ;; Search for functions/procedures
- (save-match-data
- (while (re-search-forward
- (or regexp ada-procedure-start-regexp)
- nil t)
- ;(imenu-progress-message prev-pos)
- ;; do not store forward definitions
- ;; right now we store them. We want to avoid them only in
- ;; package bodies, not in the specs!! ???RE???
- (save-match-data
-; (if (not (looking-at (concat
-; "[ \t\n]*" ; WS
-; "\([^)]+\)" ; parameterlist
-; "\\([ \n\t]+return[ \n\t]+"; potential return
-; "[a-zA-Z0-9_\\.]+\\)?"
-; "[ \t]*" ; WS
-; ";" ;; THIS is what we really look for
-; )))
-; ; (push (imenu-example--name-and-position) index-alist)
- (setq index-alist (cons (imenu-example--name-and-position)
- index-alist))
-; )
- )
- ;(imenu-progress-message 100)
- ))
- (nreverse index-alist)))
-
-;;;---------------------------------------------------
-;;; support for font-lock
-;;;---------------------------------------------------
-
-;; Strings are a real pain in Ada because both ' and " can appear in a
-;; non-string quote context (the former as an operator, the latter as
-;; a character string). We follow the least losing solution, in which
-;; only " is a string quote. Therefore a character string of the form
-;; '"' will throw fontification off on the wrong track.
-
-(defconst ada-font-lock-keywords-1
- (list
- ;;
- ;; accept, entry, function, package (body), protected (body|type),
- ;; pragma, procedure, task (body) plus name.
- (list (concat
- "\\<\\("
- "accept\\|"
- "entry\\|"
- "function\\|"
- "package[ \t]+body\\|"
- "package\\|"
- "pragma\\|"
- "procedure\\|"
- "protected[ \t]+body\\|"
- "protected[ \t]+type\\|"
- "protected\\|"
-;; "p\\(\\(ackage\\|rotected\\)\\(\\|[ \t]+\\(body\\|type\\)\\)\
-;;\\|r\\(agma\\|ocedure\\)\\)\\|"
- "task\\|"
- "task[ \t]+body\\|"
- "task[ \t]+type"
-;; "task\\(\\|[ \t]+body\\)"
- "\\)\\>[ \t]*"
- "\\(\\sw+\\(\\.\\sw*\\)*\\)?")
- '(1 font-lock-keyword-face) '(2 font-lock-function-name-face nil t)))
- "Subdued level highlighting for Ada mode.")
-
-(defconst ada-font-lock-keywords-2
- (append ada-font-lock-keywords-1
- (list
- ;;
- ;; Main keywords, except those treated specially below.
- (concat "\\<\\("
-; ("abort" "abs" "abstract" "accept" "access" "aliased" "all"
-; "and" "array" "at" "begin" "case" "declare" "delay" "delta"
-; "digits" "do" "else" "elsif" "entry" "exception" "exit" "for"
-; "generic" "if" "in" "is" "limited" "loop" "mod" "not"
-; "null" "or" "others" "private" "protected"
-; "range" "record" "rem" "renames" "requeue" "return" "reverse"
-; "select" "separate" "tagged" "task" "terminate" "then" "until"
-; "while" "xor")
- "a\\(b\\(ort\\|s\\(\\|tract\\)\\)\\|cce\\(pt\\|ss\\)\\|"
- "l\\(iased\\|l\\)\\|nd\\|rray\\|t\\)\\|begin\\|case\\|"
- "d\\(e\\(clare\\|l\\(ay\\|ta\\)\\)\\|igits\\|o\\)\\|"
- "e\\(ls\\(e\\|if\\)\\|ntry\\|x\\(ception\\|it\\)\\)\\|for\\|"
- "generic\\|i[fns]\\|l\\(imited\\|oop\\)\\|mod\\|n\\(ot\\|ull\\)\\|"
- "o\\(r\\|thers\\|ut\\)\\|pr\\(ivate\\|otected\\)\\|"
- "r\\(ange\\|e\\(cord\\|m\\|names\\|queue\\|turn\\|verse\\)\\)\\|"
- "se\\(lect\\|parate\\)\\|"
- "t\\(agged\\|erminate\\|hen\\)\\|until\\|" ; task removed
- "wh\\(ile\\|en\\)\\|xor" ; "when" added
- "\\)\\>")
- ;;
- ;; Anything following end and not already fontified is a body name.
- '("\\<\\(end\\)\\>[ \t]+\\([a-zA-Z0-9_\\.]+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- ;;
- ;; Variable name plus optional keywords followed by a type name. Slow.
-; (list (concat "\\<\\(\\sw+\\)\\>[ \t]*:?[ \t]*"
-; "\\(access\\|constant\\|in\\|in[ \t]+out\\|out\\)?[ \t]*"
-; "\\(\\sw+\\)?")
-; '(1 font-lock-variable-name-face)
-; '(2 font-lock-keyword-face nil t) '(3 font-lock-type-face nil t))
- ;;
- ;; Optional keywords followed by a type name.
- (list (concat ; ":[ \t]*"
- "\\<\\(access\\|constant\\|in\\|in[ \t]+out\\|out\\)\\>"
- "[ \t]*"
- "\\(\\sw+\\)?")
- '(1 font-lock-keyword-face nil t) '(2 font-lock-type-face nil t))
- ;;
- ;; Keywords followed by a type or function name.
- (list (concat "\\<\\("
- "new\\|of\\|subtype\\|type"
- "\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*\\((\\)?")
- '(1 font-lock-keyword-face)
- '(2 (if (match-beginning 4)
- font-lock-function-name-face
- font-lock-type-face) nil t))
- ;;
- ;; Keywords followed by a (comma separated list of) reference.
- (list (concat "\\<\\(goto\\|raise\\|use\\|with\\)\\>" ; "when" removed
- ; "[ \t]*\\(\\sw+\\(\\.\\sw*\\)*\\)?") ; RE
- "[ \t]*\\([a-zA-Z0-9_\\.\\|, ]+\\)\\W")
- '(1 font-lock-keyword-face) '(2 font-lock-reference-face nil t))
- ;;
- ;; Goto tags.
- '("<<\\(\\sw+\\)>>" 1 font-lock-reference-face)
- ))
- "Gaudy level highlighting for Ada mode.")
-
-(defvar ada-font-lock-keywords ada-font-lock-keywords-2
- "Default Expressions to highlight in Ada mode.
-See the doc to `font-lock-maximum-decoration' for user configuration.")
-
-;;;
-;;; ????
-;;;
-(defun ada-gen-comment-until-proc ()
- ;; comment until spec of a procedure or a function.
- (forward-line 1)
- (set-mark-command (point))
- (if (re-search-forward ada-procedure-start-regexp nil t)
- (progn (goto-char (match-beginning 1))
- (comment-region (mark) (point)))
- (error "No more functions/procedures")))
-
-
-(defun ada-gen-treat-proc (match)
- ;; make dummy body of a procedure/function specification.
- ;; MATCH is a cons cell containing the start and end location of the
- ;; last search for ada-procedure-start-regexp.
- (goto-char (car match))
- (let (proc-found func-found procname functype)
- (cond
- ((or (setq proc-found (looking-at "^[ \t]*procedure"))
- (setq func-found (looking-at "^[ \t]*function")))
- ;; treat it as a proc/func
- (forward-word 2)
- (forward-word -1)
- (setq procname (buffer-substring (point) (cdr match))) ; store proc name
-
- ;; goto end of procname
- (goto-char (cdr match))
-
- ;; skip over parameterlist
- (forward-sexp)
- ;; if function, skip over 'return' and result type.
- (if func-found
- (progn
- (forward-word 1)
- (skip-chars-forward " \t\n")
- (setq functype (buffer-substring (point)
- (progn
- (skip-chars-forward
- "a-zA-Z0-9_\.")
- (point))))))
- ;; look for next non WS
- (cond
- ((looking-at "[ \t]*;")
- (delete-region (match-beginning 0) (match-end 0)) ;; delete the ';'
- (ada-indent-newline-indent)
- (insert " is")
- (ada-indent-newline-indent)
- (if func-found
- (progn
- (insert "Result : ")
- (insert functype)
- (insert ";")
- (ada-indent-newline-indent)))
- (insert "begin -- ")
- (insert procname)
- (ada-indent-newline-indent)
- (insert "null;")
- (ada-indent-newline-indent)
- (if func-found
- (progn
- (insert "return Result;")
- (ada-indent-newline-indent)))
- (insert "end ")
- (insert procname)
- (insert ";")
- (ada-indent-newline-indent)
- )
- ;; else
- ((looking-at "[ \t\n]*is")
- ;; do nothing
- )
- ((looking-at "[ \t\n]*rename")
- ;; do nothing
- )
- (t
- (message "unknown syntax")))
- ))))
-
-
-(defun ada-make-body ()
- "Create an Ada package body in the current buffer.
-The potential old buffer contents is deleted first, then we copy the
-spec buffer in here and modify it to make it a body.
-
-This function typically is to be hooked into `ff-file-created-hooks'."
- (interactive)
- (delete-region (point-min) (point-max))
- (insert-buffer (car (cdr (buffer-list))))
- (ada-mode)
-
- (let (found)
- (if (setq found
- (ada-search-ignore-string-comment ada-package-start-regexp))
- (progn (goto-char (cdr found))
- (insert " body")
- ;; (forward-line -1)
- ;;(comment-region (point-min) (point))
- )
- (error "No package"))
-
- ;; (comment-until-proc)
- ;; does not work correctly
- ;; must be done by hand
-
- (while (setq found
- (ada-search-ignore-string-comment ada-procedure-start-regexp))
- (ada-gen-treat-proc found))))
-
-
-;;; provide ourself
-
-(provide 'ada-mode)
-
-;;; ada-mode.el ends here
diff --git a/lisp/progmodes/asm-mode.el b/lisp/progmodes/asm-mode.el
deleted file mode 100644
index 3a0370bdaaf..00000000000
--- a/lisp/progmodes/asm-mode.el
+++ /dev/null
@@ -1,231 +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>
-;; Maintainer: FSF
-;; Keywords: tools, 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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
-;; comment char place or move comment
-;; asm-comment-char specifies which character this is;
-;; you can use a different character in different
-;; Asm mode buffers.
-;; C-j, C-m newline and tab to tab stop
-;;
-;; Code is indented to the first tab stop level.
-
-;; This mode runs two hooks:
-;; 1) An asm-mode-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))
- ;; Note that the comment character isn't set up until asm-mode is called.
- (define-key asm-mode-map ":" 'asm-colon)
- (define-key asm-mode-map "\C-c;" 'comment-region)
- (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)
- )
-
-(defconst asm-font-lock-keywords
- '(("^\\(\\(\\sw\\|\\s_\\)+\\)\\>:?[ \t]*\\(\\sw+\\)?"
- (1 font-lock-function-name-face) (3 font-lock-keyword-face nil t))
- ("^\\s +\\(\\(\\sw\\|\\s_\\)+\\)" 1 font-lock-keyword-face))
- "Additional expressions to highlight in Assembler mode.")
-
-(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-mode-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)
- (setq mode-name "Assembler")
- (setq major-mode 'asm-mode)
- (setq local-abbrev-table asm-mode-abbrev-table)
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(asm-font-lock-keywords))
- (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)
- ;; Make our own local child of asm-mode-map
- ;; so we can define our own comment character.
- (use-local-map (nconc (make-sparse-keymap) asm-mode-map))
- (local-set-key (vector asm-comment-char) 'asm-comment)
-
- (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\n]+$" 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 3ba782bac38..00000000000
--- a/lisp/progmodes/awk-mode.el
+++ /dev/null
@@ -1,153 +0,0 @@
-;;; awk-mode.el --- AWK code editing commands for Emacs
-
-;; Copyright (C) 1988, 1994, 1996 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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)
- (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 ())
-
-;; Regexps written with help from Peter Galbraith <galbraith@mixing.qc.dfo.ca>.
-(defconst awk-font-lock-keywords
- (eval-when-compile
- (list
- ;;
- ;; Function names.
- '("^[ \t]*\\(function\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- ;;
- ;; Variable names.
- (cons (concat "\\<\\("
-; ("ARGC" "ARGIND" "ARGV" "CONVFMT" "ENVIRON" "ERRNO"
-; "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE" "NF" "NR"
-; "OFMT" "OFS" "ORS" "RLENGTH" "RS" "RSTART" "SUBSEP")
- "ARG\\([CV]\\|IND\\)\\|CONVFMT\\|E\\(NVIRON\\|RRNO\\)\\|"
- "F\\(I\\(ELDWIDTHS\\|LENAME\\)\\|NR\\|S\\)\\|IGNORECASE\\|"
- "N[FR]\\|O\\(F\\(MT\\|S\\)\\|RS\\)\\|"
- "R\\(LENGTH\\|S\\(\\|TART\\)\\)\\|SUBSEP"
- "\\)\\>")
- 'font-lock-variable-name-face)
- ;;
- ;; Keywords.
- (concat "\\<\\("
-; ("BEGIN" "END" "break" "continue" "delete" "exit" "for"
-; "getline" "if" "next" "print" "printf" "return" "while")
- "BEGIN\\|END\\|break\\|continue\\|delete\\|exit\\|for\\|"
- "getline\\|if\\|next\\|printf?\\|return\\|while"
- "\\)\\>")
- ;;
- ;; Builtins.
- (list (concat "\\<\\("
-; ("atan2" "close" "cos" "ctime" "exp" "gsub" "index" "int"
-; "length" "log" "match" "rand" "sin" "split" "sprintf"
-; "sqrt" "srand" "sub" "substr" "system" "time"
-; "tolower" "toupper")
- "atan2\\|c\\(lose\\|os\\|time\\)\\|exp\\|gsub\\|"
- "in\\(dex\\|t\\)\\|l\\(ength\\|og\\)\\|match\\|rand\\|"
- "s\\(in\\|p\\(lit\\|rintf\\)\\|qrt\\|rand\\|"
- "ub\\(\\|str\\)\\|ystem\\)\\|"
- "t\\(ime\\|o\\(lower\\|upper\\)\\)"
- "\\)(")
- 1 'font-lock-builtin-face)
- ;;
- ;; Operators. Is this too much?
- (cons (mapconcat 'identity
- '("&&" "||" "<=" "<" ">=" ">" "==" "!=" "!~" "~")
- "\\|")
- 'font-lock-reference-face)
- ))
- "Default expressions to highlight in AWK mode.")
-
-;;;###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)
- (require 'cc-mode)
- (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)
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(awk-font-lock-keywords nil nil ((?_ . "w"))))
- (run-hooks 'awk-mode-hook))
-
-(provide 'awk-mode)
-
-;;; awk-mode.el ends here
diff --git a/lisp/progmodes/c-mode.el b/lisp/progmodes/c-mode.el
deleted file mode 100644
index f3364457e18..00000000000
--- a/lisp/progmodes/c-mode.el
+++ /dev/null
@@ -1,1650 +0,0 @@
-;;; c-mode.el --- C code editing commands for Emacs
-
-;; Copyright (C) 1985, 86, 87, 92, 94, 95 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; A smart editing mode for C code. It knows a lot about C syntax and tries
-;; to position the cursor 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 "\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))
-
-;; "C-mode" is not strictly the right punctuation--it should be "C
-;; mode"--but that would look like two menu items. "C-mode" is the
-;; best alternative I can think of.
-(define-key c-mode-map [menu-bar c]
- (cons "C-mode" (make-sparse-keymap "C-mode")))
-
-(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 cpp-highlight-buffer]
- '("Highlight Conditionals" . cpp-highlight-buffer))
-(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))
-
-(put 'comment-region 'menu-enable 'mark-active)
-(put 'c-macro-expand 'menu-enable 'mark-active)
-(put 'c-backslash-region 'menu-enable 'mark-active)
-
-(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-continued-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 . 0)
- (c-continued-brace-offset . -5)
- (c-label-offset . -5)
- (c-continued-statement-offset . 5))
- ("BSD"
- (c-indent-level . 4)
- (c-argdecl-indent . 4)
- (c-brace-offset . 0)
- (c-continued-brace-offset . -4)
- (c-label-offset . -4)
- (c-continued-statement-offset . 4))
- ("C++"
- (c-indent-level . 4)
- (c-argdecl-indent . 0)
- (c-brace-offset . 0)
- (c-continued-brace-offset . -4)
- (c-label-offset . -4)
- (c-continued-statement-offset . 4)
- (c-auto-newline . t))
- ("Whitesmith"
- (c-indent-level . 4)
- (c-argdecl-indent . 4)
- (c-brace-offset . 0)
- (c-continued-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[ \t]*:")
-
-;; This is actually the expression for C++ mode, but it's used for C too.
-(defvar c-imenu-generic-expression
- (`
- ((nil
- (,
- (concat
- "^" ; beginning of line is required
- "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
- "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
- "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
-
- "\\(" ; last type spec including */&
- "[a-zA-Z0-9_:]+"
- "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either pointer/ref sign or whitespace
- "\\)?" ; if there is a last type spec
- "\\(" ; name; take that into the imenu entry
- "[a-zA-Z0-9_:~]+" ; member function, ctor or dtor...
- ; (may not contain * because then
- ; "a::operator char*" would become "char*"!)
- "\\|"
- "\\([a-zA-Z0-9_:~]*::\\)?operator"
- "[^a-zA-Z1-9_][^(]*" ; ...or operator
- " \\)"
- "[ \t]*([^)]*)[ \t\n]*[^ ;]" ; require something other than a ; after
- ; the (...) to avoid prototypes. Can't
- ; catch cases with () inside the parentheses
- ; surrounding the parameters
- ; (like "int foo(int a=bar()) {...}"
-
- )) 6)
- ("Class"
- (, (concat
- "^" ; beginning of line is required
- "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
- "class[ \t]+"
- "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
- "[ \t]*[:{]"
- )) 2)
-;; Example of generic expression for finding prototypes, structs, unions, enums.
-;; Uncomment if you want to find these too. It will be a bit slower gathering
-;; the indexes.
-; ("Prototypes"
-; (,
-; (concat
-; "^" ; beginning of line is required
-; "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
-; "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
-; "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
-
-; "\\(" ; last type spec including */&
-; "[a-zA-Z0-9_:]+"
-; "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either pointer/ref sign or whitespace
-; "\\)?" ; if there is a last type spec
-; "\\(" ; name; take that into the imenu entry
-; "[a-zA-Z0-9_:~]+" ; member function, ctor or dtor...
-; ; (may not contain * because then
-; ; "a::operator char*" would become "char*"!)
-; "\\|"
-; "\\([a-zA-Z0-9_:~]*::\\)?operator"
-; "[^a-zA-Z1-9_][^(]*" ; ...or operator
-; " \\)"
-; "[ \t]*([^)]*)[ \t\n]*;" ; require ';' after
-; ; the (...) Can't
-; ; catch cases with () inside the parentheses
-; ; surrounding the parameters
-; ; (like "int foo(int a=bar());"
-; )) 6)
-; ("Struct"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "struct[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
-; ("Enum"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "enum[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
-; ("Union"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "union[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
- ))
- "Imenu generic expression for C mode. See `imenu-generic-expression'.")
-
-(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 'fill-paragraph-function)
- (setq fill-paragraph-function 'c-fill-paragraph)
- (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 'comment-multi-line)
- (setq comment-multi-line t)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression c-imenu-generic-expression)
- (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)
- ;; Don't include part of comment terminator
- ;; in the fill-prefix.
- (and (eq (following-char) ?/)
- (eq (preceding-char) ?*)
- (backward-char 1))
- (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)))
- (save-excursion
- (goto-char (point-max))
- (forward-line -1)
- ;; And comment terminator was on a separate line before,
- ;; keep it that way.
- ;; This also avoids another problem:
- ;; if the fill-prefix ends in a *, it could eat up
- ;; the * of the comment terminator.
- (if (looking-at "[ \t]*\\*/")
- (narrow-to-region (point-min) (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)))
- t))
-
-(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))))
- ((and (looking-at "}[ \t]*else\\b")
- (not (looking-at "}[ \t]*else\\s_")))
- (setq indent (save-excursion
- (forward-char)
- (backward-sexp)
- (c-backward-to-start-of-if)
- (current-indentation))))
- ((and (looking-at "while\\b")
- (not (looking-at "while\\s_"))
- (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)))
- ;; Skip any number of paren-groups.
- ;; Consider typedef int (*fcn) (int);
- (while (= (following-char) ?\()
- (setq lim (point))
- (condition-case nil
- (forward-sexp 1)
- (error))
- (skip-chars-forward " \t\f"))
- ;; Have we reached something
- ;; that shows this isn't a function
- ;; definition?
- (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.
- (calculate-c-indent-after-brace))))))))
-
-(defun calculate-c-indent-after-brace ()
- "Return the proper C indent for the first line after an open-brace.
-This function is called with point before the brace."
- ;; 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 ((and (looking-at "else\\b")
- (not (looking-at "else\\s_")))
- (setq if-level (1+ if-level)))
- ((and (looking-at "if\\b")
- (not (looking-at "if\\s_")))
- (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
- ;; Is this line in a new nesting level?
- ;; In other words, is this the first line that
- ;; starts in the new level?
- (if (and (car indent-stack)
- (>= (car indent-stack) 0))
- nil
- ;; Yes.
- ;; Compute the standard indent for this level.
- (let (val)
- (if (= (char-after (car contain-stack)) ?{)
- (save-excursion
- (goto-char (car contain-stack))
- (setq val (calculate-c-indent-after-brace)))
- (setq 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 val)))
- ;; Adjust indent of this individual line
- ;; based on its predecessor.
- ;; Handle continuation lines, if, else, while, and so on.
- (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 (and (looking-at "else\\b")
- (not (looking-at "else\\s_"))))
- (setq at-brace (= (following-char) ?{))
- (setq at-while (and (looking-at "while\\b")
- (not (looking-at "while\\s_"))))
- (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))))))))
- ;; 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)
- (save-excursion
- (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))))
- (indent-for-comment)))))))))))
-
-;; 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 (let ((completion-ignore-case t))
- (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))))
- ;; If the line is not really a conditional, skip past it.
- (if forward (end-of-line)))))
- (or found
- (error "No containing preprocessor conditional"))
- (goto-char (setq new found)))
- (setq count (+ count increment))))
- (push-mark)
- (goto-char new)))
-
-(provide 'c-mode)
-
-;;; c-mode.el ends here
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
deleted file mode 100644
index f030ade3f67..00000000000
--- a/lisp/progmodes/cmacexp.el
+++ /dev/null
@@ -1,371 +0,0 @@
-;;; cmacexp.el --- expand C macros in a region
-
-;; Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
-
-;; Author: Francesco Potorti` <pot@cnuce.cnr.it>
-;; Version: $Id: cmacexp.el,v 1.25 1996/05/21 15:42:13 kwzh 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;; USAGE =============================================================
-
-;; In C mode C-C C-e 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. Both the preprocessor name and the
-;; initial flag can be set by the user. If c-macro-prompt-flag is set
-;; to a non-nil value the user is offered to change the options to the
-;; preprocessor each time c-macro-expand is invoked. Preprocessor
-;; arguments default to the last ones entered. If c-macro-prompt-flag
-;; is nil, one must use M-x set-variable to set a different value for
-;; c-macro-cppflags.
-
-;; A c-macro-expansion function is provided for non-interactive use.
-
-;; INSTALLATION ======================================================
-
-;; Put the following in your ~/.emacs file.
-
-;; If you want the *Macroexpansion* window to be not higher than
-;; necessary:
-;;(setq c-macro-shrink-window-flag 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:
-;;(setq c-macro-cppflags "-I /usr/include/local -DDEBUG"
-;;
-;; If you want the "Preprocessor arguments: " prompt:
-;;(setq c-macro-prompt-flag 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 and programmer 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.
-
-;; ACKNOWLEDGEMENTS ==================================================
-
-;; A lot of thanks to Don Maszle who did a great work of testing, bug
-;; reporting and suggestion of new features. This work has been
-;; partially inspired by Don Maszle and Jonathan Segal's.
-
-;; BUGS ==============================================================
-
-;; If the start point of the region is inside a macro definition the
-;; macro expansion is often inaccurate.
-
-
-(require 'cc-mode)
-
-(provide 'cmacexp)
-
-(defvar c-macro-shrink-window-flag nil
- "*Non-nil means shrink the *Macroexpansion* window to fit its contents.")
-
-(defvar c-macro-prompt-flag nil
- "*Non-nil makes `c-macro-expand' prompt for preprocessor arguments.")
-
-(defvar c-macro-preprocessor
- ;; Cannot rely on standard directory on MS-DOS to find CPP.
- (cond ((eq system-type 'ms-dos) "cpp -C")
- ;; Solaris has it in an unusual place.
- ((and (string-match "^[^-]*-[^-]*-\\(solaris\\|sunos5\\)"
- system-configuration)
- (file-exists-p "/opt/SUNWspro/SC3.0.1/bin/acomp"))
- "/opt/SUNWspro/SC3.0.1/bin/acomp -C -E")
- (t "/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-cppflags ""
- "*Preprocessor flags used by `c-macro-expand'.")
-
-(defconst c-macro-buffer-name "*Macroexpansion*")
-
-(defun c-macro-expand (start end subst)
- "Expand C macros in the region, using the C preprocessor.
-Normally display output in temp buffer, but
-prefix arg means replace the region with it.
-
-`c-macro-preprocessor' specifies the preprocessor to use.
-Prompt for arguments to the preprocessor \(e.g. `-DDEBUG -I ./include')
-if the user option `c-macro-prompt-flag' is non-nil.
-
-Noninteractive args are START, END, SUBST.
-For use inside Lisp programs, see also `c-macro-expansion'."
-
- (interactive "r\nP")
- (let ((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 c-macro-prompt-flag
- (setq c-macro-cppflags
- (read-string "Preprocessor arguments: "
- c-macro-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.
- (setq expansion (c-macro-expansion start end
- (concat c-macro-preprocessor " "
- c-macro-cppflags) t))
- (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-disable-undo displaybuf)
- (erase-buffer)
- (insert expansion)
- (set-buffer-modified-p nil)
- (if (string= "" expansion)
- (message "Null expansion")
- (c-macro-display-buffer))
- (setq buffer-read-only t)
- (setq buffer-auto-save-file-name nil)
- (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. 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-flag is nil the window size is *never*
-;; changed.
-(defun c-macro-display-buffer ()
- (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-flag ;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 (/ (frame-height) 2))
- (enlarge-window (- (min maxheight
- (max minheight
- (+ 2 (vertical-motion (point-max)))))
- (window-height)))
- (goto-char (point-min))
- (select-window oldwin))))))
-
-
-(defun c-macro-expansion (start end cppcommand &optional display)
- "Run a preprocessor on region and return the output as a string.
-Expand 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.
-Optional arg DISPLAY non-nil means show messages in the echo area."
-
-;; 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)))
- (mymsg (format "Invoking %s%s%s on region..."
- c-macro-preprocessor
- (if (string= "" c-macro-cppflags) "" " ")
- c-macro-cppflags))
- (uniquestring "??? !!! ??? start of c-macro expansion ??? !!! ???")
- (startlinenum 0)
- (linenum 0)
- (startstat ())
- (startmarker "")
- (exit-status 0)
- (tempname (make-temp-name (concat
- (or (getenv "TMPDIR") (getenv "TEMP")
- (getenv "TMP") "/tmp")
- "/"))))
- (unwind-protect
- (save-excursion
- (save-restriction
- (widen)
- (let ((in-syntax-table (syntax-table)))
- (set-buffer outbuf)
- (setq buffer-read-only nil)
- (erase-buffer)
- (set-syntax-table in-syntax-table))
- (insert-buffer-substring inbuf 1 end))
-
- ;; We have copied inbuf to outbuf. Point is at end of
- ;; outbuf. Inset a newline at the end, so cpp can correctly
- ;; parse a token ending at END.
- (insert "\n")
-
- ;; Save sexp status and line number at START.
- (setq startstat (parse-partial-sexp 1 start))
- (setq startlinenum (+ (count-lines 1 (point))
- (if (bolp) 1 0)))
-
- ;; Now we insert the #line directives after all #endif or
- ;; #else following START going backward, so the lines we
- ;; insert don't change the line numbers.
- ;(switch-to-buffer outbuf) (debug) ;debugging instructions
- (goto-char (point-max))
- (while (re-search-backward "\n#\\(endif\\|else\\)\\>" start 'move)
- (if (equal (nthcdr 3 (parse-partial-sexp start (point)
- nil nil startstat))
- '(nil nil nil 0 nil)) ;neither in string nor in
- ;comment nor after quote
- (progn
- (goto-char (match-end 0))
- (setq linenum (+ startlinenum
- (count-lines start (point))))
- (insert (format "\n#line %d \"%s\"\n" linenum filename))
- (goto-char (match-beginning 0)))))
-
- ;; Now we are at START. Insert the first #line directive.
- ;; This must work even inside a string or comment, or after a
- ;; quote.
- (let* ((startinstring (nth 3 startstat))
- (startincomment (nth 4 startstat))
- (startafterquote (nth 5 startstat))
- (startinbcomment (nth 7 startstat)))
- (insert (if startafterquote " " "")
- (cond (startinstring
- (char-to-string startinstring))
- (startincomment "*/")
- (""))
- (setq startmarker
- (concat "\n" uniquestring
- (cond (startinstring
- (char-to-string startinstring))
- (startincomment "/*")
- (startinbcomment "//"))
- (if startafterquote "\\")))
- (format "\n#line %d \"%s\"\n" startlinenum filename)))
-
- ;; Call the preprocessor.
- (if display (message mymsg))
- (setq exit-status
- (call-process-region 1 (point-max)
- shell-file-name
- t (list t tempname) nil "-c"
- cppcommand))
- (if display (message (concat mymsg "done")))
- (if (= (buffer-size) 0)
- ;; Empty output is normal after a fatal error.
- (insert "\nPreprocessor produced no output\n")
- ;; Find and delete the mark of the start of the expansion.
- ;; Look for `# nn "file.c"' lines and delete them.
- (goto-char (point-min))
- (search-forward startmarker)
- (delete-region 1 (point)))
- (while (re-search-forward (concat "^# [0-9]+ \""
- (regexp-quote filename)
- "\"") nil t)
- (beginning-of-line)
- (let ((beg (point)))
- (forward-line 1)
- (delete-region beg (point))))
-
- ;; If CPP got errors, show them at the beginning.
- ;; MS-DOS shells don't return the exit code of their children.
- ;; Look at the size of the error message file instead, but
- ;; don't punish those MS-DOS users who have a shell that does
- ;; return an error code.
- (or (and (or (not (boundp 'msdos-shells))
- (not (member (file-name-nondirectory shell-file-name)
- msdos-shells)))
- (eq exit-status 0))
- (zerop (nth 7 (file-attributes (expand-file-name tempname))))
- (progn
- (goto-char (point-min))
- ;; Put the messages inside a comment, so they won't get in
- ;; the way of font-lock, highlighting etc.
- (insert
- (format "/* Preprocessor terminated with status %s\n\n Messages from `%s\':\n\n"
- exit-status cppcommand))
- (goto-char (+ (point)
- (nth 1 (insert-file-contents tempname))))
- (insert "\n\n*/\n")))
- (delete-file tempname)
-
- ;; Compute the return value, keeping in account the space
- ;; inserted at the end of the buffer.
- (buffer-substring 1 (max 1 (- (point-max) 1))))
-
- ;; Cleanup.
- (kill-buffer outbuf))))
-
-;;; cmacexp.el ends here
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
deleted file mode 100644
index 4c9b9c56e76..00000000000
--- a/lisp/progmodes/compile.el
+++ /dev/null
@@ -1,1583 +0,0 @@
-;;; compile.el --- run compiler as inferior of Emacs, parse error messages.
-
-;; Copyright (C) 1985, 86, 87, 93, 94, 1995, 1996 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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
-(defvar compilation-window-height nil
- "*Number of lines in a compilation window. If nil, use Emacs default.")
-
-(defvar compile-auto-highlight nil
- "*Specify how many compiler errors to highlight (and parse) initially.
-\(Highlighting applies to ean error message when the mouse is over it.)
-If this is a number N, all compiler error messages in the first N lines
-are highlighted and parsed as soon as they arrive in Emacs.
-If t, highlight and parse the whole compilation output as soon as it arrives.
-If nil, don't highlight or parse any of the buffer until you try to
-move to the error messages.
-
-Those messages which are not parsed and highlighted initially
-will be parsed and highlighted as soon as you try to move to them.")
-
-(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 facilities; 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.")
-
-;;;###autoload
-(defvar compilation-finish-functions nil
- "*Functions to call when a compilation process finishes.
-Each function 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! See also 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
- ;; or GNU utilities with column (GNAT 1.82):
- ;; foo.adb:2:1: Unit name does not match file name
- ;;
- ;; 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\
-\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\)\\([) \t]\\|\
-:\\([^0-9\n]\\|\\([0-9]+:\\)\\)\\)" 1 2 5)
-
- ;; Microsoft C/C++:
- ;; keyboard.c(537) : warning C4005: 'min' : macro redefinition
- ;; d:\tmp\test.c(23) : error C2143: syntax error : missing ';' before 'if'
- ("\n\\(\\([a-zA-Z]:\\)?[^:( \t\n-]+\\)[:(][ \t]*\\([0-9]+\\)[:) \t]" 1 3)
-
- ;; Borland C++:
- ;; Error ping.c 15: Unable to open include file 'sys/types.h'
- ;; Warning ping.c 68: Call to function 'func' with no prototype
- ("\n\\(Error\\|Warning\\) \\([a-zA-Z]?:?[^:( \t\n]+\\)\
- \\([0-9]+\\)\\([) \t]\\|:[^0-9\n]\\)" 2 3)
-
- ;; 4.3BSD lint pass 2
- ;; strcmp: variable # of args. llib-lc(359) :: /usr/src/foo/foo.c(8)
- ("[ \t:]\\([a-zA-Z]?:?[^:( \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(]+\\([a-zA-Z]?:?[^:( \t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]+" 1 2)
- ;; which is regexp Impressionism - it matches almost anything!
- ("([ \t]*\\([a-zA-Z]?:?[^:( \t\n]+\\)[:(][ \t]*\\([0-9]+\\))" 1 2)
-
- ;; MIPS lint pass<n>; looks good for SunPro lint also
- ;; TrimMask (255) in solomon.c may be indistinguishable from TrimMasks (93) in solomon.c due to truncation
- ("[^ ]+ (\\([0-9]+\\)) in \\([^ ]+\\)" 2 1)
- ;; name defined but never used: LinInt in cmap_calc.c(199)
- ("in \\([^(]+\\)(\\([0-9]+\\))$" 1 2)
-
- ;; Ultrix 3.0 f77:
- ;; fort: Severe: addstf.f, line 82: Missing operator or delimiter symbol
- ;; Some SGI cc version:
- ;; cfe: Warning 835: foo.c, line 2: something
- ("\n\\(cfe\\|fort\\): [^:\n]*: \\([^ \n]*\\), line \\([0-9]+\\):" 2 3)
- ;; Error on line 3 of t.f: Execution error unclassifiable statement
- ;; Unknown who does this:
- ;; Line 45 of "foo.c": bloofle 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]+\"?\\([a-zA-Z]?:?[^\":\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"
- ;; GNAT (as of July 94):
- ;; "foo.adb", line 2(11): warning: file name does not match ...
- ;; IBM AIX xlc compiler:
- ;; "src/swapping.c", line 30.34: 1506-342 (W) "/*" detected in comment.
- ("\"\\([^,\" \n\t]+\\)\", lines? \
-\\([0-9]+\\)\\([\(.]\\([0-9]+\\)\)?\\)?[:., (-]" 1 2 4)
-
- ;; 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
- ("\n[EW], \\([^(\n]*\\)(\\([0-9]+\\),[ \t]*\\([0-9]+\\)" 1 2 3)
-
- ;; GNU messages with program name and optional column number.
- ("\n[a-zA-Z]?:?[^0-9 \n\t:]+:[ \t]*\\([^ \n\t:]+\\):\
-\\([0-9]+\\):\\(\\([0-9]+\\)[: \t]\\)?" 1 2 4)
-
- ;; Cray C compiler error messages
- ("\n\\(cc\\| cft\\)-[0-9]+ c\\(c\\|f77\\): ERROR \\([^,\n]+, \\)* File = \\([^,\n]+\\), Line = \\([0-9]+\\)" 4 5)
-
- ;; IBM C/C++ Tools 2.01:
- ;; foo.c(2:0) : informational EDC0804: Function foo is not referenced.
- ;; foo.c(3:8) : warning EDC0833: Implicit return statement encountered.
- ;; foo.c(5:5) : error EDC0350: Syntax error.
- ("\n\\([^( \n\t]+\\)(\\([0-9]+\\):\\([0-9]+\\)) : " 1 2 3)
-
- ;; Sun ada (VADS, Solaris):
- ;; /home3/xdhar/rcds_rc/main.a, line 361, char 6:syntax error: "," inserted
- ("\n\\([^, ]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3)
- )
- "Alist that specifies how to match errors in compiler output.
-Each elt has the form (REGEXP FILE-IDX LINE-IDX [COLUMN-IDX FILE-FORMAT...])
-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.
-If any FILE-FORMAT is given, each is a format string to produce a file name to
-try; %s in the string is replaced by the text matching the FILE-IDX'th
-subexpression.")
-
-(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
- '(("^\\([a-zA-Z]?:?[^:( \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))))))")
-
-(defvar 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.")
-
-(defvar 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.")
-
-(defvar compilation-exit-message-function nil "\
-If non-nil, called when a compilation process dies to return a status message.
-This should be a function of three arguments: process status, exit status,
-and exit message; it returns a cons (MESSAGE . MODELINE) of the strings to
-write into the compilation buffer, and to put in its mode line.")
-
-;; History of compile commands.
-(defvar compile-history nil)
-;; History of grep commands.
-(defvar grep-history nil)
-
-(defvar compilation-mode-font-lock-keywords
- ;; This regexp needs a bit of rewriting. What is the third grouping for?
- '(("^\\([a-zA-Z]?:?[^ \n:]*:\\([0-9]+:\\)+\\)\\(.*\\)$"
- 1 font-lock-function-name-face))
-;;; ("^\\([^\n:]*:\\([0-9]+:\\)+\\)\\(.*\\)$" 0 font-lock-keyword-face keep)
- "Additional expressions to highlight in Compilation mode.")
-
-;;;###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.
-
-Interactively, prompts for the command if `compilation-read-command' is
-non-nil; otherwise uses `compile-command'. With prefix arg, always prompts.
-
-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 (or compilation-read-command current-prefix-arg)
- (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"))
-
-;;; run compile with the default command line
-(defun recompile ()
- "Re-compile the program including the current buffer."
- (interactive)
- (save-some-buffers (not compilation-ask-about-save) nil)
- (compile-internal compile-command "No more errors"))
-
-;; The system null device. (Should reference NULL_DEVICE from C.)
-(defvar grep-null-device "/dev/null" "The system null device.")
-
-;;;###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)))
- (let ((buf (compile-internal (concat command-args " " grep-null-device)
- "No more grep hits" "grep"
- ;; Give it a simpler regexp to match.
- nil grep-regexp-alist)))
- (save-excursion
- (set-buffer buf)
- (set (make-local-variable 'compilation-exit-message-function)
- (lambda (status code msg)
- (if (eq status 'exit)
- (cond ((zerop code)
- '("finished (matches found)\n" . "matched"))
- ((= code 1)
- '("finished with no matches found\n" . "no match"))
- (t
- (cons msg code)))
- (cons msg code)))))))
-
-(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)
- (buffer-disable-undo (current-buffer))
- (erase-buffer)
- (buffer-enable-undo (current-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)
- ;; (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)))
- (compilation-set-window-height outwin)
- ;; Start the compilation.
- (if (fboundp 'start-process)
- (let* ((process-environment (cons "EMACS=t" process-environment))
- (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 "Executing `%s'..." command)
- ;; Fake modeline display as if `start-process' were run.
- (setq mode-line-process ":run")
- (force-mode-line-update)
- (sit-for 0) ; Force redisplay
- (let ((status (call-process shell-file-name nil outbuf nil "-c"
- command)))
- (cond ((numberp status)
- (compilation-handle-exit 'exit status
- (if (zerop status)
- "finished\n"
- (format "\
-exited abnormally with code %d\n"
- status))))
- ((stringp status)
- (compilation-handle-exit 'signal status
- (concat status "\n")))
- (t
- (compilation-handle-exit 'bizarre status status))))
- (message "Executing `%s'...done" command))))
- ;; Make it so the next C-x ` will use this buffer.
- (setq compilation-last-buffer outbuf)))
-
-;; Set the height of WINDOW according to compilation-window-height.
-(defun compilation-set-window-height (window)
- (and compilation-window-height
- (= (window-width window) (frame-width (window-frame window)))
- ;; If window is alone in its frame, aside from a minibuffer,
- ;; don't change its height.
- (not (eq window (frame-root-window (window-frame window))))
- ;; This save-excursion prevents us from changing the current buffer,
- ;; which might not be the same as the selected window's buffer.
- (save-excursion
- (let ((w (selected-window)))
- (unwind-protect
- (progn
- (select-window window)
- (enlarge-window (- compilation-window-height
- (window-height))))
- (select-window w))))))
-
-(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-m" '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)
- ;; Set up the menu-bar
- (define-key map [menu-bar compilation-menu]
- (cons "Compile" (make-sparse-keymap "Compile")))
-
- (define-key map [menu-bar compilation-menu compilation-mode-kill-compilation]
- '("Stop Compilation" . kill-compilation))
- (define-key map [menu-bar compilation-menu compilation-mode-separator2]
- '("----" . nil))
- (define-key map [menu-bar compilation-menu compilation-mode-first-error]
- '("First Error" . first-error))
- (define-key map [menu-bar compilation-menu compilation-mode-previous-error]
- '("Previous Error" . previous-error))
- (define-key map [menu-bar compilation-menu compilation-mode-next-error]
- '("Next Error" . next-error))
- (define-key map [menu-bar compilation-menu compilation-separator2]
- '("----" . nil))
- (define-key map [menu-bar compilation-menu compilation-mode-grep]
- '("Grep" . grep))
- (define-key map [menu-bar compilation-menu compilation-mode-recompile]
- '("Recompile" . recompile))
- (define-key map [menu-bar compilation-menu compilation-mode-compile]
- '("Compile" . compile))
- map)
- "Keymap for compilation log buffers.
-`compilation-minor-mode-map' is a cdr of this.")
-
-;;;###autoload
-(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)
- (kill-all-local-variables)
- (use-local-map compilation-mode-map)
- (setq major-mode 'compilation-mode
- mode-name "Compilation")
- (compilation-setup)
- (set (make-local-variable 'font-lock-defaults)
- '(compilation-mode-font-lock-keywords t))
- (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'.
-Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
- (interactive "P")
- (if (setq compilation-minor-mode (if (null arg)
- (null compilation-minor-mode)
- (> (prefix-numeric-value arg) 0)))
- (progn
- (compilation-setup)
- (run-hooks 'compilation-minor-mode-hook))))
-
-;; Write msg in the current buffer and hack its mode-line-process.
-(defun compilation-handle-exit (process-status exit-status msg)
- (let ((buffer-read-only nil)
- (status (if compilation-exit-message-function
- (funcall compilation-exit-message-function
- process-status exit-status msg)
- (cons msg exit-status)))
- (omax (point-max))
- (opoint (point)))
- ;; Record where we put the message, so we can ignore it
- ;; later on.
- (goto-char omax)
- (insert ?\n mode-name " " (car status))
- (forward-char -1)
- (insert " at " (substring (current-time-string) 0 19))
- (forward-char 1)
- (setq mode-line-process (format ":%s [%s]" process-status (cdr status)))
- ;; Force mode line redisplay soon.
- (force-mode-line-update)
- (if (and opoint (< opoint omax))
- (goto-char opoint))
- ;; Automatically parse (and mouse-highlight) error messages:
- (cond ((eq compile-auto-highlight t)
- (compile-reinitialize-errors nil (point-max)))
- ((numberp compile-auto-highlight)
- (compile-reinitialize-errors nil
- (save-excursion
- (goto-line compile-auto-highlight)
- (point)))))
- (if compilation-finish-function
- (funcall compilation-finish-function (current-buffer) msg))
- (let ((functions compilation-finish-functions))
- (while functions
- (funcall (car functions) (current-buffer) msg)
- (setq functions (cdr functions))))))
-
-;; 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)))
- ;; 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)
- (compilation-handle-exit (process-status proc)
- (process-exit-status proc)
- msg)
- ;; 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))
- (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'."
- (if (buffer-name (process-buffer proc))
- (save-excursion
- (set-buffer (process-buffer proc))
- (let ((buffer-read-only nil))
- (save-excursion
- (goto-char (process-mark proc))
- (insert-before-markers string)
- (run-hooks 'compilation-filter-hook)
- (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)
- (save-excursion
- (set-buffer buffer)
- (or compilation-minor-mode (eq major-mode 'compilation-mode))))
-
-(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))
- ;; Mouse-Highlight (the first line of) each error message when the
- ;; mouse pointer moves over it:
- (let ((inhibit-read-only t)
- (error-list compilation-error-list))
- (while error-list
- (save-excursion
- (put-text-property (goto-char (car (car error-list)))
- (progn (end-of-line) (point))
- 'mouse-face 'highlight))
- (setq error-list (cdr error-list))))
- )))))
-
-(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)
- (compilation-buffer-p 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 previous-error ()
- "Visit previous compilation error message and corresponding source code.
-This operates on the output from the \\[compile] command."
- (interactive)
- (next-error -1))
-
-(defun first-error ()
- "Reparse the error message buffer and start at the first error
-Visit corresponding source code.
-This operates on the output from the \\[compile] command."
- (interactive)
- (next-error '(4)))
-
-(defvar compilation-skip-to-next-location nil
- "*If non-nil, skip multiple error messages for the same source location.")
-
-(defun compilation-next-error-locus (&optional move reparse silent)
- "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). If optional third argument SILENT is non-nil, return
-nil instead of raising an error if there are no more errors.
-
-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)
- (catch 'no-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
- (and move (/= move 1)
- (error (if (> move 0)
- "Moved past last error")
- "Moved back past first error"))
- ;; Forget existing error messages if compilation has finished.
- (if (not (and (get-buffer-process (current-buffer))
- (eq (process-status
- (get-buffer-process
- (current-buffer)))
- 'run)))
- (compilation-forget-errors))
- (if silent
- (throw 'no-next-error nil)
- (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 (apply 'compilation-find-file
- (car next-error) fileinfo)))
- (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 (and column (> column 0))
- ;; Columns in error msgs are 1-origin.
- (move-to-column (1- 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 (and column (> column 1))
- (move-to-column (1- column))
- (beginning-of-line))
- (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)))))
-
- (if compilation-skip-to-next-location
- ;; 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."
- (if (and (window-dedicated-p (selected-window))
- (eq (selected-window) (frame-root-window)))
- (switch-to-buffer-other-frame (marker-buffer (cdr next-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)
- ;; Use an existing window if it is in a visible frame.
- (w (or (get-buffer-window (marker-buffer (car next-error)) 'visible)
- ;; Pop up a window.
- (display-buffer (marker-buffer (car next-error))))))
- (set-window-point w (car next-error))
- (set-window-start w (car next-error))
- (compilation-set-window-height w)))
-
-;; 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 (marker filename dir &rest formats)
- (or formats (setq formats '("%s")))
- (let ((dirs compilation-search-path)
- buffer thisdir fmts name)
- (if (file-name-absolute-p filename)
- ;; The file name is absolute. Use its explicit directory as
- ;; the first in the search path, and strip it from FILENAME.
- (setq filename (abbreviate-file-name (expand-file-name filename))
- dirs (cons (file-name-directory filename) dirs)
- filename (file-name-nondirectory filename)))
- ;; Now search the path.
- (while (and dirs (null buffer))
- (setq thisdir (or (car dirs) dir)
- fmts formats)
- ;; For each directory, try each format string.
- (while (and fmts (null buffer))
- (setq name (expand-file-name (format (car fmts) filename) thisdir)
- buffer (and (file-exists-p name)
- (find-file-noselect name))
- fmts (cdr fmts)))
- (setq dirs (cdr dirs)))
- (or buffer
- ;; 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.
- (let* ((pop-up-windows t)
- (w (display-buffer (marker-buffer marker))))
- (set-window-point w marker)
- (set-window-start w marker)
- (let ((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 (expand-file-name filename name)))
- (and (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)
- ;; Remove the highlighting added by compile-reinitialize-errors:
- (let ((inhibit-read-only t))
- (remove-text-properties (point-min) (point-max) '(mouse-face highlight)))
- )
-
-
-(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 3 (car alist))
- (+ subexpr (nth 3 (car alist)))))
- error-regexp-groups))
- (setq subexpr (+ subexpr 1 (count-regexp-groupings (car (car alist)))))
- (setq alist (cdr alist)))
-
- ;; Set up now the expanded, abbreviated directory variables
- ;; that compile-abbreviate-directory will need, so we can
- ;; compute them just once here.
- (setq orig (abbreviate-file-name default-directory)
- orig-expanded (abbreviate-file-name
- (file-truename default-directory))
- parent-expanded (abbreviate-file-name
- (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 "leaving" 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)
- (match-beginning (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)))
-
- ;; Some compilers (e.g. Sun's java compiler, reportedly)
- ;; produce bogus file names like "./bar//foo.c" for the file
- ;; "bar/foo.c"; expand-file-name will collapse these into
- ;; "/foo.c" and fail to find the appropriate file. So we look
- ;; for doubled slashes in the file name and fix them up in the
- ;; buffer.
- (setq filename (command-line-normalize-file-name filename))
- (setq filename (cons filename (cons default-directory
- (nthcdr 4 alist))))
-
-
- ;; 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
- ;; Save as the start of the error the beginning of the
- ;; line containing the match unless the match starts at a
- ;; newline, in which case the beginning of the next line.
- (goto-char beginning-of-match)
- (forward-line (if (eolp) 1 0))
- (let ((this (cons (point-marker)
- (list filename linenum column))))
- ;; Don't add the same source line more than once.
- (if (and compilation-skip-to-next-location
- (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)
- ;; Apply canonical abbreviations to DIR first thing.
- ;; Those abbreviations are already done in the other arguments passed.
- (setq dir (abbreviate-file-name dir))
-
- ;; 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 9848adcf40b..00000000000
--- a/lisp/progmodes/cplus-md.el
+++ /dev/null
@@ -1,1061 +0,0 @@
-;;; cplus-md.el --- C++ code editing commands for Emacs
-
-;; Copyright (C) 1985, 1992, 1994, 1995 Free Software Foundation, Inc.
-
-;; Maintainer: Dave Detlefs <dld@cs.cmu.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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; 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 (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)
- (modify-syntax-entry ?* ". 23b" c++-mode-syntax-table)
- (modify-syntax-entry ?/ ". 124" c++-mode-syntax-table)
- (modify-syntax-entry ?\n ">" c++-mode-syntax-table)
- (modify-syntax-entry ?\^m ">" 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.")
-
-(defvar c++-imenu-generic-expression
- (`
- ((nil
- (,
- (concat
- "^" ; beginning of line is required
- "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
- "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
- "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
-
- "\\(" ; last type spec including */&
- "[a-zA-Z0-9_:]+"
- "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either pointer/ref sign or whitespace
- "\\)?" ; if there is a last type spec
- "\\(" ; name; take that into the imenu entry
- "[a-zA-Z0-9_:~]+" ; member function, ctor or dtor...
- ; (may not contain * because then
- ; "a::operator char*" would become "char*"!)
- "\\|"
- "\\([a-zA-Z0-9_:~]*::\\)?operator"
- "[^a-zA-Z1-9_][^(]*" ; ...or operator
- " \\)"
- "[ \t]*([^)]*)[ \t\n]*[^ ;]" ; require something other than a ; after
- ; the (...) to avoid prototypes. Can't
- ; catch cases with () inside the parentheses
- ; surrounding the parameters
- ; (like "int foo(int a=bar()) {...}"
-
- )) 6)
- ("Class"
- (, (concat
- "^" ; beginning of line is required
- "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
- "class[ \t]+"
- "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
- "[ \t]*[:{]"
- )) 2)
-;; Example of generic expression for finding prototypes, structs, unions, enums.
-;; Uncomment if you want to find these too. It will be a bit slower gathering
-;; the indexes.
-; ("Prototypes"
-; (,
-; (concat
-; "^" ; beginning of line is required
-; "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
-; "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
-; "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
-
-; "\\(" ; last type spec including */&
-; "[a-zA-Z0-9_:]+"
-; "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either pointer/ref sign or whitespace
-; "\\)?" ; if there is a last type spec
-; "\\(" ; name; take that into the imenu entry
-; "[a-zA-Z0-9_:~]+" ; member function, ctor or dtor...
-; ; (may not contain * because then
-; ; "a::operator char*" would become "char*"!)
-; "\\|"
-; "\\([a-zA-Z0-9_:~]*::\\)?operator"
-; "[^a-zA-Z1-9_][^(]*" ; ...or operator
-; " \\)"
-; "[ \t]*([^)]*)[ \t\n]*;" ; require ';' after
-; ; the (...) Can't
-; ; catch cases with () inside the parentheses
-; ; surrounding the parameters
-; ; (like "int foo(int a=bar());"
-; )) 6)
-; ("Struct"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "struct[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
-; ("Enum"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "enum[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
-; ("Union"
-; (, (concat
-; "^" ; beginning of line is required
-; "\\(static[ \t]+\\)?" ; there may be static or const.
-; "\\(const[ \t]+\\)?"
-; "union[ \t]+"
-; "\\([a-zA-Z0-9_]+\\)" ; this is the string we want to get
-; "[ \t]*[{]"
-; )) 3)
- ))
- "Imenu generic expression for C++ mode. See `imenu-generic-expression'.")
-
-(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 electrically
- 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)
- ;; This code depends on the old C mode.
- (require 'c-mode)
- (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)
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression c++-imenu-generic-expression)
- (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 its indentation.
- (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 ?:)
- (or (not (or (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
- (if (= (preceding-char) ?\))
- (forward-list -1))
- (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 (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
- (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
- (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-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))))
- ;; No comment to be found.
- ;; If there's a # command on this line,
- ;; move back to it.
- (t (beginning-of-line)
- (skip-chars-forward " \t")
- ;; But don't get fooled if we are already before the #.
- (if (and (looking-at "#") (< (point) opoint))
- (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.
- nil
- ;; Just started a new nesting level.
- ;; Compute the standard indent for this level.
- (let (val)
- (if (= (char-after (car contain-stack)) ?{)
- (save-excursion
- (goto-char (car contain-stack))
- (setq val (calculate-c-indent-after-brace)))
- (setq val (calculate-c++-indent
- (if (car indent-stack)
- (- (car indent-stack))))))
- (setcar indent-stack val)))
- ;; Adjust line indentation according to its predecessor.
- (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))))))
- ;; 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/cpp.el b/lisp/progmodes/cpp.el
deleted file mode 100644
index fa0ed911e2e..00000000000
--- a/lisp/progmodes/cpp.el
+++ /dev/null
@@ -1,782 +0,0 @@
-;;; cpp.el --- Highlight or hide text according to cpp conditionals.
-
-;; Copyright (C) 1994, 1995 Free Software Foundation
-
-;; Author: Per Abrahamsen <abraham@iesd.auc.dk>
-;; Keywords: c, faces, 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Parse a text for C preprocessor conditionals, and highlight or hide
-;; the text inside the conditionals as you wish.
-
-;; This package is inspired by Jim Coplien's delta editor for SCCS.
-
-;;; Todo:
-
-;; Should parse "#if" and "#elif" expressions and merge the faces
-;; somehow.
-
-;; Somehow it is sometimes possible to make changes near a read only
-;; area which you can't undo. Their are other strange effects in that
-;; area.
-
-;; The Edit buffer should -- optionally -- appear in its own frame.
-
-;; Conditionals seem to be rear-sticky. They shouldn't be.
-
-;; Restore window configurations when exiting CPP Edit buffer.
-
-;;; Code:
-
-;;; Customization:
-
-(defvar cpp-config-file (convert-standard-filename ".cpp.el")
- "*File name to save cpp configuration.")
-
-(defvar cpp-known-face 'invisible
- "*Face used for known cpp symbols.")
-
-(defvar cpp-unknown-face 'highlight
- "*Face used for unknown cpp symbols.")
-
-(defvar cpp-face-type 'light
- "*Indicate what background face type you prefer.
-Can be either light or dark for color screens, mono for monochrome
-screens, and none if you don't use a window system.")
-
-(defvar cpp-known-writable t
- "*Non-nil means you are allowed to modify the known conditionals.")
-
-(defvar cpp-unknown-writable t
- "*Non-nil means you are allowed to modify the unknown conditionals.")
-
-(defvar cpp-edit-list nil
- "Alist of cpp macros and information about how they should be displayed.
-Each entry is a list with the following elements:
-0. The name of the macro (a string).
-1. Face used for text that is `ifdef' the macro.
-2. Face used for text that is `ifndef' the macro.
-3. `t', `nil', or `both' depending on what text may be edited.")
-
-(defvar cpp-overlay-list nil)
-;; List of cpp overlays active in the current buffer.
-(make-variable-buffer-local 'cpp-overlay-list)
-
-(defvar cpp-callback-data)
-(defvar cpp-state-stack)
-
-(defconst cpp-face-type-list
- '(("light color background" . light)
- ("dark color background" . dark)
- ("monochrome" . mono)
- ("tty" . none))
- "Alist of strings and names of the defined face collections.")
-
-(defconst cpp-writable-list
- ;; Names used for the writable property.
- '(("writable" . t)
- ("read-only" . nil)))
-
-(defvar cpp-button-event nil)
-;; This will be t in the callback for `cpp-make-button'.
-
-(defvar cpp-edit-buffer nil)
-;; Real buffer whose cpp display information we are editing.
-(make-variable-buffer-local 'cpp-edit-buffer)
-
-(defconst cpp-branch-list
- ;; Alist of branches.
- '(("false" . nil)
- ("true" . t)
- ("both" . both)))
-
-(defvar cpp-face-default-list nil
- "List of faces you can choose from for cpp conditionals.")
-
-(defvar cpp-face-light-name-list
- '("light gray" "light blue" "light cyan" "light yellow" "light pink"
- "pale green" "beige" "orange" "magenta" "violet" "medium purple"
- "turquoise")
- "Background colours useful with dark foreground colors.")
-
-(defvar cpp-face-dark-name-list
- '("dim gray" "blue" "cyan" "yellow" "red"
- "dark green" "brown" "dark orange" "dark khaki" "dark violet" "purple"
- "dark turquoise")
- "Background colours useful with light foreground colors.")
-
-(defvar cpp-face-light-list nil
- "Alist of names and faces to be used for light backgrounds.")
-
-(defvar cpp-face-dark-list nil
- "Alist of names and faces to be used for dark backgrounds.")
-
-(defvar cpp-face-mono-list
- '(("bold" . 'bold)
- ("bold-italic" . 'bold-italic)
- ("italic" . 'italic)
- ("underline" . 'underline))
- "Alist of names and faces to be used for monochrome screens.")
-
-(defvar cpp-face-none-list
- '(("default" . default)
- ("invisible" . invisible))
- "Alist of names and faces available even if you don't use a window system.")
-
-(defvar cpp-face-all-list
- (append cpp-face-light-list
- cpp-face-dark-list
- cpp-face-mono-list
- cpp-face-none-list)
- "All faces used for highlighting text inside cpp conditionals.")
-
-;;; Parse Buffer:
-
-(defvar cpp-parse-symbols nil
- "List of cpp macros used in the local buffer.")
-(make-variable-buffer-local 'cpp-parse-symbols)
-
-(defconst cpp-parse-regexp
- ;; Regexp matching all tokens needed to find conditionals.
- (concat
- "'\\|\"\\|/\\*\\|//\\|"
- "\\(^[ \t]*#[ \t]*\\(ifdef\\|ifndef\\|if\\|"
- "elif\\|else\\|endif\\)\\b\\)"))
-
-;;;###autoload
-(defun cpp-highlight-buffer (arg)
- "Highlight C code according to preprocessor conditionals.
-This command pops up a buffer which you should edit to specify
-what kind of highlighting to use, and the criteria for highlighting.
-A prefix arg suppresses display of that buffer."
- (interactive "P")
- (setq cpp-parse-symbols nil)
- (cpp-parse-reset)
- (if (null cpp-edit-list)
- (cpp-edit-load))
- (let (cpp-state-stack)
- (save-excursion
- (goto-char (point-min))
- (cpp-progress-message "Parsing...")
- (while (re-search-forward cpp-parse-regexp nil t)
- (cpp-progress-message "Parsing...%d%%"
- (/ (* 100 (- (point) (point-min))) (buffer-size)))
- (let ((match (buffer-substring (match-beginning 0) (match-end 0))))
- (cond ((or (string-equal match "'")
- (string-equal match "\""))
- (goto-char (match-beginning 0))
- (condition-case nil
- (forward-sexp)
- (error (cpp-parse-error
- "Unterminated string or character"))))
- ((string-equal match "/*")
- (or (search-forward "*/" nil t)
- (error "Unterminated comment")))
- ((string-equal match "//")
- (skip-chars-forward "^\n\r"))
- (t
- (end-of-line 1)
- (let ((from (match-beginning 1))
- (to (1+ (point)))
- (type (buffer-substring (match-beginning 2)
- (match-end 2)))
- (expr (buffer-substring (match-end 1) (point))))
- (cond ((string-equal type "ifdef")
- (cpp-parse-open t expr from to))
- ((string-equal type "ifndef")
- (cpp-parse-open nil expr from to))
- ((string-equal type "if")
- (cpp-parse-open t expr from to))
- ((string-equal type "elif")
- (let (cpp-known-face cpp-unknown-face)
- (cpp-parse-close from to))
- (cpp-parse-open t expr from to))
- ((string-equal type "else")
- (or cpp-state-stack
- (cpp-parse-error "Top level #else"))
- (let ((entry (list (not (nth 0 (car cpp-state-stack)))
- (nth 1 (car cpp-state-stack))
- from to)))
- (cpp-parse-close from to)
- (setq cpp-state-stack (cons entry cpp-state-stack))))
- ((string-equal type "endif")
- (cpp-parse-close from to))
- (t
- (cpp-parse-error "Parser error"))))))))
- (message "Parsing...done"))
- (if cpp-state-stack
- (save-excursion
- (goto-char (nth 3 (car cpp-state-stack)))
- (cpp-parse-error "Unclosed conditional"))))
- (or arg
- (null cpp-parse-symbols)
- (cpp-parse-edit)))
-
-(defun cpp-parse-open (branch expr begin end)
- "Push information about conditional-beginning onto `cpp-state-stack'."
- ;; Discard comments within this line.
- (while (string-match "\\b[ \t]*/\\*.*\\*/[ \t]*\\b" expr)
- (setq expr (concat (substring expr 0 (match-beginning 0))
- (substring expr (match-end 0)))))
- ;; If a comment starts on this line and continues past, discard it.
- (if (string-match "\\b[ \t]*/\\*" expr)
- (setq expr (substring expr 0 (match-beginning 0))))
- ;; Delete any C++ comment from the line.
- (if (string-match "\\b[ \t]*\\(//.*\\)?$" expr)
- (setq expr (substring expr 0 (match-beginning 0))))
- (while (string-match "[ \t]+" expr)
- (setq expr (concat (substring expr 0 (match-beginning 0))
- (substring expr (match-end 0)))))
- (setq cpp-state-stack (cons (list branch expr begin end) cpp-state-stack))
- (or (member expr cpp-parse-symbols)
- (setq cpp-parse-symbols
- (cons expr cpp-parse-symbols)))
- (if (assoc expr cpp-edit-list)
- (cpp-make-known-overlay begin end)
- (cpp-make-unknown-overlay begin end)))
-
-(defun cpp-parse-close (from to)
- ;; Pop top of cpp-state-stack and create overlay.
- (let ((entry (assoc (nth 1 (car cpp-state-stack)) cpp-edit-list))
- (branch (nth 0 (car cpp-state-stack)))
- (begin (nth 2 (car cpp-state-stack)))
- (end (nth 3 (car cpp-state-stack))))
- (setq cpp-state-stack (cdr cpp-state-stack))
- (if entry
- (let ((face (nth (if branch 1 2) entry))
- (read-only (eq (not branch) (nth 3 entry)))
- (priority (length cpp-state-stack))
- (overlay (make-overlay end from)))
- (cpp-make-known-overlay from to)
- (setq cpp-overlay-list (cons overlay cpp-overlay-list))
- (if priority (overlay-put overlay 'priority priority))
- (cond ((eq face 'invisible)
- (cpp-make-overlay-hidden overlay))
- ((eq face 'default))
- (t
- (overlay-put overlay 'face face)))
- (if read-only
- (cpp-make-overlay-read-only overlay)
- (cpp-make-overlay-sticky overlay)))
- (cpp-make-unknown-overlay from to))))
-
-(defun cpp-parse-error (error)
- ;; Error message issued by the cpp parser.
- (error "%s at line %d" error (count-lines (point-min) (point))))
-
-(defun cpp-parse-reset ()
- "Reset display of cpp conditionals to normal."
- (interactive)
- (while cpp-overlay-list
- (delete-overlay (car cpp-overlay-list))
- (setq cpp-overlay-list (cdr cpp-overlay-list))))
-
-;;;###autoload
-(defun cpp-parse-edit ()
- "Edit display information for cpp conditionals."
- (interactive)
- (or cpp-parse-symbols
- (cpp-highlight-buffer t))
- (let ((buffer (current-buffer)))
- (pop-to-buffer "*CPP Edit*")
- (cpp-edit-mode)
- (setq cpp-edit-buffer buffer)
- (cpp-edit-reset)))
-
-;;; Overlays:
-
-(defun cpp-make-known-overlay (start end)
- ;; Create an overlay for a known cpp command from START to END.
- (let ((overlay (make-overlay start end)))
- (if (eq cpp-known-face 'invisible)
- (cpp-make-overlay-hidden overlay)
- (or (eq cpp-known-face 'default)
- (overlay-put overlay 'face cpp-known-face))
- (if cpp-known-writable
- ()
- (overlay-put overlay 'modification-hooks '(cpp-signal-read-only))
- (overlay-put overlay 'insert-in-front-hooks '(cpp-signal-read-only))))
- (setq cpp-overlay-list (cons overlay cpp-overlay-list))))
-
-(defun cpp-make-unknown-overlay (start end)
- ;; Create an overlay for an unknown cpp command from START to END.
- (let ((overlay (make-overlay start end)))
- (cond ((eq cpp-unknown-face 'invisible)
- (cpp-make-overlay-hidden overlay))
- ((eq cpp-unknown-face 'default))
- (t
- (overlay-put overlay 'face cpp-unknown-face)))
- (if cpp-unknown-writable
- ()
- (overlay-put overlay 'modification-hooks '(cpp-signal-read-only))
- (overlay-put overlay 'insert-in-front-hooks '(cpp-signal-read-only)))
- (setq cpp-overlay-list (cons overlay cpp-overlay-list))))
-
-(defun cpp-make-overlay-hidden (overlay)
- ;; Make overlay hidden and intangible.
- (overlay-put overlay 'invisible t)
- (overlay-put overlay 'intangible t)
- ;; Unfortunately `intangible' is not implemented for overlays yet,
- ;; so we make is read-only instead.
- (overlay-put overlay 'modification-hooks '(cpp-signal-read-only))
- (overlay-put overlay 'insert-in-front-hooks '(cpp-signal-read-only)))
-
-(defun cpp-make-overlay-read-only (overlay)
- ;; Make overlay read only.
- (overlay-put overlay 'modification-hooks '(cpp-signal-read-only))
- (overlay-put overlay 'insert-in-front-hooks '(cpp-signal-read-only))
- (overlay-put overlay 'insert-behind-hooks '(cpp-signal-read-only)))
-
-(defun cpp-make-overlay-sticky (overlay)
- ;; Make OVERLAY grow when you insert text at either end.
- (overlay-put overlay 'insert-in-front-hooks '(cpp-grow-overlay))
- (overlay-put overlay 'insert-behind-hooks '(cpp-grow-overlay)))
-
-(defun cpp-signal-read-only (overlay after start end &optional len)
- ;; Only allow deleting the whole overlay.
- ;; Trying to change a read-only overlay.
- (if (and (not after)
- (or (< (overlay-start overlay) start)
- (> (overlay-end overlay) end)))
- (error "This text is read only")))
-
-(defun cpp-grow-overlay (overlay after start end &optional len)
- ;; Make OVERLAY grow to contain range START to END.
- (if after
- (move-overlay overlay
- (min start (overlay-start overlay))
- (max end (overlay-end overlay)))))
-
-;;; Edit Buffer:
-
-(defvar cpp-edit-map nil)
-;; Keymap for `cpp-edit-mode'.
-
-(if cpp-edit-map
- ()
- (setq cpp-edit-map (make-keymap))
- (suppress-keymap cpp-edit-map)
- (define-key cpp-edit-map [ down-mouse-2 ] 'cpp-push-button)
- (define-key cpp-edit-map [ mouse-2 ] 'ignore)
- (define-key cpp-edit-map " " 'scroll-up)
- (define-key cpp-edit-map "\C-?" 'scroll-down)
- (define-key cpp-edit-map [ delete ] 'scroll-down)
- (define-key cpp-edit-map "\C-c\C-c" 'cpp-edit-apply)
- (define-key cpp-edit-map "a" 'cpp-edit-apply)
- (define-key cpp-edit-map "A" 'cpp-edit-apply)
- (define-key cpp-edit-map "r" 'cpp-edit-reset)
- (define-key cpp-edit-map "R" 'cpp-edit-reset)
- (define-key cpp-edit-map "s" 'cpp-edit-save)
- (define-key cpp-edit-map "S" 'cpp-edit-save)
- (define-key cpp-edit-map "l" 'cpp-edit-load)
- (define-key cpp-edit-map "L" 'cpp-edit-load)
- (define-key cpp-edit-map "h" 'cpp-edit-home)
- (define-key cpp-edit-map "H" 'cpp-edit-home)
- (define-key cpp-edit-map "b" 'cpp-edit-background)
- (define-key cpp-edit-map "B" 'cpp-edit-background)
- (define-key cpp-edit-map "k" 'cpp-edit-known)
- (define-key cpp-edit-map "K" 'cpp-edit-known)
- (define-key cpp-edit-map "u" 'cpp-edit-unknown)
- (define-key cpp-edit-map "u" 'cpp-edit-unknown)
- (define-key cpp-edit-map "t" 'cpp-edit-true)
- (define-key cpp-edit-map "T" 'cpp-edit-true)
- (define-key cpp-edit-map "f" 'cpp-edit-false)
- (define-key cpp-edit-map "F" 'cpp-edit-false)
- (define-key cpp-edit-map "w" 'cpp-edit-write)
- (define-key cpp-edit-map "W" 'cpp-edit-write)
- (define-key cpp-edit-map "X" 'cpp-edit-toggle-known)
- (define-key cpp-edit-map "x" 'cpp-edit-toggle-known)
- (define-key cpp-edit-map "Y" 'cpp-edit-toggle-unknown)
- (define-key cpp-edit-map "y" 'cpp-edit-toggle-unknown)
- (define-key cpp-edit-map "q" 'bury-buffer)
- (define-key cpp-edit-map "Q" 'bury-buffer))
-
-(defvar cpp-edit-symbols nil)
-;; Symbols defined in the edit buffer.
-(make-variable-buffer-local 'cpp-edit-symbols)
-
-(defun cpp-edit-mode ()
- "Major mode for editing the criteria for highlighting cpp conditionals.
-Click on objects to change them.
-You can also use the keyboard accelerators indicated like this: [K]ey."
- (kill-all-local-variables)
- (buffer-disable-undo)
- (auto-save-mode -1)
- (setq buffer-read-only t)
- (setq major-mode 'cpp-edit-mode)
- (setq mode-name "CPP Edit")
- (use-local-map cpp-edit-map))
-
-(defun cpp-edit-apply ()
- "Apply edited display information to original buffer."
- (interactive)
- (cpp-edit-home)
- (cpp-highlight-buffer t))
-
-(defun cpp-edit-reset ()
- "Reset display information from original buffer."
- (interactive)
- (let ((buffer (current-buffer))
- (buffer-read-only nil)
- (start (window-start))
- (pos (point))
- symbols)
- (set-buffer cpp-edit-buffer)
- (setq symbols cpp-parse-symbols)
- (set-buffer buffer)
- (setq cpp-edit-symbols symbols)
- (erase-buffer)
- (insert "CPP Display Information for `")
- (cpp-make-button (buffer-name cpp-edit-buffer) 'cpp-edit-home)
- (insert "\n\nClick mouse-2 on item you want to change or use\n"
- "or switch to this buffer and type the keyboard equivalents.\n"
- "Keyboard equivalents are indicated with brackets like [T]his.\n\n")
- (cpp-make-button "[H]ome (display the C file)" 'cpp-edit-home)
- (insert " ")
- (cpp-make-button "[A]pply new settings" 'cpp-edit-apply)
- (insert "\n")
- (cpp-make-button "[S]ave settings" 'cpp-edit-save)
- (insert " ")
- (cpp-make-button "[L]oad settings" 'cpp-edit-load)
- (insert "\n\n")
-
- (insert "[B]ackground: ")
- (cpp-make-button (car (rassq cpp-face-type cpp-face-type-list))
- 'cpp-edit-background)
- (insert "\n[K]nown conditionals: ")
- (cpp-make-button (cpp-face-name cpp-known-face)
- 'cpp-edit-known nil t)
- (insert " [X] ")
- (cpp-make-button (car (rassq cpp-known-writable cpp-writable-list))
- 'cpp-edit-toggle-known)
- (insert "\n[U]nknown conditionals: ")
- (cpp-make-button (cpp-face-name cpp-unknown-face)
- 'cpp-edit-unknown nil t)
- (insert " [Y] ")
- (cpp-make-button (car (rassq cpp-unknown-writable cpp-writable-list))
- 'cpp-edit-toggle-unknown)
- (insert (format "\n\n\n%39s: %14s %14s %7s\n\n" "Expression"
- "[T]rue Face" "[F]alse Face" "[W]rite"))
- (while symbols
- (let* ((symbol (car symbols))
- (entry (assoc symbol cpp-edit-list))
- (true (nth 1 entry))
- (false (nth 2 entry))
- (write (if entry (nth 3 entry) 'both)))
- (setq symbols (cdr symbols))
-
- (if (and entry ; Make default entries unknown.
- (or (null true) (eq true 'default))
- (or (null false) (eq false 'default))
- (eq write 'both))
- (setq cpp-edit-list (delq entry cpp-edit-list)
- entry nil))
-
- (if (> (length symbol) 39)
- (insert (substring symbol 0 39) ": ")
- (insert (format "%39s: " symbol)))
-
- (cpp-make-button (cpp-face-name true)
- 'cpp-edit-true symbol t 14)
- (insert " ")
- (cpp-make-button (cpp-face-name false)
- 'cpp-edit-false symbol t 14)
- (insert " ")
- (cpp-make-button (car (rassq write cpp-branch-list))
- 'cpp-edit-write symbol nil 6)
- (insert "\n")))
- (insert "\n\n")
- (set-window-start nil start)
- (goto-char pos)))
-
-(defun cpp-edit-load ()
- "Load cpp configuration."
- (interactive)
- (cond ((null init-file-user)
- ;; If -q was specified, don't load any init files.
- nil)
- ((file-readable-p cpp-config-file)
- (load-file cpp-config-file))
- ((file-readable-p (concat "~/" cpp-config-file))
- (load-file cpp-config-file)))
- (if (eq major-mode 'cpp-edit-mode)
- (cpp-edit-reset)))
-
-(defun cpp-edit-save ()
- "Save the current cpp configuration in a file."
- (interactive)
- (require 'pp)
- (save-excursion
- (set-buffer cpp-edit-buffer)
- (let ((buffer (find-file-noselect cpp-config-file)))
- (set-buffer buffer)
- (erase-buffer)
- (pp (list 'setq 'cpp-known-face
- (list 'quote cpp-known-face)) buffer)
- (pp (list 'setq 'cpp-unknown-face
- (list 'quote cpp-unknown-face)) buffer)
- (pp (list 'setq 'cpp-face-type
- (list 'quote cpp-face-type)) buffer)
- (pp (list 'setq 'cpp-known-writable
- (list 'quote cpp-known-writable)) buffer)
- (pp (list 'setq 'cpp-unknown-writable
- (list 'quote cpp-unknown-writable)) buffer)
- (pp (list 'setq 'cpp-edit-list
- (list 'quote cpp-edit-list)) buffer)
- (write-file cpp-config-file))))
-
-(defun cpp-edit-home ()
- "Switch back to original buffer."
- (interactive)
- (if cpp-button-event
- (read-event))
- (pop-to-buffer cpp-edit-buffer))
-
-(defun cpp-edit-background ()
- "Change default face collection."
- (interactive)
- (call-interactively 'cpp-choose-default-face)
- (cpp-edit-reset))
-
-(defun cpp-edit-known ()
- "Select default for known conditionals."
- (interactive)
- (setq cpp-known-face (cpp-choose-face "Known face" cpp-known-face))
- (cpp-edit-reset))
-
-(defun cpp-edit-unknown ()
- "Select default for unknown conditionals."
- (interactive)
- (setq cpp-unknown-face (cpp-choose-face "Unknown face" cpp-unknown-face))
- (cpp-edit-reset))
-
-(defun cpp-edit-toggle-known (arg)
- "Toggle writable status for known conditionals.
-With optional argument ARG, make them writable iff ARG is positive."
- (interactive "@P")
- (if (or (and (null arg) cpp-known-writable)
- (<= (prefix-numeric-value arg) 0))
- (setq cpp-known-writable nil)
- (setq cpp-known-writable t))
- (cpp-edit-reset))
-
-(defun cpp-edit-toggle-unknown (arg)
- "Toggle writable status for unknown conditionals.
-With optional argument ARG, make them writable iff ARG is positive."
- (interactive "@P")
- (if (or (and (null arg) cpp-unknown-writable)
- (<= (prefix-numeric-value arg) 0))
- (setq cpp-unknown-writable nil)
- (setq cpp-unknown-writable t))
- (cpp-edit-reset))
-
-(defun cpp-edit-true (symbol face)
- "Select SYMBOL's true FACE used for highlighting taken conditionals."
- (interactive
- (let ((symbol (cpp-choose-symbol)))
- (list symbol
- (cpp-choose-face "True face"
- (nth 1 (assoc symbol cpp-edit-list))))))
- (setcar (nthcdr 1 (cpp-edit-list-entry-get-or-create symbol)) face)
- (cpp-edit-reset))
-
-(defun cpp-edit-false (symbol face)
- "Select SYMBOL's false FACE used for highlighting untaken conditionals."
- (interactive
- (let ((symbol (cpp-choose-symbol)))
- (list symbol
- (cpp-choose-face "False face"
- (nth 2 (assoc symbol cpp-edit-list))))))
- (setcar (nthcdr 2 (cpp-edit-list-entry-get-or-create symbol)) face)
- (cpp-edit-reset))
-
-(defun cpp-edit-write (symbol branch)
- "Set which branches of SYMBOL should be writable to BRANCH.
-BRANCH should be either nil (false branch), t (true branch) or 'both."
- (interactive (list (cpp-choose-symbol) (cpp-choose-branch)))
- (setcar (nthcdr 3 (cpp-edit-list-entry-get-or-create symbol)) branch)
- (cpp-edit-reset))
-
-(defun cpp-edit-list-entry-get-or-create (symbol)
- ;; Return the entry for SYMBOL in `cpp-edit-list'.
- ;; If it does not exist, create it.
- (let ((entry (assoc symbol cpp-edit-list)))
- (or entry
- (setq entry (list symbol nil nil 'both nil)
- cpp-edit-list (cons entry cpp-edit-list)))
- entry))
-
-;;; Prompts:
-
-(defun cpp-choose-symbol ()
- ;; Choose a symbol if called from keyboard, otherwise use the one clicked on.
- (if cpp-button-event
- cpp-callback-data
- (completing-read "Symbol: " (mapcar 'list cpp-edit-symbols) nil t)))
-
-(defun cpp-choose-branch ()
- ;; Choose a branch, either nil, t, or both.
- (if cpp-button-event
- (x-popup-menu cpp-button-event
- (list "Branch" (cons "Branch" cpp-branch-list)))
- (cdr (assoc (completing-read "Branch: " cpp-branch-list nil t)
- cpp-branch-list))))
-
-(defun cpp-choose-face (prompt default)
- ;; Choose a face from cpp-face-defalt-list.
- ;; PROMPT is what to say to the user.
- ;; DEFAULT is the default face.
- (or (if cpp-button-event
- (x-popup-menu cpp-button-event
- (list prompt (cons prompt cpp-face-default-list)))
- (let ((name (car (rassq default cpp-face-default-list))))
- (cdr (assoc (completing-read (if name
- (concat prompt
- " (default " name "): ")
- (concat prompt ": "))
- cpp-face-default-list nil t)
- cpp-face-all-list))))
- default))
-
-(defun cpp-choose-default-face (type)
- ;; Choose default face list for screen of TYPE.
- ;; Type must be one of the types defined in `cpp-face-type-list'.
- (interactive (list (if cpp-button-event
- (x-popup-menu cpp-button-event
- (list "Screen type"
- (cons "Screen type"
- cpp-face-type-list)))
- (cdr (assoc (completing-read "Screen type: "
- cpp-face-type-list
- nil t)
- cpp-face-type-list)))))
- (cond ((null type))
- ((eq type 'light)
- (if cpp-face-light-list
- ()
- (setq cpp-face-light-list
- (mapcar 'cpp-create-bg-face cpp-face-light-name-list))
- (setq cpp-face-all-list
- (append cpp-face-all-list cpp-face-light-list)))
- (setq cpp-face-type 'light)
- (setq cpp-face-default-list
- (append cpp-face-light-list cpp-face-none-list)))
- ((eq type 'dark)
- (if cpp-face-dark-list
- ()
- (setq cpp-face-dark-list
- (mapcar 'cpp-create-bg-face cpp-face-dark-name-list))
- (setq cpp-face-all-list
- (append cpp-face-all-list cpp-face-dark-list)))
- (setq cpp-face-type 'dark)
- (setq cpp-face-default-list
- (append cpp-face-dark-list cpp-face-none-list)))
- ((eq type 'mono)
- (setq cpp-face-type 'mono)
- (setq cpp-face-default-list
- (append cpp-face-mono-list cpp-face-none-list)))
- (t
- (setq cpp-face-type 'none)
- (setq cpp-face-default-list cpp-face-none-list))))
-
-;;; Buttons:
-
-(defun cpp-make-button (name callback &optional data face padding)
- ;; Create a button at point.
- ;; NAME is the name of the button.
- ;; CALLBACK is the function to call when the button is pushed.
- ;; DATA will be made available to CALLBACK
- ;;in the free variable cpp-callback-data.
- ;; FACE means that NAME is the name of a face in `cpp-face-all-list'.
- ;; PADDING means NAME will be right justified at that length.
- (let ((name (format "%s" name))
- from to)
- (cond ((null padding)
- (setq from (point))
- (insert name))
- ((> (length name) padding)
- (setq from (point))
- (insert (substring name 0 padding)))
- (t
- (insert (make-string (- padding (length name)) ? ))
- (setq from (point))
- (insert name)))
- (setq to (point))
- (setq face
- (if face
- (let ((check (cdr (assoc name cpp-face-all-list))))
- (if (memq check '(default invisible))
- 'bold
- check))
- 'bold))
- (add-text-properties from to
- (append (list 'face face)
- '(mouse-face highlight)
- (list 'cpp-callback callback)
- (if data (list 'cpp-data data))))))
-
-(defun cpp-push-button (event)
- ;; Pushed a CPP button.
- (interactive "@e")
- (set-buffer (window-buffer (posn-window (event-start event))))
- (let ((pos (posn-point (event-start event))))
- (let ((cpp-callback-data (get-text-property pos 'cpp-data))
- (fun (get-text-property pos 'cpp-callback))
- (cpp-button-event event))
- (cond (fun
- (call-interactively (get-text-property pos 'cpp-callback)))
- ((lookup-key global-map [ down-mouse-2])
- (call-interactively (lookup-key global-map [ down-mouse-2])))))))
-
-;;; Faces:
-
-(defun cpp-create-bg-face (color)
- ;; Create entry for face with background COLOR.
- (let ((name (intern (concat "cpp " color))))
- (make-face name)
- (set-face-background name color)
- (cons color name)))
-
-(cpp-choose-default-face (if window-system cpp-face-type 'none))
-
-(defun cpp-face-name (face)
- ;; Return the name of FACE from `cpp-face-all-list'.
- (let ((entry (rassq (if face face 'default) cpp-face-all-list)))
- (if entry
- (car entry)
- (format "<%s>" face))))
-
-;;; Utilities:
-
-(defvar cpp-progress-time 0)
-;; Last time we issued a progress message.
-
-(defun cpp-progress-message (&rest args)
- ;; Report progress at most once a second. Take same ARGS as `message'.
- (let ((time (nth 1 (current-time))))
- (if (= time cpp-progress-time)
- ()
- (setq cpp-progress-time time)
- (apply 'message args))))
-
-(provide 'cpp)
-
-;;; cpp.el ends here
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
deleted file mode 100644
index 80d56df9329..00000000000
--- a/lisp/progmodes/etags.el
+++ /dev/null
@@ -1,1606 +0,0 @@
-;;; etags.el --- etags facility for Emacs
-
-;; Copyright (C) 1985, 1986, 1988, 1989, 1992, 1993, 1994, 1995
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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
- "*Control whether to add a new tags table to the current list.
-t means do; nil means don't (always start a new list).
-Any other value means ask the user whether to add a new tags table
-to the current list (as opposed to starting a new list).")
-
-(defvar tags-table-computed-list nil
- "List of tags tables to search, computed from `tags-table-list'.
-This includes tables implicitly included by other tables. The list is not
-always complete: the included tables of a table are not known until that
-table is read into core. An element that is `t' is a placeholder
-indicating that the preceding element is a table that has not been read
-into core and might contain included tables to search.
-See `tags-table-check-computed-list'.")
-
-(defvar tags-table-computed-list-for nil
- "Value of `tags-table-list' that `tags-table-computed-list' corresponds to.
-If `tags-table-list' changes, `tags-table-computed-list' is thrown away and
-recomputed; see `tags-table-check-computed-list'.")
-
-(defvar tags-table-list-pointer nil
- "Pointer into `tags-table-computed-list' for the current state of searching.
-Use `visit-tags-table-buffer' to cycle through tags tables in this list.")
-
-(defvar tags-table-list-started-at nil
- "Pointer into `tags-table-computed-list', where the current search started.")
-
-(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 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 '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))
- (or (stringp file) (signal 'wrong-type-argument (list 'stringp file)))
- ;; Bind tags-file-name so we can control below whether the local or
- ;; global value gets set. Calling visit-tags-table-buffer will
- ;; initialize a buffer for the file and set tags-file-name to the
- ;; 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 file)
- (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)))
-
-(defun tags-table-check-computed-list ()
- "Compute `tags-table-computed-list' from `tags-table-list' if necessary."
- (let ((expanded-list (mapcar 'tags-expand-table-name tags-table-list)))
- (or (equal tags-table-computed-list-for expanded-list)
- ;; The list (or default-directory) has changed since last computed.
- (let* ((compute-for (mapcar 'copy-sequence expanded-list))
- (tables (copy-sequence compute-for)) ;Mutated in the loop.
- (computed nil)
- table-buffer)
-
- (while tables
- (setq computed (cons (car tables) computed)
- table-buffer (get-file-buffer (car tables)))
- (if (and table-buffer
- ;; There is a buffer visiting the file. Now make sure
- ;; it is initialized as a tag table buffer.
- (save-excursion
- (tags-verify-table (buffer-file-name table-buffer))))
- (save-excursion
- (set-buffer table-buffer)
- (if (tags-included-tables)
- ;; Insert the included tables into the list we
- ;; are processing.
- (setcdr tables (nconc (mapcar 'tags-expand-table-name
- (tags-included-tables))
- (cdr tables)))))
- ;; This table is not in core yet. Insert a placeholder
- ;; saying we must read it into core to check for included
- ;; tables before searching the next table in the list.
- (setq computed (cons t computed)))
- (setq tables (cdr tables)))
-
- ;; Record the tags-table-list value (and the context of the
- ;; current directory) we computed from.
- (setq tags-table-computed-list-for compute-for
- tags-table-computed-list (nreverse computed))))))
-
-;; Extend `tags-table-computed-list' to remove the first `t' placeholder.
-;; An element of the list that is `t' is a placeholder indicating that the
-;; preceding element is a table that has not been read into core and might
-;; contain included tables to search. On return, the first placeholder
-;; element will be gone and the element before it read into core and its
-;; included tables inserted into the list.
-(defun tags-table-extend-computed-list ()
- (let ((list tags-table-computed-list))
- (while (not (eq (nth 1 list) t))
- (setq list (cdr list)))
- (save-excursion
- (if (tags-verify-table (car list))
- ;; We are now in the buffer visiting (car LIST). Extract its
- ;; list of included tables and insert it into the computed list.
- (let ((tables (tags-included-tables))
- (computed nil)
- table-buffer)
- (while tables
- (setq computed (cons (car tables) computed)
- table-buffer (get-file-buffer (car tables)))
- (if table-buffer
- (save-excursion
- (set-buffer table-buffer)
- (if (tags-included-tables)
- ;; Insert the included tables into the list we
- ;; are processing.
- (setcdr tables (append (tags-included-tables)
- tables))))
- ;; This table is not in core yet. Insert a placeholder
- ;; saying we must read it into core to check for included
- ;; tables before searching the next table in the list.
- (setq computed (cons t computed)))
- (setq tables (cdr tables)))
- (setq computed (nreverse computed))
- ;; COMPUTED now contains the list of included tables (and
- ;; tables included by them, etc.). Now splice this into the
- ;; current list.
- (setcdr list (nconc computed (cdr (cdr list)))))
- ;; It was not a valid table, so just remove the following placeholder.
- (setcdr list (cdr (cdr list)))))))
-
-;; 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))
-
-;; Like member, but comparison is done after tags-expand-table-name on both
-;; sides and elements of LIST that are t are skipped.
-(defun tags-table-list-member (file list)
- (setq file (tags-expand-table-name file))
- (while (and list
- (or (eq (car list) t)
- (not (string= file (tags-expand-table-name (car list))))))
- (setq list (cdr list)))
- list)
-
-(defun tags-verify-table (file)
- "Read FILE into a buffer and verify that it is a valid tags table.
-Sets the current buffer to one visiting FILE (if it exists).
-Returns non-nil iff it is a valid table."
- (if (get-file-buffer file)
- ;; 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 file))
- (setq win (or verify-tags-table-function (initialize-new-tags-table)))
- (if (or (verify-visited-file-modtime (current-buffer))
- (not (yes-or-no-p
- (format "Tags file %s has changed, read new contents? "
- file))))
- (and win (funcall verify-tags-table-function))
- (revert-buffer t t)
- (initialize-new-tags-table)))
- (and (file-exists-p file)
- (progn
- (set-buffer (find-file-noselect file))
- (or (string= file 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 file tags-table-list)))
- (if tail
- (setcar tail buffer-file-name))
- (if (eq file tags-file-name)
- (setq tags-file-name buffer-file-name))))
- (initialize-new-tags-table)))))
-
-;; Subroutine of visit-tags-table-buffer. Search the current tags tables
-;; for one that has tags for THIS-FILE (or that includes a table that
-;; does). Return the name of the first table table listing THIS-FILE; if
-;; the table is one included by another table, it is the master table that
-;; we return. 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 core-only)
- (let ((tables tags-table-computed-list)
- (found nil))
- ;; Loop over the list, looking for a table containing tags for THIS-FILE.
- (while (and (not found)
- tables)
-
- (if core-only
- ;; Skip tables not in core.
- (while (eq (nth 1 tables) t)
- (setq tables (cdr (cdr tables))))
- (if (eq (nth 1 tables) t)
- ;; This table has not been read into core yet. Read it in now.
- (tags-table-extend-computed-list)))
-
- (if tables
- ;; Select the tags table buffer and get the file list up to date.
- (let ((tags-file-name (car tables)))
- (visit-tags-table-buffer 'same)
- (if (member this-file (mapcar 'expand-file-name
- (tags-table-files)))
- ;; Found it.
- (setq found tables))))
- (setq tables (cdr tables)))
- (if found
- ;; Now determine if the table we found was one included by another
- ;; table, not explicitly listed. We do this by checking each
- ;; element of the computed list to see if it appears in the user's
- ;; explicit list; the last element we will check is FOUND itself.
- ;; Then we return the last one which did in fact appear in
- ;; tags-table-list.
- (let ((could-be nil)
- (elt tags-table-computed-list))
- (while (not (eq elt (cdr found)))
- (if (tags-table-list-member (car elt) tags-table-list)
- ;; This table appears in the user's list, so it could be
- ;; the one which includes the table we found.
- (setq could-be (car elt)))
- (setq elt (cdr elt))
- (if (eq t (car elt))
- (setq elt (cdr elt))))
- ;; The last element we found in the computed list before FOUND
- ;; that appears in the user's list will be the table that
- ;; included the one we found.
- could-be))))
-
-;; Subroutine of visit-tags-table-buffer. Move tags-table-list-pointer
-;; along and set tags-file-name. Returns nil when out of tables.
-(defun tags-next-table ()
- ;; If there is a placeholder element next, compute the list to replace it.
- (while (eq (nth 1 tags-table-list-pointer) t)
- (tags-table-extend-computed-list))
-
- ;; 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-computed-list))
-
- (if (eq tags-table-list-pointer tags-table-list-started-at)
- ;; We have come full circle. No more tables.
- (setq tags-table-list-pointer nil)
- ;; Set tags-file-name to the name from the list. It is already expanded.
- (setq tags-file-name (car tags-table-list-pointer))))
-
-(defun visit-tags-table-buffer (&optional cont)
- "Select the buffer containing the current tags table.
-If optional arg is a string, visit that file as a 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.
- (cond ((eq cont 'same)
- ;; Use the ambient value of tags-file-name.
- (or tags-file-name
- (error "%s"
- (substitute-command-keys
- (concat "No tags table in use! "
- "Use \\[visit-tags-table] to select one.")))))
-
- ((eq t cont)
- ;; Find the next table.
- (if (tags-next-table)
- ;; Skip over nonexistent files.
- (while (and (not (or (get-file-buffer tags-file-name)
- (file-exists-p tags-file-name)))
- (tags-next-table)))))
-
- (t
- ;; Pick a table out of our hat.
- (tags-table-check-computed-list) ;Get it up to date, we might use it.
- (setq tags-file-name
- (or
- ;; If passed a string, use that.
- (if (stringp cont)
- (prog1 cont
- (setq cont nil)))
- ;; 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 CONT will be set non-nil so we don't
- ;; do it below.
- (and buffer-file-name
- (or
- ;; First check only tables already in buffers.
- (tags-table-including buffer-file-name t)
- ;; Since that didn't find any, now do the
- ;; expensive version: reading new files.
- (tags-table-including buffer-file-name nil)))
- ;; Fourth, use the user variable tags-file-name, if it is
- ;; not already in the current list.
- (and tags-file-name
- (not (tags-table-list-member tags-file-name
- tags-table-computed-list))
- 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 cont t)
- (null tags-table-list-pointer))
- ;; All out of tables.
- nil
-
- ;; Verify that tags-file-name names a valid tags table.
- ;; Bind another variable with the value of tags-file-name
- ;; before we switch buffers, in case tags-file-name is buffer-local.
- (let ((curbuf (current-buffer))
- (local-tags-file-name tags-file-name))
- (if (tags-verify-table local-tags-file-name)
-
- ;; 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 this was a new table selection (CONT is nil), make
- ;; sure tags-table-list includes the chosen table, and
- ;; update the list pointer variables.
- (or cont
- ;; Look in the list for the table we chose.
- (let ((found (tags-table-list-member
- local-tags-file-name
- tags-table-computed-list)))
- (if found
- ;; There it is. Just switch to it.
- (setq tags-table-list-pointer found
- tags-table-list-started-at found)
-
- ;; 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 (tags-table-list-member
- local-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 local-tags-file-name
- tags-table-list))
-
- ;; Make a fresh list, and store the old one.
- (message "Starting a new list of tags tables")
- (or (null tags-table-list)
- (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 local-tags-file-name))))
-
- ;; Recompute tags-table-computed-list.
- (tags-table-check-computed-list)
- ;; Set the tags table list state variables to start
- ;; over from tags-table-computed-list.
- (setq tags-table-list-started-at tags-table-computed-list
- tags-table-list-pointer
- tags-table-computed-list)))))
-
- ;; Return of t says the tags table is valid.
- t)
-
- ;; The buffer was not valid. Don't use it again.
- (set-buffer curbuf)
- (kill-local-variable 'tags-file-name)
- (if (eq local-tags-file-name tags-file-name)
- (setq tags-file-name nil))
- (error "File %s is not a valid tags table" local-tags-file-name)))))
-
-(defun tags-reset-tags-tables ()
- "Reset tags state to cancel effect of any previous \\[visit-tags-table]
-or \\[find-tag]."
- (interactive)
- (setq tags-file-name nil
- tags-location-stack nil
- tags-table-list nil
- tags-table-computed-list nil
- tags-table-computed-list-for nil
- tags-table-list-pointer nil
- tags-table-list-started-at nil
- tags-table-set-list nil))
-
-(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. The file names are returned
-as they appeared in the `etags' command that created the table, usually
-without directory names."
- (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)))))
-
-(defvar find-tag-history nil)
-
-;;;###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: "))
-
- (setq find-tag-history (cons tagname find-tag-history))
- ;; 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))
- ;; Record the location so we can pop back to it later.
- (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))
- (run-hooks 'local-find-tag-hook)
- (setq tags-location-stack
- (cons marker tags-location-stack))
- (current-buffer))))))
-
-;;;###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))
-;;;###autoload (define-key esc-map [?\C-.] 'find-tag-regexp)
-
-;; 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.
-
-(defvar tag-lines-already-matched nil) ;matches remembered here between calls
-
-(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
- (first-table t)
- (tag-order order)
- (match-marker (make-marker))
- goto-func
- )
- (save-excursion
-
- (if first-search
- ;; This is the start of a search for a fresh tag.
- ;; Clear the list of tags matched by the previous search.
- ;; find-tag-noselect has already put us in the first tags table
- ;; buffer before we got called.
- (setq tag-lines-already-matched nil)
- ;; Continuing to search for the tag specified last time.
- ;; tag-lines-already-matched lists locations matched in previous
- ;; calls so we don't visit the same tag twice if it matches twice
- ;; during two passes with different qualification predicates.
- ;; Switch to the current tags table buffer.
- (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))
-
- (and first-search first-table
- ;; Start at beginning of tags file.
- (goto-char (point-min)))
-
- (setq first-table nil)
-
- ;; 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.
- (not (member (set-marker match-marker (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.
- ;; Clear out the markers we use to avoid duplicate matches so they
- ;; don't slow down editting and are immediately available for GC.
- (while tag-lines-already-matched
- (set-marker (car tag-lines-already-matched) nil nil)
- (setq tag-lines-already-matched (cdr tag-lines-already-matched)))
- (set-marker match-marker nil nil)
- (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 match-marker
- 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)
-
- ;; 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-file-name-match-p
- tag-exact-match-p
- tag-symbol-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
- (re-search-backward "\f\n\\([^\n]+\\),[0-9]*\n")
- (expand-file-name (buffer-substring (match-beginning 1) (match-end 1))
- (file-truename default-directory))))
-
-
-(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
- "^\\(\\([^\177]+[^-a-zA-Z0-9_$\177]+\\)?\\([-a-zA-Z0-9_$?:]+\\)\
-\[^-a-zA-Z0-9_$?:\177]*\\)\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)
- (if (save-excursion
- (forward-line -1)
- (looking-at "\f\n"))
- ;; The match was for a source file name, not any tag within a file.
- ;; Give text of t, meaning to go exactly to the location we specify,
- ;; the beginning of the file.
- (setq tag-text t
- line nil
- startpos 1)
-
- ;; Find the end of the tag and record the whole tag text.
- (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. If
-;; TEXT is t, it means the tag refers to exactly LINE or POSITION
-;; (whichever is present, LINE having preference, no searching. 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)))
- (line (car (cdr tag-info)))
- offset found pat)
- (if (eq (car tag-info) t)
- ;; Direct file tag.
- (cond (line (goto-line line))
- (startpos (goto-char startpos))
- (t (error "etags.el BUG: bogus direct file tag")))
- ;; 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.
- (setq offset 1000
- found nil
- pat (concat (if (eq selective-display t)
- "\\(^\\|\^m\\)" "^")
- (regexp-quote (car tag-info))))
- ;; The character position in the tags table is 0-origin.
- ;; Convert it to a 1-origin Emacs character position.
- (if startpos (setq startpos (1+ startpos)))
- ;; If no char pos was given, try the given line number.
- (or startpos
- (if line
- (setq startpos (progn (goto-line line)
- (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 (1+ (point)) ;skip \177
- (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))
- (end-of-line)
- (skip-chars-backward "^," beg)
- (or (looking-at "include$")
- (setq files (cons (buffer-substring beg (1- (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))
- (end-of-line)
- (skip-chars-backward "^," beg)
- (if (looking-at "include$")
- ;; Expand in the default-directory of the tags table buffer.
- (setq files (cons (expand-file-name (buffer-substring beg (1- (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 (and (eq (char-after (point)) ?\001)
- (eq (char-after (- (point) (length tag) 1)) ?\177))
- ;; We are not on the explicit tag name, but perhaps it follows.
- (looking-at (concat "[^\177\n]*\177" (regexp-quote tag) "\001"))))
-
-;; t if point is at a tag line that matches TAG as a symbol.
-;; point should be just after a string that matches TAG.
-(defun tag-symbol-match-p (tag)
- (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 (length tag))
- (looking-at "\\b"))))
-
-(defun tag-exact-file-name-match-p (tag)
- (and (looking-at ",")
- (save-excursion (backward-char (length tag))
- (looking-at "\f\n"))))
-
-;; 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."
- ;; Make the interactive arg t if there was any prefix arg.
- (interactive (list (if current-prefix-arg t)))
- (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)
- ;; Copy the list so we can setcdr below, and expand the file
- ;; names while we are at it, in this buffer's default directory.
- (setq next-file-list (mapcar 'expand-file-name (tags-table-files)))
- ;; Iterate over all the tags table files, collecting
- ;; a complete list of referenced file names.
- (while (visit-tags-table-buffer t)
- ;; Find the tail of the working list and chain on the new
- ;; sublist for this tags table.
- (let ((tail next-file-list))
- (while (cdr tail)
- (setq tail (cdr tail)))
- ;; Use a copy so the next loop iteration will not modify the
- ;; list later returned by (tags-table-files).
- (if tail
- (setcdr tail (mapcar 'expand-file-name (tags-table-files)))
- (setq next-file-list (mapcar 'expand-file-name
- (tags-table-files))))))))
- (t
- ;; Initialize the list by evalling the argument.
- (setq next-file-list (eval initialize))))
- (if next-file-list
- ()
- (and novisit
- (get-buffer " *next-file*")
- (kill-buffer " *next-file*"))
- (error "All files processed."))
- (let* ((next (car next-file-list))
- (new (not (get-file-buffer next))))
- ;; Advance the list before trying to find the file.
- ;; If we get an error finding the file, don't get stuck on it.
- (setq next-file-list (cdr next-file-list))
- (if (not (and new novisit))
- (set-buffer (find-file-noselect next novisit))
- ;; Like find-file, but avoids random warning messages.
- (set-buffer (get-buffer-create " *next-file*"))
- (kill-all-local-variables)
- (erase-buffer)
- (setq new next)
- (insert-file-contents new nil))
- new))
-
-(defvar tags-loop-operate nil
- "Form for `tags-loop-continue' to eval to change one file.")
-
-(defvar tags-loop-scan
- '(error "%s"
- (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
-evaluate to operate on an interesting file. If the latter evaluates to
-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))
- (setq new nil) ;No longer in a temp buffer.
- (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 (list 'quote 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 (query-replace-read-args "Tags query replace (regexp)" t))
- (setq tags-loop-scan (list 'prog1
- (list 'if (list 're-search-forward
- (list 'quote 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
- (list 'quote from) (list 'quote to)
- t t (list 'quote delimited)))
- (tags-loop-continue (or file-list-form t)))
-
-(defun tags-complete-tags-table-file (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 (mapcar 'list (tags-table-files))
- predicate)
- (try-completion string (mapcar 'list (tags-table-files))
- predicate))))
-
-;;;###autoload
-(defun list-tags (file &optional next-match)
- "Display list of tags in file FILE.
-This searches only the first table in the list, and no included tables.
-FILE should be as it appeared in the `etags' command, usually without a
-directory specification."
- (interactive (list (completing-read "List tags in file: "
- 'tags-complete-tags-table-file
- 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-set-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)
- (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 (copy-sequence 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)
- (select-tags-table-mode))
-
-(defvar select-tags-table-mode-map)
-(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)
- (setq select-tags-table-mode-map map))
-
-(defun select-tags-table-mode ()
- "Major mode for choosing a current tags table among those already loaded.
-
-\\{select-tags-table-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (setq buffer-read-only t
- major-mode 'select-tags-table-mode
- mode-name "Select Tags Table")
- (use-local-map select-tags-table-mode-map)
- (setq selective-display t
- selective-display-ellipses nil))
-
-(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)))
-
-;;; Note, there is another definition of this function in bindings.el.
-;;;###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 "%s"
- (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/executable.el b/lisp/progmodes/executable.el
deleted file mode 100644
index 62d6f59fbbb..00000000000
--- a/lisp/progmodes/executable.el
+++ /dev/null
@@ -1,235 +0,0 @@
-;;; executable.el --- base functionality for executable interpreter scripts
-
-;; Copyright (C) 1994, 1995, 1996 by Free Software Foundation, Inc.
-
-;; Author: Daniel.Pfeiffer@Informatik.START.dbp.de, fax (+49 69) 7588-2389
-;; Keywords: languages, unix
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; executable.el is used by certain major modes to insert a suitable
-;; #! line at the beginning of the file, if the file does not already
-;; have one.
-
-;; Unless it has a magic number, a Unix file with executable mode is passed to
-;; a new instance of the running shell (or to a Bourne shell if a csh is
-;; running and the file starts with `:'). Only a shell can start such a file,
-;; exec() cannot, which is why it is important to have a magic number in every
-;; executable script. Such a magic number is made up by the characters `#!'
-;; the filename of an interpreter (in COFF, ELF or somesuch format) and one
-;; optional argument.
-
-;; This library is for certain major modes like sh-, awk-, perl-, tcl- or
-;; makefile-mode to insert or update a suitable #! line at the beginning of
-;; the file, if the file does not already have one and the file is not a
-;; default file of that interpreter (like .profile or makefile). It also
-;; makes the file executable if it wasn't, as soon as it's saved.
-
-;; It also allows debugging scripts, with an adaptation of compile, as far
-;; as interpreters give out meaningful error messages.
-
-;; Modes that use this should nconc `executable-map' to the end of their own
-;; keymap and `executable-font-lock-keywords' to the end of their own font
-;; lock keywords. Their mode-setting commands should call
-;; `executable-set-magic'.
-
-;;; Code:
-
-(defvar executable-insert t
- "*Non-nil means offer to add a magic number to a file.
-This takes effect when you switch to certain major modes,
-including Shell-script mode (`sh-mode').
-When you type \\[executable-set-magic], it always offers to add or
-update the magic number.")
-
-(defvar executable-query 'function
- "*If non-nil, ask user before changing an existing magic number.
-When this is `function', only ask when called non-interactively.")
-
-
-(defvar executable-magicless-file-regexp "/[Mm]akefile$\\|/\\.\\(z?profile\\|bash_profile\\|z?login\\|bash_login\\|z?logout\\|bash_logout\\|.+shrc\\|esrc\\|rcrc\\|[kz]shenv\\)$"
- "*On files with this kind of name no magic is inserted or changed.")
-
-
-(defvar executable-prefix "#! "
- "*Interpreter magic number prefix inserted when there was no magic number.")
-
-
-
-(defvar executable-chmod 73
- "*After saving, if the file is not executable, set this mode.
-This mode passed to `set-file-modes' is taken absolutely when negative, or
-relative to the files existing modes. Do nothing if this is nil.
-Typical values are 73 (+x) or -493 (rwxr-xr-x).")
-
-
-(defvar executable-command nil)
-
-(defvar executable-self-display "tail"
- "*Command you use with argument `+2' to make text files self-display.
-Note that the like of `more' doesn't work too well under Emacs \\[shell].")
-
-
-(defvar executable-font-lock-keywords
- '(("\\`#!.*/\\([^ \t\n]+\\)" 1 font-lock-keyword-face t))
- "*Rules for highlighting executable scripts' magic number.
-This can be included in `font-lock-keywords' by modes that call `executable'.")
-
-
-(defvar executable-error-regexp-alist
- '(;; /bin/xyz: syntax error at line 14: `(' unexpected
- ;; /bin/xyz[5]: syntax error at line 8 : ``' unmatched
- ("^\\(.*[^[/]\\)\\(\\[[0-9]+\\]\\)?: .* error .* line \\([0-9]+\\)" 1 3)
- ;; /bin/xyz[27]: ehco: not found
- ("^\\(.*[^/]\\)\\[\\([0-9]+\\)\\]: .*: " 1 2)
- ;; /bin/xyz: syntax error near unexpected token `)'
- ;; /bin/xyz: /bin/xyz: line 2: `)'
- ("^\\(.*[^/]\\): [^0-9\n]+\n\\1: \\1: line \\([0-9]+\\):" 1 2)
- ;; /usr/bin/awk: syntax error at line 5 of file /bin/xyz
- (" error .* line \\([0-9]+\\) of file \\(.+\\)$" 2 1)
- ;; /usr/bin/awk: calling undefined function toto
- ;; input record number 3, file awktestdata
- ;; source line 4 of file /bin/xyz
- ("^[^ ].+\n\\( .+\n\\)* line \\([0-9]+\\) of file \\(.+\\)$" 3 2)
- ;; makefile:1: *** target pattern contains no `%'. Stop.
- ("^\\(.+\\):\\([0-9]+\\): " 1 2))
- "Alist of regexps used to match script errors.
-See `compilation-error-regexp-alist'.")
-
-;; The C function openp slightly modified would do the trick fine
-(defun executable-find (command)
- "Search for COMMAND in exec-path and return the absolute file name.
-Return nil if COMMAND is not found anywhere in `exec-path'."
- (let ((list exec-path)
- file)
- (while list
- (setq list (if (and (setq file (expand-file-name command (car list)))
- (file-executable-p file)
- (not (file-directory-p file)))
- nil
- (setq file nil)
- (cdr list))))
- file))
-
-
-(defun executable-chmod ()
- "This gets called after saving a file to assure that it be executable.
-You can set the absolute or relative mode in variable `executable-chmod' for
-non-executable files."
- (and executable-chmod
- buffer-file-name
- (or (file-executable-p buffer-file-name)
- (set-file-modes buffer-file-name
- (if (< executable-chmod 0)
- (- executable-chmod)
- (logior executable-chmod
- (file-modes buffer-file-name)))))))
-
-
-(defun executable-interpret (command)
- "Run script with user-specified args, and collect output in a buffer.
-While script runs asynchronously, you can use the \\[next-error] command
-to find the next error."
- (interactive (list (read-string "Run script: "
- (or executable-command
- buffer-file-name))))
- (require 'compile)
- (save-some-buffers (not compilation-ask-about-save))
- (make-local-variable 'executable-command)
- (compile-internal (setq executable-command command)
- "No more errors." "Interpretation"
- ;; Give it a simpler regexp to match.
- nil executable-error-regexp-alist))
-
-
-
-;;;###autoload
-(defun executable-set-magic (interpreter &optional argument
- no-query-flag insert-flag)
- "Set this buffer's interpreter to INTERPRETER with optional ARGUMENT.
-The variables `executable-magicless-file-regexp', `executable-prefix',
-`executable-insert', `executable-query' and `executable-chmod' control
-when and how magic numbers are inserted or replaced and scripts made
-executable."
- (interactive
- (let* ((name (read-string "Name or file name of interpreter: "))
- (arg (read-string (format "Argument for %s: " name))))
- (list name arg (eq executable-query 'function) t)))
- (setq interpreter (if (file-name-absolute-p interpreter)
- interpreter
- (or (executable-find interpreter)
- (error "Interpreter %s not recognized" interpreter)))
- argument (concat interpreter
- (and argument (string< "" argument) " ")
- argument))
- (or buffer-read-only
- (if buffer-file-name
- (string-match executable-magicless-file-regexp
- buffer-file-name))
- (not (or insert-flag executable-insert))
- (> (point-min) 1)
- (save-excursion
- (let ((point (point-marker))
- (buffer-modified-p (buffer-modified-p)))
- (goto-char (point-min))
- (make-local-hook 'after-save-hook)
- (add-hook 'after-save-hook 'executable-chmod nil t)
- (if (looking-at "#![ \t]*\\(.*\\)$")
- (and (goto-char (match-beginning 1))
- ;; If the line ends in a space,
- ;; don't offer to change it.
- (not (= (char-after (1- (match-end 1))) ?\ ))
- (not (string= argument
- (buffer-substring (point) (match-end 1))))
- (if (or (not executable-query) no-query-flag
- (save-window-excursion
- ;; Make buffer visible before question.
- (switch-to-buffer (current-buffer))
- (y-or-n-p (concat "Replace magic number by `"
- executable-prefix argument "'? "))))
- (progn
- (replace-match argument t t nil 1)
- (message "Magic number changed to `%s'"
- (concat executable-prefix argument)))))
- (insert executable-prefix argument ?\n)
- (message "Magic number changed to `%s'"
- (concat executable-prefix argument)))
-;;; (or insert-flag
-;;; (eq executable-insert t)
-;;; (set-buffer-modified-p buffer-modified-p))
- )))
- interpreter)
-
-
-
-;;;###autoload
-(defun executable-self-display ()
- "Turn a text file into a self-displaying Un*x command.
-The magic number of such a command displays all lines but itself."
- (interactive)
- (if (eq this-command 'executable-self-display)
- (setq this-command 'executable-set-magic))
- (executable-set-magic executable-self-display "+2"))
-
-
-
-(provide 'executable)
-
-;; executable.el ends here
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
deleted file mode 100644
index ada277ffc05..00000000000
--- a/lisp/progmodes/f90.el
+++ /dev/null
@@ -1,1697 +0,0 @@
-;;; f90.el --- Fortran-90 mode (free format)
-
-;; Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-;; Author: Torbj\"orn Einarsson <T.Einarsson@clab.ericsson.se>
-;; Last Change: Oct. 14, 1996
-;; Keywords: fortran, f90, 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Smart mode for editing F90 programs in FREE FORMAT.
-;; Knows about continuation lines, named structured statements, and other
-;; new features in F90 including HPF (High Performance Fortran) structures.
-;; The basic feature is to provide an accurate indentation of F90 programs.
-;; In addition, there are many more features like automatic matching of all
-;; end statements, an auto-fill function to break long lines, a join-lines
-;; function which joins continued lines etc etc.
-;; To facilitate typing, a fairly complete list of abbreviations is provided.
-;; For example, `i is short-hand for integer (if abbrev-mode is on).
-
-;; There are two separate features for highlighting the code.
-;; 1) Upcasing or capitalizing of all keywords.
-;; 2) Colors/fonts using font-lock-mode. (only when using X-windows)
-;; Automatic upcase of downcase of keywords is controlled by the parameter
-;; f90-auto-keyword-case.
-
-;; The indentations of lines starting with ! is determined by the first of the
-;; following matches (the values in the left column are the default values):
-
-;; start-string/regexp indent variable holding start-string/regexp
-;; !!! 0
-;; !hpf\\$ (re) 0 f90-directive-comment-re
-;; !!$ 0 f90-comment-region
-;; ! (re) as code f90-indented-comment-re
-;; default comment-column
-
-;; Ex: Here is the result of 3 different settings of f90-indented-comment-re
-;; f90-indented-comment-re !-indentation !!-indentation
-;; ! as code as code
-;; !! comment-column as code
-;; ![^!] as code comment-column
-;; Trailing comments are indented to comment-column with indent-for-comment M-;
-;; f90-comment-region (C-c;) toggles insertion of f90-comment-region in region.
-
-;; One common convention for free vs. fixed format is that free-format files
-;; have the ending .f90 while the fixed format files have the ending .f.
-;; To make f90-mode work, put this file in, for example, your directory
-;; ~/lisp, and be sure that you have the following in your .emacs-file
-;; (setq load-path (append load-path '("~/lisp")))
-;; (autoload 'f90-mode "f90"
-;; "Major mode for editing Fortran 90 code in free format." t)
-;; (setq auto-mode-alist (append auto-mode-alist
-;; (list '("\\.f90$" . f90-mode))))
-;; Once you have entered f90-mode, you may get more info by using
-;; the command describe-mode (C-h m). For online help describing various
-;; functions use C-h f <Name of function you want described>
-
-;; To customize the f90-mode for your taste, use, for example:
-;; (you don't have to specify values for all the parameters below)
-;;(setq f90-mode-hook
-;; '(lambda () (setq f90-do-indent 3
-;; f90-if-indent 3
-;; f90-type-indent 3
-;; f90-program-indent 2
-;; f90-continuation-indent 5
-;; f90-comment-region "!!$"
-;; f90-directive-comment-re "!hpf\\$"
-;; f90-indented-comment-re "!"
-;; f90-break-delimiters "[-+\\*/,><=% \t]"
-;; f90-break-before-delimiters t
-;; f90-beginning-ampersand t
-;; f90-smart-end 'blink
-;; f90-auto-keyword-case nil
-;; f90-leave-line-no nil
-;; f90-startup-message t
-;; indent-tabs-mode nil
-;; f90-font-lock-keywords f90-font-lock-keywords-2
-;; )
-;; ;;The rest is not default.
-;; (abbrev-mode 1) ; turn on abbreviation mode
-;; (turn-on-font-lock) ; for highlighting
-;; (f90-add-imenu-menu) ; extra menu with functions etc.
-;; (if f90-auto-keyword-case ; change case of all keywords on startup
-;; (f90-change-keywords f90-auto-keyword-case))
-;; ))
-;; in your .emacs file (the shown values are the defaults). You can also
-;; change the values of the lists f90-keywords etc.
-;; The auto-fill and abbreviation minor modes are accessible from the menu,
-;; or by using M-x auto-fill-mode and M-x abbrev-mode, respectively.
-
-;; Remarks
-;; 1) Line numbers are by default left-justified. If f90-leave-line-no is
-;; non-nil, the line numbers are never touched.
-;; 2) Multi-; statements like > do i=1,20 ; j=j+i ; end do < are not handled
-;; correctly, but I imagine them to be rare.
-;; 3) Regexps for hilit19 are no longer supported.
-;; 4) For FIXED FORMAT code, use the ordinary fortran mode.
-;; 5) This mode does not work under emacs-18.x.
-;; 6) Preprocessor directives, i.e., lines starting with # are left-justified
-;; and are untouched by all case-changing commands. There is, at present, no
-;; mechanism for treating multi-line directives (continued by \ ).
-;; 7) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented.
-;; You are urged to use f90-do loops (with labels if you wish).
-;; 8) The highlighting mode under XEmacs is not as complete as under Emacs.
-
-;; List of user commands
-;; f90-previous-statement f90-next-statement
-;; f90-beginning-of-subprogram f90-end-of-subprogram f90-mark-subprogram
-;; f90-comment-region
-;; f90-indent-line f90-indent-new-line
-;; f90-indent-region (can be called by calling indent-region)
-;; f90-indent-subprogram
-;; f90-break-line f90-join-lines
-;; f90-fill-region
-;; f90-insert-end
-;; f90-upcase-keywords f90-upcase-region-keywords
-;; f90-downcase-keywords f90-downcase-region-keywords
-;; f90-capitalize-keywords f90-capitalize-region-keywords
-;; f90-add-imenu-menu
-;; f90-font-lock-1, f90-font-lock-2, f90-font-lock-3, f90-font-lock-4
-
-;; Thanks to all the people who have tested the mode. Special thanks to Jens
-;; Bloch Helmers for encouraging me to write this code, for creative
-;; suggestions as well as for the lists of hpf-commands.
-;; Also thanks to the authors of the fortran and pascal modes, on which some
-;; of this code is built.
-
-;;; Code:
-
-(defconst bug-f90-mode "T.Einarsson@clab.ericsson.se"
- "Address of mailing list for F90 mode bugs.")
-
-;; User options
-(defvar f90-do-indent 3
- "*Extra indentation applied to DO blocks.")
-
-(defvar f90-if-indent 3
- "*Extra indentation applied to IF, SELECT CASE, WHERE and FORALL blocks.")
-
-(defvar f90-type-indent 3
- "*Extra indentation applied to TYPE, INTERFACE and BLOCK DATA blocks.")
-
-(defvar f90-program-indent 2
- "*Extra indentation applied to PROGRAM/MODULE/SUBROUTINE/FUNCTION blocks.")
-
-(defvar f90-continuation-indent 5
- "*Extra indentation applied to F90 continuation lines.")
-
-(defvar f90-comment-region "!!$"
- "*String inserted by \\[f90-comment-region]\
- at start of each line in region.")
-
-(defvar f90-indented-comment-re "!"
- "*Regexp saying which comments to be indented like code.")
-
-(defvar f90-directive-comment-re "!hpf\\$"
- "*Regexp of comment-like directive like \"!HPF\\\\$\", not to be indented.")
-
-(defvar f90-beginning-ampersand t
- "*t makes automatic insertion of \& at beginning of continuation line.")
-
-(defvar f90-smart-end 'blink
- "*From an END statement, check and fill the end using matching block start.
-Allowed values are 'blink, 'no-blink, and nil, which determine
-whether to blink the matching beginning.")
-
-(defvar f90-break-delimiters "[-+\\*/><=,% \t]"
- "*Regexp holding list of delimiters at which lines may be broken.")
-
-(defvar f90-break-before-delimiters t
- "*Non-nil causes `f90-do-auto-fill' to break lines before delimiters.")
-
-(defvar f90-auto-keyword-case nil
- "*Automatic case conversion of keywords.
- The options are 'downcase-word, 'upcase-word, 'capitalize-word and nil")
-
-(defvar f90-leave-line-no nil
- "*If nil, left-justify linenumbers.")
-
-(defvar f90-startup-message t
- "*Non-nil displays a startup message when F90 mode is first called.")
-
-(defconst f90-keywords-re
- ;;("allocate" "allocatable" "assign" "assignment" "backspace" "block"
- ;;"call" "case" "character" "close" "common" "complex" "contains"
- ;;"continue" "cycle" "data" "deallocate" "dimension" "do" "double" "else"
- ;;"elseif" "elsewhere" "end" "enddo" "endfile" "endif" "entry" "equivalence"
- ;;"exit" "external" "forall" "format" "function" "goto" "if" "implicit"
- ;;"include" "inquire" "integer" "intent" "interface" "intrinsic" "logical"
- ;;"module" "namelist" "none" "nullify" "only" "open" "operator" "optional" "parameter"
- ;;"pause" "pointer" "precision" "print" "private" "procedure" "program"
- ;;"public" "read" "real" "recursive" "result" "return" "rewind" "save" "select"
- ;;"sequence" "stop" "subroutine" "target" "then" "type" "use" "where"
- ;;"while" "write")
- (concat
- "\\<\\(a\\(llocat\\(able\\|e\\)\\|ssign\\(\\|ment\\)\\)\\|b\\(ackspace\\|"
- "lock\\)\\|c\\(a\\(ll\\|se\\)\\|haracter\\|lose\\|o\\(m\\(mon\\|plex\\)\\|"
- "nt\\(ains\\|inue\\)\\)\\|ycle\\)\\|d\\(ata\\|eallocate\\|imension\\|"
- "o\\(\\|uble\\)\\)\\|e\\(lse\\(\\|if\\|where\\)\\|n\\(d\\(\\|do\\|file\\|"
- "if\\)\\|try\\)\\|quivalence\\|x\\(it\\|ternal\\)\\)\\|f\\(or\\(all\\|"
- "mat\\)\\|unction\\)\\|goto\\|i\\(f\\|mplicit\\|n\\(clude\\|quire\\|t\\("
- "e\\(ger\\|nt\\|rface\\)\\|rinsic\\)\\)\\)\\|logical\\|module\\|n\\("
- "amelist\\|one\\|ullify\\)\\|o\\(nly\\|p\\(en\\|erator\\|tional\\)\\)\\|p\\(a\\("
- "rameter\\|use\\)\\|ointer\\|r\\(ecision\\|i\\(nt\\|vate\\)\\|o\\("
- "cedure\\|gram\\)\\)\\|ublic\\)\\|re\\(a[dl]\\|cursive\\|sult\\|turn\\|wind\\)\\|"
- "s\\(ave\\|e\\(lect\\|quence\\)\\|top\\|ubroutine\\)\\|t\\(arget\\|hen\\|"
- "ype\\)\\|use\\|w\\(h\\(ere\\|ile\\)\\|rite\\)\\)\\>")
- "Regexp for F90 keywords.")
-
-(defconst f90-keywords-level-3-re
- ;; ("allocate" "allocatable" "assign" "assignment" "backspace" "close"
- ;; "deallocate" "dimension" "endfile" "entry" "equivalence" "external"
- ;; "inquire" "intent" "intrinsic" "nullify" "only" "open" "operator"
- ;; "optional" "parameter" "pause" "pointer" "print" "private" "public"
- ;; "read" "recursive" "result" "rewind" "save" "select" "sequence"
- ;; "target" "write")
- (concat
- "\\<\\(a\\(llocat\\(able\\|e\\)\\|ssign\\(\\|ment\\)\\)\\|backspace\\|"
- "close\\|d\\(eallocate\\|imension\\)\\|e\\(n\\(dfile\\|try\\)\\|"
- "quivalence\\|xternal\\)\\|"
- "in\\(quire\\|t\\(ent\\|rinsic\\)\\)\\|nullify\\|"
- "o\\(nly\\|p\\(en\\|erator\\|tional\\)\\)\\|"
- "p\\(a\\(rameter\\|use\\)\\|ointer\\|ri\\(nt\\|vate\\)\\|ublic\\)\\|re\\("
- "ad\\|cursive\\|sult\\|wind\\)\\|s\\(ave\\|e\\(lect\\|quence\\)\\)\\|target\\|"
- "write\\)\\>")
-"Keyword-regexp for font-lock level >= 3.")
-
-
-(defconst f90-procedures-re
- ;; ("abs" "achar" "acos" "adjustl" "adjustr" "aimag" "aint" "all" "allocated"
- ;; "anint" "any" "asin" "associated" "atan" "atan2" "bit_size" "btest"
- ;; "ceiling" "char" "cmplx" "conjg" "cos" "cosh" "count" "cshift"
- ;; "date_and_time" "dble" "digits" "dim" "dot_product" "dprod" "eoshift"
- ;; "epsilon" "exp" "exponent" "floor" "fraction" "huge" "iachar" "iand"
- ;; "ibclr" "ibits" "ibset" "ichar" "ieor" "index" "int" "ior" "ishft"
- ;; "ishftc" "kind" "lbound" "len" "len_trim" "lge" "lgt" "lle" "llt" "log"
- ;; "logical" "log10" "matmul" "max" "maxexponent" "maxloc" "maxval" "merge"
- ;; "min" "minexponent" "minloc" "minval" "mod" "modulo" "mvbits" "nearest"
- ;; "nint" "not" "pack" "precision" "present" "product" "radix"
- ;; "random_number" "random_seed" "range" "real" "repeat" "reshape"
- ;; "rrspacing" "scale" "scan" "selected_int_kind" "selected_real_kind"
- ;; "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing" "spread"
- ;; "sqrt" "sum" "system_clock" "tan" "tanh" "tiny" "transfer" "transpose"
- ;; "trim" "ubound" "unpack" "verify")
- ;; A left parenthesis to avoid highlighting non-procedures.
- ;; Real is taken out here to avoid highlighting declarations.
- (concat
- "\\<\\(a\\(bs\\|c\\(har\\|os\\)\\|djust[lr]\\|i\\(mag\\|nt\\)\\|ll\\(\\|"
- "ocated\\)\\|n\\(int\\|y\\)\\|s\\(in\\|sociated\\)\\|tan2?\\)\\|b\\("
- "it_size\\|test\\)\\|c\\(eiling\\|har\\|mplx\\|o\\(njg\\|sh?\\|unt\\)\\|"
- "shift\\)\\|d\\(ate_and_time\\|ble\\|i\\(gits\\|m\\)\\|ot_product\\|prod"
- "\\)\\|e\\(oshift\\|psilon\\|xp\\(\\|onent\\)\\)\\|f\\(loor\\|"
- "raction\\)\\|huge\\|i\\(a\\(char\\|nd\\)\\|b\\(clr\\|its\\|set\\)\\|"
- "char\\|eor\\|n\\(dex\\|t\\)\\|or\\|shftc?\\)\\|kind\\|l\\(bound\\|"
- "en\\(\\|_trim\\)\\|g[et]\\|l[et]\\|og\\(\\|10\\|ical\\)\\)\\|m\\(a\\("
- "tmul\\|x\\(\\|exponent\\|loc\\|val\\)\\)\\|erge\\|in\\(\\|exponent\\|"
- "loc\\|val\\)\\|od\\(\\|ulo\\)\\|vbits\\)\\|n\\(earest\\|int\\|ot\\)\\|"
- "p\\(ack\\|r\\(e\\(cision\\|sent\\)\\|oduct\\)\\)\\|r\\(a\\(dix\\|n\\("
- "dom_\\(number\\|seed\\)\\|ge\\)\\)\\|e\\(peat\\|shape\\)\\|rspacing\\)\\|"
- "s\\(ca\\(le\\|n\\)\\|e\\(lected_\\(int_kind\\|real_kind\\)\\|"
- "t_exponent\\)\\|hape\\|i\\(gn\\|nh?\\|ze\\)\\|p\\(acing\\|read\\)\\|"
- "qrt\\|um\\|ystem_clock\\)\\|t\\(anh?\\|iny\\|r\\(ans\\(fer\\|pose\\)\\|"
- "im\\)\\)\\|u\\(bound\\|npack\\)\\|verify\\)[ \t]*(")
- "Regexp whose first part matches F90 intrinsic procedures.")
-
-(defconst f90-operators-re
-;; "and" "or" "not" "eqv" "neqv" "eq" "ne" "lt" "le" "gt" "ge" "true" "false"
- (concat
- "\\.\\(and\\|eqv?\\|false\\|g[et]\\|l[et]\\|n\\(e\\(\\|qv\\)\\|"
- "ot\\)\\|or\\|true\\)\\.")
- "Regexp matching intrinsic operators.")
-
-(defconst f90-hpf-keywords-re
- ;; Intrinsic procedures
- ;; ("all_prefix" "all_scatter" "all_suffix" "any_prefix" "any_scatter"
- ;; "any_suffix" "copy_prefix" "copy_scatter" "copy_suffix" "count_prefix"
- ;; "count_scatter" "count_suffix" "grade_down" "grade_up" "hpf_alignment"
- ;; "hpf_template" "hpf_distribution" "iall" "iall_prefix" "iall_scatter"
- ;; "iall_suffix" "iany" "iany_prefix" "iany_scatter" "iany_suffix" "iparity"
- ;; "iparity_prefix" "iparity_scatter" "iparity_suffix" "leadz"
- ;; "maxval_prefix" "maxval_scatter" "maxval_suffix" "minval_prefix"
- ;; "minval_scatter" "minval_suffix" "parity" "parity_prefix"
- ;; "parity_scatter" "parity_suffix" "popcnt" "poppar" "product_prefix"
- ;; "product_scatter" "product_suffix" "sum_prefix" "sum_scatter"
- ;; "sum_suffix" "ilen" "number_of_processors" "processors_shape")
- ;; Directives
- ;; ("align" "distribute" "dynamic" "inherit" "template" "processors"
- ;; "realign" "redistribute" "independent")
- ;; Keywords
- ;; ("pure" "extrinsic" "new" "with" "onto" "block" "cyclic")
- (concat
- "\\<\\(a\\(l\\(ign\\|l_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|ny_\\("
- "prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|block\\|c\\(o\\(py_\\(prefix\\|"
- "s\\(catter\\|uffix\\)\\)\\|unt_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|"
- "yclic\\)\\|d\\(istribute\\|ynamic\\)\\|extrinsic\\|grade_\\(down\\|"
- "up\\)\\|hpf_\\(alignment\\|distribution\\|template\\)\\|i\\(a\\(ll\\(\\|"
- "_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|ny\\(\\|_\\(prefix\\|s\\("
- "catter\\|uffix\\)\\)\\)\\)\\|len\\|n\\(dependent\\|herit\\)\\|parity\\(\\|"
- "_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\)\\|leadz\\|m\\(axval_\\("
- "prefix\\|s\\(catter\\|uffix\\)\\)\\|inval_\\(prefix\\|s\\(catter\\|"
- "uffix\\)\\)\\)\\|n\\(ew\\|umber_of_processors\\)\\|onto\\|p\\(arity\\(\\|"
- "_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|op\\(cnt\\|par\\)\\|ro\\("
- "cessors\\(\\|_shape\\)\\|duct_\\(prefix\\|s\\(catter\\|uffix\\)\\)\\)\\|"
- "ure\\)\\|re\\(align\\|distribute\\)\\|sum_\\(prefix\\|s\\(catter\\|"
- "uffix\\)\\)\\|template\\|with\\)\\>")
- "Regexp for all HPF keywords, procedures and directives.")
-
-;; Highlighting patterns
-
-(defvar f90-font-lock-keywords-1
- (list ; Emacs
- '("\\<\\(end[ \t]*\\(program\\|module\\|function\\|subroutine\\|type\\)\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
- '("\\<\\(program\\|call\\|module\\|subroutine\\|function\\|use\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- ;; Special highlighting of "module procedure foo-list"
- '("\\<\\(module[ \t]*procedure\\)\\>" (1 font-lock-keyword-face t))
- ;; Highlight definition of new type
- '("\\<\\(type\\)[ \t]*\\(,.*::[ \t]*\\|[ \t]+\\)\\(\\sw+\\)"
- (1 font-lock-keyword-face) (3 font-lock-function-name-face))
- "\\<\\(\\(end[ \t]*\\)?\\(interface\\|block[ \t]*data\\)\\|contains\\)\\>")
- "This does fairly subdued highlighting of comments and function calls.")
-
-(defvar f90-font-lock-keywords-2
- (append f90-font-lock-keywords-1
- (list
- ;; Variable declarations (avoid the real function call)
- '("^[ \t0-9]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|logical\\|type[ \t]*(\\sw+)\\)\\(.*::\\|[ \t]*(.*)\\)?\\([^!\n]*\\)"
- (1 font-lock-type-face) (4 font-lock-variable-name-face))
- ;; do, if, select, where, and forall constructs
- '("\\<\\(end[ \t]*\\(do\\|if\\|select\\|forall\\|where\\)\\)\\>\\([ \t]+\\(\\sw+\\)\\)?"
- (1 font-lock-keyword-face) (3 font-lock-reference-face nil t))
- '("^[ \t0-9]*\\(\\(\\sw+\\)[ \t]*:[ \t]*\\)?\\(\\(if\\|do\\([ \t]*while\\)?\\|select[ \t]*case\\|where\\|forall\\)\\)\\>"
- (2 font-lock-reference-face nil t) (3 font-lock-keyword-face))
- ;; implicit declaration
- '("\\<\\(implicit\\)[ \t]*\\(real\\|integer\\|c\\(haracter\\|omplex\\)\\|logical\\|type[ \t]*(\\sw+)\\|none\\)\\>" (1 font-lock-keyword-face) (2 font-lock-type-face))
- '("\\<\\(namelist\\|common\\)[ \t]*\/\\(\\sw+\\)?\/" (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
- "\\<else\\([ \t]*if\\|where\\)?\\>"
- "\\<\\(then\\|continue\\|format\\|include\\|stop\\|return\\)\\>"
- '("\\<\\(exit\\|cycle\\)[ \t]*\\(\\sw+\\)?\\>"
- (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
- '("\\<\\(case\\)[ \t]*\\(default\\|(\\)" . 1)
- '("\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)"
- (1 font-lock-keyword-face) (2 font-lock-reference-face))
- ;; line numbers (lines whose first character after number is letter)
- '("^[ \t]*\\([0-9]+\\)[ \t]*[a-z]+" (1 font-lock-reference-face t))))
- "Highlights declarations, do-loops and other constructions")
-
-(defvar f90-font-lock-keywords-3
- (append f90-font-lock-keywords-2
- (list
- f90-keywords-level-3-re
- f90-operators-re
- (if (string-match "XEmacs" emacs-version)
- (append (list f90-procedures-re) '(1 font-lock-keyword-face t))
- (list f90-procedures-re '(1 font-lock-keyword-face t)))
- "\\<real\\>" ; Avoid overwriting real defs.
- ))
- "Highlights all F90 keywords and intrinsic procedures.")
-
-(defvar f90-font-lock-keywords-4
- (append f90-font-lock-keywords-3
- (list f90-hpf-keywords-re))
- "Highlights all F90 and HPF keywords.")
-
-(defvar f90-font-lock-keywords
- f90-font-lock-keywords-2
- "*Default expressions to highlight in F90 mode.")
-
-;; syntax table
-(defvar f90-mode-syntax-table nil
- "Syntax table in use in F90 mode buffers.")
-
-(if f90-mode-syntax-table
- ()
- (setq f90-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\! "<" f90-mode-syntax-table) ; beg. comment
- (modify-syntax-entry ?\n ">" f90-mode-syntax-table) ; end comment
- (modify-syntax-entry ?_ "w" f90-mode-syntax-table) ; underscore in names
- (modify-syntax-entry ?\' "\"" f90-mode-syntax-table) ; string quote
- (modify-syntax-entry ?\" "\"" f90-mode-syntax-table) ; string quote
- (modify-syntax-entry ?\` "w" f90-mode-syntax-table) ; for abbrevs
- (modify-syntax-entry ?\r " " f90-mode-syntax-table) ; return is whitespace
- (modify-syntax-entry ?+ "." f90-mode-syntax-table)
- (modify-syntax-entry ?- "." f90-mode-syntax-table)
- (modify-syntax-entry ?= "." f90-mode-syntax-table)
- (modify-syntax-entry ?* "." f90-mode-syntax-table)
- (modify-syntax-entry ?/ "." f90-mode-syntax-table)
- (modify-syntax-entry ?\\ "/" f90-mode-syntax-table)) ; escape chars
-
-;; keys
-(defvar f90-mode-map ()
- "Keymap used in F90 mode.")
-
-(if f90-mode-map
- ()
- (setq f90-mode-map (make-sparse-keymap))
- (define-key f90-mode-map "`" 'f90-abbrev-start)
- (define-key f90-mode-map "\C-c;" 'f90-comment-region)
- (define-key f90-mode-map "\C-\M-a" 'f90-beginning-of-subprogram)
- (define-key f90-mode-map "\C-\M-e" 'f90-end-of-subprogram)
- (define-key f90-mode-map "\C-\M-h" 'f90-mark-subprogram)
- (define-key f90-mode-map "\C-\M-q" 'f90-indent-subprogram)
- (define-key f90-mode-map "\C-j" 'f90-indent-new-line) ; LFD equals C-j
- (define-key f90-mode-map "\r" 'newline)
- (define-key f90-mode-map "\C-c\r" 'f90-break-line)
- ;; (define-key f90-mode-map [M-return] 'f90-break-line)
- (define-key f90-mode-map "\C-c\C-d" 'f90-join-lines)
- (define-key f90-mode-map "\C-c\C-f" 'f90-fill-region)
- (define-key f90-mode-map "\C-c\C-p" 'f90-previous-statement)
- (define-key f90-mode-map "\C-c\C-n" 'f90-next-statement)
- (define-key f90-mode-map "\C-c\C-w" 'f90-insert-end)
- (define-key f90-mode-map "\t" 'f90-indent-line)
- (define-key f90-mode-map "," 'f90-electric-insert)
- (define-key f90-mode-map "+" 'f90-electric-insert)
- (define-key f90-mode-map "-" 'f90-electric-insert)
- (define-key f90-mode-map "*" 'f90-electric-insert)
- (define-key f90-mode-map "/" 'f90-electric-insert))
-
-
-;; menus
-(if (string-match "XEmacs" emacs-version)
- (defvar f90-xemacs-menu
- '("F90"
- ["Indent Subprogram" f90-indent-subprogram t]
- ["Mark Subprogram" f90-mark-subprogram t]
- ["Beginning of Subprogram" f90-beginning-of-subprogram t]
- ["End of Subprogram" f90-end-of-subprogram t]
- "-----"
- ["(Un)Comment Region" f90-comment-region t]
- ["Indent Region" indent-region t]
- ["Fill Region" f90-fill-region t]
- "-----"
- ["Break Line at Point" f90-break-line t]
- ["Join with Next Line" f90-join-lines t]
- ["Insert Newline" newline t]
- ["Insert Block End" f90-insert-end t]
- "-----"
- ["Upcase Keywords (buffer)" f90-upcase-keywords t]
- ["Upcase Keywords (region)" f90-upcase-region-keywords
- t]
- ["Capitalize Keywords (buffer)" f90-capitalize-keywords t]
- ["Capitalize Keywords (region)"
- f90-capitalize-region-keywords t]
- ["Downcase Keywords (buffer)" f90-downcase-keywords t]
- ["Downcase Keywords (region)"
- f90-downcase-region-keywords t]
- "-----"
- ["Toggle abbrev-mode" abbrev-mode t]
- ["Toggle auto-fill" auto-fill-mode t])
- "XEmacs menu for F90 mode.")
- ;; Emacs
-
- (defvar f90-change-case-menu
- (let ((map (make-sparse-keymap "Change Keyword Case")))
-
- (define-key map [dkr] (cons "Downcase Keywords (region)"
- 'f90-downcase-region-keywords))
- (put 'f90-downcase-region-keywords 'menu-enable 'mark-active)
-
- (define-key map [ckr] (cons "Capitalize Keywords (region)"
- 'f90-capitalize-region-keywords))
- (put 'f90-capitalize-region-keywords 'menu-enable 'mark-active)
-
- (define-key map [ukr] (cons "Upcase Keywords (region)"
- 'f90-upcase-region-keywords))
- (put 'f90-upcase-region-keywords 'menu-enable 'mark-active)
-
- (define-key map [line] (list "-----------------"))
-
- (define-key map [dkb] (cons "Downcase Keywords (buffer)"
- 'f90-downcase-keywords))
-
- (define-key map [ckb] (cons "Capitalize Keywords (buffer)"
- 'f90-capitalize-keywords))
-
- (define-key map [ukb] (cons "Upcase Keywords (buffer)"
- 'f90-upcase-keywords))
- map)
- "Submenu for change of case.")
- (defalias 'f90-change-case-menu f90-change-case-menu)
-
- ;; font-lock-menu and function calls
- (defalias 'f90-font-lock-on 'font-lock-mode)
- (defalias 'f90-font-lock-off 'font-lock-mode)
- (put 'f90-font-lock-on 'menu-enable 'font-lock-mode)
- (put 'f90-font-lock-off 'menu-enable '(not font-lock-mode))
-
- (defun f90-font-lock-1 ()
- (interactive)
- "Set font-lock-keywords to f90-font-lock-keywords-1."
- (font-lock-mode 1)
- (setq font-lock-keywords f90-font-lock-keywords-1)
- (font-lock-fontify-buffer))
-
- (defun f90-font-lock-2 ()
- (interactive)
- "Set font-lock-keywords to f90-font-lock-keywords-2."
- (font-lock-mode 1)
- (setq font-lock-keywords f90-font-lock-keywords-2)
- (font-lock-fontify-buffer))
-
- (defun f90-font-lock-3 ()
- (interactive)
- "Set font-lock-keywords to f90-font-lock-keywords-3."
- (font-lock-mode 1)
- (setq font-lock-keywords f90-font-lock-keywords-3)
- (font-lock-fontify-buffer))
-
- (defun f90-font-lock-4 ()
- (interactive)
- "Set font-lock-keywords to f90-font-lock-keywords-4."
- (font-lock-mode 1)
- (setq font-lock-keywords f90-font-lock-keywords-4)
- (font-lock-fontify-buffer))
-
- (defvar f90-font-lock-menu
- (let ((map (make-sparse-keymap "f90-font-lock-menu")))
- (define-key map [h4] (cons "Maximum highlighting (level 4)"
- 'f90-font-lock-4))
- (define-key map [h3] (cons "Heavy highlighting (level 3)"
- 'f90-font-lock-3))
- (define-key map [h2] (cons "Default highlighting (level 2)"
- 'f90-font-lock-2))
- (define-key map [h1] (cons "Light highlighting (level 1)"
- 'f90-font-lock-1))
- (define-key map [line] (list "-----------------"))
- (define-key map [floff] (cons "Turn off font-lock-mode"
- 'f90-font-lock-on))
- (define-key map [flon] (cons "Turn on font-lock-mode"
- 'f90-font-lock-off))
- map)
- "Submenu for highlighting using font-lock-mode.")
- (defalias 'f90-font-lock-menu f90-font-lock-menu)
-
- (define-key f90-mode-map [menu-bar] (make-sparse-keymap))
- (define-key f90-mode-map [menu-bar f90]
- (cons "F90" (make-sparse-keymap "f90")))
-
- (define-key f90-mode-map [menu-bar f90 f90-imenu-menu]
- '("Add imenu Menu" . f90-add-imenu-menu))
- (define-key f90-mode-map [menu-bar f90 abbrev-mode]
- '("Toggle abbrev-mode" . abbrev-mode))
- (define-key f90-mode-map [menu-bar f90 auto-fill-mode]
- '("Toggle auto-fill" . auto-fill-mode))
- (define-key f90-mode-map [menu-bar f90 line1]
- '("----"))
- (define-key f90-mode-map [menu-bar f90 f90-change-case-menu]
- (cons "Change Keyword Case" 'f90-change-case-menu))
- (define-key f90-mode-map [menu-bar f90 f90-font-lock-menu]
- (cons "Highlighting" 'f90-font-lock-menu))
- (define-key f90-mode-map [menu-bar f90 line2]
- '("----"))
-
- (define-key f90-mode-map [menu-bar f90 f90-insert-end]
- '("Insert Block End" . f90-insert-end))
- (define-key f90-mode-map [menu-bar f90 f90-join-lines]
- '("Join with Next Line" . f90-join-lines))
- (define-key f90-mode-map [menu-bar f90 f90-break-line]
- '("Break Line at Point" . f90-break-line))
-
- (define-key f90-mode-map [menu-bar f90 line3]
- '("----"))
-
- (define-key f90-mode-map [menu-bar f90 f90-fill-region]
- '("Fill Region" . f90-fill-region))
- (put 'f90-fill-region 'menu-enable 'mark-active)
-
- (define-key f90-mode-map [menu-bar f90 indent-region]
- '("Indent Region" . indent-region))
-
- (define-key f90-mode-map [menu-bar f90 f90-comment-region]
- '("(Un)Comment Region" . f90-comment-region))
- (put 'f90-comment-region 'menu-enable 'mark-active)
-
- (define-key f90-mode-map [menu-bar f90 line4]
- '("----"))
-
- (define-key f90-mode-map [menu-bar f90 f90-end-of-subprogram]
- '("End of Subprogram" . f90-end-of-subprogram))
- (define-key f90-mode-map [menu-bar f90 f90-beginning-of-subprogram]
- '("Beginning of Subprogram" . f90-beginning-of-subprogram))
- (define-key f90-mode-map [menu-bar f90 f90-mark-subprogram]
- '("Mark Subprogram" . f90-mark-subprogram))
- (define-key f90-mode-map [menu-bar f90 f90-indent-subprogram]
- '("Indent Subprogram" . f90-indent-subprogram))
- )
-
-;; Regexps for finding program structures.
-(defconst f90-blocks-re
- "\\(block[ \t]*data\\|do\\|if\\|interface\\|function\\|module\\|\
-program\\|select\\|subroutine\\|type\\|where\\|forall\\)\\>")
-(defconst f90-program-block-re
- "\\(program\\|module\\|subroutine\\|function\\)")
-(defconst f90-else-like-re
- "\\(else\\([ \t]*if\\|where\\)?\\|case[ \t]*\\(default\\|(\\)\\)")
-(defconst f90-end-if-re
- "end[ \t]*\\(if\\|select\\|where\\|forall\\)\\>")
-(defconst f90-end-type-re
- "end[ \t]*\\(type\\|interface\\|block[ \t]*data\\)")
-(defconst f90-type-def-re
- "\\<\\(type\\)[ \t]*\\(,.*::[ \t]*\\|[ \t]+\\)\\(\\sw+\\)")
-(defconst f90-no-break-re "\\(\\*\\*\\|//\\|=>\\)")
-;; A temporary position to make region operators faster
-(defvar f90-cache-position nil)
-(make-variable-buffer-local 'f90-cache-position)
-;; A flag to tell whether f90-imenu is turned on.
-(defvar f90-imenu nil)
-(make-variable-buffer-local 'f90-imenu)
-
-
-;; Imenu support
-(defvar f90-imenu-generic-expression
- (let ((good-char "[^!\"\&\n \t]") (not-e "[^e!\n\"\& \t]")
- (not-n "[^n!\n\"\& \t]") (not-d "[^d!\n\"\& \t]"))
- (list
- '(nil "^[ \t0-9]*program[ \t]+\\(\\sw+\\)" 1)
- '("Modules" "^[ \t0-9]*module[ \t]+\\(\\sw+\\)[ \t]*\\(!\\|$\\)" 1)
- '("Types" "^[ \t0-9]*type[ \t]+\\(\\sw+\\)" 1)
- (list
- "Procedures"
- (concat
- "^[ \t0-9]*"
- "\\("
- ;; At least three non-space characters before function/subroutine
- ;; Check that the last three non-space characters don't spell E N D
- "[^!\"\&\n]*\\("
- not-e good-char good-char "\\|"
- good-char not-n good-char "\\|"
- good-char good-char not-d "\\)"
- "\\|"
- ;; Less than three non-space characters before function/subroutine
- good-char "?" good-char "?"
- "\\)"
- "[ \t]*\\(function\\|subroutine\\)[ \t]+\\(\\sw+\\)")
- 4)))
- "imenu generic expression for F90 mode.")
-
-(defun f90-add-imenu-menu ()
- (interactive)
- "Add an imenu menu to the menubar."
- (if (not f90-imenu)
- (progn
- (imenu-add-to-menubar "F90-imenu")
- (redraw-frame (selected-frame))
- (setq f90-imenu t))
- (message "%s" "F90-imenu already exists.")))
-(put 'f90-add-imenu-menu 'menu-enable '(not f90-imenu))
-
-
-;; When compiling under GNU Emacs, load imenu during compilation. If
-;; you have 19.22 or earlier, comment this out, or get imenu.
-(and (fboundp 'eval-when-compile)
- (eval-when-compile
- (if (not (string-match "XEmacs" emacs-version))
- (require 'imenu))
- ()))
-
-;; abbrevs have generally two letters, except standard types `c, `i, `r, `t
-(defvar f90-mode-abbrev-table nil)
-(if f90-mode-abbrev-table
- ()
- (let ((ac abbrevs-changed))
- (define-abbrev-table 'f90-mode-abbrev-table ())
- (define-abbrev f90-mode-abbrev-table "`al" "allocate" nil)
- (define-abbrev f90-mode-abbrev-table "`ab" "allocatable" nil)
- (define-abbrev f90-mode-abbrev-table "`as" "assignment" nil)
- (define-abbrev f90-mode-abbrev-table "`ba" "backspace" nil)
- (define-abbrev f90-mode-abbrev-table "`bd" "block data" nil)
- (define-abbrev f90-mode-abbrev-table "`c" "character" nil)
- (define-abbrev f90-mode-abbrev-table "`cl" "close" nil)
- (define-abbrev f90-mode-abbrev-table "`cm" "common" nil)
- (define-abbrev f90-mode-abbrev-table "`cx" "complex" nil)
- (define-abbrev f90-mode-abbrev-table "`cn" "contains" nil)
- (define-abbrev f90-mode-abbrev-table "`cy" "cycle" nil)
- (define-abbrev f90-mode-abbrev-table "`de" "deallocate" nil)
- (define-abbrev f90-mode-abbrev-table "`df" "define" nil)
- (define-abbrev f90-mode-abbrev-table "`di" "dimension" nil)
- (define-abbrev f90-mode-abbrev-table "`dw" "do while" nil)
- (define-abbrev f90-mode-abbrev-table "`el" "else" nil)
- (define-abbrev f90-mode-abbrev-table "`eli" "else if" nil)
- (define-abbrev f90-mode-abbrev-table "`elw" "elsewhere" nil)
- (define-abbrev f90-mode-abbrev-table "`eq" "equivalence" nil)
- (define-abbrev f90-mode-abbrev-table "`ex" "external" nil)
- (define-abbrev f90-mode-abbrev-table "`ey" "entry" nil)
- (define-abbrev f90-mode-abbrev-table "`fl" "forall" nil)
- (define-abbrev f90-mode-abbrev-table "`fo" "format" nil)
- (define-abbrev f90-mode-abbrev-table "`fu" "function" nil)
- (define-abbrev f90-mode-abbrev-table "`fa" ".false." nil)
- (define-abbrev f90-mode-abbrev-table "`im" "implicit none" nil)
- (define-abbrev f90-mode-abbrev-table "`in " "include" nil)
- (define-abbrev f90-mode-abbrev-table "`i" "integer" nil)
- (define-abbrev f90-mode-abbrev-table "`it" "intent" nil)
- (define-abbrev f90-mode-abbrev-table "`if" "interface" nil)
- (define-abbrev f90-mode-abbrev-table "`lo" "logical" nil)
- (define-abbrev f90-mode-abbrev-table "`mo" "module" nil)
- (define-abbrev f90-mode-abbrev-table "`na" "namelist" nil)
- (define-abbrev f90-mode-abbrev-table "`nu" "nullify" nil)
- (define-abbrev f90-mode-abbrev-table "`op" "optional" nil)
- (define-abbrev f90-mode-abbrev-table "`pa" "parameter" nil)
- (define-abbrev f90-mode-abbrev-table "`po" "pointer" nil)
- (define-abbrev f90-mode-abbrev-table "`pr" "print" nil)
- (define-abbrev f90-mode-abbrev-table "`pi" "private" nil)
- (define-abbrev f90-mode-abbrev-table "`pm" "program" nil)
- (define-abbrev f90-mode-abbrev-table "`pu" "public" nil)
- (define-abbrev f90-mode-abbrev-table "`r" "real" nil)
- (define-abbrev f90-mode-abbrev-table "`rc" "recursive" nil)
- (define-abbrev f90-mode-abbrev-table "`rt" "return" nil)
- (define-abbrev f90-mode-abbrev-table "`rw" "rewind" nil)
- (define-abbrev f90-mode-abbrev-table "`se" "select" nil)
- (define-abbrev f90-mode-abbrev-table "`sq" "sequence" nil)
- (define-abbrev f90-mode-abbrev-table "`su" "subroutine" nil)
- (define-abbrev f90-mode-abbrev-table "`ta" "target" nil)
- (define-abbrev f90-mode-abbrev-table "`tr" ".true." nil)
- (define-abbrev f90-mode-abbrev-table "`t" "type" nil)
- (define-abbrev f90-mode-abbrev-table "`wh" "where" nil)
- (define-abbrev f90-mode-abbrev-table "`wr" "write" nil)
- (setq abbrevs-changed ac)))
-
-;;;###autoload
-(defun f90-mode ()
- "Major mode for editing Fortran 90 code in free format.
-
-\\[f90-indent-new-line] corrects current indentation and creates new\
- indented line.
-\\[f90-indent-line] indents the current line correctly.
-\\[f90-indent-subprogram] indents the current subprogram.
-
-Type `? or `\\[help-command] to display a list of built-in\
- abbrevs for F90 keywords.
-
-Key definitions:
-\\{f90-mode-map}
-
-Variables controlling indentation style and extra features:
-
- f90-do-indent
- Extra indentation within do blocks. (default 3)
- f90-if-indent
- Extra indentation within if/select case/where/forall blocks. (default 3)
- f90-type-indent
- Extra indentation within type/interface/block-data blocks. (default 3)
- f90-program-indent
- Extra indentation within program/module/subroutine/function blocks.
- (default 2)
- f90-continuation-indent
- Extra indentation applied to continuation lines. (default 5)
- f90-comment-region
- String inserted by \\[f90-comment-region] at start of each line in
- region. (default \"!!!$\")
- f90-indented-comment-re
- Regexp determining the type of comment to be intended like code.
- (default \"!\")
- f90-directive-comment-re
- Regexp of comment-like directive like \"!HPF\\\\$\", not to be indented.
- (default \"!hpf\\\\$\")
- f90-break-delimiters
- Regexp holding list of delimiters at which lines may be broken.
- (default \"[-+*/><=,% \\t]\")
- f90-break-before-delimiters
- Non-nil causes `f90-do-auto-fill' to break lines before delimiters.
- (default t)
- f90-beginning-ampersand
- Automatic insertion of \& at beginning of continuation lines. (default t)
- f90-smart-end
- From an END statement, check and fill the end using matching block start.
- Allowed values are 'blink, 'no-blink, and nil, which determine
- whether to blink the matching beginning.) (default 'blink)
- f90-auto-keyword-case
- Automatic change of case of keywords. (default nil)
- The possibilities are 'downcase-word, 'upcase-word, 'capitalize-word.
- f90-leave-line-no
- Do not left-justify line numbers. (default nil)
- f90-startup-message
- Set to nil to inhibit message first time F90 mode is used. (default t)
- f90-keywords-re
- List of keywords used for highlighting/upcase-keywords etc.
-
-Turning on F90 mode calls the value of the variable `f90-mode-hook'
-with no args, if that value is non-nil."
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'f90-mode)
- (setq mode-name "F90")
- (setq local-abbrev-table f90-mode-abbrev-table)
- (set-syntax-table f90-mode-syntax-table)
- (use-local-map f90-mode-map)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'f90-indent-line)
- (make-local-variable 'indent-region-function)
- (setq indent-region-function 'f90-indent-region)
- (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-indent-function)
- (setq comment-indent-function 'f90-comment-indent)
- (make-local-variable 'abbrev-all-caps)
- (setq abbrev-all-caps t)
- (make-local-variable 'normal-auto-fill-function)
- (setq normal-auto-fill-function 'f90-do-auto-fill)
- (setq indent-tabs-mode nil)
- ;; Setting up things for font-lock
- (if (string-match "XEmacs" emacs-version)
- (progn
- (put 'f90-mode 'font-lock-keywords-case-fold-search t)
- (if (and current-menubar
- (not (assoc "F90" current-menubar)))
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-submenu nil f90-xemacs-menu)))
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords f90-font-lock-keywords))
- ;; Emacs
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(f90-font-lock-keywords nil t))
-
- ;; Tell imenu how to handle f90.
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression f90-imenu-generic-expression))
- (run-hooks 'f90-mode-hook)
- (if f90-startup-message
- (message "Emacs F90 mode; please report bugs to %s" bug-f90-mode))
- (setq f90-startup-message nil))
-
-;; inline-functions
-(defsubst f90-get-beg-of-line ()
- (save-excursion (beginning-of-line) (point)))
-
-(defsubst f90-get-end-of-line ()
- (save-excursion (end-of-line) (point)))
-
-(defsubst f90-in-string ()
- (let ((beg-pnt
- (if (and f90-cache-position (> (point) f90-cache-position))
- f90-cache-position
- (point-min))))
- (nth 3 (parse-partial-sexp beg-pnt (point)))))
-
-(defsubst f90-in-comment ()
- (let ((beg-pnt
- (if (and f90-cache-position (> (point) f90-cache-position))
- f90-cache-position
- (point-min))))
- (nth 4 (parse-partial-sexp beg-pnt (point)))))
-
-(defsubst f90-line-continued ()
- (save-excursion
- (let ((bol (f90-get-beg-of-line)))
- (end-of-line)
- (while (f90-in-comment)
- (search-backward "!" bol)
- (skip-chars-backward "!"))
- (skip-chars-backward " \t")
- (= (preceding-char) ?&))))
-
-(defsubst f90-current-indentation ()
- "Return indentation of current line.
-Line-numbers are considered whitespace characters."
- (save-excursion
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (current-column)))
-
-(defsubst f90-indent-to (col &optional no-line-number)
- "Indent current line to column COL.
-If no-line-number nil, jump over a possible line-number."
- (beginning-of-line)
- (if (not no-line-number)
- (skip-chars-forward " \t0-9"))
- (delete-horizontal-space)
- (if (zerop (current-column))
- (indent-to col)
- (indent-to col 1)))
-
-(defsubst f90-match-piece (arg)
- (if (match-beginning arg)
- (buffer-substring (match-beginning arg) (match-end arg))))
-
-(defsubst f90-get-present-comment-type ()
- (save-excursion
- (let ((type nil) (eol (f90-get-end-of-line)))
- (if (f90-in-comment)
- (progn
- (beginning-of-line)
- (re-search-forward "[!]+" eol)
- (while (f90-in-string)
- (re-search-forward "[!]+" eol))
- (setq type (buffer-substring (match-beginning 0) (match-end 0)))))
- type)))
-
-(defsubst f90-equal-symbols (a b)
- "Compare strings neglecting case and allowing for nil value."
- (let ((a-local (if a (downcase a) nil))
- (b-local (if b (downcase b) nil)))
- (equal a-local b-local)))
-
-;; XEmacs 19.11 & 19.12 gives back a single char when matching an empty regular
-;; expression. Therefore, the next 2 functions are longer than necessary.
-
-(defsubst f90-looking-at-do ()
- "Return (\"do\" name) if a do statement starts after point.
-Name is nil if the statement has no label."
- (if (looking-at "\\(\\(\\sw+\\)[ \t]*\:\\)?[ \t]*\\(do\\)\\>")
- (let (label
- (struct (f90-match-piece 3)))
- (if (looking-at "\\(\\sw+\\)[ \t]*\:")
- (setq label (f90-match-piece 1)))
- (list struct label))))
-
-(defsubst f90-looking-at-select-case ()
- "Return (\"select\" name) if a select-case statement starts after point.
-Name is nil if the statement has no label."
- (if (looking-at "\\(\\(\\sw+\\)[ \t]*\:\\)?[ \t]*\\(select\\)[ \t]*case[ \t]*(")
- (let (label
- (struct (f90-match-piece 3)))
- (if (looking-at "\\(\\sw+\\)[ \t]*\:")
- (setq label (f90-match-piece 1)))
- (list struct label))))
-
-(defsubst f90-looking-at-if-then ()
- "Return (\"if\" name) if an if () then statement starts after point.
-Name is nil if the statement has no label."
- (save-excursion
- (let (struct (label nil))
- (if (looking-at "\\(\\(\\sw+\\)[ \t]*\:\\)?[ \t]*\\(if\\)\\>")
- (progn
- (setq struct (f90-match-piece 3))
- (if (looking-at "\\(\\sw+\\)[ \t]*\:")
- (setq label (f90-match-piece 1)))
- (goto-char (scan-lists (point) 1 0))
- (skip-chars-forward " \t")
- (if (or (looking-at "then\\>")
- (if (f90-line-continued)
- (progn
- (f90-next-statement)
- (skip-chars-forward " \t0-9&")
- (looking-at "then\\>"))))
- (list struct label)))))))
-
-(defsubst f90-looking-at-where-or-forall ()
- "Return (kind name) if a where or forall statement starts after point.
-Name is nil if the statement has no label."
- (if (looking-at "\\(\\(\\sw+\\)[ \t]*\:\\)?[ \t]*\\(where\\|forall\\)[ \t]*(")
- (let (label
- (struct (f90-match-piece 3)))
- (if (looking-at "\\(\\sw+\\)[ \t]*\:")
- (setq label (f90-match-piece 1)))
- (list struct label))))
-
-(defsubst f90-looking-at-type-like ()
- "Return (kind name) at the start of a type/interface/block-data block.
-Name is non-nil only for type."
- (cond
- ((looking-at f90-type-def-re)
- (list (f90-match-piece 1) (f90-match-piece 3)))
- ((looking-at "\\(interface\\|block[\t]*data\\)\\>")
- (list (f90-match-piece 1) nil))))
-
-(defsubst f90-looking-at-program-block-start ()
- "Return (kind name) if a program block with name name starts after point."
- (cond
- ((looking-at "\\(program\\)[ \t]+\\(\\sw+\\)\\>")
- (list (f90-match-piece 1) (f90-match-piece 2)))
- ((and (not (looking-at "module[ \t]*procedure\\>"))
- (looking-at "\\(module\\)[ \t]+\\(\\sw+\\)\\>"))
- (list (f90-match-piece 1) (f90-match-piece 2)))
- ((and (not (looking-at "end[ \t]*\\(function\\|subroutine\\)"))
- (looking-at "[^!\"\&\n]*\\(function\\|subroutine\\)[ \t]+\\(\\sw+\\)"))
- (list (f90-match-piece 1) (f90-match-piece 2)))))
-
-(defsubst f90-looking-at-program-block-end ()
- "Return list of type and name of end of block."
- (if (looking-at (concat "end[ \t]*" f90-blocks-re
- "?\\([ \t]+\\(\\sw+\\)\\)?\\>"))
- (list (f90-match-piece 1) (f90-match-piece 3))))
-
-(defsubst f90-comment-indent ()
- (cond ((looking-at "!!!") 0)
- ((and f90-directive-comment-re
- (looking-at f90-directive-comment-re)) 0)
- ((looking-at (regexp-quote f90-comment-region)) 0)
- ((looking-at f90-indented-comment-re)
- (f90-calculate-indent))
- (t (skip-chars-backward " \t")
- (max (if (bolp) 0 (1+ (current-column))) comment-column))))
-
-(defsubst f90-present-statement-cont ()
- "Return continuation properties of present statement."
- (let (pcont cont)
- (save-excursion
- (setq pcont (if (f90-previous-statement) (f90-line-continued) nil)))
- (setq cont (f90-line-continued))
- (cond ((and (not pcont) (not cont)) 'single)
- ((and (not pcont) cont) 'begin)
- ((and pcont (not cont)) 'end)
- ((and pcont cont) 'middle)
- (t (error)))))
-
-(defsubst f90-indent-line-no ()
- (if f90-leave-line-no
- ()
- (if (and (not (zerop (skip-chars-forward " \t")))
- (looking-at "[0-9]"))
- (delete-horizontal-space)))
- (skip-chars-forward " \t0-9"))
-
-(defsubst f90-no-block-limit ()
- (let ((eol (f90-get-end-of-line)))
- (save-excursion
- (not (or (looking-at "end")
- (looking-at "\\(do\\|if\\|else\\(if\\|where\\)?\
-\\|select[ \t]*case\\|case\\|where\\|forall\\)\\>")
- (looking-at "\\(program\\|module\\|interface\\|\
-block[ \t]*data\\)\\>")
- (looking-at "\\(contains\\|\\sw+[ \t]*:\\)")
- (looking-at f90-type-def-re)
- (re-search-forward "\\(function\\|subroutine\\)" eol t))))))
-
-(defsubst f90-update-line ()
- (let (bol eol)
- (if f90-auto-keyword-case
- (progn (setq bol (f90-get-beg-of-line)
- eol (f90-get-end-of-line))
- (if f90-auto-keyword-case
- (f90-change-keywords f90-auto-keyword-case bol eol))))))
-
-(defun f90-electric-insert ()
- (interactive)
- "Calls f90-do-auto-fill at each operator insertion."
- (self-insert-command 1)
- (f90-update-line)
- (if auto-fill-function (f90-do-auto-fill)))
-
-(defun f90-get-correct-indent ()
- "Get correct indent for a line starting with line number.
-Does not check type and subprogram indentation."
- (let ((epnt (f90-get-end-of-line)) icol cont)
- (save-excursion
- (while (and (f90-previous-statement)
- (or (progn
- (setq cont (f90-present-statement-cont))
- (or (eq cont 'end) (eq cont 'middle)))
- (looking-at "[ \t]*[0-9]"))))
- (setq icol (current-indentation))
- (beginning-of-line)
- (if (re-search-forward "\\(if\\|do\\|select\\|where\\|forall\\)"
- (f90-get-end-of-line) t)
- (progn
- (beginning-of-line) (skip-chars-forward " \t")
- (cond ((f90-looking-at-do)
- (setq icol (+ icol f90-do-indent)))
- ((or (f90-looking-at-if-then)
- (f90-looking-at-where-or-forall)
- (f90-looking-at-select-case))
- (setq icol (+ icol f90-if-indent))))
- (end-of-line)))
- (while (re-search-forward
- "\\(if\\|do\\|select\\|where\\|forall\\)" epnt t)
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (cond ((f90-looking-at-do)
- (setq icol (+ icol f90-do-indent)))
- ((or (f90-looking-at-if-then)
- (f90-looking-at-where-or-forall)
- (f90-looking-at-select-case))
- (setq icol (+ icol f90-if-indent)))
- ((looking-at f90-end-if-re)
- (setq icol (- icol f90-if-indent)))
- ((looking-at "end[ \t]*do\\>")
- (setq icol (- icol f90-do-indent))))
- (end-of-line))
- icol)))
-
-
-(defun f90-calculate-indent ()
- "Calculate the indent column based on previous statements."
- (interactive)
- (let (icol cont (case-fold-search t) (pnt (point)))
- (save-excursion
- (if (not (f90-previous-statement))
- (setq icol 0)
- (setq cont (f90-present-statement-cont))
- (if (eq cont 'end)
- (while (not (eq 'begin (f90-present-statement-cont)))
- (f90-previous-statement)))
- (cond ((eq cont 'begin)
- (setq icol (+ (f90-current-indentation)
- f90-continuation-indent)))
- ((eq cont 'middle) (setq icol(current-indentation)))
- (t (setq icol (f90-current-indentation))
- (skip-chars-forward " \t")
- (if (looking-at "[0-9]")
- (setq icol (f90-get-correct-indent))
- (cond ((or (f90-looking-at-if-then)
- (f90-looking-at-where-or-forall)
- (f90-looking-at-select-case)
- (looking-at f90-else-like-re))
- (setq icol (+ icol f90-if-indent)))
- ((f90-looking-at-do)
- (setq icol (+ icol f90-do-indent)))
- ((f90-looking-at-type-like)
- (setq icol (+ icol f90-type-indent)))
- ((or (f90-looking-at-program-block-start)
- (looking-at "contains[ \t]*\\($\\|!\\)"))
- (setq icol (+ icol f90-program-indent)))))
- (goto-char pnt)
- (beginning-of-line)
- (cond ((looking-at "[ \t]*$"))
- ((looking-at "[ \t]*#") ; Check for cpp directive.
- (setq icol 0))
- (t
- (skip-chars-forward " \t0-9")
- (cond ((or (looking-at f90-else-like-re)
- (looking-at f90-end-if-re))
- (setq icol (- icol f90-if-indent)))
- ((looking-at "end[ \t]*do\\>")
- (setq icol (- icol f90-do-indent)))
- ((looking-at f90-end-type-re)
- (setq icol (- icol f90-type-indent)))
- ((or (looking-at "contains[ \t]*\\(!\\|$\\)")
- (f90-looking-at-program-block-end))
- (setq icol (- icol f90-program-indent))))))
- ))))
- icol))
-
-;; Statement = statement line, a line which is neither blank, nor a comment.
-(defun f90-previous-statement ()
- "Move point to beginning of the previous F90 statement.
-Return nil if no previous statement is found."
- (interactive)
- (let (not-first-statement)
- (beginning-of-line)
- (while (and (setq not-first-statement (zerop (forward-line -1)))
- (looking-at "[ \t0-9]*\\(!\\|$\\|#\\)")))
- not-first-statement))
-
-(defun f90-next-statement ()
- "Move point to beginning of the next F90 statement.
-Return nil if no later statement is found."
- (interactive)
- (let (not-last-statement)
- (beginning-of-line)
- (while (and (setq not-last-statement
- (and (zerop (forward-line 1))
- (not (eobp))))
- (looking-at "[ \t0-9]*\\(!\\|$\\)")))
- not-last-statement))
-
-(defun f90-beginning-of-subprogram ()
- "Move point to the beginning of subprogram.
-Return (type name) or nil if not found."
- (interactive)
- (let ((count 1) (case-fold-search t) matching-beg)
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (if (setq matching-beg (f90-looking-at-program-block-start))
- (setq count (- count 1)))
- (while (and (not (zerop count))
- (re-search-backward f90-program-block-re nil 'move))
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (cond
- ((setq matching-beg (f90-looking-at-program-block-start))
- (setq count (- count 1)))
- ((f90-looking-at-program-block-end)
- (setq count (+ count 1)))))
- (beginning-of-line)
- (if (zerop count)
- matching-beg
- (message "No beginning-found.")
- nil)))
-
-(defun f90-end-of-subprogram ()
- "Move point to the end of subprogram.
-Return (type name) or nil if not found."
- (interactive)
- (let ((count 1) (case-fold-search t) matching-end)
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (if (setq matching-end (f90-looking-at-program-block-end))
- (setq count (1- count)))
- (end-of-line)
- (while (and (not (zerop count))
- (re-search-forward f90-program-block-re nil 'move))
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (cond ((f90-looking-at-program-block-start)
- (setq count (+ count 1)))
- ((setq matching-end (f90-looking-at-program-block-end))
- (setq count (1- count ))))
- (end-of-line))
- (forward-line 1)
- (if (zerop count)
- matching-end
- (message "No end found.")
- nil)))
-
-(defun f90-mark-subprogram ()
- "Put mark at end of F90 subprogram, point at beginning.
-Marks are pushed and highlight (grey shadow) is turned on."
- (interactive)
- (let ((pos (point)) program)
- (f90-end-of-subprogram)
- (push-mark (point) t)
- (goto-char pos)
- (setq program (f90-beginning-of-subprogram))
- ;; The keywords in the preceding lists assume case-insensitivity.
- (if (string-match "XEmacs" emacs-version)
- (zmacs-activate-region)
- (setq mark-active t)
- (setq deactivate-mark nil))
- program))
-
-(defun f90-comment-region (beg-region end-region)
- "Comment/uncomment every line in the region.
-Insert f90-comment-region at the beginning of every line in the region
-or, if already present, remove it."
- (interactive "*r")
- (let ((end (make-marker)))
- (set-marker end end-region)
- (goto-char beg-region)
- (beginning-of-line)
- (if (looking-at (regexp-quote f90-comment-region))
- (delete-region (point) (match-end 0))
- (insert f90-comment-region))
- (while (and (zerop (forward-line 1))
- (< (point) (marker-position end)))
- (if (looking-at (regexp-quote f90-comment-region))
- (delete-region (point) (match-end 0))
- (insert f90-comment-region)))
- (set-marker end nil)))
-
-(defun f90-indent-line (&optional no-update)
- "Indent current line as F90 code."
- (interactive)
- (let (indent (no-line-number nil) (pos (make-marker)) (case-fold-search t))
- (set-marker pos (point))
- (beginning-of-line) ; Digits after & \n are not line-no
- (if (save-excursion (and (f90-previous-statement) (f90-line-continued)))
- (progn (setq no-line-number t) (skip-chars-forward " \t"))
- (f90-indent-line-no))
- (if (looking-at "!")
- (setq indent (f90-comment-indent))
- (if (and (looking-at "end") f90-smart-end)
- (f90-match-end))
- (setq indent (f90-calculate-indent)))
- (if (zerop (- indent (current-column)))
- nil
- (f90-indent-to indent no-line-number))
- ;; If initial point was within line's indentation,
- ;; position after the indentation. Else stay at same point in text.
- (if (< (point) (marker-position pos))
- (goto-char (marker-position pos)))
- (if (not no-update) (f90-update-line))
- (if auto-fill-function (f90-do-auto-fill))
- (set-marker pos nil)))
-
-(defun f90-indent-new-line ()
- "Reindent the current F90 line, insert a newline and indent the newline.
-An abbrev before point is expanded if `abbrev-mode' is non-nil.
-If run in the middle of a line, the line is not broken."
- (interactive)
- (let (string cont (case-fold-search t))
- (if abbrev-mode (expand-abbrev))
- (beginning-of-line) ; Reindent where likely to be needed.
- (f90-indent-line-no)
- (if (or (looking-at "\\(end\\|else\\|!\\)"))
- (f90-indent-line 'no-update))
- (end-of-line)
- (delete-horizontal-space) ;Destroy trailing whitespace
- (setq string (f90-in-string))
- (setq cont (f90-line-continued))
- (if (and string (not cont)) (insert "&"))
- (f90-update-line)
- (newline)
- (if (or string (and cont f90-beginning-ampersand)) (insert "&"))
- (f90-indent-line 'no-update)))
-
-
-(defun f90-indent-region (beg-region end-region)
- "Indent every line in region by forward parsing."
- (interactive "*r")
- (let ((end-region-mark (make-marker)) (save-point (point-marker))
- (block-list nil) ind-lev ind-curr ind-b cont
- struct beg-struct end-struct)
- (set-marker end-region-mark end-region)
- (goto-char beg-region)
- ;; first find a line which is not a continuation line or comment
- (beginning-of-line)
- (while (and (looking-at "[ \t]*[0-9]*\\(!\\|#\\|[ \t]*$\\)")
- (progn (f90-indent-line 'no-update)
- (zerop (forward-line 1)))
- (< (point) end-region-mark)))
- (setq cont (f90-present-statement-cont))
- (while (and (or (eq cont 'middle) (eq cont 'end))
- (f90-previous-statement))
- (setq cont (f90-present-statement-cont)))
- ;; process present line for beginning of block
- (setq f90-cache-position (point))
- (f90-indent-line 'no-update)
- (setq ind-lev (f90-current-indentation))
- (setq ind-curr ind-lev)
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (setq struct nil)
- (setq ind-b (cond ((setq struct (f90-looking-at-do)) f90-do-indent)
- ((or (setq struct (f90-looking-at-if-then))
- (setq struct (f90-looking-at-select-case))
- (setq struct (f90-looking-at-where-or-forall))
- (looking-at f90-else-like-re))
- f90-if-indent)
- ((setq struct (f90-looking-at-type-like))
- f90-type-indent)
- ((or(setq struct (f90-looking-at-program-block-start))
- (looking-at "contains[ \t]*\\($\\|!\\)"))
- f90-program-indent)))
- (if ind-b (setq ind-lev (+ ind-lev ind-b)))
- (if struct (setq block-list (cons struct block-list)))
- (while (and (f90-line-continued) (zerop (forward-line 1))
- (< (point) end-region-mark))
- (if (not (zerop (- (current-indentation)
- (+ ind-curr f90-continuation-indent))))
- (f90-indent-to (+ ind-curr f90-continuation-indent) 'no-line-no)))
- ;; process all following lines
- (while (and (zerop (forward-line 1)) (< (point) end-region-mark))
- (beginning-of-line)
- (f90-indent-line-no)
- (setq f90-cache-position (point))
- (cond ((looking-at "[ \t]*$") (setq ind-curr 0))
- ((looking-at "[ \t]*#") (setq ind-curr 0))
- ((looking-at "!") (setq ind-curr (f90-comment-indent)))
- ((f90-no-block-limit) (setq ind-curr ind-lev))
- ((looking-at f90-else-like-re) (setq ind-curr
- (- ind-lev f90-if-indent)))
- ((looking-at "contains[ \t]*\\($\\|!\\)")
- (setq ind-curr (- ind-lev f90-program-indent)))
- ((setq ind-b
- (cond ((setq struct (f90-looking-at-do)) f90-do-indent)
- ((or (setq struct (f90-looking-at-if-then))
- (setq struct (f90-looking-at-select-case))
- (setq struct (f90-looking-at-where-or-forall)))
- f90-if-indent)
- ((setq struct (f90-looking-at-type-like))
- f90-type-indent)
- ((setq struct (f90-looking-at-program-block-start))
- f90-program-indent)))
- (setq ind-curr ind-lev)
- (if ind-b (setq ind-lev (+ ind-lev ind-b)))
- (setq block-list (cons struct block-list)))
- ((setq end-struct (f90-looking-at-program-block-end))
- (setq beg-struct (car block-list)
- block-list (cdr block-list))
- (if f90-smart-end
- (save-excursion
- (f90-block-match (car beg-struct)(car (cdr beg-struct))
- (car end-struct)(car (cdr end-struct)))))
- (setq ind-b
- (cond ((looking-at f90-end-if-re) f90-if-indent)
- ((looking-at "end[ \t]*do\\>") f90-do-indent)
- ((looking-at f90-end-type-re) f90-type-indent)
- ((f90-looking-at-program-block-end)
- f90-program-indent)))
- (if ind-b (setq ind-lev (- ind-lev ind-b)))
- (setq ind-curr ind-lev))
- (t (setq ind-curr ind-lev)))
- ;; do the indentation if necessary
- (if (not (zerop (- ind-curr (current-column))))
- (f90-indent-to ind-curr))
- (while (and (f90-line-continued) (zerop (forward-line 1))
- (< (point) end-region-mark))
- (if (not (zerop (- (current-indentation)
- (+ ind-curr f90-continuation-indent))))
- (f90-indent-to (+ ind-curr f90-continuation-indent) 'no-line-no))))
- ;; restore point etc
- (setq f90-cache-position nil)
- (goto-char save-point)
- (set-marker end-region-mark nil)
- (set-marker save-point nil)
- (if (string-match "XEmacs" emacs-version)
- (zmacs-deactivate-region)
- (deactivate-mark))))
-
-(defun f90-indent-subprogram ()
- "Properly indent the subprogram which contains point."
- (interactive)
- (save-excursion
- (let (program)
- (setq program (f90-mark-subprogram))
- (if program
- (progn
- (message "Indenting %s %s..."
- (car program) (car (cdr program)))
- (f90-indent-region (point) (mark))
- (message "Indenting %s %s...done"
- (car program) (car (cdr program))))
- (message "Indenting the whole file...")
- (f90-indent-region (point) (mark))
- (message "Indenting the whole file...done")))))
-
-;; autofill and break-line
-(defun f90-break-line (&optional no-update)
- "Break line at point, insert continuation marker(s) and indent."
- (interactive)
- (let (ctype)
- (cond ((f90-in-string)
- (insert "&") (newline) (insert "&"))
- ((f90-in-comment)
- (setq ctype (f90-get-present-comment-type))
- (newline)
- (insert ctype))
- (t (insert "&")
- (if (not no-update) (f90-update-line))
- (newline)
- (if f90-beginning-ampersand (insert "&")))))
- (f90-indent-line))
-
-(defun f90-find-breakpoint ()
- "From fill-column, search backward for break-delimiter."
- (let ((bol (f90-get-beg-of-line)))
- (re-search-backward f90-break-delimiters bol)
- (if f90-break-before-delimiters
- (progn (backward-char)
- (if (not (looking-at f90-no-break-re))
- (forward-char)))
- (if (looking-at f90-no-break-re)
- (forward-char 2)
- (forward-char)))))
-
-(defun f90-do-auto-fill ()
- "Break line if non-white characters beyond fill-column. Also, update line. "
- (interactive)
- ;; Break the line before or after the last delimiter (non-word char) if
- ;; position is beyond fill-column.
- ;; Will not break **, //, or => (specified by f90-no-break-re).
- (f90-update-line)
- (while (> (current-column) fill-column)
- (let ((pos-mark (point-marker)))
- (move-to-column fill-column)
- (if (not (f90-in-string))
- (f90-find-breakpoint))
- (f90-break-line)
- (goto-char pos-mark)
- (set-marker pos-mark nil))))
-
-
-(defun f90-join-lines ()
- "Join present line with next line, if this line ends with \&."
- (interactive)
- (let (pos (oldpos (point)))
- (end-of-line)
- (skip-chars-backward " \t")
- (cond ((= (preceding-char) ?&)
- (delete-char -1)
- (setq pos (point))
- (forward-line 1)
- (skip-chars-forward " \t")
- (if (looking-at "\&") (delete-char 1))
- (delete-region pos (point))
- (if (not (f90-in-string))
- (progn (delete-horizontal-space) (insert " ")))
- (if (and auto-fill-function
- (> (save-excursion (end-of-line)
- (current-column))
- fill-column))
- (f90-do-auto-fill))
- (goto-char oldpos)
- t))))
-
-(defun f90-fill-region (beg-region end-region)
- "Fill every line in region by forward parsing. Join lines if possible."
- (interactive "*r")
- (let ((end-region-mark (make-marker))
- (f90-smart-end nil) (f90-auto-keyword-case nil) (go-on t)
- (auto-fill-function nil))
- (set-marker end-region-mark end-region)
- (goto-char beg-region)
- (while go-on
- ;; join as much as possible
- (while (f90-join-lines))
- ;; chop the line if necessary
- (while (> (save-excursion (end-of-line) (current-column))
- fill-column)
- (move-to-column fill-column)
- (f90-find-breakpoint)
- (f90-break-line 'no-update))
- (setq go-on (and (< (point) (marker-position end-region-mark))
- (zerop (forward-line 1))))
- (setq f90-cache-position (point)))
- (setq f90-cache-position nil)
- (if (string-match "XEmacs" emacs-version)
- (zmacs-deactivate-region)
- (deactivate-mark))))
-
-(defun f90-block-match (beg-block beg-name end-block end-name)
- "Match end-struct with beg-struct and complete end-block if possible.
-Leave point at the end of line."
- (search-forward "end" (f90-get-end-of-line))
- (catch 'no-match
- (if (not (f90-equal-symbols beg-block end-block))
- (if end-block
- (progn
- (message "END %s does not match %s." end-block beg-block)
- (end-of-line)
- (throw 'no-match nil))
- (message "Inserting %s." beg-block)
- (insert (concat " " beg-block)))
- (search-forward end-block))
- (if (not (f90-equal-symbols beg-name end-name))
- (cond ((and beg-name (not end-name))
- (message "Inserting %s." beg-name)
- (insert (concat " " beg-name)))
- ((and beg-name end-name)
- (message "Replacing %s with %s." end-name beg-name)
- (search-forward end-name)
- (replace-match beg-name))
- ((and (not beg-name) end-name)
- (message "Deleting %s." end-name)
- (search-forward end-name)
- (replace-match "")))
- (if end-name (search-forward end-name)))
- (if (not (looking-at "[ \t]*!")) (delete-horizontal-space))))
-
-(defun f90-match-end ()
- "From an end foo statement, find the corresponding foo including name."
- (interactive)
- (let ((count 1) (top-of-window (window-start)) (matching-beg nil)
- (end-point (point)) (case-fold-search t)
- beg-name end-name beg-block end-block end-struct)
- (if (save-excursion (beginning-of-line) (skip-chars-forward " \t0-9")
- (setq end-struct (f90-looking-at-program-block-end)))
- (progn
- (setq end-block (car end-struct))
- (setq end-name (car (cdr end-struct)))
- (save-excursion
- (beginning-of-line)
- (while
- (and (not (zerop count))
- (let ((stop nil) notexist)
- (while (not stop)
- (setq notexist
- (not (re-search-backward
- (concat "\\(" f90-blocks-re "\\)") nil t)))
- (if notexist
- (setq stop t)
- (setq stop
- (not (or (f90-in-string)
- (f90-in-comment))))))
- (not notexist)))
- (beginning-of-line) (skip-chars-forward " \t0-9")
- (cond ((setq matching-beg
- (cond
- ((f90-looking-at-do))
- ((f90-looking-at-if-then))
- ((f90-looking-at-where-or-forall))
- ((f90-looking-at-select-case))
- ((f90-looking-at-type-like))
- ((f90-looking-at-program-block-start))))
- (setq count (- count 1)))
- ((looking-at (concat "end[ \t]*" f90-blocks-re "\\b"))
- (setq count (+ count 1)))))
- (if (not (zerop count))
- (message "No matching beginning.")
- (f90-update-line)
- (if (eq f90-smart-end 'blink)
- (if (< (point) top-of-window)
- (message "Matches %s: %s"
- (what-line)
- (buffer-substring
- (progn (beginning-of-line) (point))
- (progn (end-of-line) (point))))
- (sit-for 1)))
- (setq beg-block (car matching-beg))
- (setq beg-name (car (cdr matching-beg)))
- (goto-char end-point)
- (beginning-of-line)
- (f90-block-match beg-block beg-name end-block end-name)))))))
-
-(defun f90-insert-end ()
- "Inserts an complete end statement matching beginning of present block."
- (interactive)
- (let ((f90-smart-end (if f90-smart-end f90-smart-end 'blink)))
- (insert "end")
- (f90-indent-new-line)))
-
-;; abbrevs and keywords
-
-(defun f90-abbrev-start ()
- "Typing `\\[help-command] or `? lists all the F90 abbrevs.
-Any other key combination is executed normally."
- (interactive)
- (let (e c)
- (insert last-command-char)
- (if (string-match "XEmacs" emacs-version)
- (progn
- (setq e (next-command-event))
- (setq c (event-to-character e)))
- (setq c (read-event)))
- ;; insert char if not equal to `?'
- (if (or (= c ??) (eq c help-char))
- (f90-abbrev-help)
- (if (string-match "XEmacs" emacs-version)
- (setq unread-command-event e)
- (setq unread-command-events (list c))))))
-
-(defun f90-abbrev-help ()
- "List the currently defined abbrevs in F90 mode."
- (interactive)
- (message "Listing abbrev table...")
- (display-buffer (f90-prepare-abbrev-list-buffer))
- (message "Listing abbrev table...done"))
-
-(defun f90-prepare-abbrev-list-buffer ()
- (save-excursion
- (set-buffer (get-buffer-create "*Abbrevs*"))
- (erase-buffer)
- (insert-abbrev-table-description 'f90-mode-abbrev-table t)
- (goto-char (point-min))
- (set-buffer-modified-p nil)
- (edit-abbrevs-mode))
- (get-buffer-create "*Abbrevs*"))
-
-(defun f90-upcase-keywords ()
- "Upcase all F90 keywords in the buffer."
- (interactive)
- (f90-change-keywords 'upcase-word))
-
-(defun f90-capitalize-keywords ()
- "Capitalize all F90 keywords in the buffer."
- (interactive)
- (f90-change-keywords 'capitalize-word))
-
-(defun f90-downcase-keywords ()
- "Downcase all F90 keywords in the buffer."
- (interactive)
- (f90-change-keywords 'downcase-word))
-
-(defun f90-upcase-region-keywords (beg end)
- "Upcase all F90 keywords in the region."
- (interactive "*r")
- (f90-change-keywords 'upcase-word beg end))
-
-(defun f90-capitalize-region-keywords (beg end)
- "Capitalize all F90 keywords in the region."
- (interactive "*r")
- (f90-change-keywords 'capitalize-word beg end))
-
-(defun f90-downcase-region-keywords (beg end)
- "Downcase all F90 keywords in the region."
- (interactive "*r")
- (f90-change-keywords 'downcase-word beg end))
-
-;; Change the keywords according to argument.
-(defun f90-change-keywords (change-word &optional beg end)
- (save-excursion
- (setq beg (if beg beg (point-min)))
- (setq end (if end end (point-max)))
- (let ((keyword-re
- (concat "\\("
- f90-keywords-re "\\|" f90-procedures-re "\\|"
- f90-hpf-keywords-re "\\|" f90-operators-re "\\)"))
- (ref-point (point-min)) state
- (modified (buffer-modified-p)) saveword back-point)
- (goto-char beg)
- (unwind-protect
- (while (re-search-forward keyword-re end t)
- (if (progn
- (setq state (parse-partial-sexp ref-point (point)))
- (or (nth 3 state) (nth 4 state)
- (save-excursion ; Check for cpp directive.
- (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "#"))))
- ()
- (setq ref-point (point)
- back-point (save-excursion (backward-word 1) (point)))
- (setq saveword (buffer-substring back-point ref-point))
- (funcall change-word -1)
- (or (string= saveword (buffer-substring back-point ref-point))
- (setq modified t))))
- (or modified (set-buffer-modified-p nil))))))
-
-(provide 'f90)
-
-;;; f90.el ends here
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
deleted file mode 100644
index 1c255b12a8c..00000000000
--- a/lisp/progmodes/fortran.el
+++ /dev/null
@@ -1,1589 +0,0 @@
-;;; fortran.el --- Fortran mode for GNU Emacs
-
-;; Copyright (c) 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-;; Author: Michael D. Prange <prange@erl.mit.edu>
-;; Maintainer: bug-fortran-mode@erl.mit.edu (Steve Gildea and others)
-;; Version 1.30.6 (July 27, 1995)
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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
-
-;;; Code:
-
-(defconst fortran-mode-version "version 1.30.6")
-
-;;;###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
- "*Non-nil causes \\[fortran-indent-line] on ENDIF statement to blink on matching IF.
-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-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 ?\! "<" fortran-mode-syntax-table)
- (modify-syntax-entry ?\n ">" fortran-mode-syntax-table))
-
-;; Comments are real pain in Fortran because there is no way to represent the
-;; standard comment syntax in an Emacs syntax table (we can for VAX-style).
-;; Therefore an unmatched quote in a standard comment will throw fontification
-;; off on the wrong track. So we do syntactic fontification with regexps.
-
-;; Regexps done by simon@gnu with help from Ulrik Dickow <dickow@nbi.dk> and
-;; probably others Si's forgotten about (sorry).
-
-(defconst fortran-font-lock-keywords-1 nil
- "Subdued level highlighting for Fortran mode.")
-
-(defconst fortran-font-lock-keywords-2 nil
- "Medium level highlighting for Fortran mode.")
-
-(defconst fortran-font-lock-keywords-3 nil
- "Gaudy level highlighting for Fortran mode.")
-
-(let ((comment-chars "c!*")
- (fortran-type-types
-; (make-regexp
-; (let ((simple-types '("character" "byte" "integer" "logical"
-; "none" "real" "complex"
-; "double[ \t]*precision" "double[ \t]*complex"))
-; (structured-types '("structure" "union" "map"))
-; (other-types '("record" "dimension" "parameter" "common" "save"
-; "external" "intrinsic" "data" "equivalence")))
-; (append
-; (mapcar (lambda (x) (concat "implicit[ \t]*" x)) simple-types)
-; simple-types
-; (mapcar (lambda (x) (concat "end[ \t]*" x)) structured-types)
-; structured-types
-; other-types)))
- (concat "byte\\|c\\(haracter\\|om\\(mon\\|plex\\)\\)\\|"
- "d\\(ata\\|imension\\|ouble"
- "[ \t]*\\(complex\\|precision\\)\\)\\|"
- "e\\(nd[ \t]*\\(map\\|structure\\|union\\)\\|"
- "quivalence\\|xternal\\)\\|"
- "i\\(mplicit[ \t]*\\(byte\\|"
- "c\\(haracter\\|omplex\\)\\|"
- "double[ \t]*\\(complex\\|precision\\)\\|"
- "integer\\|logical\\|none\\|real\\)\\|"
- "nt\\(eger\\|rinsic\\)\\)\\|"
- "logical\\|map\\|none\\|parameter\\|re\\(al\\|cord\\)\\|"
- "s\\(ave\\|tructure\\)\\|union"))
- (fortran-keywords
-; ("continue" "format" "end" "enddo" "if" "then" "else" "endif"
-; "elseif" "while" "inquire" "stop" "return" "include" "open"
-; "close" "read" "write" "format" "print")
- (concat "c\\(lose\\|ontinue\\)\\|"
- "e\\(lse\\(\\|if\\)\\|nd\\(\\|do\\|if\\)\\)\\|format\\|"
- "i\\(f\\|n\\(clude\\|quire\\)\\)\\|open\\|print\\|"
- "re\\(ad\\|turn\\)\\|stop\\|then\\|w\\(hile\\|rite\\)"))
- (fortran-logicals
-; ("and" "or" "not" "lt" "le" "eq" "ge" "gt" "ne" "true" "false")
- "and\\|eq\\|false\\|g[et]\\|l[et]\\|n\\(e\\|ot\\)\\|or\\|true"))
-
- (setq fortran-font-lock-keywords-1
- (list
- ;;
- ;; Fontify syntactically (assuming strings cannot be quoted or span lines).
- (cons (concat "^[" comment-chars "].*") 'font-lock-comment-face)
- '(fortran-match-!-comment . font-lock-comment-face)
- (list (concat "^[^" comment-chars "\t\n]" (make-string 71 ?.) "\\(.*\\)")
- '(1 font-lock-comment-face))
- '("'[^'\n]*'?" . font-lock-string-face)
- ;;
- ;; Program, subroutine and function declarations, plus calls.
- (list (concat "\\<\\(block[ \t]*data\\|call\\|entry\\|function\\|"
- "program\\|subroutine\\)\\>[ \t]*\\(\\sw+\\)?")
- '(1 font-lock-keyword-face)
- '(2 font-lock-function-name-face nil t))))
-
- (setq fortran-font-lock-keywords-2
- (append fortran-font-lock-keywords-1
- (list
- ;;
- ;; Fontify all type specifiers (must be first; see below).
- (cons (concat "\\<\\(" fortran-type-types "\\)\\>") 'font-lock-type-face)
- ;;
- ;; Fontify all builtin keywords (except logical, do and goto; see below).
- (concat "\\<\\(" fortran-keywords "\\)\\>")
- ;;
- ;; Fontify all builtin operators.
- (concat "\\.\\(" fortran-logicals "\\)\\.")
- ;;
- ;; Fontify do/goto keywords and targets, and goto tags.
- (list "\\<\\(do\\|go *to\\)\\>[ \t]*\\([0-9]+\\)?"
- '(1 font-lock-keyword-face)
- '(2 font-lock-reference-face nil t))
- (cons "^ *\\([0-9]+\\)" 'font-lock-reference-face))))
-
- (setq fortran-font-lock-keywords-3
- (append
- ;;
- ;; The list `fortran-font-lock-keywords-1'.
- fortran-font-lock-keywords-1
- ;;
- ;; Fontify all type specifiers plus their declared items.
- (list
- (list (concat "\\<\\(" fortran-type-types "\\)\\>[ \t(/]*\\(*\\)?")
- ;; Fontify the type specifier.
- '(1 font-lock-type-face)
- ;; Fontify each declaration item (or just the /.../ block name).
- '(font-lock-match-c-style-declaration-item-and-skip-to-next
- ;; Start after any *(...) expression.
- (and (match-beginning 15) (forward-sexp 1))
- ;; No need to clean up.
- nil
- ;; Fontify as a variable name, functions are fontified elsewhere.
- (1 font-lock-variable-name-face nil t))))
- ;;
- ;; Things extra to `fortran-font-lock-keywords-3' (must be done first).
- (list
- ;;
- ;; Fontify goto-like `err=label'/`end=label' in read/write statements.
- '(", *\\(e\\(nd\\|rr\\)\\)\\> *\\(= *\\([0-9]+\\)\\)?"
- (1 font-lock-keyword-face) (4 font-lock-reference-face nil t))
- ;;
- ;; Highlight standard continuation character and in a TAB-formatted line.
- '("^ \\([^ 0]\\)" 1 font-lock-string-face)
- '("^\t\\([1-9]\\)" 1 font-lock-string-face))
- ;;
- ;; The list `fortran-font-lock-keywords-2' less that for types (see above).
- (cdr (nthcdr (length fortran-font-lock-keywords-1)
- fortran-font-lock-keywords-2))))
- )
-
-(defvar fortran-font-lock-keywords fortran-font-lock-keywords-1
- "Default expressions to highlight in Fortran mode.")
-
-
-(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
- Non-nil causes \\[fortran-indent-line] on an ENDIF statement to blink on
- matching IF. 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-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)
- ;; Font Lock mode support.
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '((fortran-font-lock-keywords
- fortran-font-lock-keywords-1
- fortran-font-lock-keywords-2
- fortran-font-lock-keywords-3)
- t t ((?/ . "$/"))))
- (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 ((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
- (if (not (setq matching-if (fortran-beginning-if)))
- (setq message "No matching if.")
- (if (< matching-if top-of-window)
- (save-excursion
- (goto-char matching-if)
- (beginning-of-line)
- (setq message
- (concat "Matches "
- (buffer-substring
- (point) (progn (end-of-line) (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 ((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
- (if (not (setq matching-do (fortran-beginning-do)))
- (setq message "No matching do.")
- (if (< matching-do top-of-window)
- (save-excursion
- (goto-char matching-do)
- (beginning-of-line)
- (setq message
- (concat "Matches "
- (buffer-substring
- (point) (progn (end-of-line) (point))))))))
- (if message
- (message "%s" message)
- (goto-char matching-do)
- (sit-for 1)
- (goto-char enddo-point))))))
-
-(defun fortran-mark-do ()
- "Put mark at end of Fortran DO [WHILE]-ENDDO construct, point at beginning.
-The marks are pushed."
- (interactive)
- (let (enddo-point do-point)
- (if (setq enddo-point (fortran-end-do))
- (if (not (setq do-point (fortran-beginning-do)))
- (message "No matching do.")
- ;; Set mark, move point.
- (goto-char enddo-point)
- (push-mark)
- (goto-char do-point)))))
-
-(defun fortran-end-do ()
- ;; Search forward for first unmatched ENDDO. Return point or nil.
- (if (save-excursion (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "end[ \t]*do\\b"))
- ;; Sitting on one.
- (match-beginning 0)
- ;; Search for one.
- (save-excursion
- (let ((count 1))
- (while (and (not (= count 0))
- (not (eq (fortran-next-statement) 'last-statement))
- ;; Keep local to subprogram
- (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
-
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "end[ \t]*do\\b")
- (setq count (- count 1)))
- ((looking-at "do[ \t]+[^0-9]")
- (setq count (+ count 1)))))
- (and (= count 0)
- ;; All pairs accounted for.
- (point))))))
-
-(defun fortran-beginning-do ()
- ;; Search backwards for first unmatched DO [WHILE]. Return point or nil.
- (if (save-excursion (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "do[ \t]+"))
- ;; Sitting on one.
- (match-beginning 0)
- ;; Search for one.
- (save-excursion
- (let ((count 1))
- (while (and (not (= count 0))
- (not (eq (fortran-previous-statement) 'first-statement))
- ;; Keep local to subprogram
- (not (looking-at "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
-
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "do[ \t]+[^0-9]")
- (setq count (- count 1)))
- ((looking-at "end[ \t]*do\\b")
- (setq count (+ count 1)))))
-
- (and (= count 0)
- ;; All pairs accounted for.
- (point))))))
-
-(defun fortran-mark-if ()
- "Put mark at end of Fortran IF-ENDIF construct, point at beginning.
-The marks are pushed."
- (interactive)
- (let (endif-point if-point)
- (if (setq endif-point (fortran-end-if))
- (if (not (setq if-point (fortran-beginning-if)))
- (message "No matching if.")
- ;; Set mark, move point.
- (goto-char endif-point)
- (push-mark)
- (goto-char if-point)))))
-
-(defun fortran-end-if ()
- ;; Search forwards for first unmatched ENDIF. Return point or nil.
- (if (save-excursion (beginning-of-line)
- (skip-chars-forward " \t0-9")
- (looking-at "end[ \t]*if\\b"))
- ;; Sitting on one.
- (match-beginning 0)
- ;; Search for one. The point has been already been moved to first
- ;; letter on line but this should not cause troubles.
- (save-excursion
- (let ((count 1))
- (while (and (not (= count 0))
- (not (eq (fortran-next-statement) 'last-statement))
- ;; Keep local to subprogram.
- (not (looking-at
- "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
-
- (skip-chars-forward " \t0-9")
- (cond ((looking-at "end[ \t]*if\\b")
- (setq count (- count 1)))
-
- ((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)))))))
-
- (and (= count 0)
- ;; All pairs accounted for.
- (point))))))
-
-(defun fortran-beginning-if ()
- ;; Search backwards for first unmatched IF-THEN. Return point or nil.
- (if (save-excursion
- ;; May be sitting on multi-line if-then statement, first move to
- ;; beginning of current statement. Note: `fortran-previous-statement'
- ;; moves to previous statement *unless* current statement is first
- ;; one. Only move forward if not first-statement.
- (if (not (eq (fortran-previous-statement) 'first-statement))
- (fortran-next-statement))
- (skip-chars-forward " \t0-9")
- (and
- (looking-at "if[ \t]*(")
- (save-match-data
- (or (looking-at ".*)[ \t]*then\\b[ \t]*[^ \t(=a-z0-9]")
- ;; Multi-line if-then.
- (let (then-test)
- (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)))))
- ;; Sitting on one.
- (match-beginning 0)
- ;; Search for one.
- (save-excursion
- (let ((count 1))
- (while (and (not (= count 0))
- (not (eq (fortran-previous-statement) 'first-statement))
- ;; Keep local to subprogram.
- (not (looking-at
- "^[ \t0-9]*end\\b[ \t]*[^ \t=(a-z]")))
-
- (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)))))
-
- (and (= count 0)
- ;; All pairs accounted for.
- (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-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)
- (if (save-excursion
- (re-search-forward comment-start-skip
- (save-excursion (end-of-line) (point)) t))
- (let ((save-match-beginning (match-beginning 0))
- (save-match-end (match-end 0)))
- (if (fortran-is-in-string-p (match-beginning 0))
- (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: simon@gnu (Simon Marshall)
-;;; Find the next ! not in a string.
-(defun fortran-match-!-comment (limit)
- (let (found)
- (while (and (setq found (search-forward "!" limit t))
- (fortran-is-in-string-p (point))))
- (if (not found)
- nil
- ;; Cheaper than `looking-at' "!.*".
- (store-match-data
- (list (1- (point)) (progn (end-of-line) (min (point) limit))))
- t)))
-
-;; The above function is about 10% faster than the below...
-;;(defun fortran-match-!-comment (limit)
-;; (let (found)
-;; (while (and (setq found (re-search-forward "!.*" limit t))
-;; (fortran-is-in-string-p (match-beginning 0))))
-;; found))
-
-;;;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-do-auto-fill
- nil))
- (force-mode-line-update)))
-
-(defun fortran-do-auto-fill ()
- (if (> (current-column) fill-column)
- (fortran-indent-line)))
-
-(defun fortran-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
- (end-of-line)
- (delete-region (point) (match-end 0))
- (delete-horizontal-space)
- (fortran-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 5c97d41255e..00000000000
--- a/lisp/progmodes/hideif.el
+++ /dev/null
@@ -1,1048 +0,0 @@
-;;; hide-ifdef-mode.el --- hides selected code within ifdef.
-
-;; Copyright (C) 1988, 1994 Free Software Foundation, Inc.
-
-;; Author: Dan LaLiberte <liberte@a.cs.uiuc.edu>
-;; Maintainer: FSF
-;; Keywords: c, outlines
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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.
-
-;;; Code:
-
-(require 'cc-mode)
-
-(defvar hide-ifdef-mode-submap nil
- "Keymap used with Hide-Ifdef mode.")
-
-(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.")
-
-;; Set up the submap that goes after the prefix key.
-(if hide-ifdef-mode-submap
- () ; Don't redefine it.
- (setq hide-ifdef-mode-submap (make-sparse-keymap))
- (define-key hide-ifdef-mode-submap "d" 'hide-ifdef-define)
- (define-key hide-ifdef-mode-submap "u" 'hide-ifdef-undef)
- (define-key hide-ifdef-mode-submap "D" 'hide-ifdef-set-define-alist)
- (define-key hide-ifdef-mode-submap "U" 'hide-ifdef-use-define-alist)
-
- (define-key hide-ifdef-mode-submap "h" 'hide-ifdefs)
- (define-key hide-ifdef-mode-submap "s" 'show-ifdefs)
- (define-key hide-ifdef-mode-submap "\C-d" 'hide-ifdef-block)
- (define-key hide-ifdef-mode-submap "\C-s" 'show-ifdef-block)
-
- (define-key hide-ifdef-mode-submap "\C-q" 'hide-ifdef-toggle-read-only)
- (let ((where (where-is-internal 'toggle-read-only '(keymap) t)))
- (if where
- (define-key hide-ifdef-mode-submap
- where
- 'hide-ifdef-toggle-outside-read-only)))
- )
-
-;; Set up the mode's main map, which leads via the prefix key to the submap.
-(if hide-ifdef-mode-map
- ()
- (setq hide-ifdef-mode-map (make-sparse-keymap))
- (define-key hide-ifdef-mode-map hide-ifdef-mode-prefix-key
- hide-ifdef-mode-submap))
-
-(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.")
-
-;; Arrange to use the mode's map when the mode is enabled.
-(or (assq 'hide-ifdef-mode minor-mode-map-alist)
- (setq minor-mode-map-alist
- (cons (cons 'hide-ifdef-mode hide-ifdef-mode-map)
- minor-mode-map-alist)))
-
-(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)))
-
-;; fix c-mode syntax table so we can recognize whole symbols.
-(defvar hide-ifdef-syntax-table
- (copy-syntax-table c-mode-syntax-table)
- "Syntax table used for tokenizing #if expressions.")
-
-(modify-syntax-entry ?_ "w" hide-ifdef-syntax-table)
-(modify-syntax-entry ?& "." hide-ifdef-syntax-table)
-(modify-syntax-entry ?\| "." hide-ifdef-syntax-table)
-
-;;;###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 if arg is positive, off otherwise.
-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)))
-
- (force-mode-line-update)
-
- (if hide-ifdef-mode
- (progn
- ; 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)
-
- (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))
- (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))
-
-;; By putting this on after-revert-hook, we arrange that it only
-;; does anything when revert-buffer avoids turning off the mode.
-;; (That can happen in VC.)
-(defun hif-before-revert-function ()
- (and hide-ifdef-mode hide-ifdef-hiding
- (hide-ifdefs t)))
-(add-hook 'after-revert-hook 'hif-before-revert-function)
-
-(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) ===
-
-;; It is not useful to set this to anything but `eval'.
-;; In fact, the variable might as well be eliminated.
-(defvar hide-ifdef-evaluator 'eval
- "The function to use to evaluate a form.
-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 ).
-; Added ==, + and -: garyo@avs.com 8/9/94
-(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))
- (current-syntax-table (syntax-table)))
- (unwind-protect
- (progn
- (set-syntax-table hide-ifdef-syntax-table)
- (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 "==") 'equal)
- ((string-equal token "!=") 'hif-notequal)
- ((string-equal token "!") 'not)
- ((string-equal token "defined") 'hif-defined)
- ((string-equal token "(") 'lparen)
- ((string-equal token ")") 'rparen)
- ((string-equal token "+") 'hif-plus)
- ((string-equal token "-") 'hif-minus)
- (t (intern token)))
- token-list))))
- (t (error "Bad #if expression: %s" expr-string)))))
- (set-syntax-table current-syntax-table))
- (nreverse token-list)))
-
-;;;-----------------------------------------------------------------
-;;; Translate C preprocessor #if expressions using recursive descent.
-;;; This parser is limited to the operators &&, ||, !, and "defined".
-;;; Added ==, !=, +, and -. Gary Oberbrunner, garyo@avs.com, 8/9/94
-
-(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 an expression as found in #if.
- 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 : eq-expr | term '&&' eq-expr."
- (let ((result (hif-eq-expr)))
- (while (eq token 'and)
- (hif-nexttoken)
- (setq result (list 'and result (hif-eq-expr))))
- result))
-
-(defun hif-eq-expr ()
- "Parse an eq-expr : math | eq-expr '=='|'!=' math."
- (let ((result (hif-math))
- (eq-token nil))
- (while (or (eq token 'equal) (eq token 'hif-notequal))
- (setq eq-token token)
- (hif-nexttoken)
- (setq result (list eq-token result (hif-math))))
- result))
-
-(defun hif-math ()
- "Parse an expression with + or - and simpler things.
- math : factor | math '+|-' factor."
- (let ((result (hif-factor))
- (math-op nil))
- (while (or (eq token 'hif-plus) (eq token 'hif-minus))
- (setq math-op token)
- (hif-nexttoken)
- (setq result (list math-op result (hif-factor))))
- result))
-
-(defun hif-factor ()
- "Parse a 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))))
- ))
- ))
-
-(defun hif-mathify (val)
- "Treat VAL as a number: if it's t or nil, use 1 or 0."
- (cond ((eq val t)
- 1)
- ((null val)
- 0)
- (t val)))
-
-(defun hif-plus (a b)
- "Like ordinary plus but treat t and nil as 1 and 0."
- (+ (hif-mathify a) (hif-mathify b)))
-(defun hif-minus (a b)
- "Like ordinary minus but treat t and nil as 1 and 0."
- (- (hif-mathify a) (hif-mathify b)))
-(defun hif-notequal (a b)
- "Like (not (equal A B)) but as one symbol."
- (not (equal a b)))
-
-;;;----------- end of parser -----------------------
-
-
-(defun hif-canonicalize ()
- "When at beginning of #ifX, returns a Lisp expression for its condition."
- (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 ()
- "Move to next #if..., or #ifndef, at point or after."
-; (message "find ifX at %d" (point))
- (prog1
- (re-search-forward hif-ifx-regexp (point-max) t)
- (beginning-of-line)))
-
-
-(defun hif-find-next-relevant ()
- "Move to next #if..., #else, or #endif, after the current 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 ()
- "Move to previous #if..., #else, or #endif, before the current 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.
-It uses the 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 most of the work of `hide-ifdefs'.
-It does not do 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 means call `hide-ifdefs' when Hide-Ifdef mode is first activated.")
-
-;;;###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
- "*Non-nil means hide 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)))
- (force-mode-line-update))
-
-(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)
- )
- (force-mode-line-update))
-
-
-(defun hide-ifdef-define (var)
- "Define a VAR so that #ifdef VAR would be included."
- (interactive "SDefine what? ")
- (hif-set-var var 1)
- (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 (&optional nomsg)
- "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-ifdefs'."
-
- (interactive)
- (message "Hiding...")
- (setq hif-outside-read-only buffer-read-only)
- (if (not hide-ifdef-mode)
- (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode
- (if hide-ifdef-hiding
- (show-ifdefs)) ; Otherwise, deep confusion.
- (let ((inhibit-read-only t))
- (setq selective-display t)
- (setq hide-ifdef-hiding t)
- (hide-ifdef-guts))
- (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only))
- (or nomsg
- (message "Hiding done")))
-
-
-(defun show-ifdefs ()
- "Cancel the effects of `hide-ifdef': show the contents of all #ifdefs."
- (interactive)
- (setq buffer-read-only hif-outside-read-only)
- (setq selective-display nil) ; defaults
- (let ((inhibit-read-only t))
- (hif-show-all))
- (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))
- (setq selective-display t)
- (let (top bottom (inhibit-read-only t))
- (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))
- (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)))
-
-
-(defun show-ifdef-block ()
- "Show the ifdef block (true or false part) enclosing or before the cursor."
- (interactive)
- (let ((inhibit-read-only t))
- (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)))))
-
-
-;;; 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))))
-
-(provide 'hideif)
-
-;;; hideif.el ends here
-
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
deleted file mode 100644
index c49c7ea4da3..00000000000
--- a/lisp/progmodes/hideshow.el
+++ /dev/null
@@ -1,492 +0,0 @@
-;;; hideshow.el --- minor mode cmds to selectively display blocks of code
-
-;; Copyright (C) 1994,1995,1996 Free Software Foundation
-
-;; Author: Thien-Thi Nguyen <ttn@netcom.com>
-;; Version: 3.4
-;; Keywords: C C++ lisp tools editing
-;; Time-of-Day-Author-Most-Likely-to-be-Recalcitrant: early morning
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;; LCD Archive Entry:
-;; hideshow|Thien-Thi Nguyen|ttn@netcom.com|
-;; minor mode commands to selectively display blocks of code|
-;; 18-Oct-1994|3.4|~/modes/hideshow.el.Z|
-
-;;; Commentary:
-
-;; This file provides `hs-minor-mode'. When active, six commands:
-;; hs-{hide,show}-{all,block}, hs-show-region and hs-minor-mode
-;; are available. They implement block hiding and showing. Blocks are
-;; defined in mode-specific way. In c-mode or c++-mode, they are simply
-;; curly braces, while in lisp-ish modes they are parens. Multi-line
-;; comments (c-mode) can also be hidden. The command M-x hs-minor-mode
-;; toggles the minor mode or sets it (similar to outline minor mode).
-;; See documentation for each command for more info.
-;;
-;; The variable `hs-unbalance-handler-method' controls hideshow's behavior
-;; in the case of "unbalanced parentheses". See doc for more info.
-
-;; Suggested usage:
-
-;; (load-library "hideshow")
-;; (defun my-hs-setup () "enables hideshow and binds some commands"
-;; (hs-minor-mode 1)
-;; (define-key hs-minor-mode-map "\C-ch" 'hs-hide-block)
-;; (define-key hs-minor-mode-map "\C-cs" 'hs-show-block)
-;; (define-key hs-minro-mode-map "\C-cH" 'hs-hide-all)
-;; (define-key hs-minro-mode-map "\C-cS" 'hs-show-all)
-;; (define-key hs-minor-mode-map "\C-cR" 'hs-show-region))
-;; (add-hook 'X-mode-hook 'my-hs-setup t) ; other modes similarly
-;;
-;; where X = {emacs-lisp,c,c++,perl,...}. See the doc for the variable
-;; `hs-special-modes-alist' if you'd like to use hideshow w/ other modes.
-
-;; Etc:
-
-;; Bug reports and fixes welcome (comments, too). Thanks go to
-;; Dean Andrews <adahome@ix.netcom.com>
-;; Preston F. Crow <preston.f.crow@dartmouth.edu>
-;; Gael Marziou <gael@gnlab030.grenoble.hp.com>
-;; Keith Sheffield <sheff@edcsgw2.cr.usgs.gov>
-;; Jan Djarv <jan.djarv@sa.erisoft.se>
-;; Lars Lindberg <qhslali@aom.ericsson.se>
-;; Alf-Ivar Holm <alfh@ifi.uio.no>
-;; for valuable feedback, code and bug reports.
-
-;;; Code:
-
-
-;;;----------------------------------------------------------------------------
-;;; user-configurable variables
-
-(defvar hs-unbalance-handler-method 'top-level
- "*Symbol representing how \"unbalanced parentheses\" should be handled.
-This error is usually signaled by `hs-show-block'. One of four values:
-`top-level', `next-line', `signal' or `ignore'. Default is `top-level'.
-
-- `top-level' -- Show top-level block containing the currently troublesome
- block.
-- `next-line' -- Use the fact that, for an already hidden block, its end
- will be on the next line. Attempt to show this block.
-- `signal' -- Pass the error through, stopping execution.
-- `ignore' -- Ignore the error, continuing execution.
-
-Values other than these four will be interpreted as `signal'.")
-
-(defvar hs-special-modes-alist '((c-mode "{" "}")
- (c++-mode "{" "}"))
- "*Alist of the form (MODE START-RE END-RE FORWARD-SEXP-FUNC).
-If present, hideshow will use these values for the start and end regexps,
-respectively. Since Algol-ish languages do not have single-character
-block delimiters, the function `forward-sexp' which is used by hideshow
-doesn't work. In this case, if a similar function is provided, you can
-register it and have hideshow use it instead of `forward-sexp'. To add
-more values, use
-
-\t(pushnew '(new-mode st-re end-re function-name)
-\t hs-special-modes-alist :test 'equal)
-
-For example:
-
-\t(pushnew '(simula-mode \"begin\" \"end\" simula-next-statement)
-\t hs-special-modes-alist :test 'equal)
-
-Note that the regexps should not contain leading or trailing whitespace.")
-
-(defvar hs-hide-hook nil
- "*Hooks called at the end of `hs-hide-all' and `hs-hide-block'.")
-
-(defvar hs-show-hook nil
- "*Hooks called at the end of commands to show text.
-These commands include `hs-show-all', `hs-show-block' and `hs-show-region'.")
-
-(defvar hs-minor-mode-prefix "\C-c"
- "*Prefix key to use for hideshow commands in hideshow minor mode.")
-
-
-;;;----------------------------------------------------------------------------
-;;; internal variables
-
-(defvar hs-minor-mode nil
- "Non-nil if using hideshow mode as a minor mode of some other mode.
-Use the command `hs-minor-mode' to toggle this variable.")
-
-(defvar hs-minor-mode-map nil
- "Mode map for hideshow minor mode.")
-
-(defvar hs-menu-bar nil
- "Menu bar for hideshow minor mode (Xemacs only).")
-
-(defvar hs-c-start-regexp nil
- "Regexp for beginning of comments. Buffer-local.
-Differs from mode-specific comment regexps in that surrounding
-whitespace is stripped.")
-
-(defvar hs-c-end-regexp nil
- "Regexp for end of comments. Buffer-local.
-See `hs-c-start-regexp'.")
-
-(defvar hs-block-start-regexp nil
- "Regexp for beginning of block. Buffer-local.")
-
-(defvar hs-block-end-regexp nil
- "Regexp for end of block. Buffer-local.")
-
-(defvar hs-forward-sexp-func 'forward-sexp
- "Function used to do a forward-sexp. Should change for Algol-ish modes.
-For single-character block delimiters -- ie, the syntax table regexp for the
-character is either `(' or `)' -- `hs-forward-sexp-func' would just be
-`forward-sexp'. For other modes such as simula, a more specialized function
-is necessary.")
-
-(defvar hs-emacs-type 'fsf
- "Used to support both Emacs and XEmacs.")
-
-(eval-when-compile
- (if (string-match "xemacs\\|lucid" emacs-version)
- (progn
- (defvar current-menubar nil "")
- (defun set-buffer-menubar (arg1))
- (defun add-menu (arg1 arg2 arg3)))))
-
-
-;;;----------------------------------------------------------------------------
-;;; support funcs
-
-;; snarfed from outline.el, but added buffer-read-only
-(defun hs-flag-region (from to flag)
- "Hides or shows lines from FROM to TO, according to FLAG.
-If FLAG is `?\\n' (the newline character) then show the text;
-if FLAG is `?\\^M' \(control-M) then hide the text."
- (let ((modp (buffer-modified-p))
- buffer-read-only) ; nothing is immune
- (unwind-protect (progn
- (subst-char-in-region
- from to
- (if (= flag ?\n) ?\C-m ?\n)
- flag t))
- (set-buffer-modified-p modp))))
-
-(defun hs-hide-block-at-point (&optional end)
- "Hide block iff on block beginning, optional END means reposition at end."
- (if (looking-at hs-block-start-regexp)
- (let* ((p (point))
- (q (progn (funcall hs-forward-sexp-func 1) (point))))
- (forward-line -1) (end-of-line)
- (if (and (< p (point)) (> (count-lines p q) 1))
- (hs-flag-region p (point) ?\C-m))
- (goto-char (if end q p)))))
-
-(defun hs-show-block-at-point (&optional end)
- "Show block iff on block beginning. Optional END means reposition at end."
- (if (looking-at hs-block-start-regexp)
- (let* ((p (point))
- (q
- (condition-case error ; probably unbalanced paren
- (progn
- (funcall hs-forward-sexp-func 1)
- (point))
- (error
- (cond
- ((eq hs-unbalance-handler-method 'ignore)
- ;; just ignore this block
- (point))
- ((eq hs-unbalance-handler-method 'top-level)
- ;; try to get out of rat's nest and expose the whole func
- (if (/= (current-column) 0) (beginning-of-defun))
- (setq p (point))
- (re-search-forward (concat "^" hs-block-start-regexp)
- (point-max) t 2)
- (point))
- ((eq hs-unbalance-handler-method 'next-line)
- ;; assumption is that user knows what s/he's doing
- (beginning-of-line) (setq p (point))
- (end-of-line 2) (point))
- (t
- ;; pass error through -- this applies to `signal', too
- (signal (car error) (cdr error))))))))
- (hs-flag-region p q ?\n)
- (goto-char (if end (1+ (point)) p)))))
-
-(defun hs-safety-is-job-n ()
- "Warn if `selective-display' or `selective-display-ellipses' is nil."
- (let ((str ""))
- (or selective-display
- (setq str "selective-display nil "))
- (or selective-display-ellipses
- (setq str (concat str "selective-display-ellipses nil")))
- (if (= (length str) 0)
- nil
- (message "warning: %s" str)
- (sit-for 2))))
-
-(defun hs-inside-comment-p ()
- "Returns non-nil if point is inside a comment, otherwise nil.
-Actually, for multi-line-able comments, returns a list containing
-the buffer position of the start and the end of the comment."
- ;; is it single-line-only or multi-line-able?
- (save-excursion
- (let ((p (point))
- q)
- (if (string= comment-end "") ; single line
- (let (found)
- (beginning-of-line)
- (setq found (re-search-forward hs-c-start-regexp p t))
- (and found (not (search-forward "\"" p t))))
- (re-search-forward hs-c-end-regexp (point-max) 1)
- (setq q (point))
- (forward-comment -1)
- (re-search-forward hs-c-start-regexp (point-max) 1)
- (if (< (- (point) (length comment-start)) p)
- (list (match-beginning 0) q))))))
-
-(defun hs-grok-mode-type ()
- "Setup variables for new buffers where applicable."
- (if (and (boundp 'comment-start)
- (boundp 'comment-end))
- (progn
- (setq hs-c-start-regexp (regexp-quote comment-start))
- (if (string-match " +$" hs-c-start-regexp)
- (setq hs-c-start-regexp
- (substring hs-c-start-regexp 0 (1- (match-end 0)))))
- (setq hs-c-end-regexp (if (string= "" comment-end) "\n"
- (regexp-quote comment-end)))
- (if (string-match "^ +" hs-c-end-regexp)
- (setq hs-c-end-regexp
- (substring hs-c-end-regexp (match-end 0))))
- (let ((lookup (assoc major-mode hs-special-modes-alist)))
- (setq hs-block-start-regexp (or (nth 1 lookup) "\\s\(")
- hs-block-end-regexp (or (nth 2 lookup) "\\s\)")
- hs-forward-sexp-func (or (nth 3 lookup) 'forward-sexp))))))
-
-(defun hs-find-block-beginning ()
- "Repositions point at block-start. Return point, or nil if top-level."
- (let (done
- (here (point))
- (both-regexps (concat "\\(" hs-block-start-regexp "\\)\\|\\("
- hs-block-end-regexp "\\)")))
- (while (and (not done)
- (re-search-backward both-regexps (point-min) t))
- (if (match-beginning 1) ; start of start-regexp
- (setq done (match-beginning 1))
- (goto-char (match-end 2)) ; end of end-regexp
- (funcall hs-forward-sexp-func -1)))
- (goto-char (or done here))
- done))
-
-(defmacro hs-life-goes-on (&rest body)
- "Executes optional BODY iff variable `hs-minor-mode' is non-nil."
- (list 'if 'hs-minor-mode (cons 'progn body)))
-
-
-;;;----------------------------------------------------------------------------
-;;; commands
-
-;;;###autoload
-(defun hs-hide-all ()
- "Hides all top-level blocks, displaying only first and last lines.
-It moves point to the beginning of the line, and it runs the normal hook
-`hs-hide-hook'. See documentation for `run-hooks'."
- (interactive)
- (hs-life-goes-on
- (message "hiding all blocks ...")
- (save-excursion
- (hs-flag-region (point-min) (point-max) ?\n) ; eliminate weirdness
- (goto-char (point-min))
- (let ((count 0)
- (top-level-re (concat "^" hs-block-start-regexp)))
- (while (progn
- (forward-comment (buffer-size))
- (re-search-forward top-level-re (point-max) t))
- (goto-char (match-beginning 0))
- (hs-hide-block-at-point t)
- (message "hiding ... %d" (setq count (1+ count)))))
- (hs-safety-is-job-n))
- (beginning-of-line)
- (message "hiding all blocks ... done")
- (run-hooks 'hs-hide-hook)))
-
-(defun hs-show-all ()
- "Shows all top-level blocks.
-This does not change point; it runs the normal hook `hs-show-hook'.
-See documentation for `run-hooks'."
- (interactive)
- (hs-life-goes-on
- (message "showing all blocks ...")
- (hs-flag-region (point-min) (point-max) ?\n)
- (message "showing all blocks ... done")
- (run-hooks 'hs-show-hook)))
-
-;;;###autoload
-(defun hs-hide-block (&optional end)
- "Selects a block and hides it. With prefix arg, reposition at end.
-Block is defined as a sexp for lispish modes, mode-specific otherwise.
-Comments are blocks, too. Upon completion, point is at repositioned and
-the normal hook `hs-hide-hook' is run. See documentation for `run-hooks'."
- (interactive "P")
- (hs-life-goes-on
- (let ((c-reg (hs-inside-comment-p)))
- (if c-reg
- (cond ((string= comment-end "")
- (message "can't hide a single-line comment"))
- ((< (count-lines (car c-reg) (nth 1 c-reg)) 2)
- (message "not enough comment lines to hide"))
- (t
- (goto-char (nth 1 c-reg))
- (forward-line -1)
- (hs-flag-region (car c-reg) (point) ?\C-m)
- (goto-char (if end (nth 1 c-reg) (car c-reg)))
- (hs-safety-is-job-n)
- (run-hooks 'hs-hide-hook)))
- (if (or (looking-at hs-block-start-regexp)
- (hs-find-block-beginning))
- (progn
- (hs-hide-block-at-point end)
- (hs-safety-is-job-n)
- (run-hooks 'hs-hide-hook)))))))
-
-(defun hs-show-block (&optional end)
- "Selects a block and shows it. With prefix arg, reposition at end.
-Upon completion, point is repositioned and the normal hook
-`hs-show-hook' is run. See documentation for `hs-hide-block' and `run-hooks'."
- (interactive "P")
- (hs-life-goes-on
- (let ((c-reg (hs-inside-comment-p)))
- (if c-reg
- (cond ((string= comment-end "")
- (message "already looking at the entire comment"))
- (t
- (hs-flag-region (car c-reg) (nth 1 c-reg) ?\n)
- (goto-char (if end (nth 1 c-reg) (car c-reg)))))
- (if (or (looking-at hs-block-start-regexp)
- (hs-find-block-beginning))
- (progn
- (hs-show-block-at-point end)
- (hs-safety-is-job-n)
- (run-hooks 'hs-show-hook)))))))
-
-(defun hs-show-region (beg end)
- "Shows all lines from BEG to END, without doing any block analysis.
-Note:` hs-show-region' is intended for use when when `hs-show-block' signals
-`unbalanced parentheses' and so is an emergency measure only. You may
-become very confused if you use this command indiscriminately."
- (interactive "r")
- (hs-life-goes-on
- (hs-flag-region beg end ?\n)
- (hs-safety-is-job-n)
- (run-hooks 'hs-show-hook)))
-
-;;;###autoload
-(defun hs-minor-mode (&optional arg)
- "Toggle hideshow minor mode.
-With ARG, turn hideshow minor mode on if ARG is positive, off otherwise.
-When hideshow minor mode is on, the menu bar is augmented with hideshow
-commands and the hideshow commands are enabled. The variables
-`selective-display' and `selective-display-ellipses' are set to t.
-Last, the normal hook `hs-minor-mode-hook' is run; see the doc for `run-hooks'.
-
-Turning hideshow minor mode off reverts the menu bar and the
-variables to default values and disables the hideshow commands."
- (interactive "P")
- (setq hs-minor-mode
- (if (null arg)
- (not hs-minor-mode)
- (> (prefix-numeric-value arg) 0)))
- (if hs-minor-mode
- (progn
- (if (eq hs-emacs-type 'lucid)
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-menu nil (car hs-menu-bar) (cdr hs-menu-bar))))
- (setq selective-display t
- selective-display-ellipses t)
- (hs-grok-mode-type)
- (run-hooks 'hs-minor-mode-hook))
- (if (eq hs-emacs-type 'lucid)
- (set-buffer-menubar (delete hs-menu-bar current-menubar)))
- (kill-local-variable 'selective-display)
- (kill-local-variable 'selective-display-ellipses)))
-
-
-;;;----------------------------------------------------------------------------
-;;; load-time setup routines
-
-;; which emacs being used?
-(setq hs-emacs-type
- (if (string-match "xemacs\\|lucid" emacs-version)
- 'lucid
- 'fsf))
-
-;; keymaps and menus
-(if (not hs-minor-mode-map)
- (setq hs-minor-mode-map (make-sparse-keymap))
- (cond
- ((eq hs-emacs-type 'lucid)
- (setq hs-menu-bar ; build top down for lucid
- '("hideshow"
- ["Hide Block" hs-hide-block t]
- ["Show Block" hs-show-block t]
- ["Hide All" hs-hide-all t]
- ["Show All" hs-show-all t]
- ["Show Region" hs-show-region t])))
- (t ; build bottom up for others
- (define-key hs-minor-mode-map [menu-bar hideshow]
- (cons "hideshow" (make-sparse-keymap "hideshow")))
- (define-key hs-minor-mode-map [menu-bar hideshow hs-show-region]
- '("Show Region" . hs-show-region))
- (define-key hs-minor-mode-map [menu-bar hideshow hs-show-all]
- '("Show All" . hs-show-all))
- (define-key hs-minor-mode-map [menu-bar hideshow hs-hide-all]
- '("Hide All" . hs-hide-all))
- (define-key hs-minor-mode-map [menu-bar hideshow hs-show-block]
- '("Show Block" . hs-show-block))
- (define-key hs-minor-mode-map [menu-bar hideshow hs-hide-block]
- '("Hide Block" . hs-hide-block)))))
-
-;; some housekeeping
-(or (assq 'hs-minor-mode minor-mode-map-alist)
- (setq minor-mode-map-alist
- (cons (cons 'hs-minor-mode hs-minor-mode-map)
- minor-mode-map-alist)))
-(or (assq 'hs-minor-mode minor-mode-alist)
- (setq minor-mode-alist (append minor-mode-alist
- (list '(hs-minor-mode " hs")))))
-
-;; make some variables buffer-local
-(make-variable-buffer-local 'hs-minor-mode)
-(make-variable-buffer-local 'hs-c-start-regexp)
-(make-variable-buffer-local 'hs-c-end-regexp)
-(make-variable-buffer-local 'hs-block-start-regexp)
-(make-variable-buffer-local 'hs-block-end-regexp)
-(make-variable-buffer-local 'hs-forward-sexp-func)
-(put 'hs-minor-mode 'permanent-local t)
-(put 'hs-c-start-regexp 'permanent-local t)
-(put 'hs-c-end-regexp 'permanent-local t)
-(put 'hs-block-start-regexp 'permanent-local t)
-(put 'hs-block-end-regexp 'permanent-local t)
-(put 'hs-forward-sexp-func 'permanent-local t)
-
-
-;;;----------------------------------------------------------------------------
-;;; that's it
-
-(provide 'hideshow)
-
-;;; hideshow.el ends here
diff --git a/lisp/progmodes/icon.el b/lisp/progmodes/icon.el
deleted file mode 100644
index 85e30a77ade..00000000000
--- a/lisp/progmodes/icon.el
+++ /dev/null
@@ -1,556 +0,0 @@
-;;; icon.el --- mode for editing Icon code
-
-;; Copyright (C) 1989 Free Software Foundation, Inc.
-
-;; Author: Chris Smith <csmith@convex.com>
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; A major mode for editing the Icon programming language.
-
-;;; 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))
-
-(defvar icon-indent-level 4
- "*Indentation of Icon statements with respect to containing block.")
-(defvar icon-brace-imaginary-offset 0
- "*Imagined indentation of a Icon open brace that actually follows a statement.")
-(defvar icon-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context.")
-(defvar icon-continued-statement-offset 4
- "*Extra indent for lines not starting new statements.")
-(defvar icon-continued-brace-offset 0
- "*Extra indent for substatements that start with open-braces.
-This is in addition to icon-continued-statement-offset.")
-
-(defvar icon-auto-newline nil
- "*Non-nil means automatically newline before and after braces
-inserted in Icon code.")
-
-(defvar 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.")
-
-;;;###autoload
-(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 870d3f944b7..00000000000
--- a/lisp/progmodes/inf-lisp.el
+++ /dev/null
@@ -1,642 +0,0 @@
-;;; inf-lisp.el --- an inferior-lisp mode
-
-;; Copyright (C) 1988, 1993, 1994 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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*")
- (pop-to-buffer "*inferior-lisp*"))
-;;;###autoload (add-hook 'same-window-buffer-names "*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)
- (let ((pop-up-frames
- ;; Be willing to use another frame
- ;; that already has the window in it.
- (or pop-up-frames
- (get-buffer-window inferior-lisp-buffer t))))
- (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/m4-mode.el b/lisp/progmodes/m4-mode.el
deleted file mode 100644
index a9177ea91e0..00000000000
--- a/lisp/progmodes/m4-mode.el
+++ /dev/null
@@ -1,152 +0,0 @@
-;;; m4-mode.el --- m4 code editing commands for Emacs
-
-;;; Copyright (C) 1996 Free Software Foundation, Inc.
-
-;; Author: Andrew Csillag <drew@staff.prodigy.com>
-;; Maintainer: Andrew Csillag <drew@staff.prodigy.com>
-;; Keywords: languages, faces
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; A smart editing mode for m4 macro definitions. It seems to have most of the
-;; syntax right (sexp motion commands work, but function motion commands don't).
-;; It also sets the font-lock syntax stuff for colorization
-
-;; To Do's:
-
-;; * want to make m4-m4-(buffer|region) look sorta like M-x compile look&feel ?
-;; * sexp motion commands don't seem to work right
-
-;; to autoload m4 lisp code:
-;; (autoload 'm4-mode "m4-mode" nil t)
-;;
-;; or can use (load "m4-mode") or (require 'm4-mode) to just load it
-;;
-;; to try to "auto-detect" m4 files:
-;; (setq auto-mode-alist
-;; (cons '(".*\\.m4$" . m4-mode)
-;; auto-mode-alist))
-
-;;; Thanks:
-;;; to Akim Demaille and Terry Jones for the bug reports
-
-;;; Code:
-
-;;path to the m4 program
-(defvar m4-program "/usr/local/bin/m4")
-
-;;thank god for make-regexp.el!
-(defvar m4-font-lock-keywords
- `(
- ("^\\\#.*" . font-lock-comment-face)
- ("\\\$\\\*" . font-lock-variable-name-face)
- ("\\\$[0-9]" . font-lock-variable-name-face)
- ("\\\$\\\#" . font-lock-variable-name-face)
- ("\\\$\\\@" . font-lock-variable-name-face)
- ("\\\$\\\*" . font-lock-variable-name-face)
- ("\\b\\(builtin\\|change\\(com\\|quote\\|word\\)\\|d\\(e\\(bug\\(file\\|mode\\)\\|cr\\|f\\(ine\\|n\\)\\)\\|iv\\(ert\\|num\\)\\|nl\\|umpdef\\)\\|e\\(rrprint\\|syscmd\\|val\\)\\|f\\(ile\\|ormat\\)\\|gnu\\|i\\(f\\(def\\|else\\)\\|n\\(c\\(lude\\|r\\)\\|d\\(ex\\|ir\\)\\)\\)\\|l\\(en\\|ine\\)\\|m\\(4\\(exit\\|wrap\\)\\|aketemp\\)\\|p\\(atsubst\\|opdef\\|ushdef\\)\\|regexp\\|s\\(hift\\|include\\|ubstr\\|ys\\(cmd\\|val\\)\\)\\|tra\\(ceo\\(ff\\|n\\)\\|nslit\\)\\|un\\(d\\(efine\\|ivert\\)\\|ix\\)\\)\\b" . font-lock-keyword-face)
- ("\\b\\(m4_\\(builtin\\|change\\(com\\|quote\\|word\\)\\|d\\(e\\(bug\\(file\\|mode\\)\\|cr\\|f\\(ine\\|n\\)\\)\\|iv\\(ert\\|num\\)\\|nl\\|umpdef\\)\\|e\\(rrprint\\|syscmd\\|val\\)\\|f\\(ile\\|ormat\\)\\|i\\(f\\(def\\|else\\)\\|n\\(c\\(lude\\|r\\)\\|d\\(ex\\|ir\\)\\)\\)\\|l\\(en\\|ine\\)\\|m\\(4\\(_undefine\\|exit\\|wrap\\)\\|aketemp\\)\\|p\\(atsubst\\|opdef\\|ushdef\\)\\|regexp\\|s\\(hift\\|include\\|ubstr\\|ys\\(cmd\\|val\\)\\)\\|tra\\(ceo\\(ff\\|n\\)\\|nslit\\)\\|undivert\\)\\)\\b" . font-lock-keyword-face)
- "default font-lock-keywords")
-)
-
-;;this may still need some work
-(defvar m4-mode-syntax-table nil
- "syntax table used in m4 mode")
-(setq m4-mode-syntax-table (make-syntax-table))
-(modify-syntax-entry ?` "('" m4-mode-syntax-table)
-(modify-syntax-entry ?' ")`" m4-mode-syntax-table)
-(modify-syntax-entry ?# "<\n" m4-mode-syntax-table)
-(modify-syntax-entry ?\n ">#" m4-mode-syntax-table)
-(modify-syntax-entry ?{ "_" m4-mode-syntax-table)
-(modify-syntax-entry ?} "_" m4-mode-syntax-table)
-(modify-syntax-entry ?* "w" m4-mode-syntax-table)
-(modify-syntax-entry ?_ "w" m4-mode-syntax-table)
-(modify-syntax-entry ?\" "w" m4-mode-syntax-table)
-
-(defvar m4-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-b" 'm4-m4-buffer)
- (define-key map "\C-c\C-r" 'm4-m4-region)
- (define-key map "\C-c\C-c" 'comment-region)
- map))
-
-(defun m4-m4-buffer ()
- "send contents of the current buffer to m4"
- (interactive)
- (start-process "m4process" "*m4 output*" m4-program "-e")
- (process-send-region "m4process" (point-min) (point-max))
- (process-send-eof "m4process")
- (switch-to-buffer "*m4 output*")
-)
-
-(defun m4-m4-region ()
- "send contents of the current region to m4"
- (interactive)
- (start-process "m4process" "*m4 output*" m4-program "-e")
- (process-send-region "m4process" (point) (mark))
- (process-send-eof "m4process")
- (switch-to-buffer "*m4 output*")
-)
-
-(defun m4-mode ()
- "A major-mode to edit m4 macro files
-\\{m4-mode-map}
-"
- (interactive)
- (kill-all-local-variables)
- (use-local-map m4-mode-map)
-
- (make-local-variable 'comment-start)
- (setq comment-start "#")
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
-
-
- (make-local-variable 'font-lock-defaults)
- (setq major-mode 'm4-mode
- mode-name "m4"
- font-lock-defaults `(m4-font-lock-keywords nil)
- )
- (set-syntax-table m4-mode-syntax-table)
- (run-hooks 'm4-mode-hook))
-
-(provide 'm4-mode)
-;;stuff to play with for debugging
-;(char-to-string (char-syntax ?`))
-
-;;;how I generate the nasty looking regexps at the top
-;;;(make-regexp '("builtin" "changecom" "changequote" "changeword" "debugfile"
-;;; "debugmode" "decr" "define" "defn" "divert" "divnum" "dnl"
-;;; "dumpdef" "errprint" "esyscmd" "eval" "file" "format" "gnu"
-;;; "ifdef" "ifelse" "include" "incr" "index" "indir" "len" "line"
-;;; "m4exit" "m4wrap" "maketemp" "patsubst" "popdef" "pushdef" "regexp"
-;;; "shift" "sinclude" "substr" "syscmd" "sysval" "traceoff" "traceon"
-;;; "translit" "undefine" "undivert" "unix"))
-;;;(make-regexp '("m4_builtin" "m4_changecom" "m4_changequote" "m4_changeword"
-;;; "m4_debugfile" "m4_debugmode" "m4_decr" "m4_define" "m4_defn"
-;;; "m4_divert" "m4_divnum" "m4_dnl" "m4_dumpdef" "m4_errprint"
-;;; "m4_esyscmd" "m4_eval" "m4_file" "m4_format" "m4_ifdef" "m4_ifelse"
-;;; "m4_include" "m4_incr" "m4_index" "m4_indir" "m4_len" "m4_line"
-;;; "m4_m4exit" "m4_m4wrap" "m4_maketemp" "m4_patsubst" "m4_popdef"
-;;; "m4_pushdef" "m4_regexp" "m4_shift" "m4_sinclude" "m4_substr"
-;;; "m4_syscmd" "m4_sysval" "m4_traceoff" "m4_traceon" "m4_translit"
-;;; "m4_m4_undefine" "m4_undivert"))
-
-;;; m4.el ends here
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
deleted file mode 100644
index 25aaf3b8cf7..00000000000
--- a/lisp/progmodes/make-mode.el
+++ /dev/null
@@ -1,1396 +0,0 @@
-;;; make-mode.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.
-;; 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 `...'.
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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 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 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.
-
-;;
-;; To Do:
-;;
-;; * makefile-backslash-region should be given better behavior.
-;; * Consider binding C-c C-c to comment-region (like cc-mode).
-;; * Eliminate electric stuff entirely.
-;; * It might be nice to highlight targets differently depending on
-;; whether they are up-to-date or not. Not sure how this would
-;; interact with font-lock.
-;; * Would be nice to edit the commands in ksh-mode and have
-;; indentation and slashification done automatically. Hard.
-;; * Consider removing browser mode. It seems useless.
-;; * ":" should notice when a new target is made and add it to the
-;; list (or at least set makefile-need-target-pickup).
-;; * Make browser into a major mode.
-;; * Clean up macro insertion stuff. It is a mess.
-;; * Browser entry and exit is weird. Normalize.
-;; * Browser needs to be rewritten. Right now it is kind of a crock.
-;; Should at least:
-;; * Act more like dired/buffer menu/whatever.
-;; * Highlight as mouse traverses.
-;; * B2 inserts.
-;; * Update documentation above.
-;; * Update texinfo manual.
-;; * Update files.el.
-
-
-
-;;; Code:
-
-(provide 'makefile)
-
-;; Sadly we need this for a macro.
-(eval-when-compile
- (require 'imenu))
-
-;;; ------------------------------------------------------------
-;;; Configurable stuff
-;;; ------------------------------------------------------------
-
-(defvar makefile-browser-buffer-name "*Macros and Targets*"
- "Name of the macro- and target browser buffer.")
-
-(defvar makefile-target-colon ":"
- "String to append to all target names inserted by `makefile-insert-target'.
-\":\" or \"::\" are common values.")
-
-(defvar makefile-macro-assign " = "
- "String to append 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-electric-keys nil
- "If non-nil, install electric keybindings.
-Default is nil.")
-
-(defvar makefile-use-curly-braces-for-macros-p nil
- "Controls the style of generated macro references.
-t (actually non-nil) means macro references should use curly braces,
-like `${this}'.
-nil means use parentheses, like `$(this)'.")
-
-(defvar makefile-tab-after-target-colon t
- "If non-nil, insert a TAB after a target colon.
-Otherwise, a space is inserted.
-The default is t.")
-
-(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-backslash-column 48
- "*Column in which `makefile-backslash-region' inserts backslashes.")
-
-(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, cursor will move after item is selected in browser.")
-
-(defvar makefile-pickup-everything-picks-up-filenames-p nil
- "If non-nil, `makefile-pickup-everything' 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, automatically clean up continuation lines when saving.
-A line is cleaned up by removing all whitespace following a trailing
-backslash. This is done silently.
-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 '())
-
-;;
-;; 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 ( ).")
-
-;; Note that the first big subexpression is used by font lock. Note
-;; that if you change this regexp you must fix the imenu index
-;; function defined at the end of the file.
-(defconst makefile-dependency-regex
- "^ *\\([^\n\t#:]+\\([ \t]+[^ \t\n#:]+\\)*\\)[ \t]*:\\([ \t]*$\\|\\([^=\n].*$\\)\\)"
- "Regex used to find dependency lines in a makefile.")
-
-;; Note that the first subexpression is used by font lock. Note that
-;; if you change this regexp you must fix the imenu index function
-;; defined at the end of the file.
-(defconst makefile-macroassign-regex
- "^ *\\([^\n\t][^:#= \t\n]*\\)[ \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.")
-
-(if (fboundp 'facemenu-unlisted-faces)
- (add-to-list 'facemenu-unlisted-faces 'makefile-space-face))
-(defvar makefile-space-face 'makefile-space-face
- "Face to use for highlighting leading spaces in Font-Lock mode.")
-
-(defconst makefile-font-lock-keywords
- (list
- ;; Do macro assignments. These get the "variable-name" face rather
- ;; arbitrarily.
- (list makefile-macroassign-regex 1 'font-lock-variable-name-face)
- ;;
- ;; Do dependencies. These get the function name face.
- (list makefile-dependency-regex 1 'font-lock-function-name-face)
- ;;
- ;; Variable references even in targets/strings/comments:
- '("\\$[({]\\([-a-zA-Z0-9_.]+\\)[}):]" 1 font-lock-reference-face prepend)
-
- ;; Highlight lines that contain just whitespace.
- ;; They can cause trouble, especially if they start with a tab.
- '("^[ \t]+$" . makefile-space-face)
-
- ;; Highlight shell comments that Make treats as commands,
- ;; since these can fool people.
- '("^\t+#" 0 makefile-space-face t)
-
- ;; Highlight spaces that precede tabs.
- ;; They can make a tab fail to be effective.
- '("^\\( +\\)\t" 1 makefile-space-face)))
-
-;;; ------------------------------------------------------------
-;;; 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
- "Function to call to determine whether a make target is up to date.
-The function must satisfy this calling convention:
-
-* 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 "\C-c:" 'makefile-insert-target-ref)
- (if makefile-electric-keys
- (progn
- (define-key makefile-mode-map "$" 'makefile-insert-macro-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 "\C-c\C-\\" 'makefile-backslash-region)
- (define-key makefile-mode-map "\M-p" 'makefile-previous-dependency)
- (define-key makefile-mode-map "\M-n" 'makefile-next-dependency)
- (define-key makefile-mode-map "\e\t" 'makefile-complete)
-
- ;; Make menus.
- (define-key makefile-mode-map [menu-bar makefile-mode]
- (cons "Makefile" (make-sparse-keymap "Makefile")))
-
- (define-key makefile-mode-map [menu-bar makefile-mode browse]
- '("Pop up Makefile Browser" . makefile-switch-to-browser))
- (define-key makefile-mode-map [menu-bar makefile-mode complete]
- '("Complete Target or Macro" . makefile-complete))
- (define-key makefile-mode-map [menu-bar makefile-mode pickup]
- '("Find Targets and Macros" . makefile-pickup-everything))
-
- (define-key makefile-mode-map [menu-bar makefile-mode prev]
- '("Move to Previous Dependency" . makefile-previous-dependency))
- (define-key makefile-mode-map [menu-bar makefile-mode next]
- '("Move to Next Dependency" . 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)
-(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 ?\` "\" " 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 target names known for this buffer.")
-
-(defvar makefile-macro-table nil
- "Table of all macro names known for this buffer.")
-
-(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 '())
-
-;; Each element looks like '("GNU MAKE FUNCTION" "ARG" "ARG" ... )
-;; Each "ARG" is used as a prompt for a required argument.
-(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")
- ("addprefix" "Prefix" "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")))
-
-
-;;; ------------------------------------------------------------
-;;; The mode function itself.
-;;; ------------------------------------------------------------
-
-;;;###autoload
-(defun makefile-mode ()
- "Major mode for editing Makefiles.
-This function ends by invoking the function(s) `makefile-mode-hook'.
-
-\\{makefile-mode-map}
-
-In the browser, use the following keys:
-
-\\{makefile-browser-map}
-
-Makefile mode can be configured by modifying the following variables:
-
-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-variable '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)
-
- ;; Font lock.
- (if (fboundp 'make-face)
- (makefile-define-space-face))
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(makefile-font-lock-keywords))
-
- ;; Add-log.
- (make-local-variable 'add-log-current-defun-function)
- (setq add-log-current-defun-function 'makefile-add-log-defun)
-
- ;; Imenu.
- (make-local-variable 'imenu-create-index-function)
- (setq imenu-create-index-function 'makefile-menu-index-function)
-
- ;; Dabbrev.
- (make-local-variable 'dabbrev-abbrev-skip-leading-regexp)
- (setq dabbrev-abbrev-skip-leading-regexp "\\$")
-
- ;; Comment stuff.
- (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 "#+[ \t]*")
-
- ;; become the current major mode
- (setq major-mode 'makefile-mode)
- (setq mode-name "Makefile")
-
- ;; Activate keymap and syntax table.
- (use-local-map makefile-mode-map)
- (set-syntax-table makefile-mode-syntax-table)
-
- ;; Real TABs are important in makefiles
- (setq indent-tabs-mode t)
- (run-hooks 'makefile-mode-hook))
-
-
-
-;;; Motion code.
-
-(defun makefile-next-dependency ()
- "Move point to the beginning of the next dependency line."
- (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 previous dependency line."
- (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)))
-
-
-
-;;; Electric keys. Blech.
-
-(defun makefile-electric-dot (arg)
- "Prompt for the name of a special target to insert.
-Only does electric insertion at beginning of line.
-Anywhere else just self-inserts."
- (interactive "p")
- (if (bolp)
- (makefile-insert-special-target)
- (self-insert-command arg)))
-
-(defun makefile-insert-special-target ()
- "Prompt for and insert a special target name.
-Uses `makefile-special-targets' list."
- (interactive)
- (makefile-pickup-targets)
- (let ((special-target
- (completing-read "Special target: "
- makefile-special-targets-list nil nil nil)))
- (if (zerop (length special-target))
- ()
- (insert "." special-target ":")
- (makefile-forward-after-target-colon))))
-
-(defun makefile-electric-equal (arg)
- "Prompt for name of a macro to insert.
-Only does prompting if point is at beginning of line.
-Anywhere else just self-inserts."
- (interactive "p")
- (makefile-pickup-macros)
- (if (bolp)
- (call-interactively 'makefile-insert-macro)
- (self-insert-command arg)))
-
-(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 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))))
- (makefile-do-macro-insertion 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 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)))
- (insert target-name " ")))
-
-(defun makefile-electric-colon (arg)
- "Prompt for name of new target.
-Prompting only happens at beginning of line.
-Anywhere else just self-inserts."
- (interactive "p")
- (if (bolp)
- (call-interactively 'makefile-insert-target)
- (self-insert-command arg)))
-
-
-
-;;; ------------------------------------------------------------
-;;; Extracting targets and macros from an existing makefile
-;;; ------------------------------------------------------------
-
-(defun makefile-pickup-targets ()
- "Notice names of all target definitions in Makefile."
- (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 ()
- "Notice names of all macro definitions in Makefile."
- (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 (arg)
- "Notice names of all macros and targets in Makefile.
-Prefix arg means force pickups to be redone."
- (interactive "P")
- (if arg
- (progn
- (setq makefile-need-target-pickup t)
- (setq makefile-need-macro-pickup t)))
- (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 to use as targets.
-Checks each filename against `makefile-ignored-files-in-pickup-regex'
-and adds 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)))
-
-
-
-;;; Completion.
-
-(defun makefile-complete ()
- "Perform completion on Makefile construct preceding point.
-Can complete variable and target names.
-The context determines which are considered."
- (interactive)
- (let* ((beg (save-excursion
- (skip-chars-backward "^$(){}:#= \t\n")
- (point)))
- (try (buffer-substring beg (point)))
- (do-macros nil)
- (paren nil))
-
- (save-excursion
- (goto-char beg)
- (let ((pc (preceding-char)))
- (cond
- ;; Beginning of line means anything.
- ((bolp)
- ())
-
- ;; Preceding "$" means macros only.
- ((= pc ?$)
- (setq do-macros t))
-
- ;; Preceding "$(" or "${" means macros only.
- ((and (or (= pc ?{)
- (= pc ?\())
- (progn
- (setq paren pc)
- (backward-char)
- (and (not (bolp))
- (= (preceding-char) ?$))))
- (setq do-macros t)))))
-
- ;; Try completion.
- (let* ((table (append (if do-macros
- '()
- makefile-target-table)
- makefile-macro-table))
- (completion (try-completion try table)))
- (cond
- ;; Exact match, so insert closing paren or colon.
- ((eq completion t)
- (insert (if do-macros
- (if (eq paren ?{)
- ?}
- ?\))
- (if (save-excursion
- (goto-char beg)
- (bolp))
- ":"
- " "))))
-
- ;; No match.
- ((null completion)
- (message "Can't find completion for \"%s\"" try)
- (ding))
-
- ;; Partial completion.
- ((not (string= try completion))
- ;; FIXME it would be nice to supply the closing paren if an
- ;; exact, unambiguous match were found. That is not possible
- ;; right now. Ditto closing ":" for targets.
- (delete-region beg (point))
-
- ;; DO-MACROS means doing macros only. If not that, then check
- ;; to see if this completion is a macro. Special insertion
- ;; must be done for macros.
- (if (or do-macros
- (assoc completion makefile-macro-table))
- (let ((makefile-use-curly-braces-for-macros-p
- (or (eq paren ?{)
- makefile-use-curly-braces-for-macros-p)))
- (delete-backward-char 2)
- (makefile-do-macro-insertion completion)
- (delete-backward-char 1))
-
- ;; Just insert targets.
- (insert completion)))
-
- ;; Can't complete any more, so make completion list. FIXME
- ;; this doesn't do the right thing when the completion is
- ;; actually inserted. I don't think there is an easy way to do
- ;; that.
- (t
- (message "Making completion list...")
- (let ((list (all-completions try table)))
- (with-output-to-temp-buffer "*Completions*"
- (display-completion-list list)))
- (message "Making completion list...done"))))))
-
-
-
-;; Backslashification. Stolen from cc-mode.el.
-
-(defun makefile-backslashify-current-line (doit)
- (end-of-line)
- (if doit
- (if (not (save-excursion
- (forward-char -1)
- (eq (char-after (point)) ?\\ )))
- (progn
- (if (>= (current-column) makefile-backslash-column)
- (insert " \\")
- (while (<= (current-column) makefile-backslash-column)
- (insert "\t")
- (end-of-line))
- (delete-char -1)
- (while (< (current-column) makefile-backslash-column)
- (insert " ")
- (end-of-line))
- (insert "\\"))))
- (if (not (bolp))
- (progn
- (forward-char -1)
- (if (eq (char-after (point)) ?\\ )
- (let ((saved (save-excursion
- (end-of-line)
- (point))))
- (skip-chars-backward " \t")
- (delete-region (point) saved)))))))
-
-(defun makefile-backslash-region (beg end arg)
- "Insert backslashes at end of every line in region.
-Useful for defining multi-line rules.
-If called with a prefix argument, trailing backslashes are removed."
- (interactive "r\nP")
- (save-excursion
- (let ((do-lastline-p (progn (goto-char end) (not (bolp)))))
- (save-restriction
- (narrow-to-region beg end)
- (goto-char (point-min))
- (while (not (save-excursion
- (forward-line 1)
- (eobp)))
- (makefile-backslashify-current-line (null arg))
- (forward-line 1)))
- (and do-lastline-p
- (progn (goto-char end)
- (makefile-backslashify-current-line (null arg)))))))
-
-
-
-;;; ------------------------------------------------------------
-;;; Browser mode.
-;;; ------------------------------------------------------------
-
-(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 browser and return to the makefile buffer."
- (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)))
- (delete-region (point) (progn (end-of-line) (point)))
- (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)))
- (delete-region (point) (progn (end-of-line) (point)))
- (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 makefile 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 selected targets and/or macros in the makefile 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)
- "Fill the up-to-date overview buffer.
-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 ()
- "Insert a GNU make function call.
-Asks for the name of the function to use (with completion).
-Then prompts for all required parameters."
- (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-do-macro-insertion (macro-name)
- "Insert a macro reference."
- (if (not (zerop (length macro-name)))
- (if (assoc macro-name makefile-runtime-macros-list)
- (insert "$" macro-name)
- (insert (makefile-format-macro-ref macro-name)))))
-
-(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 inserting the terminating colon of a target.
-This acts 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.
-Uses `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)))
-
-
-
-;;; Support for other packages, like add-log and imenu.
-
-(defun makefile-add-log-defun ()
- "Return name of target or variable assignment that point is in.
-If it isn't in one, return nil."
- (save-excursion
- (let (found)
- (beginning-of-line)
- ;; Scan back line by line, noticing when we come to a
- ;; variable or rule definition, and giving up when we see
- ;; a line that is not part of either of those.
- (while (not found)
- (cond
- ((looking-at makefile-macroassign-regex)
- (setq found (buffer-substring-no-properties (match-beginning 1)
- (match-end 1))))
- ((looking-at makefile-dependency-regex)
- (setq found (buffer-substring-no-properties (match-beginning 1)
- (match-end 1))))
- ;; Don't keep looking across a blank line or comment. Give up.
- ((looking-at "$\\|#")
- (setq found 'bobp))
- ((bobp)
- (setq found 'bobp)))
- (or found
- (forward-line -1)))
- (if (stringp found) found))))
-
-;; FIXME it might be nice to have them separated by macro vs target.
-(defun makefile-menu-index-function ()
- ;; "Generate alist of indices for imenu."
- (let (alist
- stupid
- (re (concat makefile-dependency-regex
- "\\|"
- makefile-macroassign-regex)))
- (imenu-progress-message stupid 0)
- (goto-char (point-min))
- (while (re-search-forward re nil t)
- (imenu-progress-message stupid)
- (let ((n (if (match-beginning 1) 1 5)))
- (setq alist (cons
- (cons (buffer-substring (match-beginning n)
- (match-end n))
- (match-beginning n))
- alist))))
- (imenu-progress-message stupid 100)
- (nreverse alist)))
-
-(defun makefile-define-space-face ()
- (make-face 'makefile-space-face)
- (or (not (eq window-system 'x))
- (face-differs-from-default-p 'makefile-space-face)
- (let* ((params (frame-parameters))
- (light-bg (cdr (assq 'background-mode params)))
- (bg-color (cond ((eq (cdr (assq 'display-type params)) 'mono)
- (if light-bg "black" "white"))
- ((eq (cdr (assq 'display-type params)) 'grayscale)
- (if light-bg "black" "white"))
- (light-bg ; Light color background.
- "hotpink")
- (t ; Dark color background.
- "hotpink"))))
- (set-face-background 'makefile-space-face bg-color))))
-
-;;; make-mode.el ends here
diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el
deleted file mode 100644
index 12c6befae9d..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 statement, 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 statement, 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 statement, 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 m2-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*")
- (m2-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 1055e692689..00000000000
--- a/lisp/progmodes/pascal.el
+++ /dev/null
@@ -1,1560 +0,0 @@
-;;; pascal.el --- major mode for editing pascal source in Emacs
-
-;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
-
-;; Author: Espen Skoglund (espensk@stud.cs.uit.no)
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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-auto-lineup '(all)
-;; 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:
-
-(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 "#" 'electric-pascal-hash)
- (define-key pascal-mode-map "\r" 'electric-pascal-terminate-line)
- (define-key pascal-mode-map "\t" 'electric-pascal-tab)
- (define-key pascal-mode-map "\M-\t" 'pascal-complete-word)
- (define-key pascal-mode-map "\M-?" 'pascal-show-completions)
- (define-key pascal-mode-map "\177" 'backward-delete-char-untabify)
- (define-key pascal-mode-map "\M-\C-h" 'pascal-mark-defun)
- (define-key pascal-mode-map "\C-c\C-b" '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 "\M-\C-a" 'pascal-beg-of-defun)
- (define-key pascal-mode-map "\M-\C-e" 'pascal-end-of-defun)
- (define-key pascal-mode-map "\C-c\C-d" '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-imenu-generic-expression
- '("^[ \t]*\\(function\\|procedure\\)[ \t\n]+\\([a-zA-Z0-9_.:]+\\)" . (2))
- "Imenu expression for Pascal-mode. See `imenu-generic-expression'.")
-
-(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-font-lock-keywords
- (list
- '("^[ \t]*\\(function\\|pro\\(cedure\\|gram\\)\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
-; ("type" "const" "real" "integer" "char" "boolean" "var"
-; "record" "array" "file")
- (cons (concat "\\<\\(array\\|boolean\\|c\\(har\\|onst\\)\\|file\\|"
- "integer\\|re\\(al\\|cord\\)\\|type\\|var\\)\\>")
- 'font-lock-type-face)
- '("\\<\\(label\\|external\\|forward\\)\\>" . font-lock-reference-face)
- '("\\<\\([0-9]+\\)[ \t]*:" 1 font-lock-reference-face)
-; ("of" "to" "for" "if" "then" "else" "case" "while"
-; "do" "until" "and" "or" "not" "in" "with" "repeat" "begin" "end")
- (concat "\\<\\("
- "and\\|begin\\|case\\|do\\|e\\(lse\\|nd\\)\\|for\\|i[fn]\\|"
- "not\\|o[fr]\\|repeat\\|t\\(hen\\|o\\)\\|until\\|w\\(hile\\|ith\\)"
- "\\)\\>")
- '("\\<\\(goto\\)\\>[ \t]*\\([0-9]+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)))
- "Additional expressions to highlight in Pascal mode.")
-
-(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 semicolons and the punctuation
-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-auto-lineup '(all)
- "*List of contexts where auto lineup of :'s or ='s should be done.
-Elements can be of type: 'paramlist', 'declaration' or 'case', which will
-do auto lineup in parameterlist, declarations or case-statements
-respectively. The word 'all' will do all lineups. '(case paramlist) for
-instance will do lineup in case-statements and parameterlist, while '(all)
-will do all lineups.")
-
-(defvar pascal-toggle-completions nil
- "*Non-nil means \\<pascal-mode-map>\\[pascal-complete-word] should try all possible completions one by one.
-Repeated use of \\[pascal-complete-word] will show you all of them.
-Normally, when there is more than one possible completion,
-it displays a list of all possible completions.")
-
-(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)))
- ((looking-at "[^(\n]+)") (setq nest 0))))))
-
-
-(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 semicolons and the punctuation
- mark after an end.
- pascal-tab-always-indent (default 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.
- pascal-auto-lineup (default t)
- List of contexts where auto lineup of :'s or ='s hould be done.
-
-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)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'pascal-indent-comment)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments nil)
- (make-local-variable 'case-fold-search)
- (setq case-fold-search t)
- (make-local-variable 'comment-start)
- (setq comment-start "{")
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "(\\*+ *\\|{ *")
- (make-local-variable 'comment-end)
- (setq comment-end "}")
- ;; Font lock support
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '(pascal-font-lock-keywords nil t))
- ;; Imenu support
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression pascal-imenu-generic-expression)
- (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-hash ()
- "Insert `#', and indent to column 0 if this is a CPP directive."
- (interactive)
- (insert last-command-char)
- (if (save-excursion (beginning-of-line) (looking-at "^[ \t]*#"))
- (save-excursion (beginning-of-line)
- (delete-horizontal-space))))
-
-(defun electric-pascal-tab ()
- "Function called when TAB is pressed in Pascal mode."
- (interactive)
- ;; Do nothing if within a string or in a CPP directive.
- (if (or (pascal-within-string)
- (and (not (bolp))
- (save-excursion (beginning-of-line) (eq (following-char) ?#))))
- (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))
- (if (save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (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-end-of-statement ()
- "Move forward to end of current statement."
- (interactive)
- (let ((parse-sexp-ignore-comments t)
- (nest 0) pos
- (regexp (concat "\\(" pascal-beg-block-re "\\)\\|\\("
- pascal-end-block-re "\\)")))
- (if (not (looking-at "[ \t\n]")) (forward-sexp -1))
- (or (looking-at pascal-beg-block-re)
- ;; Skip to end of statement
- (setq pos (catch 'found
- (while t
- (forward-sexp 1)
- (cond ((looking-at "[ \t]*;")
- (skip-chars-forward "^;")
- (forward-char 1)
- (throw 'found (point)))
- ((save-excursion
- (forward-sexp -1)
- (looking-at pascal-beg-block-re))
- (goto-char (match-beginning 0))
- (throw 'found nil))
- ((eobp)
- (throw 'found (point))))))))
- (if (not pos)
- ;; Skip a whole block
- (catch 'found
- (while t
- (re-search-forward regexp nil 'move)
- (setq nest (if (match-end 1)
- (1+ nest)
- (1- nest)))
- (cond ((eobp)
- (throw 'found (point)))
- ((= 0 nest)
- (throw 'found (pascal-end-of-statement))))))
- pos)))
-
-(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))
- (caseblock . ind) (cpp . 0)
- (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 ((and (eq type 'paramlist)
- (or (memq 'all pascal-auto-lineup)
- (memq 'paramlist pascal-auto-lineup)))
- (pascal-indent-paramlist)
- (pascal-indent-paramlist))
- ((and (eq type 'declaration)
- (or (memq 'all pascal-auto-lineup)
- (memq 'declaration pascal-auto-lineup)))
- (pascal-indent-declaration))
- ((and (eq type 'case) (not (looking-at "^[ \t]*$"))
- (or (memq 'all pascal-auto-lineup)
- (memq 'case pascal-auto-lineup)))
- (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 things should not be indented
- (if (or (and (eq type 'declaration) (looking-at pascal-declaration-re))
- (eq type 'cpp)
- (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* ((parse-sexp-ignore-comments t)
- (oldpos (point))
- (state (save-excursion (parse-partial-sexp (point-min) (point))))
- (nest 0) (par 0) (complete (looking-at "[ \t]*end\\>"))
- (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))))
- ((save-excursion (beginning-of-line)
- (eq (following-char) ?#))
- (throw 'nesting 'cpp)))
- ;; Loop until correct indent is found
- (while t
- (backward-sexp 1)
- (cond (;--Escape from case statements
- (and (looking-at "[A-Za-z0-9]+[ \t]*:[^=]")
- (not complete)
- (save-excursion (skip-chars-backward " \t")
- (bolp))
- (= (save-excursion
- (end-of-line) (backward-sexp) (point))
- (point))
- (> (save-excursion (goto-char oldpos)
- (beginning-of-line)
- (point))
- (point)))
- (throw 'nesting 'caseblock))
- (;--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."
- (let ((savepos (point-marker))
- (end (prog2
- (end-of-line)
- (point-marker)
- (re-search-backward "\\<case\\>" nil t)))
- (beg (point)) oldpos
- (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))
- (if (< (point) (marker-position end))
- (progn
- (delete-horizontal-space)
- (if (> (current-column) ind)
- (setq ind (current-column)))
- (pascal-end-of-statement))))
- (goto-char beg)
- (setq oldpos (marker-position end))
- ;; 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 " "))
- (setq oldpos (point))
- (pascal-end-of-statement))
- (goto-char savepos)))
-
-(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 (and (<= (point) (marker-position edpos))
- (not (eobp)))
- (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)
- (progn
- ;; 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)))
- (goto-char (match-end 0)))))))
- ;; 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
-;;;
-(defvar pascal-str nil)
-(defvar pascal-all nil)
-(defvar pascal-pred nil)
-(defvar pascal-buffer-to-use nil)
-(defvar pascal-flag nil)
-
-(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= pascal-str "")
- (setq pascal-str "[a-zA-Z_]"))
- (let ((pascal-str (concat (cond
- ((eq type 'procedure) "\\<\\(procedure\\)\\s +")
- ((eq type 'function) "\\<\\(function\\)\\s +")
- (t "\\<\\(function\\|procedure\\)\\s +"))
- "\\<\\(" pascal-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 pascal-str (pascal-get-end-of-line) t)
- (progn (setq match (buffer-substring (match-beginning 2)
- (match-end 2)))
- (if (or (null pascal-pred)
- (funcall pascal-pred match))
- (setq pascal-all (cons match pascal-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 occurrence 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 "\\<" pascal-str) match)
- (if (or (null pascal-pred)
- (funcall pascal-pred match))
- (setq pascal-all (cons match pascal-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\\|procedure\\)\\>"
- 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 reachable
- (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 "\\<" pascal-str) s)
- (if (or (null pascal-pred)
- (funcall pascal-pred s))
- (setq pascal-all (cons s pascal-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 (pascal-str pascal-pred pascal-flag)
- (save-excursion
- (let ((pascal-all nil))
- ;; Set buffer to use for searching labels. This should be set
- ;; within functions which use pascal-completions
- (set-buffer pascal-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 pascal-flag 'lambda) (null pascal-flag))
- ;; This was not called by all-completions
- (if (null pascal-all)
- ;; Return nil if there was no matching label
- nil
- ;; Get longest string common in the labels
- (let* ((elm (cdr pascal-all))
- (match (car pascal-all))
- (min (length match))
- exact tmp)
- (if (string= match pascal-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) pascal-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 pascal-flag 'lambda) (not (equal match 't)))
- nil
- match))))
- ;; If flag is t, this was called by all-completions. Return
- ;; list of all possible completions
- (pascal-flag
- pascal-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)))
- (pascal-str (buffer-substring b e))
- ;; The following variable is used in pascal-completion
- (pascal-buffer-to-use (current-buffer))
- (allcomp (if (and pascal-toggle-completions
- (string= pascal-last-word-shown pascal-str))
- pascal-last-completions
- (all-completions pascal-str 'pascal-completion)))
- (match (if pascal-toggle-completions
- "" (try-completion
- pascal-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 "" pascal-str)
- (message "(No match)")))
- ;; The other form of completion does not necessarily do that.
-
- ;; Insert match if found, or the original string if no match
- (if (or (null match) (equal match 't))
- (progn (insert "" pascal-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 pascal-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)))
- (pascal-str (buffer-substring b e))
- ;; The following variable is used in pascal-completion
- (pascal-buffer-to-use (current-buffer))
- (allcomp (if (and pascal-toggle-completions
- (string= pascal-last-word-shown pascal-str))
- pascal-last-completions
- (all-completions pascal-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 (pascal-str pascal-pred pascal-flag)
- (save-excursion
- (let ((pascal-all nil)
- match)
-
- ;; Set buffer to use for searching labels. This should be set
- ;; within functions which use pascal-completions
- (set-buffer pascal-buffer-to-use)
-
- (let ((pascal-str pascal-str))
- ;; Build regular expression for functions
- (if (string= pascal-str "")
- (setq pascal-str (pascal-build-defun-re "[a-zA-Z_]"))
- (setq pascal-str (pascal-build-defun-re pascal-str)))
- (goto-char (point-min))
-
- ;; Build a list of all possible completions
- (while (re-search-forward pascal-str nil t)
- (setq match (buffer-substring (match-beginning 2) (match-end 2)))
- (if (or (null pascal-pred)
- (funcall pascal-pred match))
- (setq pascal-all (cons match pascal-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
- (pascal-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 "\M-\C-a" 'pascal-outline-prev-defun)
- (define-key pascal-outline-map "\M-\C-e" 'pascal-outline-next-defun)
- (define-key pascal-outline-map "\C-c\C-d" '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 pascal-flag)
- (let ((modp (buffer-modified-p)))
- (unwind-protect
- (subst-char-in-region b e (if (= pascal-flag ?\n)
- ?\^M ?\n) pascal-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 67a439da655..00000000000
--- a/lisp/progmodes/perl-mode.el
+++ /dev/null
@@ -1,732 +0,0 @@
-;;; perl-mode.el --- Perl code editing commands for GNU Emacs
-
-;; Copyright (C) 1990, 1994 Free Software Foundation, Inc.
-
-;; Author: William F. Mann
-;; Maintainer: FSF
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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 arguments 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-imenu-generic-expression
- '(
- ;; Functions
- (nil "^sub\\s-+\\([-A-Za-z0-9+_:]+\\)\\(\\s-\\|\n\\)*{" 1 )
- ;;Variables
- ("Variables" "^\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1 )
- ("Packages" "^package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1 )
- )
- "Imenu generic expression for Perl mode. See `imenu-generic-expression'.")
-
-;; Regexps updated with help from Tom Tromey <tromey@cambric.colorado.edu> and
-;; Jim Campbell <jec@murzim.ca.boeing.com>.
-
-(defconst perl-font-lock-keywords-1
- '(;; What is this for?
- ;;("\\(--- .* ---\\|=== .* ===\\)" . font-lock-string-face)
- ;;
- ;; Fontify preprocessor statements as we do in `c-font-lock-keywords'.
- ;; Ilya Zakharevich <ilya@math.ohio-state.edu> thinks this is a bad idea.
- ("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face)
- ("^#[ \t]*define[ \t]+\\(\\sw+\\)(" 1 font-lock-function-name-face)
- ("^#[ \t]*if\\>"
- ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
- (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t)))
- ("^#[ \t]*\\(\\sw+\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t))
- ;;
- ;; Fontify function and package names in declarations.
- ("\\<\\(package\\|sub\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- ("\\<\\(import\\|no\\|require\\|use\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)))
- "Subdued level highlighting for Perl mode.")
-
-(defconst perl-font-lock-keywords-2
- (append perl-font-lock-keywords-1
- (list
- ;;
- ;; Fontify keywords, except those fontified otherwise.
-; (make-regexp '("if" "until" "while" "elsif" "else" "unless" "do" "dump"
-; "for" "foreach" "exit" "die"
-; "BEGIN" "END" "return" "exec" "eval"))
- (concat "\\<\\("
- "BEGIN\\|END\\|d\\(ie\\|o\\|ump\\)\\|"
- "e\\(ls\\(e\\|if\\)\\|val\\|x\\(ec\\|it\\)\\)\\|"
- "for\\(\\|each\\)\\|if\\|return\\|un\\(less\\|til\\)\\|while"
- "\\)\\>")
- ;;
- ;; Fontify local and my keywords as types.
- '("\\<\\(local\\|my\\)\\>" . font-lock-type-face)
- ;;
- ;; Fontify function, variable and file name references.
- '("&\\(\\sw+\\)" 1 font-lock-function-name-face)
- ;; Additionally underline non-scalar variables. Maybe this is a bad idea.
- ;;'("[$@%*][#{]?\\(\\sw+\\)" 1 font-lock-variable-name-face)
- '("[$*]{?\\(\\sw+\\)" 1 font-lock-variable-name-face)
- '("\\([@%]\\|\\$#\\)\\(\\sw+\\)"
- (2 (cons font-lock-variable-name-face '(underline))))
- '("<\\(\\sw+\\)>" 1 font-lock-reference-face)
- ;;
- ;; Fontify keywords with/and labels as we do in `c++-font-lock-keywords'.
- '("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
- '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face)))
- "Gaudy level highlighting for Perl mode.")
-
-(defvar perl-font-lock-keywords perl-font-lock-keywords-1
- "Default expressions to highlight in Perl mode.")
-
-
-(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.")
-
-;; I changed the default to nil for consistency with general Emacs
-;; conventions -- rms.
-(defvar perl-tab-to-comment nil
- "*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)
- ;; Tell font-lock.el how to handle Perl.
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults '((perl-font-lock-keywords
- perl-font-lock-keywords-1
- perl-font-lock-keywords-2)
- nil nil ((?\_ . "w"))))
- ;; Tell imenu how to handle Perl.
- (make-local-variable 'imenu-generic-expression)
- (setq imenu-generic-expression perl-imenu-generic-expression)
- (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 (if (bolp) ;Else indent at comment column
- 0 ; except leave at least one space if
- (1+ (current-column))) ; not at beginning of line.
- comment-column))))
-
-(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
- (and comment-start-skip
- (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 (and comment-start-skip
- (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 (and comment-start-skip
- (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 (and comment-start-skip
- (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))
-
-(provide 'perl-mode)
-
-;;; perl-mode.el ends here
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
deleted file mode 100644
index 05a3c7ed5ac..00000000000
--- a/lisp/progmodes/prolog.el
+++ /dev/null
@@ -1,273 +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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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 ?\n ">" 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 a4393df8ee7..00000000000
--- a/lisp/progmodes/scheme.el
+++ /dev/null
@@ -1,515 +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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (make-local-variable 'comment-start)
- (setq comment-start ";")
- (make-local-variable 'comment-start-skip)
- ;; Look within the line for a ; following an even number of backslashes
- ;; after either a non-backslash or the line beginning.
- (setq comment-start-skip "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+[ \t]*")
- (make-local-variable 'comment-column)
- (setq comment-column 40)
- (make-local-variable 'comment-indent-function)
- (setq comment-indent-function 'scheme-comment-indent)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t)
- (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))
- (if (cdr 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 6ba2856938f..00000000000
--- a/lisp/progmodes/sh-script.el
+++ /dev/null
@@ -1,1388 +0,0 @@
-;;; sh-script.el --- shell-script editing commands for Emacs
-
-;; Copyright (C) 1993, 1994, 1995, 1996 by Free Software Foundation, Inc.
-
-;; Author: Daniel.Pfeiffer@Informatik.START.dbp.de, fax (+49 69) 7588-2389
-;; Version: 2.0e
-;; Maintainer: FSF
-;; Keywords: languages, unix
-
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; Major mode for editing shell scripts. Bourne, C and rc shells as well
-;; as various derivatives are supported and easily derived from. Structured
-;; statements can be inserted with one command or abbrev. Completion is
-;; available for filenames, variables known from the script, the shell and
-;; the environment as well as commands.
-
-;;; Known Bugs:
-
-;; - In Bourne the keyword `in' is not anchored to case, for, select ...
-;; - Variables in `"' strings aren't fontified because there's no way of
-;; syntactically distinguishing those from `'' strings.
-
-;;; 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
-
-(require 'executable)
-
-(defvar sh-ancestor-alist
- '((ash . sh)
- (bash . jsh)
- (dtksh . ksh)
- (es . rc)
- (itcsh . tcsh)
- (jcsh . csh)
- (jsh . sh)
- (ksh . ksh88)
- (ksh88 . jsh)
- (oash . sh)
- (pdksh . ksh88)
- (posix . sh)
- (tcsh . csh)
- (wksh . ksh88)
- (wsh . sh)
- (zsh . ksh88))
- "*Alist showing the direct ancestor of various shells.
-This is the basis for `sh-feature'. See also `sh-alias-alist'.
-By default we have the following three hierarchies:
-
-csh C Shell
- jcsh C Shell with Job Control
- tcsh Toronto C Shell
- itcsh ? Toronto C Shell
-rc Plan 9 Shell
- es Extensible Shell
-sh Bourne Shell
- ash ? Shell
- jsh Bourne Shell with Job Control
- bash GNU Bourne Again Shell
- ksh88 Korn Shell '88
- ksh Korn Shell '93
- dtksh CDE Desktop Korn Shell
- pdksh Public Domain Korn Shell
- wksh Window Korn Shell
- zsh Z Shell
- oash SCO OA (curses) Shell
- posix IEEE 1003.2 Shell Standard
- wsh ? Shell")
-
-
-(defvar sh-alias-alist
- (nconc (if (eq system-type 'gnu/linux)
- '((csh . tcsh)
- (ksh . pdksh)))
- ;; for the time being
- '((ksh . ksh88)
- (sh5 . sh)))
- "*Alist for transforming shell names to what they really are.
-Use this where the name of the executable doesn't correspond to the type of
-shell it really is.")
-
-
-(defvar sh-shell-file
- (or
- ;; On MSDOS and Windows, collapse $SHELL to lower-case and remove
- ;; the executable extension, so comparisons with the list of
- ;; known shells work.
- (and (memq system-type '(ms-dos windows-nt))
- (file-name-sans-extension (downcase (getenv "SHELL"))))
- (getenv "SHELL")
- "/bin/sh")
- "*The executable file name for the shell being programmed.")
-
-
-(defvar sh-shell-arg
- ;; bash does not need any options when run in a shell script,
- '((bash)
- (csh . "-f")
- (pdksh)
- ;; Bill_Mann@praxisint.com says -p with ksh can do harm.
- (ksh88)
- ;; -p means don't initialize functions from the environment.
- (rc . "-p")
- ;; Someone proposed -motif, but we don't want to encourage
- ;; use of a non-free widget set.
- (wksh)
- ;; -f means don't run .zshrc.
- (zsh . "-f"))
- "*Single argument string for the magic number. See `sh-feature'.")
-
-(defvar sh-shell-variables nil
- "Alist of shell variable names that should be included in completion.
-These are used for completion in addition to all the variables named
-in `process-environment'. Each element looks like (VAR . VAR), where
-the car and cdr are the same symbol.")
-
-(defvar sh-shell-variables-initialized nil
- "Non-nil if `sh-shell-variables' is initialized.")
-
-(defun sh-canonicalize-shell (shell)
- "Convert a shell name SHELL to the one we should handle it as."
- (or (symbolp shell)
- (setq shell (intern shell)))
- (or (cdr (assq shell sh-alias-alist))
- shell))
-
-(defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file))
- "The shell being programmed. This is set by \\[sh-set-shell].")
-
-;;; I turned off this feature because it doesn't permit typing commands
-;;; in the usual way without help.
-;;;(defvar sh-abbrevs
-;;; '((csh eval sh-abbrevs shell
-;;; "switch" 'sh-case
-;;; "getopts" 'sh-while-getopts)
-
-;;; (es eval sh-abbrevs shell
-;;; "function" 'sh-function)
-
-;;; (ksh88 eval sh-abbrevs sh
-;;; "select" 'sh-select)
-
-;;; (rc eval sh-abbrevs shell
-;;; "case" 'sh-case
-;;; "function" 'sh-function)
-
-;;; (sh eval sh-abbrevs shell
-;;; "case" 'sh-case
-;;; "function" 'sh-function
-;;; "until" 'sh-until
-;;; "getopts" 'sh-while-getopts)
-
-;;; ;; The next entry is only used for defining the others
-;;; (shell "for" sh-for
-;;; "loop" sh-indexed-loop
-;;; "if" sh-if
-;;; "tmpfile" sh-tmp-file
-;;; "while" sh-while)
-
-;;; (zsh eval sh-abbrevs ksh88
-;;; "repeat" 'sh-repeat))
-;;; "Abbrev-table used in Shell-Script mode. See `sh-feature'.
-;;;Due to the internal workings of abbrev tables, the shell name symbol is
-;;;actually defined as the table for the like of \\[edit-abbrevs].")
-
-
-
-(defvar sh-mode-syntax-table
- '((sh eval sh-mode-syntax-table ()
- ?\# "<"
- ?\^l ">#"
- ?\n ">#"
- ?\" "\"\""
- ?\' "\"'"
- ?\` "\"`"
- ?$ "\\" ; `escape' so $# doesn't start a comment
- ?! "_"
- ?% "_"
- ?: "_"
- ?. "_"
- ?^ "_"
- ?~ "_")
- (csh eval identity sh)
- (rc eval identity sh))
- "Syntax-table used in Shell-Script mode. See `sh-feature'.")
-
-
-
-(defvar sh-mode-map
- (let ((map (make-sparse-keymap))
- (menu-map (make-sparse-keymap "Insert")))
- (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-t" 'sh-tmp-file)
- (define-key map "\C-c\C-s" 'sh-select)
- (define-key map "\C-c\C-r" 'sh-repeat)
- (define-key map "\C-c\C-o" 'sh-while-getopts)
- (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 "=" 'sh-assignment)
- (define-key map "\C-c+" 'sh-add)
- (define-key map "\C-\M-x" 'sh-execute-region)
- (define-key map "\C-c\C-x" 'executable-interpret)
- (define-key map "<" 'sh-maybe-here-document)
- (define-key map "(" 'skeleton-pair-insert-maybe)
- (define-key map "{" 'skeleton-pair-insert-maybe)
- (define-key map "[" 'skeleton-pair-insert-maybe)
- (define-key map "'" 'skeleton-pair-insert-maybe)
- (define-key map "`" 'skeleton-pair-insert-maybe)
- (define-key map "\"" 'skeleton-pair-insert-maybe)
-
- (define-key map "\t" 'sh-indent-line)
- (substitute-key-definition 'complete-tag 'comint-dynamic-complete
- map (current-global-map))
- (substitute-key-definition 'newline-and-indent 'sh-newline-and-indent
- map (current-global-map))
- (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))
- (define-key map [menu-bar insert] (cons "Insert" menu-map))
- (define-key menu-map [sh-while] '("While Loop" . sh-while))
- (define-key menu-map [sh-until] '("Until Loop" . sh-until))
- (define-key menu-map [sh-tmp-file] '("Temporary File" . sh-tmp-file))
- (define-key menu-map [sh-select] '("Select Statement" . sh-select))
- (define-key menu-map [sh-repeat] '("Repeat Loop" . sh-repeat))
- (define-key menu-map [sh-while-getopts]
- '("Options Loop" . sh-while-getopts))
- (define-key menu-map [sh-indexed-loop]
- '("Indexed Loop" . sh-indexed-loop))
- (define-key menu-map [sh-if] '("If Statement" . sh-if))
- (define-key menu-map [sh-for] '("For Loop" . sh-for))
- (define-key menu-map [sh-case] '("Case Statement" . sh-case))
- map)
- "Keymap used in Shell-Script mode.")
-
-
-
-(defvar sh-dynamic-complete-functions
- '(shell-dynamic-complete-environment-variable
- shell-dynamic-complete-command
- comint-dynamic-complete-filename)
- "*Functions for doing TAB dynamic completion.")
-
-
-(defvar sh-require-final-newline
- '((csh . t)
- (pdksh . t)
- (rc eval . require-final-newline)
- (sh eval . require-final-newline))
- "*Value of `require-final-newline' in Shell-Script mode buffers.
-See `sh-feature'.")
-
-
-(defvar sh-assignment-regexp
- '((csh . "\\<\\([a-zA-Z0-9_]+\\)\\(\\[.+\\]\\)?[ \t]*[-+*/%^]?=")
- ;; actually spaces are only supported in let/(( ... ))
- (ksh88 . "\\<\\([a-zA-Z0-9_]+\\)\\(\\[.+\\]\\)?[ \t]*\\([-+*/%&|~^]\\|<<\\|>>\\)?=")
- (rc . "\\<\\([a-zA-Z0-9_*]+\\)[ \t]*=")
- (sh . "\\<\\([a-zA-Z0-9_]+\\)="))
- "*Regexp for the variable name and what may follow in an assignment.
-First grouping matches the variable name. This is upto and including the `='
-sign. See `sh-feature'.")
-
-
-(defvar sh-indentation 4
- "The width for further indentation in Shell-Script mode.")
-
-
-(defvar sh-remember-variable-min 3
- "*Don't remember variables less than this length for completing reads.")
-
-
-(defvar sh-header-marker nil
- "When non-`nil' is the end of header for prepending by \\[sh-execute-region].
-That command is also used for setting this variable.")
-
-
-(defvar sh-beginning-of-command
- "\\([;({`|&]\\|\\`\\|[^\\]\n\\)[ \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-here-document-word "EOF"
- "Word to delimit here documents.")
-
-(defvar sh-test
- '((sh "[ ]" . 3)
- (ksh88 "[[ ]]" . 4))
- "Initial input in Bourne if, while and until skeletons. See `sh-feature'.")
-
-
-(defvar sh-builtins
- '((bash eval sh-append posix
- "alias" "bg" "bind" "builtin" "declare" "dirs" "enable" "fc" "fg"
- "help" "history" "jobs" "kill" "let" "local" "popd" "pushd" "source"
- "suspend" "typeset" "unalias")
-
- ;; The next entry is only used for defining the others
- (bourne eval sh-append shell
- "eval" "export" "getopts" "newgrp" "pwd" "read" "readonly"
- "times" "ulimit")
-
- (csh eval sh-append shell
- "alias" "chdir" "glob" "history" "limit" "nice" "nohup" "rehash"
- "setenv" "source" "time" "unalias" "unhash")
-
- (dtksh eval identity wksh)
-
- (es "access" "apids" "cd" "echo" "eval" "false" "let" "limit" "local"
- "newpgrp" "result" "time" "umask" "var" "vars" "wait" "whatis")
-
- (jsh eval sh-append sh
- "bg" "fg" "jobs" "kill" "stop" "suspend")
-
- (jcsh eval sh-append csh
- "bg" "fg" "jobs" "kill" "notify" "stop" "suspend")
-
- (ksh88 eval sh-append bourne
- "alias" "bg" "false" "fc" "fg" "jobs" "kill" "let" "print" "time"
- "typeset" "unalias" "whence")
-
- (oash eval sh-append sh
- "checkwin" "dateline" "error" "form" "menu" "newwin" "oadeinit"
- "oaed" "oahelp" "oainit" "pp" "ppfile" "scan" "scrollok" "wattr"
- "wclear" "werase" "win" "wmclose" "wmmessage" "wmopen" "wmove"
- "wmtitle" "wrefresh")
-
- (pdksh eval sh-append ksh88
- "bind")
-
- (posix eval sh-append sh
- "command")
-
- (rc "builtin" "cd" "echo" "eval" "limit" "newpgrp" "shift" "umask" "wait"
- "whatis")
-
- (sh eval sh-append bourne
- "hash" "test" "type")
-
- ;; The next entry is only used for defining the others
- (shell "cd" "echo" "eval" "set" "shift" "umask" "unset" "wait")
-
- (wksh eval sh-append ksh88
- "Xt[A-Z][A-Za-z]*")
-
- (zsh eval sh-append ksh88
- "autoload" "bindkey" "builtin" "chdir" "compctl" "declare" "dirs"
- "disable" "disown" "echotc" "enable" "functions" "getln" "hash"
- "history" "integer" "limit" "local" "log" "popd" "pushd" "r"
- "readonly" "rehash" "sched" "setopt" "source" "suspend" "true"
- "ttyctl" "type" "unfunction" "unhash" "unlimit" "unsetopt" "vared"
- "which"))
- "*List of all shell builtins for completing read and fontification.
-Note that on some systems not all builtins are available or some are
-implemented as aliases. See `sh-feature'.")
-
-
-
-(defvar sh-leading-keywords
- '((csh "else")
-
- (es "true" "unwind-protect" "whatis")
-
- (rc "else")
-
- (sh "do" "elif" "else" "if" "then" "trap" "type" "until" "while"))
- "*List of keywords that may be immediately followed by a builtin or keyword.
-Given some confusion between keywords and builtins depending on shell and
-system, the distinction here has been based on whether they influence the
-flow of control or syntax. See `sh-feature'.")
-
-
-(defvar sh-other-keywords
- '((bash eval sh-append bourne
- "bye" "logout")
-
- ;; The next entry is only used for defining the others
- (bourne eval sh-append sh
- "function")
-
- (csh eval sh-append shell
- "breaksw" "default" "end" "endif" "endsw" "foreach" "goto"
- "if" "logout" "onintr" "repeat" "switch" "then" "while")
-
- (es "break" "catch" "exec" "exit" "fn" "for" "forever" "fork" "if"
- "return" "throw" "while")
-
- (ksh88 eval sh-append bourne
- "select")
-
- (rc "break" "case" "exec" "exit" "fn" "for" "if" "in" "return" "switch"
- "while")
-
- (sh eval sh-append shell
- "done" "esac" "fi" "for" "in" "return")
-
- ;; The next entry is only used for defining the others
- (shell "break" "case" "continue" "exec" "exit")
-
- (zsh eval sh-append bash
- "select"))
- "*List of keywords not in `sh-leading-keywords'.
-See `sh-feature'.")
-
-
-
-(defvar sh-variables
- '((bash eval sh-append sh
- "allow_null_glob_expansion" "auto_resume" "BASH" "BASH_VERSION"
- "cdable_vars" "ENV" "EUID" "FCEDIT" "FIGNORE" "glob_dot_filenames"
- "histchars" "HISTFILE" "HISTFILESIZE" "history_control" "HISTSIZE"
- "hostname_completion_file" "HOSTTYPE" "IGNOREEOF" "ignoreeof"
- "LINENO" "MAIL_WARNING" "noclobber" "nolinks" "notify"
- "no_exit_on_failed_exec" "NO_PROMPT_VARS" "OLDPWD" "OPTERR" "PPID"
- "PROMPT_COMMAND" "PS4" "pushd_silent" "PWD" "RANDOM" "REPLY"
- "SECONDS" "SHLVL" "TMOUT" "UID")
-
- (csh eval sh-append shell
- "argv" "cdpath" "child" "echo" "histchars" "history" "home"
- "ignoreeof" "mail" "noclobber" "noglob" "nonomatch" "path" "prompt"
- "shell" "status" "time" "verbose")
-
- (es eval sh-append shell
- "apid" "cdpath" "CDPATH" "history" "home" "ifs" "noexport" "path"
- "pid" "prompt" "signals")
-
- (jcsh eval sh-append csh
- "notify")
-
- (ksh88 eval sh-append sh
- "ENV" "ERRNO" "FCEDIT" "FPATH" "HISTFILE" "HISTSIZE" "LINENO"
- "OLDPWD" "PPID" "PS3" "PS4" "PWD" "RANDOM" "REPLY" "SECONDS"
- "TMOUT")
-
- (oash eval sh-append sh
- "FIELD" "FIELD_MAX" "LAST_KEY" "OALIB" "PP_ITEM" "PP_NUM")
-
- (rc eval sh-append shell
- "apid" "apids" "cdpath" "CDPATH" "history" "home" "ifs" "path" "pid"
- "prompt" "status")
-
- (sh eval sh-append shell
- "CDPATH" "IFS" "OPTARG" "OPTIND" "PS1" "PS2")
-
- ;; The next entry is only used for defining the others
- (shell "COLUMNS" "EDITOR" "HOME" "HUSHLOGIN" "LANG" "LC_COLLATE"
- "LC_CTYPE" "LC_MESSAGES" "LC_MONETARY" "LC_NUMERIC" "LC_TIME"
- "LINES" "LOGNAME" "MAIL" "MAILCHECK" "MAILPATH" "PAGER" "PATH"
- "SHELL" "TERM" "TERMCAP" "TERMINFO" "VISUAL")
-
- (tcsh eval sh-append csh
- "addsuffix" "ampm" "autocorrect" "autoexpand" "autolist"
- "autologout" "chase_symlinks" "correct" "dextract" "edit" "el"
- "fignore" "gid" "histlit" "HOST" "HOSTTYPE" "HPATH"
- "ignore_symlinks" "listjobs" "listlinks" "listmax" "matchbeep"
- "nobeep" "NOREBIND" "oid" "printexitvalue" "prompt2" "prompt3"
- "pushdsilent" "pushdtohome" "recexact" "recognize_only_executables"
- "rmstar" "savehist" "SHLVL" "showdots" "sl" "SYSTYPE" "tcsh" "term"
- "tperiod" "tty" "uid" "version" "visiblebell" "watch" "who"
- "wordchars")
-
- (zsh eval sh-append ksh88
- "BAUD" "bindcmds" "cdpath" "DIRSTACKSIZE" "fignore" "FIGNORE" "fpath"
- "HISTCHARS" "hostcmds" "hosts" "HOSTS" "LISTMAX" "LITHISTSIZE"
- "LOGCHECK" "mailpath" "manpath" "NULLCMD" "optcmds" "path" "POSTEDIT"
- "prompt" "PROMPT" "PROMPT2" "PROMPT3" "PROMPT4" "psvar" "PSVAR"
- "READNULLCMD" "REPORTTIME" "RPROMPT" "RPS1" "SAVEHIST" "SPROMPT"
- "STTY" "TIMEFMT" "TMOUT" "TMPPREFIX" "varcmds" "watch" "WATCH"
- "WATCHFMT" "WORDCHARS" "ZDOTDIR"))
- "List of all shell variables available for completing read.
-See `sh-feature'.")
-
-
-
-(defvar sh-font-lock-keywords
- '((csh eval sh-append shell
- '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1
- font-lock-variable-name-face))
-
- (es eval sh-append executable-font-lock-keywords
- '("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1
- font-lock-variable-name-face))
-
- (rc eval identity es)
-
- (sh eval sh-append shell
- '("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2
- font-lock-variable-name-face))
-
- ;; The next entry is only used for defining the others
- (shell eval sh-append executable-font-lock-keywords
- '("\\\\[^A-Za-z0-9]" 0 font-lock-string-face)
- '("\\${?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\|[$*_]\\)" 1
- font-lock-variable-name-face)))
- "*Rules for highlighting shell scripts. See `sh-feature'.")
-
-(defvar sh-font-lock-keywords-1
- '((sh "[ \t]in\\>"))
- "*Additional rules for highlighting shell scripts. See `sh-feature'.")
-
-(defvar sh-font-lock-keywords-2 ()
- "*Yet more rules for highlighting shell scripts. See `sh-feature'.")
-
-
-;; mode-command and utility functions
-
-;;;###autoload
-(put 'sh-mode 'mode-class 'special)
-
-;;;###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.
-
-This mode adapts to the variations between shells (see `sh-set-shell') by
-means of an inheritance based feature lookup (see `sh-feature'). This
-mechanism applies to all variables (including skeletons) that pertain to
-shell-specific features.
-
-The default style of this mode is that of Rosenblatt's Korn shell book.
-The syntax of the statements varies with the shell being used. 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-while-getopts] while getopts loop
-\\[sh-repeat] repeat loop
-\\[sh-select] select loop
-\\[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-execute-region] Have optional header and region be executed in a subshell.
-
-\\[sh-maybe-here-document] Without prefix, following an unquoted < inserts here document.
-{, (, [, ', \", `
- Unless quoted with \\, insert the pairs {}, (), [], or '', \"\", ``.
-
-If you generally program a shell different from your login shell you can
-set `sh-shell-file' accordingly. If your shell's file name doesn't correctly
-indicate what shell it is use `sh-alias-alist' to translate.
-
-If your shell gives error messages with line numbers, you can use \\[executable-interpret]
-with your script for an edit-interpret-debug cycle."
- (interactive)
- (kill-all-local-variables)
- (use-local-map sh-mode-map)
- (make-local-variable 'indent-line-function)
- (make-local-variable 'indent-region-function)
- (make-local-variable 'skeleton-end-hook)
- (make-local-variable 'paragraph-start)
- (make-local-variable 'paragraph-separate)
- (make-local-variable 'comment-start)
- (make-local-variable 'comment-start-skip)
- (make-local-variable 'require-final-newline)
- (make-local-variable 'sh-header-marker)
- (make-local-variable 'sh-shell-file)
- (make-local-variable 'sh-shell)
- (make-local-variable 'skeleton-pair-alist)
- (make-local-variable 'skeleton-pair-filter)
- (make-local-variable 'comint-dynamic-complete-functions)
- (make-local-variable 'comint-prompt-regexp)
- (make-local-variable 'font-lock-defaults)
- (make-local-variable 'skeleton-filter)
- (make-local-variable 'skeleton-newline-indent-rigidly)
- (make-local-variable 'sh-shell-variables)
- (make-local-variable 'sh-shell-variables-initialized)
- (setq major-mode 'sh-mode
- mode-name "Shell-script"
- indent-line-function 'sh-indent-line
- ;; not very clever, but enables wrapping skeletons around regions
- indent-region-function (lambda (b e)
- (save-excursion
- (goto-char b)
- (skip-syntax-backward "-")
- (setq b (point))
- (goto-char e)
- (skip-syntax-backward "-")
- (indent-rigidly b (point) sh-indentation)))
- skeleton-end-hook (lambda ()
- (or (eolp) (newline) (indent-relative)))
- paragraph-start (concat page-delimiter "\\|$")
- paragraph-separate paragraph-start
- comment-start "# "
- comint-dynamic-complete-functions sh-dynamic-complete-functions
- ;; we can't look if previous line ended with `\'
- comint-prompt-regexp "^[ \t]*"
- font-lock-defaults
- `((sh-font-lock-keywords
- sh-font-lock-keywords-1
- sh-font-lock-keywords-2)
- nil nil
- ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")))
- skeleton-pair-alist '((?` _ ?`))
- skeleton-pair-filter 'sh-quoted-p
- skeleton-further-elements '((< '(- (min sh-indentation
- (current-column)))))
- skeleton-filter 'sh-feature
- skeleton-newline-indent-rigidly t)
- ;; Parse or insert magic number for exec, and set all variables depending
- ;; on the shell thus determined.
- (let ((interpreter
- (save-excursion
- (goto-char (point-min))
- (if (looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")
- (buffer-substring (match-beginning 2)
- (match-end 2))))))
- (if interpreter
- (sh-set-shell interpreter nil nil)))
- (run-hooks 'sh-mode-hook))
-;;;###autoload
-(defalias 'shell-script-mode 'sh-mode)
-
-
-(defun sh-font-lock-keywords (&optional keywords)
- "Function to get simple fontification based on `sh-font-lock-keywords'.
-This adds rules for comments and assignments."
- (sh-feature sh-font-lock-keywords
- (lambda (list)
- `((,(sh-feature sh-assignment-regexp)
- 1 font-lock-variable-name-face)
- ,@keywords
- ,@list))))
-
-(defun sh-font-lock-keywords-1 (&optional builtins)
- "Function to get better fontification including keywords."
- (let ((keywords (concat "\\([;(){}`|&]\\|^\\)[ \t]*\\(\\(\\("
- (mapconcat 'identity
- (sh-feature sh-leading-keywords)
- "\\|")
- "\\)[ \t]+\\)?\\("
- (mapconcat 'identity
- (append (sh-feature sh-leading-keywords)
- (sh-feature sh-other-keywords))
- "\\|")
- "\\)")))
- (sh-font-lock-keywords
- `(,@(if builtins
- `((,(concat keywords "[ \t]+\\)?\\("
- (mapconcat 'identity (sh-feature sh-builtins) "\\|")
- "\\)\\>")
- (2 font-lock-keyword-face nil t)
- (6 font-lock-builtin-face))
- ,@(sh-feature sh-font-lock-keywords-2)))
- (,(concat keywords "\\)\\>")
- 2 font-lock-keyword-face)
- ,@(sh-feature sh-font-lock-keywords-1)))))
-
-(defun sh-font-lock-keywords-2 ()
- "Function to get better fontification including keywords and builtins."
- (sh-font-lock-keywords-1 t))
-
-
-(defun sh-set-shell (shell &optional no-query-flag insert-flag)
- "Set this buffer's shell to SHELL (a string).
-Makes this script executable via `executable-set-magic', and sets up the
-proper starting #!-line, if INSERT-FLAG is non-nil.
-Calls the value of `sh-set-shell-hook' if set."
- (interactive (list (completing-read "Name or path of shell: "
- interpreter-mode-alist
- (lambda (x) (eq (cdr x) 'sh-mode)))
- (eq executable-query 'function)
- t))
- (setq sh-shell (intern (file-name-nondirectory shell))
- sh-shell (or (cdr (assq sh-shell sh-alias-alist))
- sh-shell))
- (if insert-flag
- (setq sh-shell-file
- (executable-set-magic shell (sh-feature sh-shell-arg)
- no-query-flag insert-flag)))
- (setq require-final-newline (sh-feature sh-require-final-newline)
-;;; local-abbrev-table (sh-feature sh-abbrevs)
- font-lock-keywords nil ; force resetting
- font-lock-syntax-table nil
- comment-start-skip "#+[\t ]*"
- mode-line-process (format "[%s]" sh-shell)
- sh-shell-variables nil
- sh-shell-variables-initialized nil
- shell (sh-feature sh-variables))
- (set-syntax-table (sh-feature sh-mode-syntax-table))
- (while shell
- (sh-remember-variable (car shell))
- (setq shell (cdr shell)))
- (and (boundp 'font-lock-mode)
- font-lock-mode
- (font-lock-mode (font-lock-mode 0)))
- (run-hooks 'sh-set-shell-hook))
-
-
-
-(defun sh-feature (list &optional function)
- "Index ALIST by the current shell.
-If ALIST isn't a list where every element is a cons, it is returned as is.
-Else indexing follows an inheritance logic which works in two ways:
-
- - Fall back on successive ancestors (see `sh-ancestor-alist') as long as
- the alist contains no value for the current shell.
-
- - If the value thus looked up is a list starting with `eval' its `cdr' is
- first evaluated. If that is also a list and the first argument is a
- symbol in ALIST it is not evaluated, but rather recursively looked up in
- ALIST to allow the function called to define the value for one shell to be
- derived from another shell. While calling the function, is the car of the
- alist element is the current shell.
- The value thus determined is physically replaced into the alist.
-
-Optional FUNCTION is applied to the determined value and the result is cached
-in ALIST."
- (or (if (consp list)
- (let ((l list))
- (while (and l (consp (car l)))
- (setq l (cdr l)))
- (if l list)))
- (if function
- (cdr (assoc (setq function (cons sh-shell function)) list)))
- (let ((sh-shell sh-shell)
- elt val)
- (while (and sh-shell
- (not (setq elt (assq sh-shell list))))
- (setq sh-shell (cdr (assq sh-shell sh-ancestor-alist))))
- (if (and (consp (setq val (cdr elt)))
- (eq (car val) 'eval))
- (setcdr elt
- (setq val
- (eval (if (consp (setq val (cdr val)))
- (let ((sh-shell (car (cdr val)))
- function)
- (if (assq sh-shell list)
- (setcar (cdr val)
- (list 'quote
- (sh-feature list))))
- val)
- val)))))
- (if function
- (nconc list
- (list (cons function
- (setq sh-shell (car function)
- val (funcall (cdr function) val))))))
- val)))
-
-
-
-;;; I commented this out because nobody calls it -- rms.
-;;;(defun sh-abbrevs (ancestor &rest list)
-;;; "Iff it isn't, define the current shell as abbrev table and fill that.
-;;;Abbrev table will inherit all abbrevs from ANCESTOR, which is either an abbrev
-;;;table or a list of (NAME1 EXPANSION1 ...). In addition it will define abbrevs
-;;;according to the remaining arguments NAMEi EXPANSIONi ...
-;;;EXPANSION may be either a string or a skeleton command."
-;;; (or (if (boundp sh-shell)
-;;; (symbol-value sh-shell))
-;;; (progn
-;;; (if (listp ancestor)
-;;; (nconc list ancestor))
-;;; (define-abbrev-table sh-shell ())
-;;; (if (vectorp ancestor)
-;;; (mapatoms (lambda (atom)
-;;; (or (eq atom 0)
-;;; (define-abbrev (symbol-value sh-shell)
-;;; (symbol-name atom)
-;;; (symbol-value atom)
-;;; (symbol-function atom))))
-;;; ancestor))
-;;; (while list
-;;; (define-abbrev (symbol-value sh-shell)
-;;; (car list)
-;;; (if (stringp (car (cdr list)))
-;;; (car (cdr list))
-;;; "")
-;;; (if (symbolp (car (cdr list)))
-;;; (car (cdr list))))
-;;; (setq list (cdr (cdr list)))))
-;;; (symbol-value sh-shell)))
-
-
-(defun sh-mode-syntax-table (table &rest list)
- "Copy TABLE and set syntax for successive CHARs according to strings S."
- (setq table (copy-syntax-table table))
- (while list
- (modify-syntax-entry (car list) (car (cdr list)) table)
- (setq list (cdr (cdr list))))
- table)
-
-
-(defun sh-append (ancestor &rest list)
- "Return list composed of first argument (a list) physically appended to rest."
- (nconc list ancestor))
-
-
-(defun sh-modify (skeleton &rest list)
- "Modify a copy of SKELETON by replacing I1 with REPL1, I2 with REPL2 ..."
- (setq skeleton (copy-sequence skeleton))
- (while list
- (setcar (or (nthcdr (car list) skeleton)
- (error "Index %d out of bounds" (car list)))
- (car (cdr list)))
- (setq list (nthcdr 2 list)))
- skeleton)
-
-
-(defun sh-indent-line ()
- "Indent as far as preceding non-empty line, then by steps of `sh-indentation'.
-Lines containing only comments are considered empty."
- (interactive)
- (let ((previous (save-excursion
- (while (and (not (bobp))
- (progn
- (forward-line -1)
- (back-to-indentation)
- (or (eolp)
- (eq (following-char) ?#)))))
- (current-column)))
- current)
- (save-excursion
- (indent-to (if (eq this-command 'newline-and-indent)
- previous
- (if (< (current-column)
- (setq current (progn (back-to-indentation)
- (current-column))))
- (if (eolp) previous 0)
- (delete-region (point)
- (progn (beginning-of-line) (point)))
- (if (eolp)
- (max previous (* (1+ (/ current sh-indentation))
- sh-indentation))
- (* (1+ (/ current sh-indentation)) sh-indentation))))))
- (if (< (current-column) (current-indentation))
- (skip-chars-forward " \t"))))
-
-
-(defun sh-execute-region (start end &optional flag)
- "Pass optional header and region to a subshell for noninteractive execution.
-The working directory is that of the buffer, and only environment variables
-are already set which is why you can mark a header within the script.
-
-With a positive prefix ARG, instead of sending region, define header from
-beginning of buffer to point. With a negative prefix ARG, instead of sending
-region, clear header."
- (interactive "r\nP")
- (if flag
- (setq sh-header-marker (if (> (prefix-numeric-value flag) 0)
- (point-marker)))
- (if sh-header-marker
- (save-excursion
- (let (buffer-undo-list)
- (goto-char sh-header-marker)
- (append-to-buffer (current-buffer) start end)
- (shell-command-on-region (point-min)
- (setq end (+ sh-header-marker
- (- end start)))
- sh-shell-file)
- (delete-region sh-header-marker end)))
- (shell-command-on-region start end (concat sh-shell-file " -")))))
-
-
-(defun sh-remember-variable (var)
- "Make VARIABLE available for future completing reads in this buffer."
- (or (< (length var) sh-remember-variable-min)
- (getenv var)
- (assoc var sh-shell-variables)
- (setq sh-shell-variables (cons (cons var var) sh-shell-variables)))
- var)
-
-
-
-(defun sh-quoted-p ()
- "Is point preceded by an odd number of backslashes?"
- (eq -1 (% (save-excursion (skip-chars-backward "\\\\")) 2)))
-
-;; 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-skeleton sh-case
- "Insert a case/switch statement. See `sh-feature'."
- (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")
- (es)
- (rc "expression: "
- "switch( " str " ) {" \n
- > "case " (read-string "pattern: ") \n
- > _ \n
- ( "other pattern, %s: "
- < "case " str \n
- > _ \n)
- < "case *" \n
- > _ \n
- resume:
- < < ?})
- (sh "expression: "
- "case " str " in" \n
- > (read-string "pattern: ") ?\) \n
- > _ \n
- ";;" \n
- ( "other pattern, %s: "
- < str ?\) \n
- > _ \n
- ";;" \n)
- < "*)" \n
- > _ \n
- resume:
- < < "esac"))
-(put 'sh-case 'menu-enable '(sh-feature sh-case))
-
-
-
-(define-skeleton sh-for
- "Insert a for loop. See `sh-feature'."
- (csh eval sh-modify sh
- 1 "foreach "
- 3 " ( "
- 5 " )"
- 15 "end")
- (es eval sh-modify rc
- 3 " = ")
- (rc eval sh-modify sh
- 1 "for( "
- 5 " ) {"
- 15 ?})
- (sh "Index variable: "
- "for " str " in " _ "; do" \n
- > _ | ?$ & (sh-remember-variable str) \n
- < "done"))
-
-
-
-(define-skeleton sh-indexed-loop
- "Insert an indexed loop from 1 to n. See `sh-feature'."
- (bash eval identity posix)
- (csh "Index variable: "
- "@ " str " = 1" \n
- "while( $" str " <= " (read-string "upper limit: ") " )" \n
- > _ ?$ str \n
- "@ " str "++" \n
- < "end")
- (es eval sh-modify rc
- 3 " =")
- (ksh88 "Index variable: "
- "integer " str "=0" \n
- "while (( ( " str " += 1 ) <= "
- (read-string "upper limit: ")
- " )); do" \n
- > _ ?$ (sh-remember-variable str) \n
- < "done")
- (posix "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")
- (rc "Index variable: "
- "for( " str " in" " `{awk 'BEGIN { for( i=1; i<="
- (read-string "upper limit: ")
- "; i++ ) print i }'}) {" \n
- > _ ?$ (sh-remember-variable str) \n
- < ?})
- (sh "Index variable: "
- "for " str " in `awk 'BEGIN { for( i=1; i<="
- (read-string "upper limit: ")
- "; i++ ) print i }'`; do" \n
- > _ ?$ (sh-remember-variable str) \n
- < "done"))
-
-
-(defun sh-shell-initialize-variables ()
- "Scan the buffer for variable assignments.
-Add these variables to `sh-shell-variables'."
- (message "Scanning buffer `%s' for variable assignments..." (buffer-name))
- (save-excursion
- (goto-char (point-min))
- (setq sh-shell-variables-initialized t)
- (while (search-forward "=" nil t)
- (sh-assignment 0)))
- (message "Scanning buffer `%s' for variable assignments...done"
- (buffer-name)))
-
-(defvar sh-add-buffer)
-
-(defun sh-add-completer (string predicate code)
- "Do completion using `sh-shell-variables', but initialize it first.
-This function is designed for use as the \"completion table\",
-so it takes three arguments:
- STRING, the current buffer contents;
- PREDICATE, the predicate for filtering possible matches;
- CODE, which says what kind of things to do.
-CODE can be nil, t or `lambda'.
-nil means to return the best completion of STRING, or nil if there is none.
-t means to return a list of all possible completions of STRING.
-`lambda' means to return t if STRING is a valid completion as it stands."
- (let ((sh-shell-variables
- (save-excursion
- (set-buffer sh-add-buffer)
- (or sh-shell-variables-initialized
- (sh-shell-initialize-variables))
- (nconc (mapcar (lambda (var)
- (let ((name
- (substring var 0 (string-match "=" var))))
- (cons name name)))
- process-environment)
- sh-shell-variables))))
- (cond ((null code)
- (try-completion string sh-shell-variables predicate))
- ((eq code t)
- (all-completions string sh-shell-variables predicate))
- ((eq code 'lambda)
- (assoc string sh-shell-variables)))))
-
-(defun sh-add (var delta)
- "Insert an addition of VAR and prefix DELTA for Bourne (type) shell."
- (interactive
- (let ((sh-add-buffer (current-buffer)))
- (list (completing-read "Variable: " 'sh-add-completer)
- (prefix-numeric-value current-prefix-arg))))
- (insert (sh-feature '((bash . "$[ ")
- (ksh88 . "$(( ")
- (posix . "$(( ")
- (rc . "`{expr $")
- (sh . "`expr $")
- (zsh . "$[ ")))
- (sh-remember-variable var)
- (if (< delta 0) " - " " + ")
- (number-to-string (abs delta))
- (sh-feature '((bash . " ]")
- (ksh88 . " ))")
- (posix . " ))")
- (rc . "}")
- (sh . "`")
- (zsh . " ]")))))
-
-
-
-(define-skeleton sh-function
- "Insert a function definition. See `sh-feature'."
- (bash eval sh-modify ksh88
- 3 "() {")
- (ksh88 "name: "
- "function " str " {" \n
- > _ \n
- < "}")
- (rc eval sh-modify ksh88
- 1 "fn ")
- (sh ()
- "() {" \n
- > _ \n
- < "}"))
-
-
-
-(define-skeleton sh-if
- "Insert an if statement. See `sh-feature'."
- (csh "condition: "
- "if( " str " ) then" \n
- > _ \n
- ( "other condition, %s: "
- < "else if( " str " ) then" \n
- > _ \n)
- < "else" \n
- > _ \n
- resume:
- < "endif")
- (es "condition: "
- "if { " str " } {" \n
- > _ \n
- ( "other condition, %s: "
- < "} { " str " } {" \n
- > _ \n)
- < "} {" \n
- > _ \n
- resume:
- < ?})
- (rc eval sh-modify csh
- 3 " ) {"
- 8 '( "other condition, %s: "
- < "} else if( " str " ) {" \n
- > _ \n)
- 10 "} else {"
- 17 ?})
- (sh "condition: "
- '(setq input (sh-feature sh-test))
- "if " str "; then" \n
- > _ \n
- ( "other condition, %s: "
- < "elif " str "; then" \n
- > _ \n)
- < "else" \n
- > _ \n
- resume:
- < "fi"))
-
-
-
-(define-skeleton sh-repeat
- "Insert a repeat loop definition. See `sh-feature'."
- (es nil
- "forever {" \n
- > _ \n
- < ?})
- (zsh "factor: "
- "repeat " str "; do"\n
- > _ \n
- < "done"))
-(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat))
-
-
-
-(define-skeleton sh-select
- "Insert a select statement. See `sh-feature'."
- (ksh88 "Index variable: "
- "select " str " in " _ "; do" \n
- > ?$ str \n
- < "done"))
-(put 'sh-select 'menu-enable '(sh-feature sh-select))
-
-
-
-(define-skeleton sh-tmp-file
- "Insert code to setup temporary file handling. See `sh-feature'."
- (bash eval identity ksh88)
- (csh (file-name-nondirectory (buffer-file-name))
- "set tmp = /tmp/" str ".$$" \n
- "onintr exit" \n _
- (and (goto-char (point-max))
- (not (bolp))
- ?\n)
- "exit:\n"
- "rm $tmp* >&/dev/null" >)
- (es (file-name-nondirectory (buffer-file-name))
- "local( signals = $signals sighup sigint; tmp = /tmp/" str ".$pid ) {" \n
- > "catch @ e {" \n
- > "rm $tmp^* >[2]/dev/null" \n
- "throw $e" \n
- < "} {" \n
- > _ \n
- < ?} \n
- < ?})
- (ksh88 eval sh-modify sh
- 6 "EXIT")
- (rc (file-name-nondirectory (buffer-file-name))
- "tmp = /tmp/" str ".$pid" \n
- "fn sigexit { rm $tmp^* >[2]/dev/null }")
- (sh (file-name-nondirectory (buffer-file-name))
- "TMP=/tmp/" str ".$$" \n
- "trap \"rm $TMP* 2>/dev/null\" " ?0))
-
-
-
-(define-skeleton sh-until
- "Insert an until loop. See `sh-feature'."
- (sh "condition: "
- '(setq input (sh-feature sh-test))
- "until " str "; do" \n
- > _ \n
- < "done"))
-(put 'sh-until 'menu-enable '(sh-feature sh-until))
-
-
-
-(define-skeleton sh-while
- "Insert a while loop. See `sh-feature'."
- (csh eval sh-modify sh
- 2 "while( "
- 4 " )"
- 10 "end")
- (es eval sh-modify rc
- 2 "while { "
- 4 " } {")
- (rc eval sh-modify csh
- 4 " ) {"
- 10 ?})
- (sh "condition: "
- '(setq input (sh-feature sh-test))
- "while " str "; do" \n
- > _ \n
- < "done"))
-
-
-
-(define-skeleton sh-while-getopts
- "Insert a while getopts loop. See `sh-feature'.
-Prompts for an options string which consists of letters for each recognized
-option followed by a colon `:' if the option accepts an argument."
- (bash eval sh-modify sh
- 18 "${0##*/}")
- (csh nil
- "while( 1 )" \n
- > "switch( \"$1\" )" \n
- '(setq input '("- x" . 2))
- > >
- ( "option, %s: "
- < "case " '(eval str)
- '(if (string-match " +" str)
- (setq v1 (substring str (match-end 0))
- str (substring str 0 (match-beginning 0)))
- (setq v1 nil))
- str ?: \n
- > "set " v1 & " = $2" | -4 & _ \n
- (if v1 "shift") & \n
- "breaksw" \n)
- < "case --:" \n
- > "shift" \n
- < "default:" \n
- > "break" \n
- resume:
- < < "endsw" \n
- "shift" \n
- < "end")
- (ksh88 eval sh-modify sh
- 16 "print"
- 18 "${0##*/}"
- 36 "OPTIND-1")
- (posix eval sh-modify sh
- 18 "$(basename $0)")
- (sh "optstring: "
- "while getopts :" str " OPT; do" \n
- > "case $OPT in" \n
- > >
- '(setq v1 (append (vconcat str) nil))
- ( (prog1 (if v1 (char-to-string (car v1)))
- (if (eq (nth 1 v1) ?:)
- (setq v1 (nthcdr 2 v1)
- v2 "\"$OPTARG\"")
- (setq v1 (cdr v1)
- v2 nil)))
- < str "|+" str ?\) \n
- > _ v2 \n
- ";;" \n)
- < "*)" \n
- > "echo" " \"usage: " "`basename $0`"
- " [+-" '(setq v1 (point)) str
- '(save-excursion
- (while (search-backward ":" v1 t)
- (replace-match " ARG] [+-" t t)))
- (if (eq (preceding-char) ?-) -5)
- "] [--] ARGS...\"" \n
- "exit 2" \n
- < < "esac" \n
- < "done" \n
- "shift " (sh-add "OPTIND" -1)))
-(put 'sh-while-getopts 'menu-enable '(sh-feature sh-while-getopts))
-
-
-
-(defun sh-assignment (arg)
- "Remember preceding identifier for future completion and do self-insert."
- (interactive "p")
- (self-insert-command arg)
- (if (<= arg 1)
- (sh-remember-variable
- (save-excursion
- (if (re-search-forward (sh-feature sh-assignment-regexp)
- (prog1 (point)
- (beginning-of-line 1))
- t)
- (match-string 1))))))
-
-
-
-(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
- (backward-char 2)
- (sh-quoted-p))
- (progn
- (insert sh-here-document-word)
- (or (eolp) (looking-at "[ \t]") (insert ? ))
- (end-of-line 1)
- (while
- (sh-quoted-p)
- (end-of-line 2))
- (newline)
- (save-excursion (insert ?\n sh-here-document-word)))))
-
-
-;; various other commands
-
-(autoload 'comint-dynamic-complete "comint"
- "Dynamically perform completion at point." t)
-
-(autoload 'shell-dynamic-complete-command "shell"
- "Dynamically complete the command at point." t)
-
-(autoload 'comint-dynamic-complete-filename "comint"
- "Dynamically complete the filename at point." t)
-
-(autoload 'shell-dynamic-complete-environment-variable "shell"
- "Dynamically complete the environment variable at point." t)
-
-
-
-(defun sh-newline-and-indent ()
- "Strip unquoted whitespace, insert newline, and indent like current line."
- (interactive "*")
- (indent-to (prog1 (current-indentation)
- (delete-region (point)
- (progn
- (or (zerop (skip-chars-backward " \t"))
- (if (sh-quoted-p)
- (forward-char)))
- (point)))
- (newline))))
-
-
-
-(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))))
-
-(provide 'sh-script)
-;; sh-script.el ends here
diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el
deleted file mode 100644
index c4de80bfd61..00000000000
--- a/lisp/progmodes/simula.el
+++ /dev/null
@@ -1,1773 +0,0 @@
-;;; simula.el --- SIMULA 87 code editing commands for Emacs
-
-;; Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
-
-;; Author: Hans Henrik Eriksen <hhe@ifi.uio.no>
-;; Maintainer: simula-mode@ifi.uio.no
-;; 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, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, 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:
-
-
-(defconst simula-tab-always-indent-default 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.")
-
-(defvar simula-tab-always-indent simula-tab-always-indent-default
- "*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-default 3
- "Indentation of SIMULA statements with respect to containing block.")
-
-(defvar simula-indent-level simula-indent-level-default
- "*Indentation of SIMULA statements with respect to containing block.")
-
-(defconst simula-substatement-offset-default 3
- "Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.")
-
-(defvar simula-substatement-offset simula-substatement-offset-default
- "*Extra indentation after DO, THEN, ELSE, WHEN and OTHERWISE.")
-
-(defconst simula-continued-statement-offset-default 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.")
-
-(defvar simula-continued-statement-offset simula-continued-statement-offset-default
- "*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-default -4711
- "Offset of SIMULA label lines relative to usual indentation.")
-
-(defvar simula-label-offset simula-label-offset-default
- "*Offset of SIMULA label lines relative to usual indentation.")
-
-(defconst simula-if-indent-default '(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.")
-
-(defvar simula-if-indent simula-if-indent-default
- "*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-default '(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.")
-
-(defvar simula-inspect-indent simula-inspect-indent-default
- "*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-default nil
- "Non-nil means `simula-indent-line' function may reindent previous line.")
-
-(defvar simula-electric-indent simula-electric-indent-default
- "*Non-nil means `simula-indent-line' function may reindent previous line.")
-
-(defconst simula-abbrev-keyword-default '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.")
-
-(defvar simula-abbrev-keyword simula-abbrev-keyword-default
- "*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-default '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-stdproc simula-abbrev-stdproc-default
- "*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.")
-
-;; Regexps written with help from Alf-Ivar Holm <alfh@ifi.uio.no>.
-(defconst simula-font-lock-keywords-1
- (list
- ;;
- ;; Comments and strings.
- '(simula-match-string-or-comment 0
- (if (match-beginning 1) font-lock-string-face font-lock-comment-face))
- ;;
- ;; Compiler directives.
- '("^%\\([^ \t\n].*\\)" 1 font-lock-reference-face)
- ;;
- ;; Class and procedure names.
- '("\\<\\(class\\|procedure\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- )
- "Subdued level highlighting for Simula mode.")
-
-(defconst simula-font-lock-keywords-2
- (append simula-font-lock-keywords-1
- (list
- ;;
- ;; Constants as references.
- '("\\<\\(false\\|none\\|notext\\|true\\)\\>" . font-lock-reference-face)
- ;;
- ;; Keywords.
- (concat "\\<\\("
-; (make-regexp
-; '("activate" "after" "and" "at" "before" "begin" "delay" "do"
-; "else" "end" "eq" "eqv" "external" "for" "ge" "go" "goto" "gt"
-; "hidden" "if" "imp" "in" "inner" "inspect" "is" "label" "le"
-; "lt" "ne" "new" "not" "or" "otherwise" "prior" "protected"
-; "qua" "reactivate" "step" "switch" "then" "this" "to" "until"
-; "virtual" "when" "while"))
- "a\\(ctivate\\|fter\\|nd\\|t\\)\\|be\\(fore\\|gin\\)\\|"
- "d\\(elay\\|o\\)\\|e\\(lse\\|nd\\|qv?\\|xternal\\)\\|for\\|"
- "g\\([eot]\\|oto\\)\\|hidden\\|i\\([fns]\\|mp\\|n\\(ner\\|"
- "spect\\)\\)\\|l\\([et]\\|abel\\)\\|n\\(ew?\\|ot\\)\\|"
- "o\\(r\\|therwise\\)\\|pr\\(ior\\|otected\\)\\|qua\\|"
- "reactivate\\|s\\(tep\\|witch\\)\\|t\\(h\\(en\\|is\\)\\|o\\)\\|"
- "until\\|virtual\\|wh\\(en\\|ile\\)"
- "\\)\\>")
- ;;
- ;; Types.
- (cons (concat "\\<\\(array\\|boolean\\|character\\|integer\\|"
- "long\\|name\\|real\\|short\\|text\\|value\\|ref\\)\\>")
- 'font-lock-type-face)
- ))
- "Medium level highlighting for Simula mode.")
-
-(defconst simula-font-lock-keywords-3
- (append simula-font-lock-keywords-2
- (list
- ;;
- ;; Super-class names and super-slow.
- '("\\<\\(\\sw+\\)[ \t]+class\\>" 1 font-lock-function-name-face)
- ;;
- ;; Types and their declarations.
- (list (concat "\\<\\(array\\|boolean\\|character\\|integer\\|"
- "long\\|name\\|real\\|short\\|text\\|value\\)\\>"
- "\\([ \t]+\\sw+\\>\\)*")
- '(font-lock-match-c-style-declaration-item-and-skip-to-next
- ;; Start with point after all type specifiers.
- (goto-char (or (match-beginning 2) (match-end 1)))
- ;; Finish with point after first type specifier.
- (goto-char (match-end 1))
- ;; Fontify as a variable name.
- (1 font-lock-variable-name-face)))
- ;;
- ;; Object references and their declarations.
- '("\\<\\(ref\\)\\>[ \t]*\\((\\(\\sw+\\))\\)?"
- (3 font-lock-function-name-face nil t)
- (font-lock-match-c-style-declaration-item-and-skip-to-next nil nil
- (1 font-lock-variable-name-face)))
- ))
- "Gaudy level highlighting for Simula mode.")
-
-(defvar simula-font-lock-keywords simula-font-lock-keywords-1
- "Default expressions to highlight in Simula mode.")
-
-; The following function is taken from cc-mode.el,
-; it determines the flavor of the Emacs running
-(defconst simula-emacs-features
- (let ((major (and (boundp 'emacs-major-version)
- emacs-major-version))
- (minor (and (boundp 'emacs-minor-version)
- emacs-minor-version))
- flavor comments)
- ;; figure out version numbers if not already discovered
- (and (or (not major) (not minor))
- (string-match "\\([0-9]+\\).\\([0-9]+\\)" emacs-version)
- (setq major (string-to-int (substring emacs-version
- (match-beginning 1)
- (match-end 1)))
- minor (string-to-int (substring emacs-version
- (match-beginning 2)
- (match-end 2)))))
- (if (not (and major minor))
- (error "Cannot figure out the major and minor version numbers."))
- ;; calculate the major version
- (cond
- ((= major 18) (setq major 'v18)) ;Emacs 18
- ((= major 4) (setq major 'v18)) ;Epoch 4
- ((= major 19) (setq major 'v19 ;Emacs 19
- flavor (if (string-match "Lucid" emacs-version)
- 'Lucid 'FSF)))
- ;; I don't know
- (t (error "Cannot recognize major version number: %s" major)))
- (list major flavor comments))
- "A list of features extant in the Emacs you are using.
-There are many flavors of Emacs out there, each with different
-features supporting those needed by simula-mode. Here's the current
-supported list, along with the values for this variable:
-
- Emacs 19: (v19 FSF 1-bit)
- Vanilla Emacs 18/Epoch 4: (v18 no-dual-comments)
- Emacs 18/Epoch 4 (patch2): (v18 8-bit)
- Lucid Emacs 19: (v19 Lucid 8-bit).")
-
-(defvar simula-mode-menu
- '(["Report Bug" simula-submit-bug-report t]
- ["Indent Line" simula-indent-line t]
- ["Backward Statement" simula-previous-statement t]
- ["Forward Statement" simula-next-statement t]
- ["Backward Up Level" simula-backward-up-level t]
- ["Forward Down Statement" simula-forward-down-level t]
- )
- "Lucid Emacs menu for SIMULA mode.")
-
-(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 ?_ "_" 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 "\e\C-q" 'simula-indent-exp)
- (define-key simula-mode-map "\t" 'simula-indent-command)
- ;; Emacs 19 defines menus in the mode map
- (if (memq 'FSF simula-emacs-features)
- (progn
- (define-key simula-mode-map [menu-bar] (make-sparse-keymap))
-
- (define-key simula-mode-map [menu-bar simula]
- (cons "SIMULA" (make-sparse-keymap "SIMULA")))
- (define-key simula-mode-map [menu-bar simula bug-report]
- '("Submit Bug Report" . simula-submit-bug-report))
- (define-key simula-mode-map [menu-bar simula separator-indent]
- '("--"))
- (define-key simula-mode-map [menu-bar simula indent-exp]
- '("Indent Expression" . simula-indent-exp))
- (define-key simula-mode-map [menu-bar simula indent-line]
- '("Indent Line" . simula-indent-command))
- (define-key simula-mode-map [menu-bar simula separator-navigate]
- '("--"))
- (define-key simula-mode-map [menu-bar simula backward-stmt]
- '("Previous Statement" . simula-previous-statement))
- (define-key simula-mode-map [menu-bar simula forward-stmt]
- '("Next Statement" . simula-next-statement))
- (define-key simula-mode-map [menu-bar simula backward-up]
- '("Backward Up Level" . simula-backward-up-level))
- (define-key simula-mode-map [menu-bar simula forward-down]
- '("Forward Down Statement" . simula-forward-down-level))
-
- (put 'simula-next-statement 'menu-enable '(not (eobp)))
- (put 'simula-previous-statement 'menu-enable '(not (bobp)))
- (put 'simula-forward-down-level 'menu-enable '(not (eobp)))
- (put 'simula-backward-up-level 'menu-enable '(not (bobp)))
- (put 'simula-indent-command 'menu-enable '(not buffer-read-only))
- (put 'simula-indent-exp 'menu-enable '(not buffer-read-only))))
-
- ;; RMS: mouse-3 should not select this menu. mouse-3's global
- ;; definition is useful in SIMULA mode and we should not interfere
- ;; with that. The menu is mainly for beginners, and for them,
- ;; the menubar requires less memory than a special click.
- ;; in Lucid Emacs, we want the menu to popup when the 3rd button is
- ;; hit. In 19.10 and beyond this is done automatically if we put
- ;; the menu on mode-popup-menu variable, see c-common-init [cc-mode.el]
- (if (memq 'Lucid simula-emacs-features)
- (if (not (boundp 'mode-popup-menu))
- (define-key simula-mode-map 'button3 'simula-popup-menu))))
-
-;; menus for Lucid
-(defun simula-popup-menu (e)
- "Pops up the SIMULA menu."
- (interactive "@e")
- (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu))
- (simula-keep-region-active))
-
-;; active regions, and auto-newline/hungry delete key
-(defun simula-keep-region-active ()
- ;; do whatever is necessary to keep the region active in
- ;; Lucid. ignore byte-compiler warnings you might see
- (and (boundp 'zmacs-region-stays)
- (setq zmacs-region-stays t)))
-
-(defvar simula-mode-abbrev-table nil
- "Abbrev table in SIMULA mode buffers")
-
-
-;;;###autoload
-(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)
- (make-local-variable 'font-lock-defaults)
- (setq font-lock-defaults
- '((simula-font-lock-keywords simula-font-lock-keywords-1
- simula-font-lock-keywords-2 simula-font-lock-keywords-3)
- t t ((?_ . "w"))))
- (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-exp ()
- "Indent SIMULA expression following point."
- (interactive)
- (let ((here (point))
- (simula-electric-indent nil)
- end)
- (simula-skip-comment-forward)
- (if (eobp)
- (goto-char here)
- (unwind-protect
- (progn
- (simula-next-statement 1)
- (setq end (point-marker))
- (simula-previous-statement 1)
- (beginning-of-line)
- (while (< (point) end)
- (if (not (looking-at "[ \t]*$"))
- (simula-indent-line))
- (forward-line 1)))
- (and end (set-marker end nil))))))
-
-
-(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
- (if simula-electric-indent
- (progn
- ;;
- ;; manually expand abbrev on last line, if any
- ;;
- (end-of-line 0)
- (expand-abbrev)
- ;; now maybe we should reindent that line
- (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 (re-search-forward
- ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\|^%"
- origin 'move)
- ;; found another END?
- (or (memq (preceding-char) '(?d ?D))
- ;; if directive, skip line
- (and (eq (preceding-char) ?%)
- (beginning-of-line 2))
- ;; found other keyword, out of END comment
- (setq return-value nil))))
- (if (and (eq (char-syntax (preceding-char)) ?w)
- (eq (char-syntax (following-char)) ?w))
- (save-excursion
- (backward-word 1)
- (if (looking-at "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 take a peek at next typed character...
- (next-char (read-event)))
- (unwind-protect
- (setq unread-command-events (append unread-command-events
- (list next-char)))
- ;; 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 (&optional stop-at-end)
- "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))
- (if (and stop-at-end (eq context 2))
- (setq context nil)))
- (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)
- (beginning-of-line)
- (if (bobp)
- (throw 'simula-out nil)
- (backward-char)))
- ((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")
- ;; BUG: the following (0 2) branches don't take into account intermixing
- ;; directive lines
- (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)))
- ((eq where 1)
- ;;
- ;; Directive. Always 0.
- ;;
- 0)
- ;;
- ;; 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 'dont-skip-end)
- (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))
- ((eq simula-abbrev-stdproc 'abbrev-table)
- ;; If not in lowercase, expansions are always capitalized.
- ;; We then want to replace with the exact expansion.
- (if (equal (symbol-name last-abbrev) last-abbrev-text)
- ()
- (downcase-word -1)
- (expand-abbrev))))))
-
-
-(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))
- ((eq simula-abbrev-stdproc 'abbrev-table)
- (if (equal (symbol-name last-abbrev) last-abbrev-text)
- ()
- (downcase-word -1)
- (expand-abbrev))))))
-
-
-(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 "Matches %s"
- (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 (regexp &optional bound noerror)
- "Search backward from point for regular expression REGEXP, ignoring matches
-found inside SIMULA comments, string literals, and BEGIN..END blocks.
-Set point to the end of the occurrence found, and return point.
-An optional second argument BOUND bounds the search, it is a buffer position.
-The match found must not extend after that position. Optional third argument
-NOERROR, if t, means if fail just return nil (no error).
-If not nil and not t, move to limit of search and return nil."
- (let (begin end context (comb-regexp (concat regexp "\\|\\<end\\>"))
- match (start-point (point)))
- (catch 'simula-backward
- (while (re-search-backward comb-regexp bound 1)
- ;; We have a match, check SIMULA context at match-beginning
- ;; to see if we are outside comments etc.
- ;; Set MATCH to t if we found a true match,
- ;; set MATCH to 'BLOCK if we found a BEGIN..END block,
- ;; else set MATCH to nil.
- (save-match-data
- (setq context (simula-context))
- (cond
- ((eq context nil)
- (setq match (if (looking-at regexp) t 'BLOCK)))
-;;; A comment-ending semicolon is part of the comment, and shouldn't match.
-;;; ((eq context 0)
-;;; (setq match (if (eq (following-char) ?\;) t nil)))
- ((eq context 2)
- (setq match (if (and (looking-at regexp)
- (looking-at ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>"))
- t
- (if (looking-at "\\<end\\>") 'BLOCK nil))))
- (t (setq match nil))))
- ;; Exit if true match
- (if (eq match t) (throw 'simula-backward (point)))
- (if (eq match 'BLOCK)
- ;; We found the END of a block
- (let ((level 0))
- (while (natnump level)
- (if (re-search-backward "\\<begin\\>\\|\\<end\\>" bound 1)
- (let ((context (simula-context)))
- ;; We found a BEGIN -> decrease level count
- (cond ((and (eq context nil)
- (memq (following-char) '(?b ?B)))
- (setq level (1- level)))
- ;; END -> increase level count
- ((and (memq context '(nil 2))
- (memq (following-char) '(?e ?E)))
- (setq level (1+ level)))))
- ;; Block search failed. Action depends on noerror.
- (if (or (not noerror) (eq noerror t))
- (goto-char start-point))
- (if (not noerror)
- (signal 'search-failed (list regexp)))
- (throw 'simula-backward nil))))))
- ;; Search failed. Action depends on noerror.
- (if (or (not noerror) (eq noerror t))
- (goto-char start-point))
- (if noerror
- nil
- (signal 'search-failed (list regexp))))))
-
-
-(defun simula-search-forward (regexp &optional bound noerror)
- "Search forward from point for regular expression REGEXP, ignoring matches
-found inside SIMULA comments, string literals, and BEGIN..END blocks.
-Set point to the end of the occurrence found, and return point.
-An optional second argument BOUND bounds the search, it is a buffer position.
-The match found must not extend after that position. Optional third argument
-NOERROR, if t, means if fail just return nil (no error).
-If not nil and not t, move to limit of search and return nil."
- (let (begin end context (comb-regexp (concat regexp "\\|\\<begin\\>"))
- match (start-point (point)))
- (catch 'simula-forward
- (while (re-search-forward comb-regexp bound 1)
- ;; We have a match, check SIMULA context at match-beginning
- ;; to see if we are outside comments.
- ;; Set MATCH to t if we found a true match,
- ;; set MATCH to 'BLOCK if we found a BEGIN..END block,
- ;; else set MATCH to nil.
- (save-match-data
- (save-excursion
- (goto-char (match-beginning 0))
- (setq context (simula-context))
- (cond
- ((not context)
- (setq match (if (looking-at regexp) t 'BLOCK)))
-;;; A comment-ending semicolon is part of the comment, and shouldn't match.
-;;; ((eq context 0)
-;;; (setq match (if (eq (following-char) ?\;) t nil)))
- ((eq context 2)
- (setq match (if (and (looking-at regexp)
- (looking-at ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>")) t nil)))
- (t (setq match nil)))))
- ;; Exit if true match
- (if (eq match t) (throw 'simula-forward (point)))
- (if (eq match 'BLOCK)
- ;; We found the BEGINning of a block
- (let ((level 0))
- (while (natnump level)
- (if (re-search-forward "\\<begin\\>\\|\\<end\\>" bound 1)
- (let ((context (simula-context)))
- ;; We found a BEGIN -> increase level count
- (cond ((eq context nil) (setq level (1+ level)))
- ;; END -> decrease level count
- ((and (eq context 2)
- ;; Don't match BEGIN inside END comment
- (memq (preceding-char) '(?d ?D)))
- (setq level (1- level)))))
- ;; Block search failed. Action depends on noerror.
- (if (or (not noerror) (eq noerror t))
- (goto-char start-point))
- (if (not noerror)
- (signal 'search-failed (list regexp)))
- (throw 'simula-forward nil))))))
- ;; Search failed. Action depends on noerror.
- (if (or (not noerror) (eq noerror t))
- (goto-char start-point))
- (if noerror
- nil
- (signal 'search-failed (list regexp))))))
-
-
-(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))))
-
-;;; Font Lock mode support.
-(eval-when-compile
- (require 'cl))
-
-;; SIMULA comments and strings are a mess. If we rely on the syntax table,
-;; then %-comments may be shown incorrectly (and prematurely) ended by a
-;; semicolon, !-comments by a newline and '-strings may screw up the rest of
-;; the buffer. And of course we can't do comment- or end-comments using the
-;; syntax table. We can do everything except end-comments in one fast regexp,
-;; but we aught to do end-comments too, so we need a function. simon@gnu.
-(defun simula-match-string-or-comment (limit)
- ;; Return t if there is a string or comment before LIMIT.
- ;; Matches buffer text so that if (match-string 1) is non-nil, it is the
- ;; string. Otherwise, (match-string 0) is non-nil, and is the comment.
- (when (re-search-forward
- (eval-when-compile
- (concat "\\(\"[^\"\n]*\"\\|'\\(.\\|![0-9]+!\\)'\\)\\|"
- "\\(\\<end[ \t\n]+\\)\\|"
- "^%[ \t].*\\|\\(!\\|\\<comment\\>\\)[^;]*;?"))
- limit t)
- (when (match-beginning 3)
- ;; We've matched an end-comment. Yuck. Find the extent of it.
- (store-match-data
- (list (point)
- (if (re-search-forward "\\<\\(end\\|else\\|when\\|otherwise\\)\\>\\|;"
- limit 'move)
- (match-beginning 0)
- (point)))))
- t))
-
-;;; Hilit mode support.
-(if (and (fboundp 'hilit-set-mode-patterns)
- (boundp 'hilit-patterns-alist)
- (not (assoc 'simula-mode hilit-patterns-alist)))
- (hilit-set-mode-patterns
- 'simula-mode
- '(
- ("^%\\([ \t\f].*\\)?$" nil comment)
- ("^%include\\>" nil include)
- ("\"[^\"\n]*\"\\|'.'\\|'![0-9]+!'" nil string)
- ("\\<\\(ACTIVATE\\|AFTER\\|AND\\|ARRAY\\|AT\\|BEFORE\\|BEGIN\\|BOOLEAN\\|CHARACTER\\|CLASS\\|DELAY\\|DO\\|ELSE\\|END\\|EQ\\|EQV\\|EXTERNAL\\|FALSE\\|FOR\\|GE\\|GO\\|GOTO\\|GT\\|HIDDEN\\|IF\\|IMP\\|IN\\|INNER\\|INSPECT\\|INTEGER\\|IS\\|LABEL\\|LE\\|LONG\\|LT\\|NAME\\|NE\\|NEW\\|NONE\\|NOT\\|NOTEXT\\|OR\\|OTHERWISE\\|PRIOR\\|PROCEDURE\\|PROTECTED\\|QUA\\|REACTIVATE\\|REAL\\|REF\\|SHORT\\|STEP\\|SWITCH\\|TEXT\\|THEN\\|THIS\\|TO\\|TRUE\\|UNTIL\\|VALUE\\|VIRTUAL\\|WHEN\\|WHILE\\)\\>" nil keyword)
- ("!\\|\\<COMMENT\\>" ";" comment))
- nil 'case-insensitive))
-
-;; None of this seems to be used by anything, including hilit19.el. simon@gnu.
-;(setq simula-find-comment-point -1
-; simula-find-comment-context nil)
-;
-;;; function used by hilit19
-;(defun simula-find-next-comment-region (param)
-; "Return region (start end) cons of comment after point, or NIL"
-; (let (start end)
-; ;; This function is called repeatedly, check if point is
-; ;; where we left it in the last call
-; (if (not (eq simula-find-comment-point (point)))
-; (setq simula-find-comment-point (point)
-; simula-find-comment-context (simula-context)))
-; ;; loop as long as we haven't found the end of a comment
-; (if (memq simula-find-comment-context '(0 1 2))
-; (setq start (point))
-; (if (re-search-forward "\\<end\\>\\|!\\|\"\\|'\\|^%\\|\\<comment\\>"
-; nil 'move)
-; (let ((previous-char (preceding-char)))
-; (cond
-; ((memq previous-char '(?d ?D))
-; (setq start (point)
-; simula-find-comment-context 2))
-; ((memq previous-char '(?t ?T ?\!))
-; (setq start (point)
-; simula-find-comment-context 0))
-; ((eq previous-char ?%)
-; (setq start (point)
-; simula-find-comment-context 0))))))
-; ;; BUG: the following (0 2) branches don't take into account intermixing
-; ;; directive lines
-; (cond
-; ((eq simula-find-comment-context 0)
-; (search-forward ";" nil 'move))
-; ((eq simula-find-comment-context 1)
-; (beginning-of-line 2))
-; ((eq simula-find-comment-context 2)
-; (re-search-forward ";\\|\\<end\\>\\|\\<else\\>\\|\\<otherwise\\>\\|\\<when\\>\\" (point-max) 'move)))
-; (if start
-; (setq end (point)))
-; ;; save point for later calls to this function
-; (setq simula-find-comment-point (if end (point) -1))
-; (and end (cons start end))))
-
-;; defuns for submitting bug reports
-
-(defconst simula-mode-help-address "simula-mode@ifi.uio.no"
- "Address accepting submission of simula-mode bug reports.")
-
-(defun simula-submit-bug-report ()
- "Submit via mail a bug report on simula-mode."
- (interactive)
- (and
- (y-or-n-p "Do you want to submit a report on simula-mode? ")
- (reporter-submit-bug-report
- simula-mode-help-address
- (concat "simula-mode from Emacs " emacs-version)
- (list
- ;; report only the vars that affect indentation
- 'simula-emacs-features
- 'simula-indent-level
- 'simula-substatement-offset
- 'simula-continued-statement-offset
- 'simula-label-offset
- 'simula-if-indent
- 'simula-inspect-indent
- 'simula-electric-indent
- 'simula-abbrev-keyword
- 'simula-abbrev-stdproc
- 'simula-abbrev-file
- 'simula-tab-always-indent
- ))))
-
-(provide 'simula-mode)
-
-;;; simula.el ends here
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
deleted file mode 100644
index ef8e27b68df..00000000000
--- a/lisp/progmodes/tcl.el
+++ /dev/null
@@ -1,2227 +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.50 $
-
-;; 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-list to point to the topmost
-;; directories containing the TclX help files. Eg:
-;;
-;; (setq tcl-help-directory-list '("/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: 1996/03/23 05:14:50 $|$Revision: 1.50 $|~/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:
-;; $Log: tcl.el,v $
-;; Revision 1.50 1996/03/23 05:14:50 tromey
-;; (tcl-using-emacs-19): Work with XEmacs 20.0. From Ben Wing.
-;;
-;; Revision 1.49 1995/12/07 18:27:47 tromey
-;; (add-log-tcl-defun): Don't use tcl-beginning-of-defun; just go to end
-;; of line before searching.
-;;
-;; Revision 1.48 1995/12/07 18:18:21 tromey
-;; (add-log-tcl-defun): Now uses tcl-beginning-of-defun.
-;;
-;; Revision 1.47 1995/08/22 17:49:45 tromey
-;; (tcl-hilit): New function from "Chris Alfeld" <calfeld@math.utah.edu>
-;; (tcl-mode): Call it
-;;
-;; Revision 1.46 1995/08/07 16:02:01 tromey
-;; (tcl-do-auto-fill): Only fill past fill-column; for 19.29.
-;; (tcl-auto-fill-mode): Use force-mode-line-update.
-;;
-;; Revision 1.45 1995/07/23 23:51:25 tromey
-;; (tcl-word-no-props): New function.
-;; (tcl-figure-type): Use it.
-;; (tcl-current-word): Ditto.
-;;
-;; Revision 1.44 1995/07/23 20:26:47 tromey
-;; Doc fixes.
-;;
-;; Revision 1.43 1995/07/17 19:59:49 tromey
-;; (inferior-tcl-mode): Use modeline-process if it exists.
-;;
-;; Revision 1.42 1995/07/17 19:55:25 tromey
-;; XEmacs currently must use tcl-internal-end-of-defun
-;;
-;; Revision 1.41 1995/07/14 21:54:56 tromey
-;; Changes to make menus work in XEmacs.
-;; From Mike Scheidler <c23mts@kocrsv01.delcoelect.com>
-;;
-;; Revision 1.40 1995/07/11 03:13:15 tromey
-;; (tcl-mode): Customize for new dabbrev.
-;;
-;; Revision 1.39 1995/07/09 21:58:03 tromey
-;; (tcl-do-fill-paragraph): New function.
-;; (tcl-mode): Set up for paragraph filling.
-;;
-;; Revision 1.38 1995/07/09 21:30:32 tromey
-;; (tcl-mode): Fixes to 19.29 paragraph variables.
-;;
-;; Revision 1.37 1995/07/09 18:52:16 tromey
-;; (tcl-do-auto-fill): Set fill-prefix.
-;;
-;; Revision 1.36 1995/07/09 01:07:57 tromey
-;; (tcl-imenu-create-index-function): Work with imenu from Emacs 19.29
-;;
-;; Revision 1.35 1995/06/27 20:12:00 tromey
-;; (tcl-type-alist): More itcl changes.
-;;
-;; Revision 1.34 1995/06/27 20:06:05 tromey
-;; More changes for itcl.
-;; Bug fixes for Emacs 19.29.
-;;
-;; Revision 1.33 1995/06/27 20:01:29 tromey
-;; (tcl-set-proc-regexp): Allow leading spaces.
-;; (tcl-proc-list): Changes for itcl.
-;; (tcl-typeword-list): Ditto.
-;; (tcl-keyword-list): Ditto.
-;;
-;; Revision 1.32 1995/05/11 22:12:49 tromey
-;; (tcl-type-alist): Include entry for "proc".
-;;
-;; Revision 1.31 1995/05/10 23:38:12 tromey
-;; (tcl-add-fsf-menu): Use make-lucid-menu-keymap, not
-;; "make-xemacs-menu-keymap".
-;;
-;; Revision 1.30 1995/05/10 18:22:21 tromey
-;; Bug fix in menu code for XEmacs.
-;;
-;; Revision 1.29 1995/05/09 21:36:53 tromey
-;; Changed "Lucid Emacs" to "XEmacs".
-;; Tcl's popup menu now added to existing one, courtesy
-;; dfarmer@evolving.com (Doug Farmer)
-;;
-;; Revision 1.28 1995/04/08 19:52:50 tromey
-;; (tcl-outline-level): New function
-;; (tcl-mode): Added outline-handling stuff.
-;; From Jesper Pedersen <blackie@imada.ou.dk>
-;;
-;; Revision 1.27 1994/10/11 02:01:27 tromey
-;; (tcl-mode): imenu-create-index-function made buffer local.
-;;
-;; Revision 1.26 1994/09/01 18:06:24 tromey
-;; Added filename completion in inferior tcl mode
-;;
-;; Revision 1.25 1994/08/22 15:56:24 tromey
-;; tcl-load-file default to current buffer.
-;;
-;; Revision 1.24 1994/08/21 20:33:05 tromey
-;; Fixed bug in tcl-guess-application.
-;;
-;; Revision 1.23 1994/08/21 03:54:45 tromey
-;; Keybindings don't overshadown comint bindings.
-;;
-;; Revision 1.22 1994/07/26 00:46:07 tromey
-;; Emacs 18 changes from Carl Witty.
-;;
-;; Revision 1.21 1994/07/14 22:49:21 tromey
-;; Added ";;;###autoload" comments where appropriate.
-;;
-; Revision 1.20 1994/06/05 16:57:22 tromey
-; tcl-current-word does the right thing in inferior-tcl-mode.
-;
-; Revision 1.19 1994/06/03 21:09:19 tromey
-; Another menu fix.
-;
-; Revision 1.18 1994/06/03 20:39:14 tromey
-; Fixed menu bug.
-;
-; Revision 1.17 1994/06/03 00:47:15 tromey
-; Fixed bug in bug-reporting code.
-;
-; Revision 1.16 1994/05/26 05:06:14 tromey
-; Menu items now sensitive as appropriate.
-;
-; Revision 1.15 1994/05/22 20:38:11 tromey
-; Added bug-report keybindings and menu entries.
-;
-; Revision 1.14 1994/05/22 20:18:28 tromey
-; Even more compile stuff.
-;
-; Revision 1.13 1994/05/22 20:17:15 tromey
-; Moved emacs version checking code to very beginning.
-;
-; Revision 1.12 1994/05/22 20:14:59 tromey
-; Compile fixes.
-;
-; Revision 1.11 1994/05/22 20:12:44 tromey
-; Fixed mark-defun for 19.23.
-; More menu fixes.
-;
-; Revision 1.10 1994/05/22 20:02:03 tromey
-; Fixed bug with M-;.
-; Wrote bug-reporting code.
-;
-; Revision 1.9 1994/05/22 05:26:51 tromey
-; Fixes for imenu.
-;
-; Revision 1.8 1994/05/22 03:38:07 tromey
-; Fixed menu support.
-;
-; Revision 1.7 1994/05/03 01:23:42 tromey
-; *** empty log message ***
-;
-; Revision 1.6 1994/04/23 16:23:36 tromey
-; Wrote tcl-indent-for-comment
-;
-;;
-;; 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)
-;; warsaw@nlm.nih.gov (Barry A. Warsaw)
-;; Carl Witty <cwitty@ai.mit.edu>
-;; T. V. Raman <raman@crl.dec.com>
-;; Jesper Pedersen <blackie@imada.ou.dk>
-;; dfarmer@evolving.com (Doug Farmer)
-;; "Chris Alfeld" <calfeld@math.utah.edu>
-;; Ben Wing <wing@666.com>
-
-;; 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).
-;; * 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.
-;; * Indentation should deal with "switch".
-;; * Consider writing code to find help files automatically (for
-;; common cases).
-;; * `#' shouldn't insert `\#' when point is in string.
-
-
-
-;;; Code:
-
-;; I sure wish Emacs had a package that made it easy to extract this
-;; sort of information. Strange definition works with XEmacs 20.0.
-(defconst tcl-using-emacs-19 (not (string-match "18\\." emacs-version))
- "Nil unless using Emacs 19 (XEmacs 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-xemacs-19 (string-match "XEmacs" emacs-version)
- "Nil unless using XEmacs).")
-
-(require 'comint)
-
-;; When compiling under GNU Emacs, load imenu during compilation. If
-;; you have 19.22 or earlier, comment this out, or get imenu.
-(and (fboundp 'eval-when-compile)
- (eval-when-compile
- (if (and (string-match "19\\." emacs-version)
- (not (string-match "XEmacs" emacs-version)))
- (require 'imenu))
- ()))
-
-(defconst tcl-version "$Revision: 1.50 $")
-(defconst tcl-maintainer "Tom Tromey <tromey@drip.colorado.edu>")
-
-;;
-;; 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-list nil
- "*List of topmost directories 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 ()))
-
-(defvar tcl-mode-map ()
- "Keymap used in Tcl mode.")
-
-(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.")
-
-;; XEmacs menu.
-(defvar tcl-xemacs-menu
- '(["Beginning of function" tcl-beginning-of-defun t]
- ["End of function" tcl-end-of-defun t]
- ["Mark function" tcl-mark-defun t]
- ["Indent region" indent-region (tcl-mark)]
- ["Comment region" comment-region (tcl-mark)]
- ["Uncomment region" tcl-uncomment-region (tcl-mark)]
- "----"
- ["Show Tcl process buffer" inferior-tcl t]
- ["Send function to Tcl process" tcl-eval-defun
- (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
- ["Send region to Tcl process" tcl-eval-region
- (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
- ["Send file to Tcl process" tcl-load-file
- (and inferior-tcl-buffer (get-buffer inferior-tcl-buffer))]
- ["Restart Tcl process with file" tcl-restart-with-file t]
- "----"
- ["Tcl help" tcl-help-on-word tcl-help-directory-list]
- ["Send bug report" tcl-submit-bug-report t])
- "XEmacs menu for Tcl mode.")
-
-;; GNU Emacs does menus via keymaps. Do it in a function in case we
-;; later decide to add it to inferior Tcl mode as well.
-(defun tcl-add-fsf-menu (map)
- (define-key map [menu-bar] (make-sparse-keymap))
- ;; This fails in Emacs 19.22 and earlier.
- (require 'lmenu)
- (let ((menu (make-lucid-menu-keymap "Tcl" tcl-xemacs-menu)))
- (define-key map [menu-bar tcl] (cons "Tcl" menu))
- ;; The following is intended to compute the key sequence
- ;; information for the menu. It doesn't work.
- (x-popup-menu nil menu)))
-
-(defun tcl-fill-mode-map ()
- (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" 'tcl-mark-defun)
- (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-;" 'tcl-indent-for-comment)
- (define-key tcl-mode-map "\M-\C-x" 'tcl-eval-defun)
- (define-key tcl-mode-map "\C-c\C-b" 'tcl-submit-bug-report)
- (and (fboundp 'comment-region)
- (define-key tcl-mode-map "\C-c\C-c" 'comment-region))
- (define-key tcl-mode-map "\C-c\C-i" 'tcl-help-on-word)
- (define-key tcl-mode-map "\C-c\C-v" 'tcl-eval-defun)
- (define-key tcl-mode-map "\C-c\C-f" 'tcl-load-file)
- (define-key tcl-mode-map "\C-c\C-t" 'inferior-tcl)
- (define-key tcl-mode-map "\C-c\C-x" 'tcl-eval-region)
- (define-key tcl-mode-map "\C-c\C-s" 'switch-to-tcl)
-
- ;; Make menus.
- (if (and tcl-using-emacs-19 (not tcl-using-xemacs-19))
- (progn
- (tcl-add-fsf-menu tcl-mode-map))))
-
-(defun tcl-fill-inferior-map ()
- (define-key inferior-tcl-mode-map "\t" 'comint-dynamic-complete)
- (define-key inferior-tcl-mode-map "\M-?"
- 'comint-dynamic-list-filename-completions)
- (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-b" 'tcl-submit-bug-report)
- (define-key inferior-tcl-mode-map "\C-c\C-i" 'tcl-help-on-word)
- (define-key inferior-tcl-mode-map "\C-c\C-v" 'tcl-eval-defun)
- (define-key inferior-tcl-mode-map "\C-c\C-f" 'tcl-load-file)
- (define-key inferior-tcl-mode-map "\C-c\C-t" 'inferior-tcl)
- (define-key inferior-tcl-mode-map "\C-c\C-x" 'tcl-eval-region)
- (define-key inferior-tcl-mode-map "\C-c\C-s" 'switch-to-tcl))
-
-(if tcl-mode-map
- ()
- (setq tcl-mode-map (make-sparse-keymap))
- (tcl-fill-mode-map))
-
-(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))
- (tcl-fill-inferior-map))
-
-
-(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-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" "method" "itcl_class")
- "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" "inherit" "public" "protected" "common")
- "List of Tcl keywords denoting \"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" "constructor" "destructor" "itcl_class" "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
- '(
- ("proc" nil tcl-expr tcl-commands)
- ("method" nil tcl-expr tcl-commands)
- ("destructor" tcl-commands)
- ("constructor" tcl-commands)
- ("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-xemacs-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))
-
-;; Ditto end-of-defun.
-(fset 'tcl-end-of-defun
- (if (and tcl-using-emacs-19 (not tcl-using-xemacs-19))
- 'end-of-defun
- 'tcl-internal-end-of-defun))
-
-;; Internal mark-defun that is used for losing Emacsen.
-(defun tcl-internal-mark-defun ()
- "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))
-
-;; In GNU Emacs 19-23 and later, mark-defun works as advertised. I
-;; don't know about XEmacs, so for now it and Emacs 18 just lose.
-(fset 'tcl-mark-defun
- (if tcl-using-emacs-19-23
- 'mark-defun
- 'tcl-internal-mark-defun))
-
-;; In GNU Emacs 19, mark takes an additional "force" argument. I
-;; don't know about XEmacs, so I'm just assuming it is the same.
-;; Emacs 18 doesn't have this argument.
-(defun tcl-mark ()
- "Return mark, or nil if none."
- (if tcl-using-emacs-19
- (mark t)
- (mark)))
-
-
-
-;;
-;; Some helper functions.
-;;
-
-(defun tcl-set-proc-regexp ()
- "Set `tcl-proc-regexp' from variable `tcl-proc-list'."
- (setq tcl-proc-regexp (concat "^\\s-*\\("
- (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.
-;;
-
-;;;###autoload
-(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.
- tcl-use-smart-word-finder
- If not nil, use a smarter, Tcl-specific way to find the current
- word when looking up help on a Tcl command.
-
-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)
- (make-local-variable 'paragraph-separate)
- (if (and tcl-using-emacs-19-23
- (>= emacs-minor-version 29))
- (progn
- ;; In Emacs 19.29, you aren't supposed to start these with a
- ;; ^.
- (setq paragraph-start "$\\| ")
- (setq paragraph-separate paragraph-start))
- (setq paragraph-start (concat "^$\\|" page-delimiter))
- (setq paragraph-separate paragraph-start))
- (make-local-variable 'paragraph-ignore-fill-prefix)
- (setq paragraph-ignore-fill-prefix t)
- (make-local-variable 'fill-paragraph-function)
- (setq fill-paragraph-function 'tcl-do-fill-paragraph)
-
- (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 'outline-regexp)
- (setq outline-regexp "[^\n\^M]")
- (make-local-variable 'outline-level)
- (setq outline-level 'tcl-outline-level)
-
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords tcl-font-lock-keywords)
-
- ;; The following only really makes sense under GNU Emacs 19.
- (make-local-variable 'imenu-create-index-function)
- (setq imenu-create-index-function 'tcl-imenu-create-index-function)
- (make-local-variable 'parse-sexp-ignore-comments)
-
- ;; Settings for new dabbrev code.
- (make-local-variable 'dabbrev-case-fold-search)
- (setq dabbrev-case-fold-search nil)
- (make-local-variable 'dabbrev-case-replace)
- (setq dabbrev-case-replace nil)
- (make-local-variable 'dabbrev-abbrev-skip-leading-regexp)
- (setq dabbrev-abbrev-skip-leading-regexp "[$!]")
- (make-local-variable 'dabbrev-abbrev-char-regexp)
- (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
-
- (if tcl-using-emacs-19
- (progn
- ;; This can only be set to t in Emacs 19 and XEmacs.
- ;; Emacs 18 and Epoch lose.
- (setq parse-sexp-ignore-comments t)
- ;; XEmacs 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))
-
- ;; Put Tcl menu into menubar for XEmacs. This happens
- ;; automatically for GNU Emacs.
- (if (and tcl-using-xemacs-19
- current-menubar
- (not (assoc "Tcl" current-menubar)))
- (progn
- (set-buffer-menubar (copy-sequence current-menubar))
- (add-menu nil "Tcl" tcl-xemacs-menu)))
- ;; Append Tcl menu to popup menu for XEmacs.
- (if (and tcl-using-xemacs-19 (boundp 'mode-popup-menu))
- (setq mode-popup-menu
- (cons (concat mode-name " Mode Commands") tcl-xemacs-menu)))
-
- ;; If hilit19 is loaded, add our stuff.
- (if (featurep 'hilit19)
- (tcl-hilit))
-
- (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 indentation area, otherwise insert TAB.
- (if (<= (current-column) (current-indentation))
- (tcl-indent-line)
- (insert-tab 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)
- (tcl-indent-line)
- (tcl-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 (tcl-word-no-props) 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 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 prev-pos)
- (goto-char (point-min))
- (imenu-progress-message prev-pos 0)
- (save-match-data
- (while (re-search-forward re nil t)
- (imenu-progress-message prev-pos)
- ;; 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 prev-pos 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
- (end-of-line)
- (if (re-search-backward (concat tcl-proc-regexp "\\([^ \t\n{]+\\)") nil t)
- (buffer-substring (match-beginning 2)
- (match-end 2)))))
-
-(defun tcl-outline-level ()
- (save-excursion
- (skip-chars-forward " \t")
- (current-column)))
-
-
-
-;;
-;; 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)))))
- (if tcl-using-emacs-19
- (comint-output-filter proc string)
- (funcall comint-output-filter 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")
- (if (boundp 'modeline-process)
- (setq modeline-process '(": %s")) ; For XEmacs.
- (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))
-
-;;;###autoload
-(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-fill-paragraph (ignore)
- "fill-paragraph function for Tcl mode. Only fills in a comment."
- (let (in-comment col where)
- (save-excursion
- (end-of-line)
- (setq in-comment (tcl-in-comment))
- (if in-comment
- (progn
- (setq where (1+ (point)))
- (setq col (1- (current-column))))))
- (and in-comment
- (save-excursion
- (back-to-indentation)
- (= col (current-column)))
- ;; In a comment. Set the fill prefix, and find the paragraph
- ;; boundaries by searching for lines that look like
- ;; comment-only lines.
- (let ((fill-prefix (buffer-substring (progn
- (beginning-of-line)
- (point))
- where))
- p-start p-end)
- ;; Search backwards.
- (save-excursion
- (while (looking-at "^[ \t]*#")
- (forward-line -1))
- (forward-line)
- (setq p-start (point)))
-
- ;; Search forwards.
- (save-excursion
- (while (looking-at "^[ \t]*#")
- (forward-line))
- (setq p-end (point)))
-
- ;; Narrow and do the fill.
- (save-restriction
- (narrow-to-region p-start p-end)
- (fill-paragraph ignore)))))
- t)
-
-(defun tcl-do-auto-fill ()
- "Auto-fill function for Tcl mode. Only auto-fills in a comment."
- (if (> (current-column) fill-column)
- (let ((fill-prefix "# ")
- 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-dirs nil
- "Saved help directories.
-If `tcl-help-directory-list' 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 (dirlist)
- "Build alist of commands and filenames."
- (while dirlist
- (let ((files (directory-files (car dirlist) 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))))
- (setq dirlist (cdr dirlist))))
-
-(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-dirs tcl-help-directory-list)
- (setq tcl-help-alist nil)
- (tcl-help-snarf-commands tcl-help-directory-list)
- (message "Building Tcl help file index...done"))
-
-(defun tcl-word-no-props ()
- "Like current-word, but strips properties."
- (let ((word (current-word)))
- (and (fboundp 'set-text-properties)
- (set-text-properties 0 (length word) nil word))
- word))
-
-(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
- (memq major-mode '(tcl-mode inferior-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 (tcl-word-no-props) tcl-help-alist)
- (tcl-word-no-props)))
- (error nil))
- (tcl-word-no-props)))
-
-;;;###autoload
-(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 (equal tcl-help-directory-list tcl-help-saved-dirs))
- (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 (equal tcl-help-directory-list tcl-help-saved-dirs))
- (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: "
- (or (and
- (eq major-mode 'tcl-mode)
- (buffer-file-name))
- 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)))
-
-(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))
- (force-mode-line-update)))
-
-;; hilit19 support from "Chris Alfeld" <calfeld@math.utah.edu>
-(defun tcl-hilit ()
- (hilit-set-mode-patterns
- '(tcl-mode)
- '(
- ("\\(^ *\\|\; *\\)#.*$" nil comment)
- ("[^\\]\\(\\$[A-Za-z0-9\\-\\_./\\(\\)]+\\)" 1 label)
- ("[^_]\\<\\(append\\|array\\|auto_execok\\|auto_load\\|auto_mkindex\\|auto_reset\\|break\\|case\\|catch\\|cd\\|close\\|concat\\|continue\\|eof\\|error\\|eval\\|exec\\|exit\\|expr\\|file\\|flush\\|for\\|foreach\\|format\\|gets\\|glob\\|global\\|history\\|if\\|incr\\|info\\|join\\|lappend\\|lindex\\|linsert\\|list\\|llength\\|lrange\\|lreplace\\|lsearch\\|lsort\\|open\\|pid\\|proc\\|puts\\|pwd\\|read\\|regexp\\|regsub\\|rename\\|return\\|scan\\|seek\\|set\\|source\\|split\\|string\\|switch\\|tell\\|time\\|trace\\|unknown\\|unset\\|uplevel\\|upvar\\|while\\)\\>[^_]" 1 keyword) ; tcl keywords
- ("[^_]\\<\\(after\\|bell\\|bind\\|bindtags\\|clipboard\\|destroy\\|fileevent\\|focus\\|grab\\|image\\|lower\\|option\\|pack\\|place\\|raise\\|scale\\|selection\\|send\\|subst\\|tk\\|tk_popup\\|tkwait\\|update\\|winfo\\|wm\\)\\>[^_]" 1 define) ; tk keywords
- ("[^_]\\<\\(button\\|canvas\\|checkbutton\\|entry\\|frame\\|label\\|listbox\\|menu\\|menubutton\\|message\\|radiobutton\\|scrollbar\\|text\\|toplevel\\)\\>[^_]" 1 decl) ; tk widgets
- ("[^_]\\<\\(tix\\((ButtonBox\\|Baloon\\|Control\\|DirList\\|ExFileSelectBox\\|ExFileSelectDialog\\|FileEntry\\|HList\\|LabelEntry\\|LabelFrame\\|NoteBook\\|OptionMenu\\|PanedWindow\\|PopupMenu\\|ScrolledHList\\|ScrolledText\\|ScrolledWindow\\|Select\\|StdButtonBox\\)\\)\\>[^_]" 1 defun) ; tix widgets
- ("[{}\\\"\\(\\)]" nil include) ; misc punctuation
- )))
-
-(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))))))
-
-(defun tcl-indent-for-comment ()
- "Indent this line's comment to comment column, or insert an empty comment.
-Is smart about syntax of Tcl comments.
-Parts of this were taken from indent-for-comment (simple.el)."
- (interactive "*")
- (end-of-line)
- (or (tcl-in-comment)
- (progn
- ;; Not in a comment, so we have to insert one. Create an
- ;; empty comment (since there isn't one on this line). If
- ;; line is not blank, make sure we insert a ";" first.
- (skip-chars-backward " \t")
- (let ((eolpoint (point)))
- (beginning-of-line)
- (if (/= (point) eolpoint)
- (progn
- (goto-char eolpoint)
- (insert
- (if (tcl-real-command-p) "" ";")
- "# ")
- (backward-char))))))
- ;; Point is just after the "#" starting a comment. Move it as
- ;; appropriate.
- (let* ((indent (if comment-indent-hook
- (funcall comment-indent-hook)
- (funcall comment-indent-function)))
- (begpos (progn
- (backward-char)
- (point))))
- (if (/= begpos indent)
- (progn
- (skip-chars-backward " \t" (save-excursion
- (beginning-of-line)
- (point)))
- (delete-region (point) begpos)
- (indent-to indent)))
- (looking-at comment-start-skip) ; Always true.
- (goto-char (match-end 0))
- ;; I don't like the effect of the next two.
- ;;(skip-chars-backward " \t" (match-beginning 0))
- ;;(skip-chars-backward "^ \t" (match-beginning 0))
- ))
-
-;; 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.
-;; FIXME should make sure that the application mentioned actually
-;; exists.
-(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\n/]+\\)\\([ \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))
-
-
-
-;;
-;; XEmacs menu support.
-;; Taken from schmid@fb3-s7.math.TU-Berlin.DE (Gregor Schmid),
-;; who wrote a different Tcl mode.
-;; We also have support for menus in FSF. We do this by
-;; loading the XEmacs menu emulation code.
-;;
-
-(defun tcl-popup-menu (e)
- (interactive "@e")
- (and tcl-using-emacs-19
- (not tcl-using-xemacs-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
- ;; IMHO popup-menu should be autoloaded in FSF Emacs. Oh well.
- (popup-menu tcl-xemacs-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 ""))
-
-
-
-;;
-;; Bug reporting.
-;;
-
-(and (fboundp 'eval-when-compile)
- (eval-when-compile
- (require 'reporter)))
-
-(defun tcl-submit-bug-report ()
- "Submit via mail a bug report on Tcl mode."
- (interactive)
- (require 'reporter)
- (and
- (y-or-n-p "Do you really want to submit a bug report on Tcl mode? ")
- (reporter-submit-bug-report
- tcl-maintainer
- (concat "Tcl mode " tcl-version)
- '(tcl-indent-level
- tcl-continued-indent-level
- tcl-auto-newline
- tcl-tab-always-indent
- tcl-use-hairy-comment-detector
- tcl-electric-hash-style
- tcl-help-directory-list
- tcl-use-smart-word-finder
- tcl-application
- tcl-command-switches
- tcl-prompt-regexp
- inferior-tcl-source-command
- tcl-using-emacs-19
- tcl-using-emacs-19-23
- tcl-using-xemacs-19
- tcl-proc-list
- tcl-proc-regexp
- tcl-typeword-list
- tcl-keyword-list
- tcl-font-lock-keywords
- tcl-pps-has-arg-6))))
-
-
-
-(provide 'tcl)
-
-;;; tcl.el ends here