mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-17 01:34:21 +00:00
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 commit88378acbfcRename arguments of ERC's '/whois' and simplify doc string205eb7f801; s/class/type86da812afbMigrate Xref off EIEIO5c73dfcbcb* 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:
commit
823bc66e74
8 changed files with 294 additions and 235 deletions
75
admin/release-branch.txt
Normal file
75
admin/release-branch.txt
Normal 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.
|
||||
14
etc/NEWS.28
14
etc/NEWS.28
|
|
@ -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
198
etc/TODO
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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))))
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue