New directory
[bpt/emacs.git] / lisp / emacs-lisp / lisp.el
CommitLineData
6594deb0
ER
1;;; lisp.el --- Lisp editing commands for Emacs
2
c6eeec65 3;; Copyright (C) 1985, 1986, 1994, 2000 Free Software Foundation, Inc.
9750e079 4
e5167999 5;; Maintainer: FSF
e9571d2a 6;; Keywords: lisp, languages
e5167999 7
b73b9811 8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
e5167999 12;; the Free Software Foundation; either version 2, or (at your option)
b73b9811 13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
b73b9811 24
e41b2db1
ER
25;;; Commentary:
26
e50c4203
DL
27;; Lisp editing commands to go with Lisp major mode. More-or-less
28;; applicable in other modes too.
e41b2db1 29
e5167999 30;;; Code:
b73b9811 31
7fe78b07 32;; Note that this variable is used by non-lisp modes too.
30e19aee 33(defcustom defun-prompt-regexp nil
e50c4203 34 "*If non-nil, a regexp to ignore before the character that starts a defun.
7fe78b07 35This is only necessary if the opening paren or brace is not in column 0.
c7f18fba
GM
36See function `beginning-of-defun'.
37
38Setting this variable automatically makes it local to the current buffer."
ba6b3a2a
RS
39 :type '(choice (const nil)
40 regexp)
30e19aee 41 :group 'lisp)
24ff5498 42(make-variable-buffer-local 'defun-prompt-regexp)
b73b9811 43
30e19aee 44(defcustom parens-require-spaces t
e50c4203 45 "Non-nil means `insert-parentheses' should insert whitespace as needed."
30e19aee
RS
46 :type 'boolean
47 :group 'lisp)
44a53673 48
11ae6c5d
SM
49(defvar forward-sexp-function nil
50 "If non-nil, `forward-sexp' delegates to this function.
51Should take the same arguments and behave similarly to `forward-sexp'.")
52
b73b9811 53(defun forward-sexp (&optional arg)
54 "Move forward across one balanced expression (sexp).
c6eeec65 55With ARG, do it that many times. Negative arg -N means
e3f99b91 56move backward across N balanced expressions."
b73b9811 57 (interactive "p")
58 (or arg (setq arg 1))
11ae6c5d
SM
59 (if forward-sexp-function
60 (funcall forward-sexp-function arg)
61 (goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
62 (if (< arg 0) (backward-prefix-chars))))
b73b9811 63
64(defun backward-sexp (&optional arg)
65 "Move backward across one balanced expression (sexp).
c6eeec65 66With ARG, do it that many times. Negative arg -N means
e3f99b91 67move forward across N balanced expressions."
b73b9811 68 (interactive "p")
69 (or arg (setq arg 1))
70 (forward-sexp (- arg)))
71
e50c4203 72(defun mark-sexp (&optional arg)
b73b9811 73 "Set mark ARG sexps from point.
e3f99b91 74The place mark goes is the same place \\[forward-sexp] would
f07493e7
SM
75move to with the same argument.
76If this command is repeated, it marks the next ARG sexps after the ones
77already marked."
b73b9811 78 (interactive "p")
cad113ae
KG
79 (cond ((and (eq last-command this-command) (mark t))
80 (set-mark
81 (save-excursion
82 (goto-char (mark))
83 (forward-sexp (or arg 1))
84 (point))))
85 (t
86 (push-mark
87 (save-excursion
88 (forward-sexp (or arg 1))
89 (point))
90 nil t))))
b73b9811 91
92(defun forward-list (&optional arg)
93 "Move forward across one balanced group of parentheses.
c6eeec65 94With ARG, do it that many times.
b73b9811 95Negative arg -N means move backward across N groups of parentheses."
96 (interactive "p")
97 (or arg (setq arg 1))
98 (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
99
100(defun backward-list (&optional arg)
101 "Move backward across one balanced group of parentheses.
c6eeec65 102With ARG, do it that many times.
b73b9811 103Negative arg -N means move forward across N groups of parentheses."
104 (interactive "p")
105 (or arg (setq arg 1))
106 (forward-list (- arg)))
107
e50c4203 108(defun down-list (&optional arg)
b73b9811 109 "Move forward down one level of parentheses.
c6eeec65 110With ARG, do this that many times.
b41c9501 111A negative argument means move backward but still go down a level."
b73b9811 112 (interactive "p")
e50c4203 113 (or arg (setq arg 1))
b73b9811 114 (let ((inc (if (> arg 0) 1 -1)))
115 (while (/= arg 0)
116 (goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
117 (setq arg (- arg inc)))))
118
e50c4203 119(defun backward-up-list (&optional arg)
b73b9811 120 "Move backward out of one level of parentheses.
c6eeec65 121With ARG, do this that many times.
b41c9501 122A negative argument means move forward but still to a less deep spot."
b73b9811 123 (interactive "p")
e50c4203 124 (up-list (- (or arg 1))))
b73b9811 125
e50c4203 126(defun up-list (&optional arg)
b73b9811 127 "Move forward out of one level of parentheses.
c6eeec65 128With ARG, do this that many times.
b41c9501 129A negative argument means move backward but still to a less deep spot."
b73b9811 130 (interactive "p")
e50c4203 131 (or arg (setq arg 1))
b73b9811 132 (let ((inc (if (> arg 0) 1 -1)))
133 (while (/= arg 0)
134 (goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
135 (setq arg (- arg inc)))))
136
e50c4203 137(defun kill-sexp (&optional arg)
b73b9811 138 "Kill the sexp (balanced expression) following the cursor.
c6eeec65 139With ARG, kill that many sexps after the cursor.
b73b9811 140Negative arg -N means kill N sexps before the cursor."
141 (interactive "p")
142 (let ((opoint (point)))
e50c4203 143 (forward-sexp (or arg 1))
b73b9811 144 (kill-region opoint (point))))
145
e50c4203 146(defun backward-kill-sexp (&optional arg)
b73b9811 147 "Kill the sexp (balanced expression) preceding the cursor.
c6eeec65 148With ARG, kill that many sexps before the cursor.
b73b9811 149Negative arg -N means kill N sexps after the cursor."
150 (interactive "p")
e50c4203 151 (kill-sexp (- (or arg 1))))
b73b9811 152\f
ab22ee53 153(defvar beginning-of-defun-function nil
c6eeec65
DL
154 "If non-nil, function for `beginning-of-defun-raw' to call.
155This is used to find the beginning of the defun instead of using the
ab22ee53
RS
156normal recipe (see `beginning-of-defun'). Major modes can define this
157if defining `defun-prompt-regexp' is not sufficient to handle the mode's
158needs.
c6eeec65 159
463f5630
KH
160The function should go to the line on which the current defun starts,
161and return non-nil, or should return nil if it can't find the beginning.")
c6eeec65 162
b73b9811 163(defun beginning-of-defun (&optional arg)
164 "Move backward to the beginning of a defun.
c6eeec65 165With ARG, do it that many times. Negative arg -N
b73b9811 166means move forward to Nth following beginning of defun.
167Returns t unless search stops due to beginning or end of buffer.
168
1269ae51 169Normally a defun starts when there is a char with open-parenthesis
b73b9811 170syntax at the beginning of a line. If `defun-prompt-regexp' is
171non-nil, then a string which matches that regexp may precede the
c6eeec65
DL
172open-parenthesis, and point ends up at the beginning of the line.
173
ab22ee53
RS
174If variable `beginning-of-defun-function' is non-nil, its value
175is called as a function to find the defun's beginning."
afa995e1
KH
176 (interactive "p")
177 (and (beginning-of-defun-raw arg)
178 (progn (beginning-of-line) t)))
179
180(defun beginning-of-defun-raw (&optional arg)
181 "Move point to the character that starts a defun.
c6eeec65
DL
182This is identical to function `beginning-of-defun', except that point
183does not move to the beginning of the line when `defun-prompt-regexp'
184is non-nil.
185
ab22ee53
RS
186If variable `beginning-of-defun-function' is non-nil, its value
187is called as a function to find the defun's beginning."
b73b9811 188 (interactive "p")
ab22ee53
RS
189 (if beginning-of-defun-function
190 (funcall beginning-of-defun-function)
c6eeec65
DL
191 (and arg (< arg 0) (not (eobp)) (forward-char 1))
192 (and (re-search-backward (if defun-prompt-regexp
418d645c
GM
193 (concat (if open-paren-in-column-0-is-defun-start
194 "^\\s(\\|" "")
b5ed9def 195 "\\(?:" defun-prompt-regexp "\\)\\s(")
c6eeec65
DL
196 "^\\s(")
197 nil 'move (or arg 1))
198 (progn (goto-char (1- (match-end 0)))) t)))
199
ab22ee53 200(defvar end-of-defun-function nil
c6eeec65
DL
201 "If non-nil, function for function `end-of-defun' to call.
202This is used to find the end of the defun instead of using the normal
ab22ee53
RS
203recipe (see `end-of-defun'). Major modes can define this if the
204normal method is not appropriate.")
b73b9811 205
206(defun buffer-end (arg)
207 (if (> arg 0) (point-max) (point-min)))
208
209(defun end-of-defun (&optional arg)
210 "Move forward to next end of defun. With argument, do it that many times.
211Negative argument -N means move back to Nth preceding end of defun.
212
c6eeec65
DL
213An end of a defun occurs right after the close-parenthesis that
214matches the open-parenthesis that starts a defun; see function
ab22ee53
RS
215`beginning-of-defun'.
216
217If variable `end-of-defun-function' is non-nil, its value
218is called as a function to find the defun's end."
b73b9811 219 (interactive "p")
ab22ee53
RS
220 (if end-of-defun-function
221 (funcall end-of-defun-function)
c6eeec65
DL
222 (if (or (null arg) (= arg 0)) (setq arg 1))
223 (let ((first t))
224 (while (and (> arg 0) (< (point) (point-max)))
225 (let ((pos (point)) npos)
226 (while (progn
227 (if (and first
228 (progn
229 (end-of-line 1)
230 (beginning-of-defun-raw 1)))
231 nil
232 (or (bobp) (forward-char -1))
233 (beginning-of-defun-raw -1))
234 (setq first nil)
235 (forward-list 1)
236 (skip-chars-forward " \t")
237 (if (looking-at "\\s<\\|\n")
238 (forward-line 1))
239 (<= (point) pos))))
240 (setq arg (1- arg)))
241 (while (< arg 0)
242 (let ((pos (point)))
243 (beginning-of-defun-raw 1)
244 (forward-sexp 1)
245 (forward-line 1)
246 (if (>= (point) pos)
247 (if (beginning-of-defun-raw 2)
248 (progn
249 (forward-list 1)
250 (skip-chars-forward " \t")
251 (if (looking-at "\\s<\\|\n")
252 (forward-line 1)))
253 (goto-char (point-min)))))
254 (setq arg (1+ arg))))))
b73b9811 255
256(defun mark-defun ()
257 "Put mark at end of this defun, point at beginning.
cad113ae
KG
258The defun marked is the one that contains point or follows point.
259If this command is repeated, marks more defuns after the ones
260already marked."
b73b9811 261 (interactive)
be0d25b6
KG
262 (cond ((and (eq last-command this-command) (mark t))
263 (set-mark
264 (save-excursion
265 (goto-char (mark))
266 (end-of-defun)
267 (point))))
268 (t
269 (push-mark (point))
270 (end-of-defun)
271 (push-mark (point) nil t)
272 (beginning-of-defun)
273 (re-search-backward "^\n" (- (point) 1) t))))
b73b9811 274
3f7e952d
RS
275(defun narrow-to-defun (&optional arg)
276 "Make text outside current defun invisible.
c6eeec65
DL
277The defun visible is the one that contains point or follows point.
278Optional ARG is ignored."
3f7e952d
RS
279 (interactive)
280 (save-excursion
281 (widen)
e3ac26cb
EN
282 (end-of-defun)
283 (let ((end (point)))
284 (beginning-of-defun)
285 (narrow-to-region (point) end))))
3f7e952d 286
b73b9811 287(defun insert-parentheses (arg)
e3ac26cb
EN
288 "Enclose following ARG sexps in parentheses. Leave point after open-paren.
289A negative ARG encloses the preceding ARG sexps instead.
44a53673 290No argument is equivalent to zero: just insert `()' and leave point between.
d5bfe076
KH
291If `parens-require-spaces' is non-nil, this command also inserts a space
292before and after, depending on the surrounding characters."
b73b9811 293 (interactive "P")
a17f9e55
RS
294 (if arg (setq arg (prefix-numeric-value arg))
295 (setq arg 0))
e3ac26cb
EN
296 (cond ((> arg 0) (skip-chars-forward " \t"))
297 ((< arg 0) (forward-sexp arg) (setq arg (- arg))))
78e367e9 298 (and parens-require-spaces
6696af65 299 (not (bobp))
44a53673 300 (memq (char-syntax (preceding-char)) '(?w ?_ ?\) ))
b73b9811 301 (insert " "))
b73b9811 302 (insert ?\()
303 (save-excursion
a17f9e55 304 (or (eq arg 0) (forward-sexp arg))
b73b9811 305 (insert ?\))
78e367e9 306 (and parens-require-spaces
6696af65 307 (not (eobp))
44a53673 308 (memq (char-syntax (following-char)) '(?w ?_ ?\( ))
a17f9e55 309 (insert " "))))
b73b9811 310
311(defun move-past-close-and-reindent ()
312 "Move past next `)', delete indentation before it, then indent after it."
313 (interactive)
314 (up-list 1)
315 (forward-char -1)
316 (while (save-excursion ; this is my contribution
317 (let ((before-paren (point)))
318 (back-to-indentation)
adce3b5f
RS
319 (and (= (point) before-paren)
320 (progn
321 ;; Move to end of previous line.
322 (beginning-of-line)
323 (forward-char -1)
324 ;; Verify it doesn't end within a string or comment.
325 (let ((end (point))
326 state)
327 (beginning-of-line)
328 ;; Get state at start of line.
c6eeec65 329 (setq state (list 0 nil nil
adce3b5f
RS
330 (null (calculate-lisp-indent))
331 nil nil nil nil
332 nil))
333 ;; Parse state across the line to get state at end.
334 (setq state (parse-partial-sexp (point) end nil nil
335 state))
336 ;; Check not in string or comment.
337 (and (not (elt state 3)) (not (elt state 4))))))))
b73b9811 338 (delete-indentation))
339 (forward-char 1)
340 (newline-and-indent))
c6eeec65
DL
341
342(defun check-parens () ; lame name?
343 "Check for unbalanced parentheses in the current buffer.
344More accurately, check the narrowed part of the buffer for unbalanced
345expressions (\"sexps\") in general. This is done according to the
346current syntax table and will find unbalanced brackets or quotes as
347appropriate. (See Info node `(emacs)Lists and Sexps'.) If imbalance
348is found, an error is signalled and point is left at the first
349unbalanced character."
350 (interactive)
351 (condition-case data
352 ;; Buffer can't have more than (point-max) sexps.
353 (scan-sexps (point-min) (point-max))
354 (scan-error (goto-char (nth 2 data))
355 ;; Could print (nth 1 data), which is either
356 ;; "Containing expression ends prematurely" or
357 ;; "Unbalanced parentheses", but those may not be so
358 ;; accurate/helpful, e.g. quotes may actually be
359 ;; mismatched.
360 (error "Unmatched bracket or quote"))
361 (error (cond ((eq 'scan-error (car data))
362 (goto-char (nth 2 data))
363 (error "Unmatched bracket or quote"))
364 (t (signal (car data) (cdr data)))))))
b73b9811 365\f
e50c4203 366(defun lisp-complete-symbol (&optional predicate)
2eb9adab
RS
367 "Perform completion on Lisp symbol preceding point.
368Compare that symbol against the known Lisp symbols.
1fa1cb1b
RS
369If no characters can be completed, display a list of possible completions.
370Repeating the command at that point scrolls the list.
2eb9adab 371
e50c4203
DL
372When called from a program, optional arg PREDICATE is a predicate
373determining which symbols are considered, e.g. `commandp'.
374If PREDICATE is nil, the context determines which symbols are
375considered. If the symbol starts just after an open-parenthesis, only
376symbols with function definitions are considered. Otherwise, all
377symbols with function definitions, values or properties are
378considered."
b73b9811 379 (interactive)
1fa1cb1b
RS
380
381 (let ((window (get-buffer-window "*Completions*")))
382 (if (and (eq last-command this-command)
383 window (window-live-p window) (window-buffer window)
384 (buffer-name (window-buffer window)))
385 ;; If this command was repeated, and
386 ;; there's a fresh completion window with a live buffer,
387 ;; and this command is repeated, scroll that window.
388 (with-current-buffer (window-buffer window)
389 (if (pos-visible-in-window-p (point-max) window)
390 (set-window-start window (point-min))
391 (save-selected-window
392 (select-window window)
393 (scroll-up))))
394
395 ;; Do completion.
396 (let* ((end (point))
397 (beg (with-syntax-table emacs-lisp-mode-syntax-table
398 (save-excursion
399 (backward-sexp 1)
400 (while (= (char-syntax (following-char)) ?\')
401 (forward-char 1))
402 (point))))
403 (pattern (buffer-substring-no-properties beg end))
404 (predicate
405 (or predicate
406 (save-excursion
407 (goto-char beg)
408 (if (not (eq (char-before) ?\())
409 (lambda (sym) ;why not just nil ? -sm
410 (or (boundp sym) (fboundp sym)
411 (symbol-plist sym)))
412 ;; Looks like a funcall position. Let's double check.
413 (if (condition-case nil
414 (progn (up-list -2) (forward-char 1)
415 (eq (char-after) ?\())
416 (error nil))
417 ;; If the first element of the parent list is an open
418 ;; parenthesis we are probably not in a funcall position.
419 ;; Maybe a `let' varlist or something.
420 nil
421 ;; Else, we assume that a function name is expected.
422 'fboundp)))))
423 (completion (try-completion pattern obarray predicate)))
424 (cond ((eq completion t))
425 ((null completion)
426 (message "Can't find completion for \"%s\"" pattern)
427 (ding))
428 ((not (string= pattern completion))
429 (delete-region beg end)
430 (insert completion))
431 (t
432 (message "Making completion list...")
433 (let ((list (all-completions pattern obarray predicate)))
434 (setq list (sort list 'string<))
435 (or (eq predicate 'fboundp)
436 (let (new)
437 (while list
438 (setq new (cons (if (fboundp (intern (car list)))
439 (list (car list) " <f>")
440 (car list))
441 new))
442 (setq list (cdr list)))
443 (setq list (nreverse new))))
444 (with-output-to-temp-buffer "*Completions*"
445 (display-completion-list list)))
446 (message "Making completion list...%s" "done")))))))
6594deb0
ER
447
448;;; lisp.el ends here