commit 8cdb9d9d24be0894ec3adc79f7f4af61e131850e (HEAD, refs/remotes/origin/master) Merge: 62349fe82a 5b6401b001 Author: Dmitry Gutov Date: Fri May 24 04:53:39 2019 +0300 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit 62349fe82ad42d7d2a7fb19e40860ee5d6ebd017 Author: Dmitry Gutov Date: Fri May 24 04:50:44 2019 +0300 Support "reverting" Xref buffers (bug#35702) * lisp/progmodes/xref.el (xref--fetcher): New variable. (xref--xref-buffer-mode-map): Add binding for 'g'. (xref--revert-xref-buffer): New command. (xref--show-xref-buffer): Accept a function as the first argument. (xref--show-xrefs): Same. (xref--find-xrefs): Pass the above a fetcher function. * lisp/progmodes/project.el (project-find-regexp) (project-or-external-find-regexp): Same. * lisp/dired-aux.el (dired-do-find-regexp): Same. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index f699b79432..51749acb21 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2906,15 +2906,18 @@ REGEXP should use constructs supported by your local `grep' command." #'file-name-as-directory (rgrep-find-ignored-directories default-directory)) grep-find-ignored-files)) - (xrefs (mapcan - (lambda (file) - (xref-collect-matches regexp "*" file - (and (file-directory-p file) - ignores))) - files))) - (unless xrefs - (user-error "No matches for: %s" regexp)) - (xref--show-xrefs xrefs nil))) + (fetcher + (lambda () + (let ((xrefs (mapcan + (lambda (file) + (xref-collect-matches regexp "*" file + (and (file-directory-p file) + ignores))) + files))) + (unless xrefs + (user-error "No matches for: %s" regexp)) + xrefs)))) + (xref--show-xrefs fetcher nil))) ;;;###autoload (defun dired-do-find-regexp-and-replace (from to) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index e44cee2133..d494efa493 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -351,7 +351,9 @@ requires quoting, e.g. `\\[quoted-insert]'." (project--files-in-directory dir nil (grep-read-files regexp)))))) - (project--find-regexp-in-files regexp files))) + (xref--show-xrefs + (apply-partially #'project--find-regexp-in-files regexp files) + nil))) (defun project--dir-ignores (project dir) (let* ((roots (project-roots project)) @@ -376,7 +378,9 @@ pattern to search for." (project-files pr (append (project-roots pr) (project-external-roots pr))))) - (project--find-regexp-in-files regexp files))) + (xref--show-xrefs + (apply-partially #'project--find-regexp-in-files regexp files) + nil))) (defun project--find-regexp-in-files (regexp files) (pcase-let* @@ -418,7 +422,7 @@ pattern to search for." (setq xrefs (xref--convert-hits (nreverse hits) regexp)) (unless xrefs (user-error "No matches for: %s" regexp)) - (xref--show-xrefs xrefs nil))) + xrefs)) (defun project--process-file-region (start end program &optional buffer display diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index b226a41929..6a4906a232 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -477,6 +477,9 @@ If SELECT is non-nil, select the target window." (defvar-local xref--original-window nil "The original window this xref buffer was created from.") +(defvar-local xref--fetcher nil + "The original function to call to fetch the list of xrefs.") + (defun xref--show-pos-in-buf (pos buf) "Goto and display position POS of buffer BUF in a window. Honor `xref--original-window-intent', run `xref-after-jump-hook' @@ -692,6 +695,7 @@ references displayed in the current *xref* buffer." ;; suggested by Johan Claesson "to further reduce finger movement": (define-key map (kbd ".") #'xref-next-line) (define-key map (kbd ",") #'xref-prev-line) + (define-key map (kbd "g") #'xref--revert-xref-buffer) map)) (define-derived-mode xref--xref-buffer-mode special-mode "XREF" @@ -777,8 +781,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (xref-location-group (xref-item-location x))) #'equal)) -(defun xref--show-xref-buffer (xrefs alist) - (let ((xref-alist (xref--analyze xrefs))) +(defun xref--show-xref-buffer (fetcher alist) + (let* ((xrefs (if (functionp fetcher) (funcall fetcher) fetcher)) + (xref-alist (xref--analyze xrefs))) (with-current-buffer (get-buffer-create xref-buffer-name) (setq buffer-undo-list nil) (let ((inhibit-read-only t) @@ -790,8 +795,28 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (goto-char (point-min)) (setq xref--original-window (assoc-default 'window alist) xref--original-window-intent (assoc-default 'display-action alist)) + (when (functionp fetcher) + (setq xref--fetcher fetcher)) (current-buffer))))) +(defun xref--revert-xref-buffer () + (interactive) + (unless xref--fetcher + (user-error "Reverting not supported")) + (let ((inhibit-read-only t) + (buffer-undo-list t)) + (save-excursion + (erase-buffer) + (condition-case err + (xref--insert-xrefs + (xref--analyze (funcall xref--fetcher))) + (user-error + (insert + (propertize + (error-message-string err) + 'face 'error)))) + (goto-char (point-min))))) + (defun xref--show-defs-buffer (xrefs alist) (cond ((not (cdr xrefs)) @@ -811,9 +836,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (defvar xref--read-pattern-history nil) -(defun xref--show-xrefs (xrefs display-action) +(defun xref--show-xrefs (fetcher display-action) (xref--push-markers) - (funcall xref-show-xrefs-function xrefs + (funcall xref-show-xrefs-function fetcher `((window . ,(selected-window)) (display-action . ,display-action)))) @@ -860,12 +885,20 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." ;;; Commands (defun xref--find-xrefs (input kind arg display-action) - (let ((xrefs (funcall (intern (format "xref-backend-%s" kind)) - (xref-find-backend) - arg))) - (unless xrefs - (xref--not-found-error kind input)) - (xref--show-xrefs xrefs display-action))) + (let* ((orig-buffer (current-buffer)) + (orig-position (point)) + (backend (xref-find-backend)) + (method (intern (format "xref-backend-%s" kind))) + (fetcher (lambda () + (save-excursion + (when (buffer-live-p orig-buffer) + (set-buffer orig-buffer) + (ignore-errors (goto-char orig-position))) + (let ((xrefs (funcall method backend arg))) + (unless xrefs + (xref--not-found-error kind input)) + xrefs))))) + (xref--show-xrefs fetcher display-action))) (defun xref--find-definitions (id display-action) (let ((xrefs (funcall #'xref-backend-definitions commit 5b6401b001c770f5426597175a90ba78ddca79ef Author: YAMAMOTO Mitsuharu Date: Fri May 24 09:52:56 2019 +0900 Undo use of Emacs_Pixmap over Pixmap for x_kill_gs_process * src/dispextern.h (x_kill_gs_process): * src/image.c (x_kill_gs_process): Undo use of Emacs_Pixmap over Pixmap. * src/dispextern.h (x_kill_gs_process): Move extern inside HAVE_X_WINDOWS. diff --git a/src/dispextern.h b/src/dispextern.h index ec1c9620be..aa80fa653d 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3396,10 +3396,10 @@ extern void image_destroy_bitmap (struct frame *, ptrdiff_t); extern void image_destroy_all_bitmaps (Display_Info *); #ifdef HAVE_X_WINDOWS extern void x_create_bitmap_mask (struct frame *, ptrdiff_t); +extern void x_kill_gs_process (Pixmap, struct frame *); #endif extern Lisp_Object image_find_image_file (Lisp_Object); -void x_kill_gs_process (Emacs_Pixmap, struct frame *); struct image_cache *make_image_cache (void); void free_image_cache (struct frame *); void clear_image_caches (Lisp_Object); diff --git a/src/image.c b/src/image.c index 57b405f6db..699bdfd4fa 100644 --- a/src/image.c +++ b/src/image.c @@ -9550,7 +9550,7 @@ gs_load (struct frame *f, struct image *img) telling Emacs that Ghostscript has finished drawing. */ void -x_kill_gs_process (Emacs_Pixmap pixmap, struct frame *f) +x_kill_gs_process (Pixmap pixmap, struct frame *f) { struct image_cache *c = FRAME_IMAGE_CACHE (f); ptrdiff_t i; commit 84a3da15e96504cfcbaf295cfb0babca8d8700e5 Author: Michael Heerdegen Date: Sat Apr 27 09:40:10 2019 +0200 Improve documentation of the 'function' special form Point out that 'function' quoting is beneficial also for symbols. * src/eval.c (function): Enhance docstring. * doc/lispref/functions.texi (Anonymous Functions): Improve documentation. diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index 97f7fb9f79..2f9d898c9b 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -1122,6 +1122,10 @@ a byte-code function object (@pxref{Byte Compilation}). When lexical binding is enabled, @var{function-object} is converted into a closure. @xref{Closures}. @end itemize + +When @var{function-object} is a symbol and the code is byte compiled, +the byte-compiler will warn if that function is not defined or might +not be known at run time. @end defspec @cindex @samp{#'} syntax diff --git a/src/eval.c b/src/eval.c index 567c32e0d7..5bba876637 100644 --- a/src/eval.c +++ b/src/eval.c @@ -544,8 +544,8 @@ usage: (quote ARG) */) DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0, doc: /* Like `quote', but preferred for objects which are functions. -In byte compilation, `function' causes its argument to be compiled. -`quote' cannot do that. +In byte compilation, `function' causes its argument to be handled by +the byte compiler. `quote' cannot do that. usage: (function ARG) */) (Lisp_Object args) { commit a564d6e8bb0e5058c4c356a85a42c091436ad382 Author: Michael Heerdegen Date: Fri May 24 00:50:20 2019 +0200 * lisp/emacs-lisp/cl-macs.el (cl-callf): Tweak in docstring Say that lambdas are also allowed as FUNC argument. diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index c4a1dcb8ba..24e79acfa5 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -2597,8 +2597,9 @@ rather than all at the end (i.e. like `let*' rather than like `let')." ;;;###autoload (defmacro cl-callf (func place &rest args) "Set PLACE to (FUNC PLACE ARGS...). -FUNC should be an unquoted function name. PLACE may be a symbol, -or any generalized variable allowed by `setf'." +FUNC should be an unquoted function name or a lambda expression. +PLACE may be a symbol, or any generalized variable allowed by +`setf'." (declare (indent 2) (debug (cl-function place &rest form))) (gv-letplace (getter setter) place (let* ((rargs (cons getter args))) commit 1cadab78e242834adab0fae3cb1feb691d52f8c5 Author: Dmitry Gutov Date: Thu May 23 01:30:50 2019 +0300 Make xref-find-definitions more customizable * lisp/progmodes/xref.el (xref--show-defs-buffer): New function. Move a bit of logic from xref--show-defs to make it more customizable. (xref--push-markers): New function, extracted from xref--show-xrefs. (xref-show-definitions-function): Set to the new function. diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 3951b9f1dd..b226a41929 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -792,11 +792,19 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." xref--original-window-intent (assoc-default 'display-action alist)) (current-buffer))))) +(defun xref--show-defs-buffer (xrefs alist) + (cond + ((not (cdr xrefs)) + (xref--pop-to-location (car xrefs) + (assoc-default 'display-action alist))) + (t + (xref--show-xref-buffer xrefs alist)))) + (defvar xref-show-xrefs-function 'xref--show-xref-buffer "Function to display a list of search results.") -(defvar xref-show-definitions-function 'xref--show-xref-buffer +(defvar xref-show-definitions-function 'xref--show-defs-buffer "Function to display a list of definitions.") (defvar xref--read-identifier-history nil) @@ -804,22 +812,20 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (defvar xref--read-pattern-history nil) (defun xref--show-xrefs (xrefs display-action) - (unless (region-active-p) (push-mark nil t)) - (xref-push-marker-stack) + (xref--push-markers) (funcall xref-show-xrefs-function xrefs `((window . ,(selected-window)) (display-action . ,display-action)))) (defun xref--show-defs (xrefs display-action) + (xref--push-markers) + (funcall xref-show-definitions-function xrefs + `((window . ,(selected-window)) + (display-action . ,display-action)))) + +(defun xref--push-markers () (unless (region-active-p) (push-mark nil t)) - (xref-push-marker-stack) - (cond - ((not (cdr xrefs)) - (xref--pop-to-location (car xrefs) display-action)) - (t - (funcall xref-show-definitions-function xrefs - `((window . ,(selected-window)) - (display-action . ,display-action)))))) + (xref-push-marker-stack)) (defun xref--prompt-p (command) (or (eq xref-prompt-for-identifier t) commit 49a363c875c66f3d937a7d33e1a1451227a1887d Author: Dmitry Gutov Date: Thu May 23 01:16:41 2019 +0300 Separate xref-find-definitions' behavior from other commands * lisp/progmodes/xref.el (xref-show-definitions-function): New variable. (xref--show-defs): Split off from xref--show-xrefs. (xref--find-definitions): Use it. (xref--not-found-error): New function. (xref--show-xrefs): Simplify. Show the list buffer even when there is just one item in the list. Remove the last argument. * lisp/dired-aux.el (dired-do-find-regexp): Update accordingly. diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index aae521287e..f699b79432 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -2914,7 +2914,7 @@ REGEXP should use constructs supported by your local `grep' command." files))) (unless xrefs (user-error "No matches for: %s" regexp)) - (xref--show-xrefs xrefs nil t))) + (xref--show-xrefs xrefs nil))) ;;;###autoload (defun dired-do-find-regexp-and-replace (from to) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index bf999aeb0d..3951b9f1dd 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -793,30 +793,31 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (current-buffer))))) -;; This part of the UI seems fairly uncontroversial: it reads the -;; identifier and deals with the single definition case. -;; (FIXME: do we really want this case to be handled like that in -;; "find references" and "find regexp searches"?) -;; -;; The controversial multiple definitions case is handed off to -;; xref-show-xrefs-function. - (defvar xref-show-xrefs-function 'xref--show-xref-buffer - "Function to display a list of xrefs.") + "Function to display a list of search results.") + +(defvar xref-show-definitions-function 'xref--show-xref-buffer + "Function to display a list of definitions.") (defvar xref--read-identifier-history nil) (defvar xref--read-pattern-history nil) -(defun xref--show-xrefs (xrefs display-action &optional always-show-list) +(defun xref--show-xrefs (xrefs display-action) + (unless (region-active-p) (push-mark nil t)) + (xref-push-marker-stack) + (funcall xref-show-xrefs-function xrefs + `((window . ,(selected-window)) + (display-action . ,display-action)))) + +(defun xref--show-defs (xrefs display-action) (unless (region-active-p) (push-mark nil t)) + (xref-push-marker-stack) (cond - ((and (not (cdr xrefs)) (not always-show-list)) - (xref-push-marker-stack) + ((not (cdr xrefs)) (xref--pop-to-location (car xrefs) display-action)) (t - (xref-push-marker-stack) - (funcall xref-show-xrefs-function xrefs + (funcall xref-show-definitions-function xrefs `((window . ,(selected-window)) (display-action . ,display-action)))))) @@ -857,11 +858,19 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)." (xref-find-backend) arg))) (unless xrefs - (user-error "No %s found for: %s" (symbol-name kind) input)) + (xref--not-found-error kind input)) (xref--show-xrefs xrefs display-action))) (defun xref--find-definitions (id display-action) - (xref--find-xrefs id 'definitions id display-action)) + (let ((xrefs (funcall #'xref-backend-definitions + (xref-find-backend) + id))) + (unless xrefs + (xref--not-found-error 'definitions id)) + (xref--show-defs xrefs display-action))) + +(defun xref--not-found-error (kind input) + (user-error "No %s found for: %s" (symbol-name kind) input)) ;;;###autoload (defun xref-find-definitions (identifier)