Merge from origin/emacs-28

ad0798a395 * etc/TODO: Add interactive mode tagging.
879ef5b19a * etc/TODO: Rearrange to start with "Simple tasks".
d73f0e96a7 ; * etc/TODO: Move elpa.gnu.org items to the end.
7cf1229706 ; * etc/TODO: Mention a relevant bug report.
f733b909ff * etc/TODO: Remove outdated item.  (Bug#50904)
94c247d659 ; Oops, fix up last commit
88378acbfc Rename arguments of ERC's '/whois' and simplify doc string
205eb7f801 ; s/class/type
86da812afb Migrate Xref off EIEIO
5c73dfcbcb * admin/release-branch.txt: New file.
f060d1c9a4 * lisp/dired.el (dired-omit-mode): Declare, to avoid compi...

# Conflicts:
#	etc/NEWS
This commit is contained in:
Glenn Morris 2021-10-01 07:50:25 -07:00
commit 823bc66e74
8 changed files with 294 additions and 235 deletions

75
admin/release-branch.txt Normal file
View file

@ -0,0 +1,75 @@
Instructions for cutting the Emacs release branch
1. In the clone of the Emacs Git repository, switch to the 'master'
branch, "git pull", and build it to make sure it's not broken.
Consider deleting all the *.elc and *.o files, or running the
command "make extraclean", before building.
2. Create the release branch and switch to it. Assuming that it is
for releasing Emacs versions XY.1, XY.2, etc., the command is:
git checkout -b emacs-XY
3. Switch the release branch to the suitable version. The convention
is that release branches start with version XY.0.60, whereas the
master branch from which the release branch was cut was at the
version XY.0.50. To change the version, do the following inside
Emacs:
M-x load-file RET admin/admin.el RET
M-x set-version RET XY.0.60 RET
Change the value of 'customize-changed-options-previous-release'
in cus-edit.el to reference the last release from the emacs-XY-1
branch (last release for the previous major version).
The above modifies several files in the tree; commit the changes
with the appropriate log message, something like "Bump Emacs
version to XY.0.60", and with header saying "Cut the emacs-XY
release branch". Then push the changes:
git push --set-upstream origin emacs-XY
The "push" command should show the new branch just created.
4. Switch back to the master branch.
git checkout master
git pull
Set the version on the master branch to the next major release:
M-x set-version RET XY+1.0.50 RET
This creates a new file etc/NEWS.XY. "git add" it.
Change the value of 'customize-changed-options-previous-release'
in cus-edit.el to reference emacs-XY.1, the next version to be
released from the newly-committed release branch.
Update the emacs-module sources for the new version XY+1. This
entails:
. adding a new file src/module-env-XY+1.h, with contents just the
comment taken from the beginning of src/module-env-XY.h
. removing the comment from the beginning of src/module-env-XY.h
. adding two lines to configure.ac:
AC_SUBST_FILE([module_env_snippet_XY+1])
module_env_snippet_XY+1="$srcdir/src/module-env-XY+1.h"
. adding a new 'struct emacs_env_XY+1' to src/emacs-module.h.in,
with the contents identical to'struct emacs_env_XY', with one
line added:
@module_env_snippet_XY+1@
(FIXME: "M-x set-version" should do this emacs-module stuff
automatically when the version is NN.0.60, or when there's no
src/module-env-NN.h file.)
"git add" the new src/module-env-XY+1.h file.
Then rebuild Emacs. Then commit the new/changed files and push.
5. Announce the new release branch on emacs-devel.

View file

@ -3294,6 +3294,20 @@ file:
(add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
** Xref migrated from EIEIO to cl-defstruct for its core objects.
This means that 'oref' and 'with-slots' no longer works on them, and
'make-instance' can no longer be used to create those instances (which
wasn't recommended anyway). Packages should keep to using the
functions like 'xref-make', 'xref-make-match', 'xref-make-*-location',
as well as accessor functions 'xref-item-summary' and
'xref-item-location'.
Among the benefits are better performance (noticeable when there are a
lot of matches) and improved flexibility: 'xref-match-item' instances
do not require that 'location' inherits from 'xref-location' anymore
(that class was removed), so packages can create new location types to
use with "match items" without adding EIEIO as a dependency.
* Incompatible Lisp Changes in Emacs 28.1

198
etc/TODO
View file

@ -29,99 +29,8 @@ are the ones we consider more important, but these also may be
difficult to fix. Bugs with severity "minor" may be simpler, but this
is not always true.
* Speed up Elisp execution
** Speed up function calls
Change src/bytecode.c so that calls from byte-code functions to byte-code
functions don't go through Ffuncall/funcall_lambda/exec_byte_code but instead
stay within exec_byte_code.
** Improve the byte-compiler to recognize immutable bindings
Recognize immutable (lexical) bindings and get rid of them if they're
used only once and/or they're bound to a constant expression.
Such things aren't present in hand-written code, but macro expansion and
defsubst can often end up generating things like
(funcall (lambda (arg) (body)) actual) which then get optimized to
(let ((arg actual)) (body)) but should additionally get optimized further
when 'actual' is a constant/copyable expression.
** Add an "indirect goto" byte-code
Such a byte-code can be used for local lambda expressions.
E.g. when you have code like
(let ((foo (lambda (x) bar)))
(dosomething
(funcall foo toto)
(blabla (funcall foo titi))))
turn those 'funcalls' into jumps and their return into indirect jumps back.
** Compile efficiently local recursive functions
Similar to the previous point, we should be able to handle something like
(letrec ((loop () (blabla) (if (toto) (loop))))
(loop))
which ideally should generate the same byte-code as
(while (progn (blabla) (toto)))
* Things that were planned for Emacs-24
** concurrency
Including it as an "experimental" compile-time option sounds good. Of
course there might still be big questions around "which form of
concurrency" we'll want.
** better support for dynamic embedded graphics
I like this idea (my mpc.el code could use it for the volume widget),
though I wonder if the resulting efficiency will be sufficient.
** Spread Semantic
** Improve the "code snippets" support
Consolidate skeleton.el, tempo.el, and expand.el (any other?) and then
advertise/use/improve it.
** Improve VC
Yes, there's a lot of work to be done there :-(
** Random things that cross my mind right now that I'd like to see
Some of them from my local hacks, but it's not obvious at all whether
they'll make it.
*** Prog-mode could/should provide a better fill-paragraph default
That default should use syntax-tables to recognize string/comment
boundaries.
*** Provide more completion-at-point-functions
Make existing in-buffer completion use completion-at-point.
*** "Functional" function-key-map
It would make it easy to add (and remove) mappings like
"FOO-mouse-4 -> FOO-scroll-down", "FOO-tab -> ?\FOO-\t",
"uppercase -> lowercase", "[fringe KEY...] -> [KEY]",
"H-FOO -> M-FOO", "C-x C-y FOO -> H-FOO", ...
* Things related to elpa.gnu.org.
** Move idlwave to elpa.gnu.org
Need to sync up the Emacs and external versions.
See <https://lists.gnu.org/r/emacs-devel/2014-07/msg00008.html>
** Move Org mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2014-08/msg00300.html>
<https://lists.gnu.org/r/emacs-devel/2014-11/msg00257.html>
** Move verilog-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
** Move vhdl-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
* Simple tasks
These don't require much Emacs knowledge, they are suitable for anyone
These don't require much Emacs knowledge and are suitable for anyone
from beginners to experts.
** Convert modes that use view-mode to be derived from special-mode instead
@ -143,6 +52,13 @@ things in their .emacs.
** See if other files can use generated-autoload-file (see eg ps-print)
** Do interactive mode tagging for commands
Change "(interactive)" to "(interactive nil foo-mode)" for command
completion purposes. Pick a major mode or ELisp library, and check
all interactive commands to see if they are only relevant in one
particular mode. This requires care as some commands might be useful
outside of the mode they were written for.
** Write more tests
Pick a fixed bug from the database, write a test case to make sure it
stays fixed. Or pick your favorite programming major-mode, and write
@ -235,6 +151,44 @@ https://lists.gnu.org/r/emacs-devel/2008-08/msg00456.html
* Important features
** Speed up Elisp execution
*** Speed up function calls
Change src/bytecode.c so that calls from byte-code functions to byte-code
functions don't go through Ffuncall/funcall_lambda/exec_byte_code but instead
stay within exec_byte_code.
*** Improve the byte-compiler to recognize immutable bindings
Recognize immutable (lexical) bindings and get rid of them if they're
used only once and/or they're bound to a constant expression.
Such things aren't present in hand-written code, but macro expansion and
defsubst can often end up generating things like
(funcall (lambda (arg) (body)) actual) which then get optimized to
(let ((arg actual)) (body)) but should additionally get optimized further
when 'actual' is a constant/copyable expression.
*** Add an "indirect goto" byte-code
Such a byte-code can be used for local lambda expressions.
E.g. when you have code like
(let ((foo (lambda (x) bar)))
(dosomething
(funcall foo toto)
(blabla (funcall foo titi))))
turn those 'funcalls' into jumps and their return into indirect jumps back.
*** Compile efficiently local recursive functions
Similar to the previous point, we should be able to handle something like
(letrec ((loop () (blabla) (if (toto) (loop))))
(loop))
which ideally should generate the same byte-code as
(while (progn (blabla) (toto)))
** "Emacs as word processor"
https://lists.gnu.org/r/emacs-devel/2013-11/msg00515.html
rms writes:
@ -492,6 +446,15 @@ consistency checks that make sure the new code computes the same results
as the old code. And once that works well, we can remove the old code
and old fields.
** Better support for dynamic embedded graphics
I like this idea (my mpc.el code could use it for the volume widget),
though I wonder if the resulting efficiency will be sufficient.
** Concurrency
Including it as an "experimental" compile-time option sounds good. Of
course there might still be big questions around "which form of
concurrency" we'll want.
** FFI (foreign function interface)
See eg https://lists.gnu.org/r/emacs-devel/2013-10/msg00246.html
@ -829,11 +792,6 @@ gametree, page-ext, refbib, refer, scribe, texinfo, underline,
cmacexp, hideif, pcomplete, xml, cvs-status (should be described in
PCL-CVS manual); other progmodes, probably in separate manual.
** Deprecate and remove XPM icons
Convert the XPM bitmaps to PPM, replace the PBMs with them and scrap
the XPMs so that the color versions work generally. (Requires care
with the color used for the transparent regions.)
** Convenient access to the 'values' variable
It would be nice to have an interface that would show you the printed
reps of the elements of the list in a menu, let you select one of the
@ -904,6 +862,32 @@ The idea is to add an "X" of some kind, that when clicked deletes the
window associated with that modeline.
https://lists.gnu.org/r/emacs-devel/2007-09/msg02416.html
** Improve the "code snippets" support
Consolidate skeleton.el, tempo.el, and expand.el (any other?) and then
advertise/use/improve it.
** Improve VC
Yes, there's a lot of work to be done there :-(
** Spread Semantic
** Random things that crossed Stefan Monnier's mind for Emacs 24
Stefan Monnier writes: "Some of them from my local hacks, but it's not
obvious at all whether they'll make it."
*** Prog-mode could/should provide a better fill-paragraph default
That default should use syntax-tables to recognize string/comment
boundaries.
*** Provide more completion-at-point-functions
Make existing in-buffer completion use completion-at-point.
*** "Functional" function-key-map
It would make it easy to add (and remove) mappings like
"FOO-mouse-4 -> FOO-scroll-down", "FOO-tab -> ?\FOO-\t",
"uppercase -> lowercase", "[fringe KEY...] -> [KEY]",
"H-FOO -> M-FOO", "C-x C-y FOO -> H-FOO", ...
* Things to be done for specific packages or features
** NeXTstep port
@ -1757,6 +1741,26 @@ Add a standard button-class named "link", and make all other link-like
button classes inherit from it. Set the default face of the "link"
button class to the standard "link" face.
* Things related to elpa.gnu.org.
We need to figure out how to best include GNU ELPA packages in the
Emacs tarball before doing any of the items below.
** Move idlwave to elpa.gnu.org
Need to sync up the Emacs and external versions.
See <https://lists.gnu.org/r/emacs-devel/2014-07/msg00008.html>
<https://debbugs.gnu.org/39992>
** Move Org mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2014-08/msg00300.html>
<https://lists.gnu.org/r/emacs-devel/2014-11/msg00257.html>
** Move verilog-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
** Move vhdl-mode to elpa.gnu.org
See <https://lists.gnu.org/r/emacs-devel/2015-02/msg01180.html>
* Wishlist items
** Maybe replace etags.c with a Lisp implementation.

View file

@ -4490,6 +4490,7 @@ Ask means pop up a menu for the user to select one of copy, move or link."
(defvar archive-superior-buffer)
(defvar tar-superior-buffer)
(declare-function dired-omit-mode "dired-x" (&optional arg))
;;;###autoload
(defun dired-jump (&optional other-window file-name)

View file

@ -3298,24 +3298,22 @@ a script after exceeding the flood threshold."
t)
(t nil)))
(defun erc-cmd-WHOIS (nick-or-server &optional nick-if-server)
(defun erc-cmd-WHOIS (first &optional second)
"Display whois information for the given user.
If NICK-IF-SERVER is nil, NICK-OR-SERVER should be the nick of
the user about whom the whois information is to be requested.
Otherwise, if NICK-IF-SERVER is non-nil, NICK-OR-SERVER should be
the server to which the user with the nick NICK-IF-USER is
connected to.
With one argument, FIRST is the nickname of the user to request
whois information for.
Specifying the server NICK-OR-SERVER that the nick NICK-IF-SERVER
is connected to is useful for getting the time the NICK-IF-SERVER
user has been idle for, when the user NICK-IF-SERVER is connected
to a different server of the network than the one current user is
connected to, since only the server a user is connected to knows
the idle time of that user."
(let ((send (if nick-if-server
(format "WHOIS %s %s" nick-or-server nick-if-server)
(format "WHOIS %s" nick-or-server))))
With two arguments, FIRST is the server, and SECOND is the user
nickname.
Specifying the server is useful for getting the time the user has
been idle for, when the user is connected to a different server
on the same IRC network. (Only the server a user is connected to
knows how long the user has been idle for.)"
(let ((send (if second
(format "WHOIS %s %s" first second)
(format "WHOIS %s" first))))
(erc-log (format "cmd: %s" send))
(erc-server-send send)
t))

View file

@ -2161,18 +2161,16 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
(nreverse res))))
tags-apropos-additional-actions))
(defclass xref-etags-location (xref-location)
((tag-info :type list :initarg :tag-info)
(file :type string :initarg :file
:reader xref-location-group))
:documentation "Location of an etags tag.")
(cl-defstruct (xref-etags-location
(:constructor xref-make-etags-location (tag-info file)))
"Location of an etags tag."
tag-info file)
(defun xref-make-etags-location (tag-info file)
(make-instance 'xref-etags-location :tag-info tag-info
:file (expand-file-name file)))
(cl-defmethod xref-location-group ((l xref-etags-location))
(xref-etags-location-file l))
(cl-defmethod xref-location-marker ((l xref-etags-location))
(with-slots (tag-info file) l
(pcase-let (((cl-struct xref-etags-location tag-info file) l))
(let ((buffer (find-file-noselect file)))
(with-current-buffer buffer
(save-excursion
@ -2182,25 +2180,20 @@ file name, add `tag-partial-file-name-match-p' to the list value.")
(point-marker)))))))
(cl-defmethod xref-location-line ((l xref-etags-location))
(with-slots (tag-info) l
(pcase-let (((cl-struct xref-etags-location tag-info) l))
(nth 1 tag-info)))
(defclass xref-etags-apropos-location (xref-location)
((symbol :type symbol :initarg :symbol)
(goto-fun :type function :initarg :goto-fun)
(group :type string :initarg :group
:reader xref-location-group))
:documentation "Location of an additional apropos etags symbol.")
(cl-defstruct (xref-etags-apropos-location
(:constructor xref-make-etags-apropos-location (symbol goto-fun group)))
"Location of an additional apropos etags symbol."
symbol goto-fun group)
(defun xref-make-etags-apropos-location (symbol goto-fun group)
(make-instance 'xref-etags-apropos-location
:symbol symbol
:goto-fun goto-fun
:group group))
(cl-defmethod xref-location-group ((l xref-etags-apropos-location))
(xref-etags-apropos-location-group l))
(cl-defmethod xref-location-marker ((l xref-etags-apropos-location))
(save-window-excursion
(with-slots (goto-fun symbol) l
(pcase-let (((cl-struct xref-etags-apropos-location goto-fun symbol) l))
(funcall goto-fun symbol)
(point-marker))))

View file

@ -46,9 +46,9 @@
;;
;; One would usually call `make-xref' and `xref-make-file-location',
;; `xref-make-buffer-location' or `xref-make-bogus-location' to create
;; them. More generally, a location must be an instance of an EIEIO
;; class inheriting from `xref-location' and implementing
;; `xref-location-group' and `xref-location-marker'.
;; them. More generally, a location must be an instance of a type for
;; which methods `xref-location-group' and `xref-location-marker' are
;; implemented.
;;
;; There's a special kind of xrefs we call "match xrefs", which
;; correspond to search results. For these values,
@ -62,12 +62,15 @@
;; distinct, because the user can't see the properties when making the
;; choice.
;;
;; Older versions of Xref used EIEIO for implementation of the
;; built-in types, and included a class called `xref-location' which
;; was supposed to be inherited from. Neither is true anymore.
;;
;; See the etags and elisp-mode implementations for full examples.
;;; Code:
(require 'cl-lib)
(require 'eieio)
(require 'ring)
(require 'project)
@ -78,9 +81,6 @@
;;; Locations
(defclass xref-location () ()
:documentation "A location represents a position in a file or buffer.")
(cl-defgeneric xref-location-marker (location)
"Return the marker for LOCATION.")
@ -99,7 +99,7 @@ When it is a file name, it should be the \"expanded\" version.")
"Return the length of the match."
nil)
;;;; Commonly needed location classes are defined here:
;;;; Commonly needed location types are defined here:
(defcustom xref-file-name-display 'project-relative
"Style of file name display in *xref* buffers.
@ -121,19 +121,20 @@ in its full absolute form."
;; FIXME: might be useful to have an optional "hint" i.e. a string to
;; search for in case the line number is slightly out of date.
(defclass xref-file-location (xref-location)
((file :type string :initarg :file :reader xref-location-group)
(line :type fixnum :initarg :line :reader xref-location-line)
(column :type fixnum :initarg :column :reader xref-file-location-column))
:documentation "A file location is a file/line/column triple.
Line numbers start from 1 and columns from 0.")
(cl-defstruct (xref-file-location
(:constructor xref-make-file-location (file line column)))
"A file location is a file/line/column triple.
Line numbers start from 1 and columns from 0."
file line column)
(defun xref-make-file-location (file line column)
"Create and return a new `xref-file-location'."
(make-instance 'xref-file-location :file file :line line :column column))
(cl-defmethod xref-location-group ((l xref-file-location))
(xref-file-location-file l))
(cl-defmethod xref-location-line ((l xref-file-location))
(xref-file-location-line l))
(cl-defmethod xref-location-marker ((l xref-file-location))
(with-slots (file line column) l
(pcase-let (((cl-struct xref-file-location file line column) l))
(with-current-buffer
(or (get-file-buffer file)
(let ((find-file-suppress-same-file-warnings t))
@ -151,77 +152,51 @@ Line numbers start from 1 and columns from 0.")
(forward-char column))
(point-marker))))))
(defclass xref-buffer-location (xref-location)
((buffer :type buffer :initarg :buffer)
(position :type fixnum :initarg :position)))
(defun xref-make-buffer-location (buffer position)
"Create and return a new `xref-buffer-location'."
(make-instance 'xref-buffer-location :buffer buffer :position position))
(cl-defstruct (xref-buffer-location
(:constructor xref-make-buffer-location (buffer position)))
buffer position)
(cl-defmethod xref-location-marker ((l xref-buffer-location))
(with-slots (buffer position) l
(pcase-let (((cl-struct xref-buffer-location buffer position) l))
(let ((m (make-marker)))
(move-marker m position buffer))))
(cl-defmethod xref-location-group ((l xref-buffer-location))
(with-slots (buffer) l
(pcase-let (((cl-struct xref-buffer-location buffer) l))
(or (buffer-file-name buffer)
(format "(buffer %s)" (buffer-name buffer)))))
(defclass xref-bogus-location (xref-location)
((message :type string :initarg :message
:reader xref-bogus-location-message))
:documentation "Bogus locations are sometimes useful to
indicate errors, e.g. when we know that a function exists but the
actual location is not known.")
(defun xref-make-bogus-location (message)
"Create and return a new `xref-bogus-location'."
(make-instance 'xref-bogus-location :message message))
(cl-defstruct (xref-bogus-location
(:constructor xref-make-bogus-location (message)))
"Bogus locations are sometimes useful to indicate errors,
e.g. when we know that a function exists but the actual location
is not known."
message)
(cl-defmethod xref-location-marker ((l xref-bogus-location))
(user-error "%s" (oref l message)))
(user-error "%s" (xref-bogus-location-message l)))
(cl-defmethod xref-location-group ((_ xref-bogus-location)) "(No location)")
;;; Cross-reference
(defclass xref-item ()
((summary :type string :initarg :summary
:reader xref-item-summary
:documentation "One line which will be displayed for
this item in the output buffer.")
(location :initarg :location
:reader xref-item-location
:documentation "An object describing how to navigate
to the reference's target."))
:comment "An xref item describes a reference to a location
somewhere.")
(cl-defstruct (xref-item
(:constructor xref-make (summary location))
(:noinline t))
"An xref item describes a reference to a location somewhere."
summary location)
(defun xref-make (summary location)
"Create and return a new `xref-item'.
SUMMARY is a short string to describe the xref.
LOCATION is an `xref-location'."
(make-instance 'xref-item :summary summary :location location))
(cl-defstruct (xref-match-item
(:include xref-item)
(:constructor xref-make-match (summary location length))
(:noinline t))
"A match xref item describes a search result."
length)
(defclass xref-match-item ()
((summary :type string :initarg :summary
:reader xref-item-summary)
(location :initarg :location
:type xref-location
:reader xref-item-location)
(length :initarg :length :reader xref-match-length))
:comment "A match xref item describes a search result.")
(defun xref-make-match (summary location length)
"Create and return a new `xref-match-item'.
SUMMARY is a short string to describe the xref.
LOCATION is an `xref-location'.
LENGTH is the match length, in characters."
(make-instance 'xref-match-item :summary summary
:location location :length length))
(cl-defgeneric xref-match-length ((item xref-match-item))
"Return the length of the match."
(xref-match-item-length item))
;;; API
@ -970,7 +945,7 @@ GROUP is a string for decoration purposes and XREF is an
for max-line-width =
(cl-loop for xref in xrefs
maximize (let ((line (xref-location-line
(oref xref location))))
(xref-item-location xref))))
(and line (1+ (floor (log line 10))))))
for line-format = (and max-line-width
(format "%%%dd: " max-line-width))
@ -985,7 +960,7 @@ GROUP is a string for decoration purposes and XREF is an
(xref--insert-propertized '(face xref-file-header xref-group t)
group "\n")
(cl-loop for xref in xrefs do
(with-slots (summary location) xref
(pcase-let (((cl-struct xref-item summary location) xref))
(let* ((line (xref-location-line location))
(prefix
(cond
@ -1024,7 +999,7 @@ to that style. Otherwise it is returned unchanged."
;; `tags-apropos-additional-actions', is pretty lax. But we don't
;; want to use `file-exists-p' for performance reasons. If this
;; ever turns out to be a problem, some other alternatives are to
;; either have every location class which uses file names format the
;; either have every location type which uses file names format the
;; values themselves (e.g. by piping through some public function),
;; or adding a new accessor to locations, like GROUP-TYPE.
(cl-ecase xref-file-name-display
@ -1206,22 +1181,23 @@ between them by typing in the minibuffer with completion."
(cl-loop for ((group . xrefs) . more1) on xref-alist
do
(cl-loop for (xref . more2) on xrefs do
(with-slots (summary location) xref
(let* ((line (xref-location-line location))
(line-fmt
(if line
(format #("%d:" 0 2 (face xref-line-number))
line)
""))
(group-prefix
(substring group group-prefix-length))
(group-fmt
(propertize group-prefix
'face 'xref-file-header
'xref--group group-prefix))
(candidate
(format "%s:%s%s" group-fmt line-fmt summary)))
(push (cons candidate xref) xref-alist-with-line-info)))))
(let* ((summary (xref-item-summary xref))
(location (xref-item-location xref))
(line (xref-location-line location))
(line-fmt
(if line
(format #("%d:" 0 2 (face xref-line-number))
line)
""))
(group-prefix
(substring group group-prefix-length))
(group-fmt
(propertize group-prefix
'face 'xref-file-header
'xref--group group-prefix))
(candidate
(format "%s:%s%s" group-fmt line-fmt summary)))
(push (cons candidate xref) xref-alist-with-line-info))))
(setq xref (if (not (cdr xrefs))
(car xrefs)

View file

@ -317,27 +317,27 @@
(expected (pop expected-xrefs))
(expected-xref (or (when (consp expected) (car expected)) expected))
(expected-source (when (consp expected) (cdr expected)))
(xref-file (xref-elisp-location-file (oref xref location)))
(xref-file (xref-elisp-location-file (xref-item-location xref)))
(expected-file (xref-elisp-location-file
(oref expected-xref location))))
(xref-item-location expected-xref))))
;; Make sure file names compare as strings.
(when (file-name-absolute-p xref-file)
(setf (xref-elisp-location-file (oref xref location))
(file-truename (xref-elisp-location-file (oref xref location)))))
(setf (xref-elisp-location-file (xref-item-location xref))
(file-truename (xref-elisp-location-file (xref-item-location xref)))))
(when (file-name-absolute-p expected-file)
(setf (xref-elisp-location-file (oref expected-xref location))
(setf (xref-elisp-location-file (xref-item-location expected-xref))
(file-truename (xref-elisp-location-file
(oref expected-xref location)))))
(xref-item-location expected-xref)))))
;; Downcase the filenames for case-insensitive file systems.
(when xref--case-insensitive
(setf (xref-elisp-location-file (oref xref location))
(downcase (xref-elisp-location-file (oref xref location))))
(setf (xref-elisp-location-file (xref-item-location xref))
(downcase (xref-elisp-location-file (xref-item-location xref))))
(setf (xref-elisp-location-file (oref expected-xref location))
(setf (xref-elisp-location-file (xref-item-location expected-xref))
(downcase (xref-elisp-location-file
(oref expected-xref location)))))
(xref-item-location expected-xref)))))
(should (equal xref expected-xref))
@ -418,8 +418,6 @@ to (xref-elisp-test-descr-to-target xref)."
;; FIXME: defconst
;; FIXME: eieio defclass
;; Possible ways of defining the default method implementation for a
;; generic function. We declare these here, so we know we cover all
;; cases, and we don't rely on other code not changing.