comparison lisp/emacs-lisp/lisp.el @ 27190:f132d890985a

(beginning-of-defun): New variable. (beginning-of-defun-raw): Use it. (end-of-defun): New variable. (end-of-defun): Use it. (check-parens): New command.
author Dave Love <fx@gnu.org>
date Wed, 05 Jan 2000 15:08:36 +0000
parents 4b8c40cf1931
children 59243c413664
comparison
equal deleted inserted replaced
27189:d2e5f1b7d8e2 27190:f132d890985a
1 ;;; lisp.el --- Lisp editing commands for Emacs 1 ;;; lisp.el --- Lisp editing commands for Emacs
2 2
3 ;; Copyright (C) 1985, 1986, 1994 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985, 1986, 1994, 2000 Free Software Foundation, Inc.
4 4
5 ;; Maintainer: FSF 5 ;; Maintainer: FSF
6 ;; Keywords: lisp, languages 6 ;; Keywords: lisp, languages
7 7
8 ;; This file is part of GNU Emacs. 8 ;; This file is part of GNU Emacs.
30 30
31 ;; Note that this variable is used by non-lisp modes too. 31 ;; Note that this variable is used by non-lisp modes too.
32 (defcustom defun-prompt-regexp nil 32 (defcustom defun-prompt-regexp nil
33 "*Non-nil => regexp to ignore, before the character that starts a defun. 33 "*Non-nil => regexp to ignore, before the character that starts a defun.
34 This is only necessary if the opening paren or brace is not in column 0. 34 This is only necessary if the opening paren or brace is not in column 0.
35 See `beginning-of-defun'." 35 See function `beginning-of-defun'."
36 :type '(choice (const nil) 36 :type '(choice (const nil)
37 regexp) 37 regexp)
38 :group 'lisp) 38 :group 'lisp)
39 (make-variable-buffer-local 'defun-prompt-regexp) 39 (make-variable-buffer-local 'defun-prompt-regexp)
40 40
43 :type 'boolean 43 :type 'boolean
44 :group 'lisp) 44 :group 'lisp)
45 45
46 (defun forward-sexp (&optional arg) 46 (defun forward-sexp (&optional arg)
47 "Move forward across one balanced expression (sexp). 47 "Move forward across one balanced expression (sexp).
48 With argument, do it that many times. Negative arg -N means 48 With ARG, do it that many times. Negative arg -N means
49 move backward across N balanced expressions." 49 move backward across N balanced expressions."
50 (interactive "p") 50 (interactive "p")
51 (or arg (setq arg 1)) 51 (or arg (setq arg 1))
52 (goto-char (or (scan-sexps (point) arg) (buffer-end arg))) 52 (goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
53 (if (< arg 0) (backward-prefix-chars))) 53 (if (< arg 0) (backward-prefix-chars)))
54 54
55 (defun backward-sexp (&optional arg) 55 (defun backward-sexp (&optional arg)
56 "Move backward across one balanced expression (sexp). 56 "Move backward across one balanced expression (sexp).
57 With argument, do it that many times. Negative arg -N means 57 With ARG, do it that many times. Negative arg -N means
58 move forward across N balanced expressions." 58 move forward across N balanced expressions."
59 (interactive "p") 59 (interactive "p")
60 (or arg (setq arg 1)) 60 (or arg (setq arg 1))
61 (forward-sexp (- arg))) 61 (forward-sexp (- arg)))
62 62
71 (point)) 71 (point))
72 nil t)) 72 nil t))
73 73
74 (defun forward-list (&optional arg) 74 (defun forward-list (&optional arg)
75 "Move forward across one balanced group of parentheses. 75 "Move forward across one balanced group of parentheses.
76 With argument, do it that many times. 76 With ARG, do it that many times.
77 Negative arg -N means move backward across N groups of parentheses." 77 Negative arg -N means move backward across N groups of parentheses."
78 (interactive "p") 78 (interactive "p")
79 (or arg (setq arg 1)) 79 (or arg (setq arg 1))
80 (goto-char (or (scan-lists (point) arg 0) (buffer-end arg)))) 80 (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
81 81
82 (defun backward-list (&optional arg) 82 (defun backward-list (&optional arg)
83 "Move backward across one balanced group of parentheses. 83 "Move backward across one balanced group of parentheses.
84 With argument, do it that many times. 84 With ARG, do it that many times.
85 Negative arg -N means move forward across N groups of parentheses." 85 Negative arg -N means move forward across N groups of parentheses."
86 (interactive "p") 86 (interactive "p")
87 (or arg (setq arg 1)) 87 (or arg (setq arg 1))
88 (forward-list (- arg))) 88 (forward-list (- arg)))
89 89
90 (defun down-list (arg) 90 (defun down-list (arg)
91 "Move forward down one level of parentheses. 91 "Move forward down one level of parentheses.
92 With argument, do this that many times. 92 With ARG, do this that many times.
93 A negative argument means move backward but still go down a level. 93 A negative argument means move backward but still go down a level.
94 In Lisp programs, an argument is required." 94 In Lisp programs, an argument is required."
95 (interactive "p") 95 (interactive "p")
96 (let ((inc (if (> arg 0) 1 -1))) 96 (let ((inc (if (> arg 0) 1 -1)))
97 (while (/= arg 0) 97 (while (/= arg 0)
98 (goto-char (or (scan-lists (point) inc -1) (buffer-end arg))) 98 (goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
99 (setq arg (- arg inc))))) 99 (setq arg (- arg inc)))))
100 100
101 (defun backward-up-list (arg) 101 (defun backward-up-list (arg)
102 "Move backward out of one level of parentheses. 102 "Move backward out of one level of parentheses.
103 With argument, do this that many times. 103 With ARG, do this that many times.
104 A negative argument means move forward but still to a less deep spot. 104 A negative argument means move forward but still to a less deep spot.
105 In Lisp programs, an argument is required." 105 In Lisp programs, an argument is required."
106 (interactive "p") 106 (interactive "p")
107 (up-list (- arg))) 107 (up-list (- arg)))
108 108
109 (defun up-list (arg) 109 (defun up-list (arg)
110 "Move forward out of one level of parentheses. 110 "Move forward out of one level of parentheses.
111 With argument, do this that many times. 111 With ARG, do this that many times.
112 A negative argument means move backward but still to a less deep spot. 112 A negative argument means move backward but still to a less deep spot.
113 In Lisp programs, an argument is required." 113 In Lisp programs, an argument is required."
114 (interactive "p") 114 (interactive "p")
115 (let ((inc (if (> arg 0) 1 -1))) 115 (let ((inc (if (> arg 0) 1 -1)))
116 (while (/= arg 0) 116 (while (/= arg 0)
117 (goto-char (or (scan-lists (point) inc 1) (buffer-end arg))) 117 (goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
118 (setq arg (- arg inc))))) 118 (setq arg (- arg inc)))))
119 119
120 (defun kill-sexp (arg) 120 (defun kill-sexp (arg)
121 "Kill the sexp (balanced expression) following the cursor. 121 "Kill the sexp (balanced expression) following the cursor.
122 With argument, kill that many sexps after the cursor. 122 With ARG, kill that many sexps after the cursor.
123 Negative arg -N means kill N sexps before the cursor." 123 Negative arg -N means kill N sexps before the cursor."
124 (interactive "p") 124 (interactive "p")
125 (let ((opoint (point))) 125 (let ((opoint (point)))
126 (forward-sexp arg) 126 (forward-sexp arg)
127 (kill-region opoint (point)))) 127 (kill-region opoint (point))))
128 128
129 (defun backward-kill-sexp (arg) 129 (defun backward-kill-sexp (arg)
130 "Kill the sexp (balanced expression) preceding the cursor. 130 "Kill the sexp (balanced expression) preceding the cursor.
131 With argument, kill that many sexps before the cursor. 131 With ARG, kill that many sexps before the cursor.
132 Negative arg -N means kill N sexps after the cursor." 132 Negative arg -N means kill N sexps after the cursor."
133 (interactive "p") 133 (interactive "p")
134 (kill-sexp (- arg))) 134 (kill-sexp (- arg)))
135 135
136 (defvar beginning-of-defun nil
137 "If non-nil, function for `beginning-of-defun-raw' to call.
138 This is used to find the beginning of the defun instead of using the
139 normal recipe described in the doc of function `beginning-of-defun'.
140 Major modes can define this if defining `defun-prompt-regexp' is not
141 sufficient to use the normal recipe.
142
143 The function should go to the line on which the current \"defun\"
144 starts and return non-nil or should return nil if it can't find the
145 beginning.
146
147 Buffer-local.")
148 (make-variable-buffer-local 'beginning-of-defun)
149
136 (defun beginning-of-defun (&optional arg) 150 (defun beginning-of-defun (&optional arg)
137 "Move backward to the beginning of a defun. 151 "Move backward to the beginning of a defun.
138 With argument, do it that many times. Negative arg -N 152 With ARG, do it that many times. Negative arg -N
139 means move forward to Nth following beginning of defun. 153 means move forward to Nth following beginning of defun.
140 Returns t unless search stops due to beginning or end of buffer. 154 Returns t unless search stops due to beginning or end of buffer.
141 155
142 Normally a defun starts when there is an char with open-parenthesis 156 Normally a defun starts when there is an char with open-parenthesis
143 syntax at the beginning of a line. If `defun-prompt-regexp' is 157 syntax at the beginning of a line. If `defun-prompt-regexp' is
144 non-nil, then a string which matches that regexp may precede the 158 non-nil, then a string which matches that regexp may precede the
145 open-parenthesis, and point ends up at the beginning of the line." 159 open-parenthesis, and point ends up at the beginning of the line.
160
161 If variable `beginning-of-defun' is non-nil, its value is called as a
162 function to find the defun's beginning."
146 (interactive "p") 163 (interactive "p")
147 (and (beginning-of-defun-raw arg) 164 (and (beginning-of-defun-raw arg)
148 (progn (beginning-of-line) t))) 165 (progn (beginning-of-line) t)))
149 166
150 (defun beginning-of-defun-raw (&optional arg) 167 (defun beginning-of-defun-raw (&optional arg)
151 "Move point to the character that starts a defun. 168 "Move point to the character that starts a defun.
152 This is identical to beginning-of-defun, except that point does not move 169 This is identical to function `beginning-of-defun', except that point
153 to the beginning of the line when `defun-prompt-regexp' is non-nil." 170 does not move to the beginning of the line when `defun-prompt-regexp'
154 (interactive "p") 171 is non-nil.
155 (and arg (< arg 0) (not (eobp)) (forward-char 1)) 172
156 (and (re-search-backward (if defun-prompt-regexp 173 If variable `beginning-of-defun' is non-nil, its value is called as a
157 (concat "^\\s(\\|" 174 function to find the defun's beginning."
158 "\\(" defun-prompt-regexp "\\)\\s(") 175 (interactive "p")
159 "^\\s(") 176 (if beginning-of-defun
160 nil 'move (or arg 1)) 177 (funcall beginning-of-defun)
161 (progn (goto-char (1- (match-end 0)))) t)) 178 (and arg (< arg 0) (not (eobp)) (forward-char 1))
179 (and (re-search-backward (if defun-prompt-regexp
180 (concat "^\\s(\\|"
181 "\\(" defun-prompt-regexp "\\)\\s(")
182 "^\\s(")
183 nil 'move (or arg 1))
184 (progn (goto-char (1- (match-end 0)))) t)))
185
186 (defvar end-of-defun nil
187 "If non-nil, function for function `end-of-defun' to call.
188 This is used to find the end of the defun instead of using the normal
189 recipe described in the doc of function `end-of-defun'. Major modes
190 can define this if the normal recipe is not appropriate.
191
192 Buffer-local.")
193 (make-variable-buffer-local 'end-of-defun)
162 194
163 (defun buffer-end (arg) 195 (defun buffer-end (arg)
164 (if (> arg 0) (point-max) (point-min))) 196 (if (> arg 0) (point-max) (point-min)))
165 197
166 (defun end-of-defun (&optional arg) 198 (defun end-of-defun (&optional arg)
167 "Move forward to next end of defun. With argument, do it that many times. 199 "Move forward to next end of defun. With argument, do it that many times.
168 Negative argument -N means move back to Nth preceding end of defun. 200 Negative argument -N means move back to Nth preceding end of defun.
169 201
170 An end of a defun occurs right after the close-parenthesis that matches 202 An end of a defun occurs right after the close-parenthesis that
171 the open-parenthesis that starts a defun; see `beginning-of-defun'." 203 matches the open-parenthesis that starts a defun; see function
172 (interactive "p") 204 `beginning-of-defun'."
173 (if (or (null arg) (= arg 0)) (setq arg 1)) 205 (interactive "p")
174 (let ((first t)) 206 (if end-of-defun
175 (while (and (> arg 0) (< (point) (point-max))) 207 (funcall end-of-defun)
176 (let ((pos (point)) npos) 208 (if (or (null arg) (= arg 0)) (setq arg 1))
177 (while (progn 209 (let ((first t))
178 (if (and first 210 (while (and (> arg 0) (< (point) (point-max)))
179 (progn 211 (let ((pos (point)) npos)
180 (end-of-line 1) 212 (while (progn
181 (beginning-of-defun-raw 1))) 213 (if (and first
182 nil 214 (progn
183 (or (bobp) (forward-char -1)) 215 (end-of-line 1)
184 (beginning-of-defun-raw -1)) 216 (beginning-of-defun-raw 1)))
185 (setq first nil) 217 nil
186 (forward-list 1) 218 (or (bobp) (forward-char -1))
187 (skip-chars-forward " \t") 219 (beginning-of-defun-raw -1))
188 (if (looking-at "\\s<\\|\n") 220 (setq first nil)
189 (forward-line 1)) 221 (forward-list 1)
190 (<= (point) pos)))) 222 (skip-chars-forward " \t")
191 (setq arg (1- arg))) 223 (if (looking-at "\\s<\\|\n")
192 (while (< arg 0) 224 (forward-line 1))
193 (let ((pos (point))) 225 (<= (point) pos))))
194 (beginning-of-defun-raw 1) 226 (setq arg (1- arg)))
195 (forward-sexp 1) 227 (while (< arg 0)
196 (forward-line 1) 228 (let ((pos (point)))
197 (if (>= (point) pos) 229 (beginning-of-defun-raw 1)
198 (if (beginning-of-defun-raw 2) 230 (forward-sexp 1)
199 (progn 231 (forward-line 1)
200 (forward-list 1) 232 (if (>= (point) pos)
201 (skip-chars-forward " \t") 233 (if (beginning-of-defun-raw 2)
202 (if (looking-at "\\s<\\|\n") 234 (progn
203 (forward-line 1))) 235 (forward-list 1)
204 (goto-char (point-min))))) 236 (skip-chars-forward " \t")
205 (setq arg (1+ arg))))) 237 (if (looking-at "\\s<\\|\n")
238 (forward-line 1)))
239 (goto-char (point-min)))))
240 (setq arg (1+ arg))))))
206 241
207 (defun mark-defun () 242 (defun mark-defun ()
208 "Put mark at end of this defun, point at beginning. 243 "Put mark at end of this defun, point at beginning.
209 The defun marked is the one that contains point or follows point." 244 The defun marked is the one that contains point or follows point."
210 (interactive) 245 (interactive)
214 (beginning-of-defun) 249 (beginning-of-defun)
215 (re-search-backward "^\n" (- (point) 1) t)) 250 (re-search-backward "^\n" (- (point) 1) t))
216 251
217 (defun narrow-to-defun (&optional arg) 252 (defun narrow-to-defun (&optional arg)
218 "Make text outside current defun invisible. 253 "Make text outside current defun invisible.
219 The defun visible is the one that contains point or follows point." 254 The defun visible is the one that contains point or follows point.
255 Optional ARG is ignored."
220 (interactive) 256 (interactive)
221 (save-excursion 257 (save-excursion
222 (widen) 258 (widen)
223 (end-of-defun) 259 (end-of-defun)
224 (let ((end (point))) 260 (let ((end (point)))
265 ;; Verify it doesn't end within a string or comment. 301 ;; Verify it doesn't end within a string or comment.
266 (let ((end (point)) 302 (let ((end (point))
267 state) 303 state)
268 (beginning-of-line) 304 (beginning-of-line)
269 ;; Get state at start of line. 305 ;; Get state at start of line.
270 (setq state (list 0 nil nil 306 (setq state (list 0 nil nil
271 (null (calculate-lisp-indent)) 307 (null (calculate-lisp-indent))
272 nil nil nil nil 308 nil nil nil nil
273 nil)) 309 nil))
274 ;; Parse state across the line to get state at end. 310 ;; Parse state across the line to get state at end.
275 (setq state (parse-partial-sexp (point) end nil nil 311 (setq state (parse-partial-sexp (point) end nil nil
277 ;; Check not in string or comment. 313 ;; Check not in string or comment.
278 (and (not (elt state 3)) (not (elt state 4)))))))) 314 (and (not (elt state 3)) (not (elt state 4))))))))
279 (delete-indentation)) 315 (delete-indentation))
280 (forward-char 1) 316 (forward-char 1)
281 (newline-and-indent)) 317 (newline-and-indent))
318
319 (defun check-parens () ; lame name?
320 "Check for unbalanced parentheses in the current buffer.
321 More accurately, check the narrowed part of the buffer for unbalanced
322 expressions (\"sexps\") in general. This is done according to the
323 current syntax table and will find unbalanced brackets or quotes as
324 appropriate. (See Info node `(emacs)Lists and Sexps'.) If imbalance
325 is found, an error is signalled and point is left at the first
326 unbalanced character."
327 (interactive)
328 (condition-case data
329 ;; Buffer can't have more than (point-max) sexps.
330 (scan-sexps (point-min) (point-max))
331 (scan-error (goto-char (nth 2 data))
332 ;; Could print (nth 1 data), which is either
333 ;; "Containing expression ends prematurely" or
334 ;; "Unbalanced parentheses", but those may not be so
335 ;; accurate/helpful, e.g. quotes may actually be
336 ;; mismatched.
337 (error "Unmatched bracket or quote"))
338 (error (cond ((eq 'scan-error (car data))
339 (goto-char (nth 2 data))
340 (error "Unmatched bracket or quote"))
341 (t (signal (car data) (cdr data)))))))
282 342
283 (defun lisp-complete-symbol () 343 (defun lisp-complete-symbol ()
284 "Perform completion on Lisp symbol preceding point. 344 "Perform completion on Lisp symbol preceding point.
285 Compare that symbol against the known Lisp symbols. 345 Compare that symbol against the known Lisp symbols.
286 346