# HG changeset patch # User Dave Love # Date 947084916 0 # Node ID f132d890985afed7db1b751f7f8ccaca718c722f # Parent d2e5f1b7d8e2e3825c8a8d40e015d4e3580bc599 (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. diff -r d2e5f1b7d8e2 -r f132d890985a lisp/emacs-lisp/lisp.el --- a/lisp/emacs-lisp/lisp.el Wed Jan 05 14:59:32 2000 +0000 +++ b/lisp/emacs-lisp/lisp.el Wed Jan 05 15:08:36 2000 +0000 @@ -1,6 +1,6 @@ ;;; lisp.el --- Lisp editing commands for Emacs -;; Copyright (C) 1985, 1986, 1994 Free Software Foundation, Inc. +;; Copyright (C) 1985, 1986, 1994, 2000 Free Software Foundation, Inc. ;; Maintainer: FSF ;; Keywords: lisp, languages @@ -32,7 +32,7 @@ (defcustom defun-prompt-regexp nil "*Non-nil => regexp to ignore, before the character that starts a defun. This is only necessary if the opening paren or brace is not in column 0. -See `beginning-of-defun'." +See function `beginning-of-defun'." :type '(choice (const nil) regexp) :group 'lisp) @@ -45,7 +45,7 @@ (defun forward-sexp (&optional arg) "Move forward across one balanced expression (sexp). -With argument, do it that many times. Negative arg -N means +With ARG, do it that many times. Negative arg -N means move backward across N balanced expressions." (interactive "p") (or arg (setq arg 1)) @@ -54,7 +54,7 @@ (defun backward-sexp (&optional arg) "Move backward across one balanced expression (sexp). -With argument, do it that many times. Negative arg -N means +With ARG, do it that many times. Negative arg -N means move forward across N balanced expressions." (interactive "p") (or arg (setq arg 1)) @@ -73,7 +73,7 @@ (defun forward-list (&optional arg) "Move forward across one balanced group of parentheses. -With argument, do it that many times. +With ARG, do it that many times. Negative arg -N means move backward across N groups of parentheses." (interactive "p") (or arg (setq arg 1)) @@ -81,7 +81,7 @@ (defun backward-list (&optional arg) "Move backward across one balanced group of parentheses. -With argument, do it that many times. +With ARG, do it that many times. Negative arg -N means move forward across N groups of parentheses." (interactive "p") (or arg (setq arg 1)) @@ -89,7 +89,7 @@ (defun down-list (arg) "Move forward down one level of parentheses. -With argument, do this that many times. +With ARG, do this that many times. A negative argument means move backward but still go down a level. In Lisp programs, an argument is required." (interactive "p") @@ -100,15 +100,15 @@ (defun backward-up-list (arg) "Move backward out of one level of parentheses. -With argument, do this that many times. +With ARG, do this that many times. A negative argument means move forward but still to a less deep spot. In Lisp programs, an argument is required." (interactive "p") (up-list (- arg))) -(defun up-list (arg) +(defun up-list (arg) "Move forward out of one level of parentheses. -With argument, do this that many times. +With ARG, do this that many times. A negative argument means move backward but still to a less deep spot. In Lisp programs, an argument is required." (interactive "p") @@ -119,7 +119,7 @@ (defun kill-sexp (arg) "Kill the sexp (balanced expression) following the cursor. -With argument, kill that many sexps after the cursor. +With ARG, kill that many sexps after the cursor. Negative arg -N means kill N sexps before the cursor." (interactive "p") (let ((opoint (point))) @@ -128,37 +128,69 @@ (defun backward-kill-sexp (arg) "Kill the sexp (balanced expression) preceding the cursor. -With argument, kill that many sexps before the cursor. +With ARG, kill that many sexps before the cursor. Negative arg -N means kill N sexps after the cursor." (interactive "p") (kill-sexp (- arg))) +(defvar beginning-of-defun nil + "If non-nil, function for `beginning-of-defun-raw' to call. +This is used to find the beginning of the defun instead of using the +normal recipe described in the doc of function `beginning-of-defun'. +Major modes can define this if defining `defun-prompt-regexp' is not +sufficient to use the normal recipe. + +The function should go to the line on which the current \"defun\" +starts and return non-nil or should return nil if it can't find the +beginning. + +Buffer-local.") +(make-variable-buffer-local 'beginning-of-defun) + (defun beginning-of-defun (&optional arg) "Move backward to the beginning of a defun. -With argument, do it that many times. Negative arg -N +With ARG, do it that many times. Negative arg -N means move forward to Nth following beginning of defun. Returns t unless search stops due to beginning or end of buffer. Normally a defun starts when there is an char with open-parenthesis syntax at the beginning of a line. If `defun-prompt-regexp' is non-nil, then a string which matches that regexp may precede the -open-parenthesis, and point ends up at the beginning of the line." +open-parenthesis, and point ends up at the beginning of the line. + +If variable `beginning-of-defun' is non-nil, its value is called as a +function to find the defun's beginning." (interactive "p") (and (beginning-of-defun-raw arg) (progn (beginning-of-line) t))) (defun beginning-of-defun-raw (&optional arg) "Move point to the character that starts a defun. -This is identical to beginning-of-defun, except that point does not move -to the beginning of the line when `defun-prompt-regexp' is non-nil." +This is identical to function `beginning-of-defun', except that point +does not move to the beginning of the line when `defun-prompt-regexp' +is non-nil. + +If variable `beginning-of-defun' is non-nil, its value is called as a +function to find the defun's beginning." (interactive "p") - (and arg (< arg 0) (not (eobp)) (forward-char 1)) - (and (re-search-backward (if defun-prompt-regexp - (concat "^\\s(\\|" - "\\(" defun-prompt-regexp "\\)\\s(") - "^\\s(") - nil 'move (or arg 1)) - (progn (goto-char (1- (match-end 0)))) t)) + (if beginning-of-defun + (funcall beginning-of-defun) + (and arg (< arg 0) (not (eobp)) (forward-char 1)) + (and (re-search-backward (if defun-prompt-regexp + (concat "^\\s(\\|" + "\\(" defun-prompt-regexp "\\)\\s(") + "^\\s(") + nil 'move (or arg 1)) + (progn (goto-char (1- (match-end 0)))) t))) + +(defvar end-of-defun nil + "If non-nil, function for function `end-of-defun' to call. +This is used to find the end of the defun instead of using the normal +recipe described in the doc of function `end-of-defun'. Major modes +can define this if the normal recipe is not appropriate. + +Buffer-local.") +(make-variable-buffer-local 'end-of-defun) (defun buffer-end (arg) (if (> arg 0) (point-max) (point-min))) @@ -167,42 +199,45 @@ "Move forward to next end of defun. With argument, do it that many times. Negative argument -N means move back to Nth preceding end of defun. -An end of a defun occurs right after the close-parenthesis that matches -the open-parenthesis that starts a defun; see `beginning-of-defun'." +An end of a defun occurs right after the close-parenthesis that +matches the open-parenthesis that starts a defun; see function +`beginning-of-defun'." (interactive "p") - (if (or (null arg) (= arg 0)) (setq arg 1)) - (let ((first t)) - (while (and (> arg 0) (< (point) (point-max))) - (let ((pos (point)) npos) - (while (progn - (if (and first - (progn - (end-of-line 1) - (beginning-of-defun-raw 1))) - nil - (or (bobp) (forward-char -1)) - (beginning-of-defun-raw -1)) - (setq first nil) - (forward-list 1) - (skip-chars-forward " \t") - (if (looking-at "\\s<\\|\n") - (forward-line 1)) - (<= (point) pos)))) - (setq arg (1- arg))) - (while (< arg 0) - (let ((pos (point))) - (beginning-of-defun-raw 1) - (forward-sexp 1) - (forward-line 1) - (if (>= (point) pos) - (if (beginning-of-defun-raw 2) - (progn - (forward-list 1) - (skip-chars-forward " \t") - (if (looking-at "\\s<\\|\n") - (forward-line 1))) - (goto-char (point-min))))) - (setq arg (1+ arg))))) + (if end-of-defun + (funcall end-of-defun) + (if (or (null arg) (= arg 0)) (setq arg 1)) + (let ((first t)) + (while (and (> arg 0) (< (point) (point-max))) + (let ((pos (point)) npos) + (while (progn + (if (and first + (progn + (end-of-line 1) + (beginning-of-defun-raw 1))) + nil + (or (bobp) (forward-char -1)) + (beginning-of-defun-raw -1)) + (setq first nil) + (forward-list 1) + (skip-chars-forward " \t") + (if (looking-at "\\s<\\|\n") + (forward-line 1)) + (<= (point) pos)))) + (setq arg (1- arg))) + (while (< arg 0) + (let ((pos (point))) + (beginning-of-defun-raw 1) + (forward-sexp 1) + (forward-line 1) + (if (>= (point) pos) + (if (beginning-of-defun-raw 2) + (progn + (forward-list 1) + (skip-chars-forward " \t") + (if (looking-at "\\s<\\|\n") + (forward-line 1))) + (goto-char (point-min))))) + (setq arg (1+ arg)))))) (defun mark-defun () "Put mark at end of this defun, point at beginning. @@ -216,7 +251,8 @@ (defun narrow-to-defun (&optional arg) "Make text outside current defun invisible. -The defun visible is the one that contains point or follows point." +The defun visible is the one that contains point or follows point. +Optional ARG is ignored." (interactive) (save-excursion (widen) @@ -267,7 +303,7 @@ state) (beginning-of-line) ;; Get state at start of line. - (setq state (list 0 nil nil + (setq state (list 0 nil nil (null (calculate-lisp-indent)) nil nil nil nil nil)) @@ -279,6 +315,30 @@ (delete-indentation)) (forward-char 1) (newline-and-indent)) + +(defun check-parens () ; lame name? + "Check for unbalanced parentheses in the current buffer. +More accurately, check the narrowed part of the buffer for unbalanced +expressions (\"sexps\") in general. This is done according to the +current syntax table and will find unbalanced brackets or quotes as +appropriate. (See Info node `(emacs)Lists and Sexps'.) If imbalance +is found, an error is signalled and point is left at the first +unbalanced character." + (interactive) + (condition-case data + ;; Buffer can't have more than (point-max) sexps. + (scan-sexps (point-min) (point-max)) + (scan-error (goto-char (nth 2 data)) + ;; Could print (nth 1 data), which is either + ;; "Containing expression ends prematurely" or + ;; "Unbalanced parentheses", but those may not be so + ;; accurate/helpful, e.g. quotes may actually be + ;; mismatched. + (error "Unmatched bracket or quote")) + (error (cond ((eq 'scan-error (car data)) + (goto-char (nth 2 data)) + (error "Unmatched bracket or quote")) + (t (signal (car data) (cdr data))))))) (defun lisp-complete-symbol () "Perform completion on Lisp symbol preceding point.