diff options
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/find-func.el | 41 | ||||
-rw-r--r-- | lisp/emacs-lisp/lisp.el | 57 |
2 files changed, 78 insertions, 20 deletions
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 5a7cd1093c4..54efd14b358 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -1,6 +1,6 @@ ;;; find-func.el --- find the definition of the Emacs Lisp function near point -;; Copyright (C) 1997, 1999, 2001 Free Software Foundation, Inc. +;; Copyright (C) 1997, 1999, 2001, 2004 Free Software Foundation, Inc. ;; Author: Jens Petersen <petersen@kurims.kyoto-u.ac.jp> ;; Maintainer: petersen@kurims.kyoto-u.ac.jp @@ -128,6 +128,40 @@ See the functions `find-function' and `find-variable'." (append (find-library-suffixes) '(""))) (error "Can't find library %s" library))) +(defvar find-function-C-source-directory + (let ((dir (expand-file-name "src" source-directory))) + (when (and (file-directory-p dir) (file-readable-p dir)) + dir)) + "Directory where the C source files of Emacs can be found. +If nil, do not try to find the source code of functions and variables +defined in C.") + +(defun find-function-C-source (fun-or-var file variable-p) + "Find the source location where SUBR-OR-VAR is defined in FILE. +VARIABLE-P should be non-nil for a variable or nil for a subroutine." + (unless find-function-C-source-directory + (setq find-function-C-source-directory + (read-directory-name "Emacs C source dir: " nil nil t))) + (setq file (expand-file-name file find-function-C-source-directory)) + (unless (file-readable-p file) + (error "The C source file %s is not available" + (file-name-nondirectory file))) + (unless variable-p + (setq fun-or-var (indirect-function fun-or-var))) + (with-current-buffer (find-file-noselect file) + (goto-char (point-min)) + (unless (re-search-forward + (if variable-p + (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\"" + (regexp-quote (symbol-name fun-or-var)) + "\"") + (concat "DEFUN[ \t\n]*([ \t\n]*\"" + (regexp-quote (subr-name fun-or-var)) + "\"")) + nil t) + (error "Can't find source for %s" fun-or-var)) + (cons (current-buffer) (match-beginning 0)))) + ;;;###autoload (defun find-library (library) "Find the elisp source of LIBRARY." @@ -149,9 +183,10 @@ If VARIABLE-P is nil, `find-function-regexp' is used, otherwise (error "Don't know where `%s' is defined" symbol)) ;; Some functions are defined as part of the construct ;; that defines something else. - (while (get symbol 'definition-name) + (while (and (symbolp symbol) (get symbol 'definition-name)) (setq symbol (get symbol 'definition-name))) - (save-match-data + (if (string-match "\\`src/\\(.*\\.c\\)\\'" library) + (find-function-C-source symbol (match-string 1 library) variable-p) (if (string-match "\\.el\\(c\\)\\'" library) (setq library (substring library 0 (match-beginning 1)))) (let* ((filename (find-library-name library))) diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index e1ed508b865..8fe839b474d 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -175,6 +175,8 @@ open-parenthesis, and point ends up at the beginning of the line. If variable `beginning-of-defun-function' is non-nil, its value is called as a function to find the defun's beginning." (interactive "p") + (and (eq this-command 'beginning-of-defun) + (or (eq last-command 'beginning-of-defun) (push-mark))) (and (beginning-of-defun-raw arg) (progn (beginning-of-line) t))) @@ -223,6 +225,8 @@ matches the open-parenthesis that starts a defun; see function If variable `end-of-defun-function' is non-nil, its value is called as a function to find the defun's end." (interactive "p") + (and (eq this-command 'end-of-defun) + (or (eq last-command 'end-of-defun) (push-mark))) (if (or (null arg) (= arg 0)) (setq arg 1)) (if end-of-defun-function (if (> arg 0) @@ -302,29 +306,48 @@ Optional ARG is ignored." (end-of-defun) (narrow-to-region beg (point))))) -(defun insert-parentheses (arg) - "Enclose following ARG sexps in parentheses. Leave point after open-paren. +(defun insert-pair (arg &optional open close) + "Enclose following ARG sexps in a pair of OPEN and CLOSE characters. +Leave point after the first character. A negative ARG encloses the preceding ARG sexps instead. -No argument is equivalent to zero: just insert `()' and leave point between. +No argument is equivalent to zero: just insert characters +and leave point between. If `parens-require-spaces' is non-nil, this command also inserts a space -before and after, depending on the surrounding characters." +before and after, depending on the surrounding characters. +If region is active, insert enclosing characters at region boundaries." (interactive "P") (if arg (setq arg (prefix-numeric-value arg)) (setq arg 0)) - (cond ((> arg 0) (skip-chars-forward " \t")) - ((< arg 0) (forward-sexp arg) (setq arg (- arg)))) - (and parens-require-spaces - (not (bobp)) - (memq (char-syntax (preceding-char)) '(?w ?_ ?\) )) - (insert " ")) - (insert ?\() - (save-excursion - (or (eq arg 0) (forward-sexp arg)) - (insert ?\)) + (or open (setq open ?\()) + (or close (setq close ?\))) + (if (and transient-mark-mode mark-active) + (progn + (save-excursion (goto-char (region-end)) (insert close)) + (save-excursion (goto-char (region-beginning)) (insert open))) + (cond ((> arg 0) (skip-chars-forward " \t")) + ((< arg 0) (forward-sexp arg) (setq arg (- arg)))) (and parens-require-spaces - (not (eobp)) - (memq (char-syntax (following-char)) '(?w ?_ ?\( )) - (insert " ")))) + (not (bobp)) + (memq (char-syntax (preceding-char)) (list ?w ?_ (char-syntax close))) + (insert " ")) + (insert open) + (save-excursion + (or (eq arg 0) (forward-sexp arg)) + (insert close) + (and parens-require-spaces + (not (eobp)) + (memq (char-syntax (following-char)) (list ?w ?_ (char-syntax open))) + (insert " "))))) + +(defun insert-parentheses (arg) + "Enclose following ARG sexps in parentheses. Leave point after open-paren. +A negative ARG encloses the preceding ARG sexps instead. +No argument is equivalent to zero: just insert `()' and leave point between. +If `parens-require-spaces' is non-nil, this command also inserts a space +before and after, depending on the surrounding characters. +If region is active, insert enclosing characters at region boundaries." + (interactive "P") + (insert-pair arg ?\( ?\))) (defun move-past-close-and-reindent () "Move past next `)', delete indentation before it, then indent after it." |