1997-04-10 19:41:00 +00:00
|
|
|
|
;;; scheme.el --- Scheme (and DSSSL) editing mode.
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
;; Copyright (C) 1986, 87, 88, 1997 Free Software Foundation, Inc.
|
1992-07-22 04:22:42 +00:00
|
|
|
|
|
1997-05-27 17:46:19 +00:00
|
|
|
|
;; Author: Bill Rozas <jinx@martigny.ai.mit.edu>
|
1997-11-24 03:43:19 +00:00
|
|
|
|
;; Maintainer: FSF
|
1992-07-17 20:24:00 +00:00
|
|
|
|
;; Keywords: languages, lisp
|
1992-07-16 21:47:34 +00:00
|
|
|
|
|
1990-05-29 16:50:24 +00:00
|
|
|
|
;; 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
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;; the Free Software Foundation; either version 2, or (at your option)
|
1990-05-29 16:50:24 +00:00
|
|
|
|
;; 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
|
1996-01-14 07:34:30 +00:00
|
|
|
|
;; 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.
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
;; Originally adapted from Lisp mode by Bill Rozas, jinx@prep with a
|
|
|
|
|
;; comment that the code should be merged back. Merging done by
|
|
|
|
|
;; d.love@dl.ac.uk when DSSSL features added.
|
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;;; Commentary:
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
;; The major mode for editing Scheme-type Lisp code, very similar to
|
|
|
|
|
;; the Lisp mode documented in the Emacs manual. `dsssl-mode' is a
|
|
|
|
|
;; variant of scheme-mode for editing DSSSL specifications for SGML
|
|
|
|
|
;; documents. [As of Apr 1997, some pointers for DSSSL may be found,
|
|
|
|
|
;; for instance, at <URL:http://www.sil.org/sgml/related.html#dsssl>.]
|
|
|
|
|
;; All these Lisp-ish modes vary basically in details of the language
|
|
|
|
|
;; syntax they highlight/indent/index, but dsssl-mode uses "^;;;" as
|
|
|
|
|
;; the page-delimiter since ^L isn't normally a legal SGML character.
|
|
|
|
|
;;
|
|
|
|
|
;; For interacting with a Scheme interpreter See also `run-scheme' in
|
|
|
|
|
;; the `cmuscheme' package and also the implementation-specific
|
|
|
|
|
;; `xscheme' package.
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;;; Code:
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(require 'lisp-mode)
|
|
|
|
|
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(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.
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(modify-syntax-entry ?\[ "(] ")
|
|
|
|
|
(modify-syntax-entry ?\] ")[ ")
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(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 ())
|
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(defvar scheme-imenu-generic-expression
|
|
|
|
|
'((nil
|
|
|
|
|
"^(define\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)*\\s-+(?\\(\\(\\sw\\|\\s_\\)+\\)" 4)
|
|
|
|
|
(" Types"
|
|
|
|
|
"^(define-class\\s-+(?\\(\\(\\sw\\|\\s_\\)+\\)" 1)
|
|
|
|
|
(" Macros"
|
|
|
|
|
"^(\\(defmacro\\|define-macro\\|define-syntax\\)\\s-+(?\\(\\(\\sw\\|\\s_\\)+\\)" 2))
|
|
|
|
|
"Imenu generic expression for Scheme mode. See `imenu-generic-expression'.")
|
|
|
|
|
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(defun scheme-mode-variables ()
|
|
|
|
|
(set-syntax-table scheme-mode-syntax-table)
|
|
|
|
|
(setq local-abbrev-table scheme-mode-abbrev-table)
|
|
|
|
|
(make-local-variable 'paragraph-start)
|
1995-03-02 15:40:12 +00:00
|
|
|
|
(setq paragraph-start (concat "$\\|" page-delimiter))
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(make-local-variable 'paragraph-separate)
|
|
|
|
|
(setq paragraph-separate paragraph-start)
|
|
|
|
|
(make-local-variable 'paragraph-ignore-fill-prefix)
|
|
|
|
|
(setq paragraph-ignore-fill-prefix t)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(make-local-variable 'fill-paragraph-function)
|
|
|
|
|
(setq fill-paragraph-function 'lisp-fill-paragraph)
|
|
|
|
|
;; Adaptive fill mode gets in the way of auto-fill,
|
|
|
|
|
;; and should make no difference for explicit fill
|
|
|
|
|
;; because lisp-fill-paragraph should do the job.
|
|
|
|
|
(make-local-variable 'adaptive-fill-mode)
|
|
|
|
|
(setq adaptive-fill-mode nil)
|
1997-11-24 03:43:19 +00:00
|
|
|
|
(make-local-variable 'normal-auto-fill-function)
|
|
|
|
|
(setq normal-auto-fill-function 'lisp-mode-auto-fill)
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(make-local-variable 'indent-line-function)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(setq indent-line-function 'lisp-indent-line)
|
1994-11-14 18:52:51 +00:00
|
|
|
|
(make-local-variable 'parse-sexp-ignore-comments)
|
|
|
|
|
(setq parse-sexp-ignore-comments t)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(make-local-variable 'outline-regexp)
|
|
|
|
|
(setq outline-regexp ";;; \\|(....")
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(make-local-variable 'comment-start)
|
|
|
|
|
(setq comment-start ";")
|
|
|
|
|
(make-local-variable 'comment-start-skip)
|
1996-07-04 05:45:55 +00:00
|
|
|
|
;; 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]*")
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(make-local-variable 'comment-column)
|
|
|
|
|
(setq comment-column 40)
|
1993-03-22 03:27:18 +00:00
|
|
|
|
(make-local-variable 'comment-indent-function)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(setq comment-indent-function 'lisp-comment-indent)
|
1994-09-29 18:54:19 +00:00
|
|
|
|
(make-local-variable 'parse-sexp-ignore-comments)
|
|
|
|
|
(setq parse-sexp-ignore-comments t)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(make-local-variable 'lisp-indent-function)
|
|
|
|
|
(set lisp-indent-function 'scheme-indent-function)
|
|
|
|
|
(setq mode-line-process '("" scheme-mode-line-process))
|
|
|
|
|
(make-local-variable 'imenu-generic-expression)
|
|
|
|
|
(setq imenu-generic-expression scheme-imenu-generic-expression))
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
|
|
|
|
(defvar scheme-mode-line-process "")
|
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(defvar scheme-mode-map nil
|
|
|
|
|
"Keymap for Scheme mode.
|
|
|
|
|
All commands in `shared-lisp-mode-map' are inherited by this map.")
|
|
|
|
|
|
|
|
|
|
(if scheme-mode-map
|
|
|
|
|
()
|
|
|
|
|
(let ((map (make-sparse-keymap "Scheme")))
|
|
|
|
|
(setq scheme-mode-map
|
|
|
|
|
(nconc (make-sparse-keymap) shared-lisp-mode-map))
|
|
|
|
|
(define-key scheme-mode-map "\e\t" 'lisp-complete-symbol)
|
|
|
|
|
(define-key scheme-mode-map [menu-bar] (make-sparse-keymap))
|
|
|
|
|
(define-key scheme-mode-map [menu-bar scheme]
|
|
|
|
|
(cons "Scheme" map))
|
|
|
|
|
(define-key map [run-scheme] '("Run Inferior Scheme" . run-scheme))
|
|
|
|
|
(define-key map [comment-region] '("Comment Out Region" . comment-region))
|
|
|
|
|
(define-key map [indent-region] '("Indent Region" . indent-region))
|
|
|
|
|
(define-key map [indent-line] '("Indent Line" . lisp-indent-line))
|
|
|
|
|
(put 'comment-region 'menu-enable 'mark-active)
|
|
|
|
|
(put 'indent-region 'menu-enable 'mark-active)))
|
|
|
|
|
|
|
|
|
|
;; Used by cmuscheme
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(defun scheme-mode-commands (map)
|
1997-06-17 21:54:16 +00:00
|
|
|
|
;;(define-key map "\t" 'indent-for-tab-command) ; default
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(define-key map "\177" 'backward-delete-char-untabify)
|
1997-06-17 21:54:16 +00:00
|
|
|
|
(define-key map "\e\C-q" 'indent-sexp))
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1991-05-13 20:36:24 +00:00
|
|
|
|
;;;###autoload
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(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"))
|
|
|
|
|
|
1997-06-17 21:54:16 +00:00
|
|
|
|
(defgroup scheme nil
|
|
|
|
|
"Editing Scheme code"
|
|
|
|
|
:group 'lisp)
|
|
|
|
|
|
|
|
|
|
(defcustom scheme-mit-dialect t
|
1990-05-29 16:50:24 +00:00
|
|
|
|
"If non-nil, scheme mode is specialized for MIT Scheme.
|
1997-06-17 21:54:16 +00:00
|
|
|
|
Set this to nil if you normally use another dialect."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'scheme)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
|
1997-06-17 21:54:16 +00:00
|
|
|
|
(defcustom dsssl-sgml-declaration
|
1997-04-10 19:41:00 +00:00
|
|
|
|
"<!DOCTYPE style-sheet PUBLIC \"-//James Clark//DTD DSSSL Style Sheet//EN\">
|
|
|
|
|
"
|
1997-06-17 21:54:16 +00:00
|
|
|
|
"*An SGML declaration for the DSSSL file.
|
|
|
|
|
This will be inserted into an empty buffer in dsssl-mode if it is
|
|
|
|
|
defined as a string. It is typically James Clark's style-sheet
|
|
|
|
|
doctype, as required for Jade."
|
|
|
|
|
:group 'scheme)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
|
|
|
|
|
(defvar dsssl-imenu-generic-expression
|
|
|
|
|
;; Perhaps this should also look for the style-sheet DTD tags. I'm
|
|
|
|
|
;; not sure it's the best way to organize it; perhaps one type
|
|
|
|
|
;; should be at the first level, though you don't see this anyhow if
|
|
|
|
|
;; it gets split up.
|
|
|
|
|
'((" Defines"
|
|
|
|
|
"^(define\\s-+(?\\(\\(\\sw\\|\\s_\\)+\\)" 1)
|
|
|
|
|
(" Modes"
|
|
|
|
|
"^\\s-*(mode\\s-+\\(\\(\\sw\\|\\s-\\|\\s_\\)+\\)" 1)
|
|
|
|
|
(" Elements"
|
|
|
|
|
;; (element foo ...) or (element (foo bar ...) ...)
|
1997-04-27 17:50:39 +00:00
|
|
|
|
;; Fixme: Perhaps it should do `root'.
|
1997-04-10 19:41:00 +00:00
|
|
|
|
"^\\s-*(element\\s-+(?\\(\\(\\sw\\|\\s-\\|\\s_\\)+\\))?" 1)
|
|
|
|
|
(" Declarations"
|
|
|
|
|
"^(declare\\(-\\sw+\\)+\\>\\s-+\\(\\(\\sw\\|\\s_\\)+\\)" 2))
|
|
|
|
|
"Imenu generic expression for DSSSL mode. See `imenu-generic-expression'.")
|
|
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
|
(defun dsssl-mode ()
|
|
|
|
|
"Major mode for editing DSSSL code.
|
|
|
|
|
Editing commands are similar to those of lisp-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 dsssl-mode-hook
|
1997-04-27 17:50:39 +00:00
|
|
|
|
if that value is non-nil and inserts the value of
|
|
|
|
|
`dsssl-sgml-declaration' if that variable's value is a string."
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(kill-all-local-variables)
|
|
|
|
|
(use-local-map scheme-mode-map)
|
|
|
|
|
(scheme-mode-initialize)
|
|
|
|
|
(make-local-variable 'font-lock-defaults)
|
|
|
|
|
(setq font-lock-defaults '(dsssl-font-lock-keywords
|
|
|
|
|
nil t (("+-*/.<>=!?$%_&~^:" . "w"))
|
|
|
|
|
beginning-of-defun
|
|
|
|
|
(font-lock-comment-start-regexp . ";")
|
|
|
|
|
(font-lock-mark-block-function . mark-defun)))
|
|
|
|
|
(make-local-variable 'page-delimiter)
|
|
|
|
|
(setq page-delimiter "^;;;" ; ^L not valid SGML char
|
|
|
|
|
major-mode 'dsssl-mode
|
|
|
|
|
mode-name "DSSSL")
|
|
|
|
|
;; Insert a suitable SGML declaration into an empty buffer.
|
|
|
|
|
(and (zerop (buffer-size))
|
1997-04-27 17:50:39 +00:00
|
|
|
|
(stringp dsssl-sgml-declaration)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(not buffer-read-only)
|
|
|
|
|
(insert dsssl-sgml-declaration))
|
|
|
|
|
(run-hooks 'scheme-mode-hook)
|
|
|
|
|
(run-hooks 'dsssl-mode-hook)
|
|
|
|
|
(scheme-mode-variables)
|
|
|
|
|
(setq imenu-generic-expression dsssl-imenu-generic-expression))
|
|
|
|
|
|
|
|
|
|
;; Extra syntax for DSSSL. This isn't separated from Scheme, but
|
|
|
|
|
;; shouldn't cause much trouble in scheme-mode.
|
|
|
|
|
(put 'element 'scheme-indent-function 1)
|
|
|
|
|
(put 'mode 'scheme-indent-function 1)
|
|
|
|
|
(put 'with-mode 'scheme-indent-function 1)
|
1997-04-11 20:05:42 +00:00
|
|
|
|
(put 'make 'scheme-indent-function 1)
|
1997-04-27 17:50:39 +00:00
|
|
|
|
(put 'style 'scheme-indent-function 1)
|
|
|
|
|
(put 'root 'scheme-indent-function 1)
|
1997-04-10 19:41:00 +00:00
|
|
|
|
|
|
|
|
|
(defvar dsssl-font-lock-keywords
|
1997-04-27 17:50:39 +00:00
|
|
|
|
(eval-when-compile
|
|
|
|
|
(list
|
|
|
|
|
;; Similar to Scheme
|
|
|
|
|
(list "(\\(define\\(-\\w+\\)?\\)\\>[ ]*\\\((?\\)\\(\\sw+\\)\\>"
|
|
|
|
|
'(1 font-lock-keyword-face)
|
|
|
|
|
'(4 font-lock-function-name-face))
|
|
|
|
|
(cons
|
|
|
|
|
(concat "(\\("
|
|
|
|
|
;; (make-regexp '("case" "cond" "else" "if" "lambda"
|
|
|
|
|
;; "let" "let*" "letrec" "and" "or" "map" "with-mode"))
|
|
|
|
|
"and\\|c\\(ase\\|ond\\)\\|else\\|if\\|"
|
|
|
|
|
"l\\(ambda\\|et\\(\\|*\\|rec\\)\\)\\|map\\|or\\|with-mode"
|
|
|
|
|
"\\)\\>")
|
|
|
|
|
1)
|
|
|
|
|
;; DSSSL syntax
|
|
|
|
|
'("(\\(element\\|mode\\|declare-\\w+\\)\\>[ ]*\\(\\sw+\\)"
|
|
|
|
|
(1 font-lock-keyword-face)
|
|
|
|
|
(2 font-lock-type-face))
|
|
|
|
|
'("(\\(element\\)\\>[ ]*(\\(\\S)+\\))"
|
|
|
|
|
(1 font-lock-keyword-face)
|
|
|
|
|
(2 font-lock-type-face))
|
|
|
|
|
'("\\<\\sw+:\\>" . font-lock-reference-face) ; trailing `:' c.f. scheme
|
|
|
|
|
;; SGML markup (from sgml-mode) :
|
|
|
|
|
'("<\\([!?][-a-z0-9]+\\)" 1 font-lock-keyword-face)
|
|
|
|
|
'("<\\(/?[-a-z0-9]+\\)" 1 font-lock-function-name-face)))
|
1997-04-10 19:41:00 +00:00
|
|
|
|
"Default expressions to highlight in DSSSL mode.")
|
|
|
|
|
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(defvar calculate-lisp-indent-last-sexp)
|
|
|
|
|
|
|
|
|
|
;; Copied from lisp-indent-function, but with gets of
|
|
|
|
|
;; scheme-indent-{function,hook}.
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(defun scheme-indent-function (indent-point state)
|
|
|
|
|
(let ((normal-indent (current-column)))
|
1997-04-10 19:41:00 +00:00
|
|
|
|
(goto-char (1+ (elt state 1)))
|
|
|
|
|
(parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
|
|
|
|
|
(if (and (elt state 2)
|
|
|
|
|
(not (looking-at "\\sw\\|\\s_")))
|
|
|
|
|
;; car of form doesn't seem to be a a symbol
|
|
|
|
|
(progn
|
|
|
|
|
(if (not (> (save-excursion (forward-line 1) (point))
|
|
|
|
|
calculate-lisp-indent-last-sexp))
|
|
|
|
|
(progn (goto-char calculate-lisp-indent-last-sexp)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(parse-partial-sexp (point)
|
|
|
|
|
calculate-lisp-indent-last-sexp 0 t)))
|
|
|
|
|
;; Indent under the list or under the first sexp on the same
|
|
|
|
|
;; line as calculate-lisp-indent-last-sexp. Note that first
|
|
|
|
|
;; thing on that line has to be complete sexp since we are
|
|
|
|
|
;; inside the innermost containing sexp.
|
|
|
|
|
(backward-prefix-chars)
|
|
|
|
|
(current-column))
|
|
|
|
|
(let ((function (buffer-substring (point)
|
|
|
|
|
(progn (forward-sexp 1) (point))))
|
|
|
|
|
method)
|
|
|
|
|
(setq method (or (get (intern-soft function) 'scheme-indent-function)
|
|
|
|
|
(get (intern-soft function) 'scheme-indent-hook)))
|
|
|
|
|
(cond ((or (eq method 'defun)
|
|
|
|
|
(and (null method)
|
|
|
|
|
(> (length function) 3)
|
|
|
|
|
(string-match "\\`def" function)))
|
|
|
|
|
(lisp-indent-defform state indent-point))
|
|
|
|
|
((integerp method)
|
|
|
|
|
(lisp-indent-specform method state
|
|
|
|
|
indent-point normal-indent))
|
|
|
|
|
(method
|
1997-10-16 18:07:23 +00:00
|
|
|
|
(funcall method state indent-point normal-indent)))))))
|
1997-04-10 19:41:00 +00:00
|
|
|
|
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
|
|
|
|
;;; 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)))
|
|
|
|
|
|
1997-10-16 18:07:23 +00:00
|
|
|
|
(defun scheme-let-indent (state indent-point normal-indent)
|
1990-05-29 16:50:24 +00:00
|
|
|
|
(skip-chars-forward " \t")
|
1994-03-12 01:23:16 +00:00
|
|
|
|
(if (looking-at "[-a-zA-Z0-9+*/?!@$%^&_:~]")
|
1997-10-16 18:07:23 +00:00
|
|
|
|
(lisp-indent-specform 2 state indent-point normal-indent)
|
|
|
|
|
(lisp-indent-specform 1 state indent-point normal-indent)))
|
1990-05-29 16:50:24 +00:00
|
|
|
|
|
|
|
|
|
;; (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)))
|
1992-03-16 20:39:07 +00:00
|
|
|
|
|
|
|
|
|
(provide 'scheme)
|
1992-05-30 21:11:25 +00:00
|
|
|
|
|
|
|
|
|
;;; scheme.el ends here
|