Add arch taglines
[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
7a0e9874
DL
160The function (of no args) should go to the line on which the current
161defun starts, and return non-nil, or should return nil if it can't
162find the beginning.")
c6eeec65 163
b73b9811 164(defun beginning-of-defun (&optional arg)
165 "Move backward to the beginning of a defun.
c6eeec65 166With ARG, do it that many times. Negative arg -N
b73b9811 167means move forward to Nth following beginning of defun.
168Returns t unless search stops due to beginning or end of buffer.
169
1269ae51 170Normally a defun starts when there is a char with open-parenthesis
b73b9811 171syntax at the beginning of a line. If `defun-prompt-regexp' is
172non-nil, then a string which matches that regexp may precede the
c6eeec65
DL
173open-parenthesis, and point ends up at the beginning of the line.
174
ab22ee53
RS
175If variable `beginning-of-defun-function' is non-nil, its value
176is called as a function to find the defun's beginning."
afa995e1
KH
177 (interactive "p")
178 (and (beginning-of-defun-raw arg)
179 (progn (beginning-of-line) t)))
180
181(defun beginning-of-defun-raw (&optional arg)
182 "Move point to the character that starts a defun.
c6eeec65
DL
183This is identical to function `beginning-of-defun', except that point
184does not move to the beginning of the line when `defun-prompt-regexp'
185is non-nil.
186
ab22ee53
RS
187If variable `beginning-of-defun-function' is non-nil, its value
188is called as a function to find the defun's beginning."
b73b9811 189 (interactive "p")
ab22ee53
RS
190 (if beginning-of-defun-function
191 (funcall beginning-of-defun-function)
c6eeec65
DL
192 (and arg (< arg 0) (not (eobp)) (forward-char 1))
193 (and (re-search-backward (if defun-prompt-regexp
418d645c
GM
194 (concat (if open-paren-in-column-0-is-defun-start
195 "^\\s(\\|" "")
b5ed9def 196 "\\(?:" defun-prompt-regexp "\\)\\s(")
c6eeec65
DL
197 "^\\s(")
198 nil 'move (or arg 1))
199 (progn (goto-char (1- (match-end 0)))) t)))
200
ab22ee53 201(defvar end-of-defun-function nil
c6eeec65
DL
202 "If non-nil, function for function `end-of-defun' to call.
203This is used to find the end of the defun instead of using the normal
ab22ee53
RS
204recipe (see `end-of-defun'). Major modes can define this if the
205normal method is not appropriate.")
b73b9811 206
207(defun buffer-end (arg)
208 (if (> arg 0) (point-max) (point-min)))
209
210(defun end-of-defun (&optional arg)
211 "Move forward to next end of defun. With argument, do it that many times.
212Negative argument -N means move back to Nth preceding end of defun.
213
c6eeec65
DL
214An end of a defun occurs right after the close-parenthesis that
215matches the open-parenthesis that starts a defun; see function
ab22ee53
RS
216`beginning-of-defun'.
217
218If variable `end-of-defun-function' is non-nil, its value
219is called as a function to find the defun's end."
b73b9811 220 (interactive "p")
ab22ee53
RS
221 (if end-of-defun-function
222 (funcall end-of-defun-function)
c6eeec65
DL
223 (if (or (null arg) (= arg 0)) (setq arg 1))
224 (let ((first t))
225 (while (and (> arg 0) (< (point) (point-max)))
226 (let ((pos (point)) npos)
227 (while (progn
228 (if (and first
229 (progn
230 (end-of-line 1)
231 (beginning-of-defun-raw 1)))
232 nil
233 (or (bobp) (forward-char -1))
234 (beginning-of-defun-raw -1))
235 (setq first nil)
236 (forward-list 1)
237 (skip-chars-forward " \t")
238 (if (looking-at "\\s<\\|\n")
239 (forward-line 1))
240 (<= (point) pos))))
241 (setq arg (1- arg)))
242 (while (< arg 0)
243 (let ((pos (point)))
244 (beginning-of-defun-raw 1)
245 (forward-sexp 1)
246 (forward-line 1)
247 (if (>= (point) pos)
248 (if (beginning-of-defun-raw 2)
249 (progn
250 (forward-list 1)
251 (skip-chars-forward " \t")
252 (if (looking-at "\\s<\\|\n")
253 (forward-line 1)))
254 (goto-char (point-min)))))
255 (setq arg (1+ arg))))))
b73b9811 256
257(defun mark-defun ()
258 "Put mark at end of this defun, point at beginning.
cad113ae
KG
259The defun marked is the one that contains point or follows point.
260If this command is repeated, marks more defuns after the ones
261already marked."
b73b9811 262 (interactive)
be0d25b6
KG
263 (cond ((and (eq last-command this-command) (mark t))
264 (set-mark
265 (save-excursion
266 (goto-char (mark))
267 (end-of-defun)
268 (point))))
269 (t
270 (push-mark (point))
271 (end-of-defun)
272 (push-mark (point) nil t)
273 (beginning-of-defun)
274 (re-search-backward "^\n" (- (point) 1) t))))
b73b9811 275
3f7e952d
RS
276(defun narrow-to-defun (&optional arg)
277 "Make text outside current defun invisible.
c6eeec65
DL
278The defun visible is the one that contains point or follows point.
279Optional ARG is ignored."
3f7e952d
RS
280 (interactive)
281 (save-excursion
282 (widen)
e3ac26cb
EN
283 (end-of-defun)
284 (let ((end (point)))
285 (beginning-of-defun)
286 (narrow-to-region (point) end))))
3f7e952d 287
b73b9811 288(defun insert-parentheses (arg)
e3ac26cb
EN
289 "Enclose following ARG sexps in parentheses. Leave point after open-paren.
290A negative ARG encloses the preceding ARG sexps instead.
44a53673 291No argument is equivalent to zero: just insert `()' and leave point between.
d5bfe076
KH
292If `parens-require-spaces' is non-nil, this command also inserts a space
293before and after, depending on the surrounding characters."
b73b9811 294 (interactive "P")
a17f9e55
RS
295 (if arg (setq arg (prefix-numeric-value arg))
296 (setq arg 0))
e3ac26cb
EN
297 (cond ((> arg 0) (skip-chars-forward " \t"))
298 ((< arg 0) (forward-sexp arg) (setq arg (- arg))))
78e367e9 299 (and parens-require-spaces
6696af65 300 (not (bobp))
44a53673 301 (memq (char-syntax (preceding-char)) '(?w ?_ ?\) ))
b73b9811 302 (insert " "))
b73b9811 303 (insert ?\()
304 (save-excursion
a17f9e55 305 (or (eq arg 0) (forward-sexp arg))
b73b9811 306 (insert ?\))
78e367e9 307 (and parens-require-spaces
6696af65 308 (not (eobp))
44a53673 309 (memq (char-syntax (following-char)) '(?w ?_ ?\( ))
a17f9e55 310 (insert " "))))
b73b9811 311
312(defun move-past-close-and-reindent ()
313 "Move past next `)', delete indentation before it, then indent after it."
314 (interactive)
315 (up-list 1)
316 (forward-char -1)
317 (while (save-excursion ; this is my contribution
318 (let ((before-paren (point)))
319 (back-to-indentation)
adce3b5f
RS
320 (and (= (point) before-paren)
321 (progn
322 ;; Move to end of previous line.
323 (beginning-of-line)
324 (forward-char -1)
325 ;; Verify it doesn't end within a string or comment.
326 (let ((end (point))
327 state)
328 (beginning-of-line)
329 ;; Get state at start of line.
c6eeec65 330 (setq state (list 0 nil nil
adce3b5f
RS
331 (null (calculate-lisp-indent))
332 nil nil nil nil
333 nil))
334 ;; Parse state across the line to get state at end.
335 (setq state (parse-partial-sexp (point) end nil nil
336 state))
337 ;; Check not in string or comment.
338 (and (not (elt state 3)) (not (elt state 4))))))))
b73b9811 339 (delete-indentation))
340 (forward-char 1)
341 (newline-and-indent))
c6eeec65
DL
342
343(defun check-parens () ; lame name?
344 "Check for unbalanced parentheses in the current buffer.
345More accurately, check the narrowed part of the buffer for unbalanced
346expressions (\"sexps\") in general. This is done according to the
347current syntax table and will find unbalanced brackets or quotes as
348appropriate. (See Info node `(emacs)Lists and Sexps'.) If imbalance
349is found, an error is signalled and point is left at the first
350unbalanced character."
351 (interactive)
352 (condition-case data
353 ;; Buffer can't have more than (point-max) sexps.
354 (scan-sexps (point-min) (point-max))
355 (scan-error (goto-char (nth 2 data))
356 ;; Could print (nth 1 data), which is either
357 ;; "Containing expression ends prematurely" or
358 ;; "Unbalanced parentheses", but those may not be so
359 ;; accurate/helpful, e.g. quotes may actually be
360 ;; mismatched.
361 (error "Unmatched bracket or quote"))
362 (error (cond ((eq 'scan-error (car data))
363 (goto-char (nth 2 data))
364 (error "Unmatched bracket or quote"))
365 (t (signal (car data) (cdr data)))))))
b73b9811 366\f
e50c4203 367(defun lisp-complete-symbol (&optional predicate)
2eb9adab
RS
368 "Perform completion on Lisp symbol preceding point.
369Compare that symbol against the known Lisp symbols.
1fa1cb1b
RS
370If no characters can be completed, display a list of possible completions.
371Repeating the command at that point scrolls the list.
2eb9adab 372
e50c4203
DL
373When called from a program, optional arg PREDICATE is a predicate
374determining which symbols are considered, e.g. `commandp'.
375If PREDICATE is nil, the context determines which symbols are
376considered. If the symbol starts just after an open-parenthesis, only
377symbols with function definitions are considered. Otherwise, all
378symbols with function definitions, values or properties are
379considered."
b73b9811 380 (interactive)
1fa1cb1b
RS
381
382 (let ((window (get-buffer-window "*Completions*")))
383 (if (and (eq last-command this-command)
384 window (window-live-p window) (window-buffer window)
385 (buffer-name (window-buffer window)))
386 ;; If this command was repeated, and
387 ;; there's a fresh completion window with a live buffer,
388 ;; and this command is repeated, scroll that window.
389 (with-current-buffer (window-buffer window)
390 (if (pos-visible-in-window-p (point-max) window)
391 (set-window-start window (point-min))
392 (save-selected-window
393 (select-window window)
394 (scroll-up))))
395
396 ;; Do completion.
397 (let* ((end (point))
398 (beg (with-syntax-table emacs-lisp-mode-syntax-table
399 (save-excursion
400 (backward-sexp 1)
401 (while (= (char-syntax (following-char)) ?\')
402 (forward-char 1))
403 (point))))
404 (pattern (buffer-substring-no-properties beg end))
405 (predicate
406 (or predicate
407 (save-excursion
408 (goto-char beg)
409 (if (not (eq (char-before) ?\())
410 (lambda (sym) ;why not just nil ? -sm
411 (or (boundp sym) (fboundp sym)
412 (symbol-plist sym)))
413 ;; Looks like a funcall position. Let's double check.
414 (if (condition-case nil
415 (progn (up-list -2) (forward-char 1)
416 (eq (char-after) ?\())
417 (error nil))
418 ;; If the first element of the parent list is an open
419 ;; parenthesis we are probably not in a funcall position.
420 ;; Maybe a `let' varlist or something.
421 nil
422 ;; Else, we assume that a function name is expected.
423 'fboundp)))))
424 (completion (try-completion pattern obarray predicate)))
425 (cond ((eq completion t))
426 ((null completion)
427 (message "Can't find completion for \"%s\"" pattern)
428 (ding))
429 ((not (string= pattern completion))
430 (delete-region beg end)
431 (insert completion))
432 (t
433 (message "Making completion list...")
434 (let ((list (all-completions pattern obarray predicate)))
435 (setq list (sort list 'string<))
436 (or (eq predicate 'fboundp)
437 (let (new)
438 (while list
439 (setq new (cons (if (fboundp (intern (car list)))
440 (list (car list) " <f>")
441 (car list))
442 new))
443 (setq list (cdr list)))
444 (setq list (nreverse new))))
445 (with-output-to-temp-buffer "*Completions*"
446 (display-completion-list list)))
447 (message "Making completion list...%s" "done")))))))
6594deb0 448
ab5796a9 449;;; arch-tag: aa7fa8a4-2e6f-4e9b-9cd9-fef06340e67e
6594deb0 450;;; lisp.el ends here