(scheme-font-lock-keywords-2): Handle named-let.
[bpt/emacs.git] / lisp / progmodes / scheme.el
CommitLineData
e8af40ee 1;;; scheme.el --- Scheme (and DSSSL) editing mode
c88ab9ce 2
150bbae7
SM
3;; Copyright (C) 1986, 1987, 1988, 1997, 1998, 2005
4;; Free Software Foundation, Inc.
3a801d0c 5
4228277d 6;; Author: Bill Rozas <jinx@martigny.ai.mit.edu>
d575e99d 7;; Adapted-by: Dave Love <d.love@dl.ac.uk>
d7b4d18f 8;; Keywords: languages, lisp
e5167999 9
ac5b21ac
RS
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
e5167999 14;; the Free Software Foundation; either version 2, or (at your option)
ac5b21ac
RS
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
b578f267
EN
23;; along with GNU Emacs; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25;; Boston, MA 02111-1307, USA.
ac5b21ac 26
e5167999 27;;; Commentary:
ac5b21ac 28
1367ff3a
RS
29;; The major mode for editing Scheme-type Lisp code, very similar to
30;; the Lisp mode documented in the Emacs manual. `dsssl-mode' is a
31;; variant of scheme-mode for editing DSSSL specifications for SGML
32;; documents. [As of Apr 1997, some pointers for DSSSL may be found,
33;; for instance, at <URL:http://www.sil.org/sgml/related.html#dsssl>.]
34;; All these Lisp-ish modes vary basically in details of the language
35;; syntax they highlight/indent/index, but dsssl-mode uses "^;;;" as
36;; the page-delimiter since ^L isn't normally a legal SGML character.
37;;
38;; For interacting with a Scheme interpreter See also `run-scheme' in
39;; the `cmuscheme' package and also the implementation-specific
40;; `xscheme' package.
ac5b21ac 41
2b20743d
DL
42;; Here's a recipe to generate a TAGS file for DSSSL, by the way:
43;; etags --lang=scheme --regex='/[ \t]*(\(mode\|element\)[ \t
44;; ]+\([^ \t(
45;; ]+\)/\2/' --regex='/[ \t]*(element[ \t
46;; ]*([^)]+[ \t
47;; ]+\([^)]+\)[ \t
48;; ]*)/\1/' --regex='/(declare[^ \t
49;; ]*[ \t
50;; ]+\([^ \t
51;; ]+\)/\1/' "$@"
52
e5167999 53;;; Code:
ac5b21ac 54\f
1367ff3a
RS
55(require 'lisp-mode)
56
9fce950d
SM
57(defvar scheme-mode-syntax-table
58 (let ((st (make-syntax-table))
59 (i 0))
c676c4e5
TTN
60
61 ;; Default is atom-constituent.
62 (while (< i 256)
63 (modify-syntax-entry i "_ " st)
64 (setq i (1+ i)))
65
66 ;; Word components.
67 (setq i ?0)
68 (while (<= i ?9)
69 (modify-syntax-entry i "w " st)
70 (setq i (1+ i)))
71 (setq i ?A)
72 (while (<= i ?Z)
73 (modify-syntax-entry i "w " st)
74 (setq i (1+ i)))
75 (setq i ?a)
76 (while (<= i ?z)
77 (modify-syntax-entry i "w " st)
78 (setq i (1+ i)))
79
80 ;; Whitespace
81 (modify-syntax-entry ?\t " " st)
82 (modify-syntax-entry ?\n "> " st)
83 (modify-syntax-entry ?\f " " st)
84 (modify-syntax-entry ?\r " " st)
85 (modify-syntax-entry ? " " st)
86
87 ;; These characters are delimiters but otherwise undefined.
88 ;; Brackets and braces balance for editing convenience.
89 (modify-syntax-entry ?\[ "(] " st)
90 (modify-syntax-entry ?\] ")[ " st)
91 (modify-syntax-entry ?{ "(} " st)
92 (modify-syntax-entry ?} "){ " st)
93 (modify-syntax-entry ?\| " 23" st)
94
95 ;; Other atom delimiters
96 (modify-syntax-entry ?\( "() " st)
97 (modify-syntax-entry ?\) ")( " st)
98 (modify-syntax-entry ?\; "< " st)
99 (modify-syntax-entry ?\" "\" " st)
0a08535e
RS
100 (modify-syntax-entry ?' "' " st)
101 (modify-syntax-entry ?` "' " st)
c676c4e5
TTN
102
103 ;; Special characters
0a08535e
RS
104 (modify-syntax-entry ?, "' " st)
105 (modify-syntax-entry ?@ "' " st)
106 (modify-syntax-entry ?# "' 14" st)
c676c4e5 107 (modify-syntax-entry ?\\ "\\ " st)
9fce950d 108 st))
ac5b21ac 109\f
d17f0db5 110(defvar scheme-mode-abbrev-table nil)
ac5b21ac
RS
111(define-abbrev-table 'scheme-mode-abbrev-table ())
112
1367ff3a 113(defvar scheme-imenu-generic-expression
d17f0db5 114 '((nil
d575e99d 115 "^(define\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)*\\s-+(?\\(\\sw+\\)" 4)
d17f0db5 116 ("Types"
d575e99d 117 "^(define-class\\s-+(?\\(\\sw+\\)" 1)
93a7d76f 118 ("Macros"
d575e99d 119 "^(\\(defmacro\\|define-macro\\|define-syntax\\)\\s-+(?\\(\\sw+\\)" 2))
1367ff3a
RS
120 "Imenu generic expression for Scheme mode. See `imenu-generic-expression'.")
121
ac5b21ac
RS
122(defun scheme-mode-variables ()
123 (set-syntax-table scheme-mode-syntax-table)
124 (setq local-abbrev-table scheme-mode-abbrev-table)
125 (make-local-variable 'paragraph-start)
53e84345 126 (setq paragraph-start (concat "$\\|" page-delimiter))
ac5b21ac
RS
127 (make-local-variable 'paragraph-separate)
128 (setq paragraph-separate paragraph-start)
129 (make-local-variable 'paragraph-ignore-fill-prefix)
130 (setq paragraph-ignore-fill-prefix t)
1367ff3a
RS
131 (make-local-variable 'fill-paragraph-function)
132 (setq fill-paragraph-function 'lisp-fill-paragraph)
133 ;; Adaptive fill mode gets in the way of auto-fill,
134 ;; and should make no difference for explicit fill
135 ;; because lisp-fill-paragraph should do the job.
136 (make-local-variable 'adaptive-fill-mode)
137 (setq adaptive-fill-mode nil)
761aea38
RS
138 (make-local-variable 'normal-auto-fill-function)
139 (setq normal-auto-fill-function 'lisp-mode-auto-fill)
ac5b21ac 140 (make-local-variable 'indent-line-function)
1367ff3a 141 (setq indent-line-function 'lisp-indent-line)
446e6a14
KH
142 (make-local-variable 'parse-sexp-ignore-comments)
143 (setq parse-sexp-ignore-comments t)
1367ff3a
RS
144 (make-local-variable 'outline-regexp)
145 (setq outline-regexp ";;; \\|(....")
ac5b21ac
RS
146 (make-local-variable 'comment-start)
147 (setq comment-start ";")
150bbae7 148 (set (make-local-variable 'comment-add) 1)
ac5b21ac 149 (make-local-variable 'comment-start-skip)
a24c42f7
MB
150 ;; Look within the line for a ; following an even number of backslashes
151 ;; after either a non-backslash or the line beginning.
152 (setq comment-start-skip "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\);+[ \t]*")
ac5b21ac
RS
153 (make-local-variable 'comment-column)
154 (setq comment-column 40)
e41b2db1 155 (make-local-variable 'comment-indent-function)
1367ff3a 156 (setq comment-indent-function 'lisp-comment-indent)
2441d53d
RS
157 (make-local-variable 'parse-sexp-ignore-comments)
158 (setq parse-sexp-ignore-comments t)
1367ff3a
RS
159 (make-local-variable 'lisp-indent-function)
160 (set lisp-indent-function 'scheme-indent-function)
161 (setq mode-line-process '("" scheme-mode-line-process))
1b9a1e9d 162 (set (make-local-variable 'imenu-case-fold-search) t)
c0b08eb0 163 (setq imenu-generic-expression scheme-imenu-generic-expression)
1b9a1e9d
DL
164 (set (make-local-variable 'imenu-syntax-alist)
165 '(("+-*/.<>=?!$%_&~^:" . "w")))
d17f0db5 166 (make-local-variable 'font-lock-defaults)
22dcd0d1
DL
167 (setq font-lock-defaults
168 '((scheme-font-lock-keywords
169 scheme-font-lock-keywords-1 scheme-font-lock-keywords-2)
cb049c41 170 nil t (("+-*/.<>=!?$%_&~^:#" . "w")) beginning-of-defun
c676c4e5
TTN
171 (font-lock-mark-block-function . mark-defun)
172 (font-lock-syntactic-face-function . lisp-font-lock-syntactic-face-function))))
ac5b21ac
RS
173
174(defvar scheme-mode-line-process "")
175
150bbae7
SM
176(defvar scheme-mode-map
177 (let ((smap (make-sparse-keymap))
178 (map (make-sparse-keymap "Scheme")))
179 (set-keymap-parent smap lisp-mode-shared-map)
180 (define-key smap [menu-bar scheme] (cons "Scheme" map))
ece8c34d
DL
181 (define-key map [run-scheme] '("Run Inferior Scheme" . run-scheme))
182 (define-key map [uncomment-region]
183 '("Uncomment Out Region" . (lambda (beg end)
184 (interactive "r")
185 (comment-region beg end '(4)))))
186 (define-key map [comment-region] '("Comment Out Region" . comment-region))
187 (define-key map [indent-region] '("Indent Region" . indent-region))
188 (define-key map [indent-line] '("Indent Line" . lisp-indent-line))
189 (put 'comment-region 'menu-enable 'mark-active)
190 (put 'uncomment-region 'menu-enable 'mark-active)
150bbae7
SM
191 (put 'indent-region 'menu-enable 'mark-active)
192 smap)
193 "Keymap for Scheme mode.
194All commands in `lisp-mode-shared-map' are inherited by this map.")
1367ff3a
RS
195
196;; Used by cmuscheme
ac5b21ac 197(defun scheme-mode-commands (map)
48879301 198 ;;(define-key map "\t" 'indent-for-tab-command) ; default
ac5b21ac 199 (define-key map "\177" 'backward-delete-char-untabify)
48879301 200 (define-key map "\e\C-q" 'indent-sexp))
ac5b21ac 201\f
e2ab0aa6 202;;;###autoload
ac5b21ac
RS
203(defun scheme-mode ()
204 "Major mode for editing Scheme code.
d17f0db5 205Editing commands are similar to those of `lisp-mode'.
ac5b21ac
RS
206
207In addition, if an inferior Scheme process is running, some additional
208commands will be defined, for evaluating expressions and controlling
209the interpreter, and the state of the process will be displayed in the
210modeline of all Scheme buffers. The names of commands that interact
1b9a1e9d
DL
211with the Scheme process start with \"xscheme-\" if you use the MIT
212Scheme-specific `xscheme' package; for more information see the
213documentation for `xscheme-interaction-mode'. Use \\[run-scheme] to
214start an inferior Scheme using the more general `cmuscheme' package.
ac5b21ac
RS
215
216Commands:
217Delete converts tabs to spaces as it moves back.
218Blank lines separate paragraphs. Semicolons start comments.
219\\{scheme-mode-map}
d17f0db5 220Entry to this mode calls the value of `scheme-mode-hook'
ac5b21ac
RS
221if that value is non-nil."
222 (interactive)
223 (kill-all-local-variables)
ac5b21ac
RS
224 (use-local-map scheme-mode-map)
225 (setq major-mode 'scheme-mode)
150bbae7
SM
226 (setq mode-name "Scheme")
227 (scheme-mode-variables)
228 (run-mode-hooks 'scheme-mode-hook))
ac5b21ac 229
48879301
RS
230(defgroup scheme nil
231 "Editing Scheme code"
232 :group 'lisp)
233
234(defcustom scheme-mit-dialect t
ac5b21ac 235 "If non-nil, scheme mode is specialized for MIT Scheme.
48879301
RS
236Set this to nil if you normally use another dialect."
237 :type 'boolean
238 :group 'scheme)
1367ff3a 239
48879301 240(defcustom dsssl-sgml-declaration
1367ff3a
RS
241 "<!DOCTYPE style-sheet PUBLIC \"-//James Clark//DTD DSSSL Style Sheet//EN\">
242"
48879301 243 "*An SGML declaration for the DSSSL file.
2b20743d 244If it is defined as a string this will be inserted into an empty buffer
d17f0db5 245which is in `dsssl-mode'. It is typically James Clark's style-sheet
48879301 246doctype, as required for Jade."
d17f0db5 247 :type '(choice (string :tag "Specified string")
2b20743d
DL
248 (const :tag "None" :value nil))
249 :group 'scheme)
250
251(defcustom scheme-mode-hook nil
d17f0db5 252 "Normal hook run when entering `scheme-mode'.
2b20743d
DL
253See `run-hooks'."
254 :type 'hook
255 :group 'scheme)
256
257(defcustom dsssl-mode-hook nil
d17f0db5 258 "Normal hook run when entering `dsssl-mode'.
2b20743d
DL
259See `run-hooks'."
260 :type 'hook
48879301 261 :group 'scheme)
1367ff3a 262
f7a6110d
DL
263;; This is shared by cmuscheme and xscheme.
264(defcustom scheme-program-name "scheme"
265 "*Program invoked by the `run-scheme' command."
266 :type 'string
267 :group 'scheme)
268
1367ff3a
RS
269(defvar dsssl-imenu-generic-expression
270 ;; Perhaps this should also look for the style-sheet DTD tags. I'm
271 ;; not sure it's the best way to organize it; perhaps one type
272 ;; should be at the first level, though you don't see this anyhow if
273 ;; it gets split up.
d17f0db5 274 '(("Defines"
d575e99d 275 "^(define\\s-+(?\\(\\sw+\\)" 1)
93a7d76f 276 ("Modes"
d575e99d 277 "^\\s-*(mode\\s-+\\(\\(\\sw\\|\\s-\\)+\\)" 1)
93a7d76f 278 ("Elements"
1367ff3a 279 ;; (element foo ...) or (element (foo bar ...) ...)
26d05e22 280 ;; Fixme: Perhaps it should do `root'.
d575e99d 281 "^\\s-*(element\\s-+(?\\(\\(\\sw\\|\\s-\\)+\\))?" 1)
d17f0db5 282 ("Declarations"
d575e99d 283 "^(declare\\(-\\sw+\\)+\\>\\s-+\\(\\sw+\\)" 2))
1367ff3a
RS
284 "Imenu generic expression for DSSSL mode. See `imenu-generic-expression'.")
285
22dcd0d1
DL
286(defconst scheme-font-lock-keywords-1
287 (eval-when-compile
288 (list
289 ;;
290 ;; Declarations. Hannes Haug <hannes.haug@student.uni-tuebingen.de> says
291 ;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS.
405ff5ea 292 (list (concat "(\\(define\\*?\\("
22dcd0d1 293 ;; Function names.
405ff5ea 294 "\\(\\|-public\\|-method\\|-generic\\(-procedure\\)?\\)\\|"
22dcd0d1 295 ;; Macro names, as variable names. A bit dubious, this.
1b9a1e9d 296 "\\(-syntax\\|-macro\\)\\|"
22dcd0d1
DL
297 ;; Class names.
298 "-class"
405ff5ea
RS
299 ;; Guile modules.
300 "\\|-module"
22dcd0d1
DL
301 "\\)\\)\\>"
302 ;; Any whitespace and declared object.
303 "[ \t]*(?"
304 "\\(\\sw+\\)?")
305 '(1 font-lock-keyword-face)
306 '(6 (cond ((match-beginning 3) font-lock-function-name-face)
307 ((match-beginning 5) font-lock-variable-name-face)
308 (t font-lock-type-face))
309 nil t))
310 ))
311 "Subdued expressions to highlight in Scheme modes.")
312
313(defconst scheme-font-lock-keywords-2
314 (append scheme-font-lock-keywords-1
315 (eval-when-compile
316 (list
317 ;;
318 ;; Control structures.
319 (cons
320 (concat
321 "(" (regexp-opt
322 '("begin" "call-with-current-continuation" "call/cc"
323 "call-with-input-file" "call-with-output-file" "case" "cond"
324 "do" "else" "for-each" "if" "lambda"
325 "let" "let*" "let-syntax" "letrec" "letrec-syntax"
326 ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
c1bfdd54 327 "and" "or" "delay" "force"
22dcd0d1
DL
328 ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
329 ;;"quasiquote" "quote" "unquote" "unquote-splicing"
330 "map" "syntax" "syntax-rules") t)
331 "\\>") 1)
332 ;;
22071507
TTN
333 ;; It wouldn't be Scheme w/o named-let.
334 '("(let\\s-+\\(\\sw+\\)"
335 (1 font-lock-function-name-face))
336 ;;
22dcd0d1
DL
337 ;; David Fox <fox@graphics.cs.nyu.edu> for SOS/STklos class specifiers.
338 '("\\<<\\sw+>\\>" . font-lock-type-face)
339 ;;
cb049c41
TTN
340 ;; Scheme `:' and `#:' keywords as builtins.
341 '("\\<#?:\\sw+\\>" . font-lock-builtin-face)
22dcd0d1
DL
342 )))
343 "Gaudy expressions to highlight in Scheme modes.")
344
345(defvar scheme-font-lock-keywords scheme-font-lock-keywords-1
346 "Default expressions to highlight in Scheme modes.")
347
1367ff3a 348;;;###autoload
150bbae7 349(define-derived-mode dsssl-mode scheme-mode "DSSSL"
1367ff3a 350 "Major mode for editing DSSSL code.
d17f0db5 351Editing commands are similar to those of `lisp-mode'.
1367ff3a
RS
352
353Commands:
354Delete converts tabs to spaces as it moves back.
355Blank lines separate paragraphs. Semicolons start comments.
356\\{scheme-mode-map}
22dcd0d1
DL
357Entering this mode runs the hooks `scheme-mode-hook' and then
358`dsssl-mode-hook' and inserts the value of `dsssl-sgml-declaration' if
359that variable's value is a string."
1367ff3a
RS
360 (make-local-variable 'page-delimiter)
361 (setq page-delimiter "^;;;" ; ^L not valid SGML char
362 major-mode 'dsssl-mode
363 mode-name "DSSSL")
364 ;; Insert a suitable SGML declaration into an empty buffer.
150bbae7 365 ;; FIXME: This should use `auto-insert-alist' instead.
1367ff3a 366 (and (zerop (buffer-size))
26d05e22 367 (stringp dsssl-sgml-declaration)
1367ff3a
RS
368 (not buffer-read-only)
369 (insert dsssl-sgml-declaration))
22dcd0d1
DL
370 (setq font-lock-defaults '(dsssl-font-lock-keywords
371 nil t (("+-*/.<>=?$%_&~^:" . "w"))
372 beginning-of-defun
373 (font-lock-mark-block-function . mark-defun)))
1b9a1e9d 374 (set (make-local-variable 'imenu-case-fold-search) nil)
c0b08eb0 375 (setq imenu-generic-expression dsssl-imenu-generic-expression)
1b9a1e9d 376 (set (make-local-variable 'imenu-syntax-alist)
150bbae7 377 '(("+-*/.<>=?$%_&~^:" . "w"))))
1367ff3a
RS
378
379;; Extra syntax for DSSSL. This isn't separated from Scheme, but
380;; shouldn't cause much trouble in scheme-mode.
381(put 'element 'scheme-indent-function 1)
382(put 'mode 'scheme-indent-function 1)
383(put 'with-mode 'scheme-indent-function 1)
2f5029f3 384(put 'make 'scheme-indent-function 1)
26d05e22
RS
385(put 'style 'scheme-indent-function 1)
386(put 'root 'scheme-indent-function 1)
1367ff3a
RS
387
388(defvar dsssl-font-lock-keywords
26d05e22
RS
389 (eval-when-compile
390 (list
391 ;; Similar to Scheme
392 (list "(\\(define\\(-\\w+\\)?\\)\\>[ ]*\\\((?\\)\\(\\sw+\\)\\>"
393 '(1 font-lock-keyword-face)
394 '(4 font-lock-function-name-face))
395 (cons
396 (concat "(\\("
397 ;; (make-regexp '("case" "cond" "else" "if" "lambda"
398 ;; "let" "let*" "letrec" "and" "or" "map" "with-mode"))
399 "and\\|c\\(ase\\|ond\\)\\|else\\|if\\|"
400 "l\\(ambda\\|et\\(\\|*\\|rec\\)\\)\\|map\\|or\\|with-mode"
401 "\\)\\>")
402 1)
403 ;; DSSSL syntax
404 '("(\\(element\\|mode\\|declare-\\w+\\)\\>[ ]*\\(\\sw+\\)"
405 (1 font-lock-keyword-face)
406 (2 font-lock-type-face))
407 '("(\\(element\\)\\>[ ]*(\\(\\S)+\\))"
408 (1 font-lock-keyword-face)
409 (2 font-lock-type-face))
883212ce 410 '("\\<\\sw+:\\>" . font-lock-constant-face) ; trailing `:' c.f. scheme
26d05e22
RS
411 ;; SGML markup (from sgml-mode) :
412 '("<\\([!?][-a-z0-9]+\\)" 1 font-lock-keyword-face)
413 '("<\\(/?[-a-z0-9]+\\)" 1 font-lock-function-name-face)))
1367ff3a
RS
414 "Default expressions to highlight in DSSSL mode.")
415
ac5b21ac 416\f
1367ff3a
RS
417(defvar calculate-lisp-indent-last-sexp)
418
419;; Copied from lisp-indent-function, but with gets of
420;; scheme-indent-{function,hook}.
ac5b21ac
RS
421(defun scheme-indent-function (indent-point state)
422 (let ((normal-indent (current-column)))
1367ff3a
RS
423 (goto-char (1+ (elt state 1)))
424 (parse-partial-sexp (point) calculate-lisp-indent-last-sexp 0 t)
425 (if (and (elt state 2)
426 (not (looking-at "\\sw\\|\\s_")))
4696802b 427 ;; car of form doesn't seem to be a symbol
1367ff3a
RS
428 (progn
429 (if (not (> (save-excursion (forward-line 1) (point))
430 calculate-lisp-indent-last-sexp))
431 (progn (goto-char calculate-lisp-indent-last-sexp)
432 (beginning-of-line)
433 (parse-partial-sexp (point)
434 calculate-lisp-indent-last-sexp 0 t)))
435 ;; Indent under the list or under the first sexp on the same
436 ;; line as calculate-lisp-indent-last-sexp. Note that first
437 ;; thing on that line has to be complete sexp since we are
438 ;; inside the innermost containing sexp.
439 (backward-prefix-chars)
440 (current-column))
441 (let ((function (buffer-substring (point)
442 (progn (forward-sexp 1) (point))))
443 method)
444 (setq method (or (get (intern-soft function) 'scheme-indent-function)
445 (get (intern-soft function) 'scheme-indent-hook)))
446 (cond ((or (eq method 'defun)
447 (and (null method)
448 (> (length function) 3)
449 (string-match "\\`def" function)))
450 (lisp-indent-defform state indent-point))
451 ((integerp method)
452 (lisp-indent-specform method state
453 indent-point normal-indent))
454 (method
61185f42 455 (funcall method state indent-point normal-indent)))))))
1367ff3a 456
ac5b21ac
RS
457\f
458;;; Let is different in Scheme
459
460(defun would-be-symbol (string)
461 (not (string-equal (substring string 0 1) "(")))
462
463(defun next-sexp-as-string ()
d17f0db5 464 ;; Assumes that it is protected by a save-excursion
ac5b21ac
RS
465 (forward-sexp 1)
466 (let ((the-end (point)))
467 (backward-sexp 1)
468 (buffer-substring (point) the-end)))
469
470;; This is correct but too slow.
471;; The one below works almost always.
472;;(defun scheme-let-indent (state indent-point)
473;; (if (would-be-symbol (next-sexp-as-string))
474;; (scheme-indent-specform 2 state indent-point)
475;; (scheme-indent-specform 1 state indent-point)))
476
61185f42 477(defun scheme-let-indent (state indent-point normal-indent)
ac5b21ac 478 (skip-chars-forward " \t")
61361a07 479 (if (looking-at "[-a-zA-Z0-9+*/?!@$%^&_:~]")
61185f42
KH
480 (lisp-indent-specform 2 state indent-point normal-indent)
481 (lisp-indent-specform 1 state indent-point normal-indent)))
ac5b21ac
RS
482
483;; (put 'begin 'scheme-indent-function 0), say, causes begin to be indented
484;; like defun if the first form is placed on the next line, otherwise
485;; it is indented like any other form (i.e. forms line up under first).
486
487(put 'begin 'scheme-indent-function 0)
488(put 'case 'scheme-indent-function 1)
489(put 'delay 'scheme-indent-function 0)
490(put 'do 'scheme-indent-function 2)
491(put 'lambda 'scheme-indent-function 1)
492(put 'let 'scheme-indent-function 'scheme-let-indent)
493(put 'let* 'scheme-indent-function 1)
494(put 'letrec 'scheme-indent-function 1)
2b20743d
DL
495(put 'sequence 'scheme-indent-function 0) ; SICP, not r4rs
496(put 'let-syntax 'scheme-indent-function 1)
497(put 'letrec-syntax 'scheme-indent-function 1)
498(put 'syntax-rules 'scheme-indent-function 1)
0ec2c350 499(put 'syntax-case 'scheme-indent-function 2) ; not r5rs
ac5b21ac
RS
500
501(put 'call-with-input-file 'scheme-indent-function 1)
502(put 'with-input-from-file 'scheme-indent-function 1)
503(put 'with-input-from-port 'scheme-indent-function 1)
504(put 'call-with-output-file 'scheme-indent-function 1)
505(put 'with-output-to-file 'scheme-indent-function 1)
506(put 'with-output-to-port 'scheme-indent-function 1)
2b20743d
DL
507(put 'call-with-values 'scheme-indent-function 1) ; r5rs?
508(put 'dynamic-wind 'scheme-indent-function 3) ; r5rs?
ac5b21ac
RS
509\f
510;;;; MIT Scheme specific indentation.
511
512(if scheme-mit-dialect
513 (progn
514 (put 'fluid-let 'scheme-indent-function 1)
515 (put 'in-package 'scheme-indent-function 1)
ac5b21ac
RS
516 (put 'local-declare 'scheme-indent-function 1)
517 (put 'macro 'scheme-indent-function 1)
518 (put 'make-environment 'scheme-indent-function 0)
519 (put 'named-lambda 'scheme-indent-function 1)
520 (put 'using-syntax 'scheme-indent-function 1)
521
522 (put 'with-input-from-string 'scheme-indent-function 1)
523 (put 'with-output-to-string 'scheme-indent-function 0)
524 (put 'with-values 'scheme-indent-function 1)
525
526 (put 'syntax-table-define 'scheme-indent-function 2)
527 (put 'list-transform-positive 'scheme-indent-function 1)
528 (put 'list-transform-negative 'scheme-indent-function 1)
529 (put 'list-search-positive 'scheme-indent-function 1)
530 (put 'list-search-negative 'scheme-indent-function 1)
531
532 (put 'access-components 'scheme-indent-function 1)
533 (put 'assignment-components 'scheme-indent-function 1)
534 (put 'combination-components 'scheme-indent-function 1)
535 (put 'comment-components 'scheme-indent-function 1)
536 (put 'conditional-components 'scheme-indent-function 1)
537 (put 'disjunction-components 'scheme-indent-function 1)
538 (put 'declaration-components 'scheme-indent-function 1)
539 (put 'definition-components 'scheme-indent-function 1)
540 (put 'delay-components 'scheme-indent-function 1)
541 (put 'in-package-components 'scheme-indent-function 1)
542 (put 'lambda-components 'scheme-indent-function 1)
543 (put 'lambda-components* 'scheme-indent-function 1)
544 (put 'lambda-components** 'scheme-indent-function 1)
545 (put 'open-block-components 'scheme-indent-function 1)
546 (put 'pathname-components 'scheme-indent-function 1)
547 (put 'procedure-components 'scheme-indent-function 1)
548 (put 'sequence-components 'scheme-indent-function 1)
549 (put 'unassigned\?-components 'scheme-indent-function 1)
550 (put 'unbound\?-components 'scheme-indent-function 1)
551 (put 'variable-components 'scheme-indent-function 1)))
49116ac0
JB
552
553(provide 'scheme)
c88ab9ce 554
150bbae7 555;; arch-tag: a8f06bc1-ad11-42d2-9e36-ce651df37a90
c88ab9ce 556;;; scheme.el ends here