>From 0c309fb5ad41d4c8c7e356ef365a02b6550a0e2e Mon Sep 17 00:00:00 2001 From: Charles A. Roelli Date: Mon, 29 May 2017 21:35:24 +0200 Subject: [PATCH] New commands: find-function-or-library (-other-window/-frame) * lisp/emacs-lisp/find-func.el (read-function-or-library-name): New function for reading a function or library name. (find-function-or-library, find-function-or-library-other-window) (find-function-or-library-other-frame): New commands. (find-function-setup-keys): Replace 'find-function' bindings with bindings to 'find-function-or-library'. * etc/NEWS: Mention 'find-function-or-library' and new bindings made by 'find-function-setup-keys'. --- etc/NEWS | 6 +++ lisp/emacs-lisp/find-func.el | 90 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 60066b7..ee6efb9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -363,6 +363,12 @@ large integers from being displayed as characters. ** Two new commands for finding the source code of Emacs Lisp libraries: 'find-library-other-window' and 'find-library-other-frame'. +** 'find-function-setup-keys' now binds 'C-x F', 'C-x 4 F' and 'C-x 5 +F' to the new command 'find-function-or-library' and its +other-window/-frame counterparts. The new commands find the Emacs +Lisp source code of a function or library, defaulting to the function +or library closest to point. + * Editing Changes in Emacs 26.1 diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 9b98f05..9943598 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -310,6 +310,40 @@ read-library-name "Library name: ") table nil nil nil nil def))) +(defun read-function-or-library-name () + "Read and return a function or library name, defaulting to the one near point. + +A function name is the name of a symbol that satisfies the +predicate `fboundp'. A library name is the filename of an Emacs +Lisp library located in a directory under `load-path' (or +`find-function-source-path', if non-nil)." + (let* ((dirs (or find-function-source-path load-path)) + (suffixes (find-library-suffixes)) + (table (completion-table-merge + (apply-partially 'completion-table-with-predicate + obarray 'fboundp t) + (apply-partially 'locate-file-completion-table + dirs suffixes))) + (def (if (eq (function-called-at-point) 'require) + ;; `function-called-at-point' may return 'require + ;; with `point' anywhere on this line. So wrap the + ;; `save-excursion' below in a `condition-case' to + ;; avoid reporting a scan-error here. + (condition-case nil + (save-excursion + (backward-up-list) + (forward-char) + (forward-sexp 2) + (thing-at-point 'symbol)) + (error nil)) + (symbol-name (function-called-at-point))))) + (when (and def (not (test-completion def table))) + (setq def nil)) + (completing-read (if def + (format "Function or library name (default %s): " def) + "Function or library name: ") + table nil nil nil nil def))) + ;;;###autoload (defun find-library-other-window (library) "Find the Emacs Lisp source of LIBRARY in another window. @@ -537,6 +571,56 @@ find-function-other-frame (find-function-do-it function nil 'switch-to-buffer-other-frame)) ;;;###autoload +(defun find-function-or-library (function-or-library) + "Find the definition of the FUNCTION-OR-LIBRARY near point. + +Finds the source file containing the definition of the +function (selected by `function-called-at-point') or +library (loaded with `require') near point in a buffer and places +point before the definition. + +FUNCTION-OR-LIBRARY is searched for in +`find-function-source-path', if non-nil, otherwise in +`load-path'. See also `find-function-recenter-line' and +`find-function-after-hook'. + +If FUNCTION-OR-LIBRARY names both a function and a library, finds +the corresponding function definition." + (interactive (list (read-function-or-library-name))) + (let ((sym (if (stringp function-or-library) + (intern function-or-library) + function-or-library))) + (if (fboundp sym) + (find-function-do-it sym nil 'switch-to-buffer) + (find-library function-or-library)))) + +;;;###autoload +(defun find-function-or-library-other-window (function-or-library) + "Find, in another window, the definition of FUNCTION-OR-LIBRARY near point. + +See `find-function' for more details." + (interactive (list (read-function-or-library-name))) + (let ((sym (if (stringp function-or-library) + (intern function-or-library) + function-or-library))) + (if (fboundp sym) + (find-function-do-it sym nil 'switch-to-buffer-other-window) + (find-library-other-window function-or-library)))) + +;;;###autoload +(defun find-function-or-library-other-frame (function-or-library) + "Find, in another frame, the definition of FUNCTION-OR-LIBRARY near point. + +See `find-function' for more details." + (interactive (list (read-function-or-library-name))) + (let ((sym (if (stringp function-or-library) + (intern function-or-library) + function-or-library))) + (if (fboundp sym) + (find-function-do-it sym nil 'switch-to-buffer-other-frame) + (find-library-other-frame function-or-library)))) + +;;;###autoload (defun find-variable-noselect (variable &optional file) "Return a pair `(BUFFER . POINT)' pointing to the definition of VARIABLE. @@ -691,9 +775,9 @@ find-variable-at-point ;;;###autoload (defun find-function-setup-keys () "Define some key bindings for the find-function family of functions." - (define-key ctl-x-map "F" 'find-function) - (define-key ctl-x-4-map "F" 'find-function-other-window) - (define-key ctl-x-5-map "F" 'find-function-other-frame) + (define-key ctl-x-map "F" 'find-function-or-library) + (define-key ctl-x-4-map "F" 'find-function-or-library-other-window) + (define-key ctl-x-5-map "F" 'find-function-or-library-other-frame) (define-key ctl-x-map "K" 'find-function-on-key) (define-key ctl-x-4-map "K" 'find-function-on-key-other-window) (define-key ctl-x-5-map "K" 'find-function-on-key-other-frame) -- 1.7.4.4