(update-authors): New target for maintenance
[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
JB
74The place mark goes is the same place \\[forward-sexp] would
75move to with the same argument."
b73b9811 76 (interactive "p")
77 (push-mark
78 (save-excursion
e50c4203 79 (forward-sexp (or arg 1))
0ba91115
RS
80 (point))
81 nil t))
b73b9811 82
83(defun forward-list (&optional arg)
84 "Move forward across one balanced group of parentheses.
c6eeec65 85With ARG, do it that many times.
b73b9811 86Negative arg -N means move backward across N groups of parentheses."
87 (interactive "p")
88 (or arg (setq arg 1))
89 (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
90
91(defun backward-list (&optional arg)
92 "Move backward across one balanced group of parentheses.
c6eeec65 93With ARG, do it that many times.
b73b9811 94Negative arg -N means move forward across N groups of parentheses."
95 (interactive "p")
96 (or arg (setq arg 1))
97 (forward-list (- arg)))
98
e50c4203 99(defun down-list (&optional arg)
b73b9811 100 "Move forward down one level of parentheses.
c6eeec65 101With ARG, do this that many times.
b41c9501 102A negative argument means move backward but still go down a level."
b73b9811 103 (interactive "p")
e50c4203 104 (or arg (setq arg 1))
b73b9811 105 (let ((inc (if (> arg 0) 1 -1)))
106 (while (/= arg 0)
107 (goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
108 (setq arg (- arg inc)))))
109
e50c4203 110(defun backward-up-list (&optional arg)
b73b9811 111 "Move backward out of one level of parentheses.
c6eeec65 112With ARG, do this that many times.
b41c9501 113A negative argument means move forward but still to a less deep spot."
b73b9811 114 (interactive "p")
e50c4203 115 (up-list (- (or arg 1))))
b73b9811 116
e50c4203 117(defun up-list (&optional arg)
b73b9811 118 "Move forward out of one level of parentheses.
c6eeec65 119With ARG, do this that many times.
b41c9501 120A negative argument means move backward but still to a less deep spot."
b73b9811 121 (interactive "p")
e50c4203 122 (or arg (setq arg 1))
b73b9811 123 (let ((inc (if (> arg 0) 1 -1)))
124 (while (/= arg 0)
125 (goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
126 (setq arg (- arg inc)))))
127
e50c4203 128(defun kill-sexp (&optional arg)
b73b9811 129 "Kill the sexp (balanced expression) following the cursor.
c6eeec65 130With ARG, kill that many sexps after the cursor.
b73b9811 131Negative arg -N means kill N sexps before the cursor."
132 (interactive "p")
133 (let ((opoint (point)))
e50c4203 134 (forward-sexp (or arg 1))
b73b9811 135 (kill-region opoint (point))))
136
e50c4203 137(defun backward-kill-sexp (&optional arg)
b73b9811 138 "Kill the sexp (balanced expression) preceding the cursor.
c6eeec65 139With ARG, kill that many sexps before the cursor.
b73b9811 140Negative arg -N means kill N sexps after the cursor."
141 (interactive "p")
e50c4203 142 (kill-sexp (- (or arg 1))))
b73b9811 143\f
ab22ee53 144(defvar beginning-of-defun-function nil
c6eeec65
DL
145 "If non-nil, function for `beginning-of-defun-raw' to call.
146This is used to find the beginning of the defun instead of using the
ab22ee53
RS
147normal recipe (see `beginning-of-defun'). Major modes can define this
148if defining `defun-prompt-regexp' is not sufficient to handle the mode's
149needs.
c6eeec65 150
ab22ee53
RS
151The function should go to the line on which the current defun starts,
152and return non-nil, or should return nil if it can't find the beginning.")
c6eeec65 153
b73b9811 154(defun beginning-of-defun (&optional arg)
155 "Move backward to the beginning of a defun.
c6eeec65 156With ARG, do it that many times. Negative arg -N
b73b9811 157means move forward to Nth following beginning of defun.
158Returns t unless search stops due to beginning or end of buffer.
159
160Normally a defun starts when there is an char with open-parenthesis
161syntax at the beginning of a line. If `defun-prompt-regexp' is
162non-nil, then a string which matches that regexp may precede the
c6eeec65
DL
163open-parenthesis, and point ends up at the beginning of the line.
164
ab22ee53
RS
165If variable `beginning-of-defun-function' is non-nil, its value
166is called as a function to find the defun's beginning."
afa995e1
KH
167 (interactive "p")
168 (and (beginning-of-defun-raw arg)
169 (progn (beginning-of-line) t)))
170
171(defun beginning-of-defun-raw (&optional arg)
172 "Move point to the character that starts a defun.
c6eeec65
DL
173This is identical to function `beginning-of-defun', except that point
174does not move to the beginning of the line when `defun-prompt-regexp'
175is non-nil.
176
ab22ee53
RS
177If variable `beginning-of-defun-function' is non-nil, its value
178is called as a function to find the defun's beginning."
b73b9811 179 (interactive "p")
ab22ee53
RS
180 (if beginning-of-defun-function
181 (funcall beginning-of-defun-function)
c6eeec65
DL
182 (and arg (< arg 0) (not (eobp)) (forward-char 1))
183 (and (re-search-backward (if defun-prompt-regexp
418d645c
GM
184 (concat (if open-paren-in-column-0-is-defun-start
185 "^\\s(\\|" "")
c6eeec65
DL
186 "\\(" defun-prompt-regexp "\\)\\s(")
187 "^\\s(")
188 nil 'move (or arg 1))
189 (progn (goto-char (1- (match-end 0)))) t)))
190
ab22ee53 191(defvar end-of-defun-function nil
c6eeec65
DL
192 "If non-nil, function for function `end-of-defun' to call.
193This is used to find the end of the defun instead of using the normal
ab22ee53
RS
194recipe (see `end-of-defun'). Major modes can define this if the
195normal method is not appropriate.")
b73b9811 196
197(defun buffer-end (arg)
198 (if (> arg 0) (point-max) (point-min)))
199
200(defun end-of-defun (&optional arg)
201 "Move forward to next end of defun. With argument, do it that many times.
202Negative argument -N means move back to Nth preceding end of defun.
203
c6eeec65
DL
204An end of a defun occurs right after the close-parenthesis that
205matches the open-parenthesis that starts a defun; see function
ab22ee53
RS
206`beginning-of-defun'.
207
208If variable `end-of-defun-function' is non-nil, its value
209is called as a function to find the defun's end."
b73b9811 210 (interactive "p")
ab22ee53
RS
211 (if end-of-defun-function
212 (funcall end-of-defun-function)
c6eeec65
DL
213 (if (or (null arg) (= arg 0)) (setq arg 1))
214 (let ((first t))
215 (while (and (> arg 0) (< (point) (point-max)))
216 (let ((pos (point)) npos)
217 (while (progn
218 (if (and first
219 (progn
220 (end-of-line 1)
221 (beginning-of-defun-raw 1)))
222 nil
223 (or (bobp) (forward-char -1))
224 (beginning-of-defun-raw -1))
225 (setq first nil)
226 (forward-list 1)
227 (skip-chars-forward " \t")
228 (if (looking-at "\\s<\\|\n")
229 (forward-line 1))
230 (<= (point) pos))))
231 (setq arg (1- arg)))
232 (while (< arg 0)
233 (let ((pos (point)))
234 (beginning-of-defun-raw 1)
235 (forward-sexp 1)
236 (forward-line 1)
237 (if (>= (point) pos)
238 (if (beginning-of-defun-raw 2)
239 (progn
240 (forward-list 1)
241 (skip-chars-forward " \t")
242 (if (looking-at "\\s<\\|\n")
243 (forward-line 1)))
244 (goto-char (point-min)))))
245 (setq arg (1+ arg))))))
b73b9811 246
247(defun mark-defun ()
248 "Put mark at end of this defun, point at beginning.
249The defun marked is the one that contains point or follows point."
250 (interactive)
251 (push-mark (point))
252 (end-of-defun)
0ba91115 253 (push-mark (point) nil t)
b73b9811 254 (beginning-of-defun)
255 (re-search-backward "^\n" (- (point) 1) t))
256
3f7e952d
RS
257(defun narrow-to-defun (&optional arg)
258 "Make text outside current defun invisible.
c6eeec65
DL
259The defun visible is the one that contains point or follows point.
260Optional ARG is ignored."
3f7e952d
RS
261 (interactive)
262 (save-excursion
263 (widen)
e3ac26cb
EN
264 (end-of-defun)
265 (let ((end (point)))
266 (beginning-of-defun)
267 (narrow-to-region (point) end))))
3f7e952d 268
b73b9811 269(defun insert-parentheses (arg)
e3ac26cb
EN
270 "Enclose following ARG sexps in parentheses. Leave point after open-paren.
271A negative ARG encloses the preceding ARG sexps instead.
44a53673 272No argument is equivalent to zero: just insert `()' and leave point between.
d5bfe076
KH
273If `parens-require-spaces' is non-nil, this command also inserts a space
274before and after, depending on the surrounding characters."
b73b9811 275 (interactive "P")
a17f9e55
RS
276 (if arg (setq arg (prefix-numeric-value arg))
277 (setq arg 0))
e3ac26cb
EN
278 (cond ((> arg 0) (skip-chars-forward " \t"))
279 ((< arg 0) (forward-sexp arg) (setq arg (- arg))))
78e367e9 280 (and parens-require-spaces
6696af65 281 (not (bobp))
44a53673 282 (memq (char-syntax (preceding-char)) '(?w ?_ ?\) ))
b73b9811 283 (insert " "))
b73b9811 284 (insert ?\()
285 (save-excursion
a17f9e55 286 (or (eq arg 0) (forward-sexp arg))
b73b9811 287 (insert ?\))
78e367e9 288 (and parens-require-spaces
6696af65 289 (not (eobp))
44a53673 290 (memq (char-syntax (following-char)) '(?w ?_ ?\( ))
a17f9e55 291 (insert " "))))
b73b9811 292
293(defun move-past-close-and-reindent ()
294 "Move past next `)', delete indentation before it, then indent after it."
295 (interactive)
296 (up-list 1)
297 (forward-char -1)
298 (while (save-excursion ; this is my contribution
299 (let ((before-paren (point)))
300 (back-to-indentation)
adce3b5f
RS
301 (and (= (point) before-paren)
302 (progn
303 ;; Move to end of previous line.
304 (beginning-of-line)
305 (forward-char -1)
306 ;; Verify it doesn't end within a string or comment.
307 (let ((end (point))
308 state)
309 (beginning-of-line)
310 ;; Get state at start of line.
c6eeec65 311 (setq state (list 0 nil nil
adce3b5f
RS
312 (null (calculate-lisp-indent))
313 nil nil nil nil
314 nil))
315 ;; Parse state across the line to get state at end.
316 (setq state (parse-partial-sexp (point) end nil nil
317 state))
318 ;; Check not in string or comment.
319 (and (not (elt state 3)) (not (elt state 4))))))))
b73b9811 320 (delete-indentation))
321 (forward-char 1)
322 (newline-and-indent))
c6eeec65
DL
323
324(defun check-parens () ; lame name?
325 "Check for unbalanced parentheses in the current buffer.
326More accurately, check the narrowed part of the buffer for unbalanced
327expressions (\"sexps\") in general. This is done according to the
328current syntax table and will find unbalanced brackets or quotes as
329appropriate. (See Info node `(emacs)Lists and Sexps'.) If imbalance
330is found, an error is signalled and point is left at the first
331unbalanced character."
332 (interactive)
333 (condition-case data
334 ;; Buffer can't have more than (point-max) sexps.
335 (scan-sexps (point-min) (point-max))
336 (scan-error (goto-char (nth 2 data))
337 ;; Could print (nth 1 data), which is either
338 ;; "Containing expression ends prematurely" or
339 ;; "Unbalanced parentheses", but those may not be so
340 ;; accurate/helpful, e.g. quotes may actually be
341 ;; mismatched.
342 (error "Unmatched bracket or quote"))
343 (error (cond ((eq 'scan-error (car data))
344 (goto-char (nth 2 data))
345 (error "Unmatched bracket or quote"))
346 (t (signal (car data) (cdr data)))))))
b73b9811 347\f
e50c4203 348(defun lisp-complete-symbol (&optional predicate)
2eb9adab
RS
349 "Perform completion on Lisp symbol preceding point.
350Compare that symbol against the known Lisp symbols.
351
e50c4203
DL
352When called from a program, optional arg PREDICATE is a predicate
353determining which symbols are considered, e.g. `commandp'.
354If PREDICATE is nil, the context determines which symbols are
355considered. If the symbol starts just after an open-parenthesis, only
356symbols with function definitions are considered. Otherwise, all
357symbols with function definitions, values or properties are
358considered."
b73b9811 359 (interactive)
360 (let* ((end (point))
e50c4203 361 (beg (with-syntax-table emacs-lisp-mode-syntax-table
11ae6c5d
SM
362 (save-excursion
363 (backward-sexp 1)
364 (while (= (char-syntax (following-char)) ?\')
365 (forward-char 1))
366 (point))))
e50c4203 367 (pattern (buffer-substring-no-properties beg end))
b73b9811 368 (predicate
e50c4203 369 (or predicate
11ae6c5d
SM
370 (save-excursion
371 (goto-char beg)
372 (if (not (eq (char-before) ?\())
373 (lambda (sym) ;why not just nil ? -sm
374 (or (boundp sym) (fboundp sym)
375 (symbol-plist sym)))
376 ;; Looks like a funcall position. Let's double check.
11ae6c5d
SM
377 (if (condition-case nil
378 (progn (up-list -2) (forward-char 1)
379 (eq (char-after) ?\())
380 (error nil))
381 ;; If the first element of the parent list is an open
382 ;; parenthesis we are probably not in a funcall position.
383 ;; Maybe a `let' varlist or something.
384 nil
385 ;; Else, we assume that a function name is expected.
386 'fboundp)))))
b73b9811 387 (completion (try-completion pattern obarray predicate)))
388 (cond ((eq completion t))
389 ((null completion)
390 (message "Can't find completion for \"%s\"" pattern)
391 (ding))
392 ((not (string= pattern completion))
393 (delete-region beg end)
394 (insert completion))
395 (t
396 (message "Making completion list...")
e323ab22 397 (let ((list (all-completions pattern obarray predicate)))
030dccec 398 (setq list (sort list 'string<))
b73b9811 399 (or (eq predicate 'fboundp)
400 (let (new)
401 (while list
402 (setq new (cons (if (fboundp (intern (car list)))
403 (list (car list) " <f>")
404 (car list))
405 new))
406 (setq list (cdr list)))
407 (setq list (nreverse new))))
1af808dc 408 (with-output-to-temp-buffer "*Completions*"
b73b9811 409 (display-completion-list list)))
410 (message "Making completion list...%s" "done")))))
6594deb0
ER
411
412;;; lisp.el ends here