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