[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
From: |
dick . r . chiang |
Subject: |
bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there. |
Date: |
Fri, 03 Jun 2022 02:27:59 -0400 |
User-agent: |
Gnus/5.14 (Gnus v5.14) Commercial/29.0.50 (gnu/linux) |
Was https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00340.html
Some guys symlink their PATH emacs to src/emacs.
Other guys still prefer `make install`, and live in constant fear of
meta-dotting into a .gz file. Well, live in fear no more.
emacs -Q --eval "(custom-set-variables '(xref-prefer-source-directory t))"
>From fb6f100bb1f588322c6a501ff2876a773189a9b9 Mon Sep 17 00:00:00 2001
From: dickmao <dick.r.chiang@gmail.com>
Date: Fri, 3 Jun 2022 02:11:20 -0400
Subject: [PATCH] xref-prefer-source-directory
emacs -Q --eval "(custom-set-variables '(xref-prefer-source-directory t))"
* lisp/emacs-lisp/find-func.el (find-function-regexp-alist):
Was crashing on this missing entry in find-function-regexp-alist.
(find-function-C-source-directory): Style.
(find-function-C-source): Style.
(find-function-search-for-symbol): English.
* lisp/help-fns.el (help-C-file-name): English.
(find-lisp-object-file-name): Use it.
* lisp/help-mode.el (xref): Require.
(help-function-def--button-function): Use it.
(help-face-def): Use it.
* lisp/progmodes/elisp-mode.el (xref-backend-definitions): Style.
(elisp--xref-find-definitions): Style.
(xref-location-marker): Use it.
* lisp/progmodes/project.el (project-root): Snuff bytecomp warning.
* lisp/progmodes/xref.el (xref-prefer-source-directory): New defcustom.
(xref-preferred-message): Message user.
(xref-preferred-source): Act on new defcustom.
(xref-show-definitions-buffer): Style.
(xref--create-fetcher): Style.
* src/emacs.c (syms_of_emacs): English.
* src/lread.c (load_path_default): English.
(init_lread): Style.
(syms_of_lread): New defvar.
* test/lisp/progmodes/elisp-mode-tests.el (xref-tests-prefer-source):
Test it.
* test/lisp/progmodes/xref-tests.el
(xref-matches-in-directory-finds-none-for-some-regexp): Style.
(xref--buf-pairs-iterator-groups-markers-by-buffers-1): Style.
(xref--buf-pairs-iterator-groups-markers-by-buffers-2): Style.
(xref--buf-pairs-iterator-cleans-up-markers): Style.
---
lisp/emacs-lisp/find-func.el | 119 +++++++------
lisp/help-fns.el | 55 +++---
lisp/help-mode.el | 13 +-
lisp/progmodes/elisp-mode.el | 214 +++++++++++-------------
lisp/progmodes/project.el | 2 +-
lisp/progmodes/xref.el | 56 +++++--
src/emacs.c | 13 +-
src/lread.c | 154 ++++++-----------
test/lisp/progmodes/elisp-mode-tests.el | 42 +++++
test/lisp/progmodes/xref-tests.el | 14 +-
10 files changed, 343 insertions(+), 339 deletions(-)
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 96eaf1ab642..063e3c8bcd7 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -143,6 +143,7 @@ find-function--defface
(defvar find-function-regexp-alist
'((nil . find-function-regexp)
+ (define-type . find-function-regexp)
(defvar . find-variable-regexp)
(defface . find-function--defface)
(feature . find-feature-regexp)
@@ -257,7 +258,7 @@ find-library--from-load-history
(defvar find-function-C-source-directory
(let ((dir (expand-file-name "src" source-directory)))
- (if (file-accessible-directory-p dir) dir))
+ (when (file-accessible-directory-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.")
@@ -283,8 +284,8 @@ find-function-C-source
(read-directory-name "Emacs C source dir: " nil nil t))))
(setq file (expand-file-name file dir))
(if (file-readable-p file)
- (if (null find-function-C-source-directory)
- (setq find-function-C-source-directory dir))
+ (unless find-function-C-source-directory
+ (setq find-function-C-source-directory dir))
(error "The C source file %s is not available"
(file-name-nondirectory file))))
(unless type
@@ -391,16 +392,18 @@ find-library-other-frame
;;;###autoload
(defun find-function-search-for-symbol (symbol type library)
- "Search for SYMBOL's definition of type TYPE in LIBRARY.
-Visit the library in a buffer, and return a cons cell (BUFFER . POSITION),
-or just (BUFFER . nil) if the definition can't be found in the file.
-
-If TYPE is nil, look for a function definition.
-Otherwise, TYPE specifies the kind of definition,
-and it is interpreted via `find-function-regexp-alist'.
-The search is done in the source for library LIBRARY."
- (if (null library)
- (error "Don't know where `%s' is defined" symbol))
+ "Find SYMBOL's defun, or other definitional TYPE, in LIBRARY.
+When TYPE is a non-nil key in `find-function-regexp-alist',
+interpret SYMBOL according to the corresponding definitional,
+e.g., defvar or defface.
+
+After visiting file LIBRARY, return a cons cell (BUFFER
+. POS), where POS is the character position of the definition,
+or nil if not found.
+
+LIBRARY can be an absolute or relative path."
+ (unless library
+ (error "Don't know where `%s' is defined" symbol))
;; Some functions are defined as part of the construct
;; that defines something else.
(while (and (symbolp symbol) (get symbol 'definition-name))
@@ -413,48 +416,54 @@ find-function-search-for-symbol
;; .emacs too.
(when (string-match "\\.emacs\\(.el\\)" library)
(setq library (substring library 0 (match-beginning 1))))
- (let* ((filename (find-library-name library))
- (regexp-symbol (cdr (assq type find-function-regexp-alist))))
- (with-current-buffer (find-file-noselect filename)
- (let ((regexp (if (functionp regexp-symbol) regexp-symbol
- (format (symbol-value regexp-symbol)
- ;; Entry for ` (backquote) macro in
loaddefs.el,
- ;; (defalias (quote \`)..., has a \ but
- ;; (symbol-name symbol) doesn't. Add an
- ;; optional \ to catch this.
- (concat "\\\\?"
- (regexp-quote (symbol-name symbol))))))
- (case-fold-search))
- (save-restriction
- (widen)
- (with-syntax-table emacs-lisp-mode-syntax-table
- (goto-char (point-min))
- (if (if (functionp regexp)
- (funcall regexp symbol)
- (or (re-search-forward regexp nil t)
- ;; `regexp' matches definitions using known forms like
- ;; `defun', or `defvar'. But some functions/variables
- ;; are defined using special macros (or functions), so
- ;; if `regexp' can't find the definition, we look for
- ;; something of the form "(SOMETHING <symbol> ...)".
- ;; This fails to distinguish function definitions from
- ;; variable declarations (or even uses thereof), but is
- ;; a good pragmatic fallback.
- (re-search-forward
- (concat "^([^ ]+" find-function-space-re "['(]?"
- (regexp-quote (symbol-name symbol))
- "\\_>")
- nil t)))
- (progn
- (beginning-of-line)
- (cons (current-buffer) (point)))
- ;; If the regexp search didn't find the location of
- ;; the symbol (for example, because it is generated by
- ;; a macro), try a slightly more expensive search that
- ;; expands macros until it finds the symbol.
- (cons (current-buffer)
- (find-function--search-by-expanding-macros
- (current-buffer) symbol type))))))))))
+ (let ((filename (find-library-name library))
+ (regexp-symbol (cdr (assq type find-function-regexp-alist))))
+ (cond ((not filename)
+ (error "Could not find '%s'" library))
+ ((not regexp-symbol)
+ (error "No find-function regexp entry for '%s'" type))
+ (t
+ (with-current-buffer (find-file-noselect filename)
+ (let ((regexp (if (functionp regexp-symbol)
+ regexp-symbol
+ (format (symbol-value regexp-symbol)
+ ;; Entry for ` (backquote) macro in
loaddefs.el,
+ ;; (defalias (quote \`)..., has a \ but
+ ;; (symbol-name symbol) doesn't. Add an
+ ;; optional \ to catch this.
+ (concat "\\\\?"
+ (regexp-quote (symbol-name
symbol))))))
+ (case-fold-search))
+ (save-restriction
+ (widen)
+ (with-syntax-table emacs-lisp-mode-syntax-table
+ (goto-char (point-min))
+ (if (if (functionp regexp)
+ (funcall regexp symbol)
+ (or (re-search-forward regexp nil t)
+ ;; `regexp' matches definitions using known
forms like
+ ;; `defun', or `defvar'. But some
functions/variables
+ ;; are defined using special macros (or
functions), so
+ ;; if `regexp' can't find the definition, we
look for
+ ;; something of the form "(SOMETHING <symbol>
...)".
+ ;; This fails to distinguish function
definitions from
+ ;; variable declarations (or even uses
thereof), but is
+ ;; a good pragmatic fallback.
+ (re-search-forward
+ (concat "^([^ ]+" find-function-space-re
"['(]?"
+ (regexp-quote (symbol-name symbol))
+ "\\_>")
+ nil t)))
+ (progn
+ (beginning-of-line)
+ (cons (current-buffer) (point)))
+ ;; If the regexp search didn't find the location of
+ ;; the symbol (for example, because it is generated by
+ ;; a macro), try a slightly more expensive search that
+ ;; expands macros until it finds the symbol.
+ (cons (current-buffer)
+ (find-function--search-by-expanding-macros
+ (current-buffer) symbol type))))))))))))
(defun find-function--try-macroexpand (form)
"Try to macroexpand FORM in full or partially.
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index f200077faec..cab712a2f1f 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -299,8 +299,8 @@ describe-command
;;;###autoload
(defun help-C-file-name (subr-or-var kind)
"Return the name of the C file where SUBR-OR-VAR is defined.
-KIND should be `var' for a variable or `subr' for a subroutine.
-If we can't find the file name, nil is returned."
+KIND should be 'var for a variable or 'subr for a subroutine. If
+we can't find the file name, nil is returned."
(let ((docbuf (get-buffer-create " *DOC*"))
(name (if (eq 'var kind)
(concat "V" (symbol-name subr-or-var))
@@ -309,29 +309,28 @@ help-C-file-name
(subr-name (advice--cd*r subr-or-var)))))))
(with-current-buffer docbuf
(goto-char (point-min))
- (if (eobp)
- (insert-file-contents-literally
- (expand-file-name internal-doc-file-name doc-directory)))
- (let ((file (catch 'loop
+ (when (eobp)
+ (insert-file-contents-literally
+ (expand-file-name internal-doc-file-name doc-directory)))
+ (when-let ((file
+ (catch 'loop
(while t
- (let ((pnt (search-forward (concat "\^_" name "\n")
- nil t)))
- (if (not pnt)
- (throw 'loop nil)
- (re-search-backward "\^_S\\(.*\\)")
- (let ((file (match-string 1)))
- (if (member file build-files)
- (throw 'loop file)
- (goto-char pnt)))))))))
- (if (not file)
- nil
- (if (string-match "^ns.*\\(\\.o\\|obj\\)\\'" file)
- (setq file (replace-match ".m" t t file 1))
- (if (string-match "\\.\\(o\\|obj\\)\\'" file)
- (setq file (replace-match ".c" t t file))))
- (if (string-match "\\.\\(c\\|m\\)\\'" file)
- (concat "src/" file)
- file))))))
+ (if-let ((pnt (search-forward (concat "\^_" name "\n")
+ nil t)))
+ (progn
+ (re-search-backward "\^_S\\(.*\\)")
+ (let ((file (match-string 1)))
+ (if (member file build-files)
+ (throw 'loop file)
+ (goto-char pnt))))
+ (throw 'loop nil))))))
+ (if (string-match "^ns.*\\(\\.o\\|obj\\)\\'" file)
+ (setq file (replace-match ".m" t t file 1))
+ (if (string-match "\\.\\(o\\|obj\\)\\'" file)
+ (setq file (replace-match ".c" t t file))))
+ (if (string-match "\\.\\(c\\|m\\)\\'" file)
+ (concat "src/" file)
+ file)))))
(defcustom help-downcase-arguments nil
"If non-nil, argument names in *Help* buffers are downcased."
@@ -440,10 +439,10 @@ find-lisp-object-file-name
;; An autoloaded variable or face. Visit loaddefs.el in a buffer
;; and try to extract the defining file. The following form is
;; from `describe-function-1' and `describe-variable'.
- (let ((location
- (condition-case nil
- (find-function-search-for-symbol object nil file-name)
- (error nil))))
+ (let* ((prefer-file (xref-preferred-source file-name))
+ (location
+ (ignore-errors
+ (find-function-search-for-symbol object nil prefer-file))))
(when (cdr location)
(with-current-buffer (car location)
(goto-char (cdr location))
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index 2fcb8b9f3e6..ba3b9d4f4b5 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -30,6 +30,7 @@
;;; Code:
(require 'cl-lib)
+(require 'xref)
(defvar help-mode-map
(let ((map (make-sparse-keymap)))
@@ -265,8 +266,9 @@ help-function-def--button-function
(help-C-file-name (indirect-function fun) 'fun)))
;; Don't use find-function-noselect because it follows
;; aliases (which fails for built-in functions).
- (let* ((location
- (find-function-search-for-symbol fun type file))
+ (let* ((prefer-file (xref-preferred-source file))
+ (location
+ (find-function-search-for-symbol fun type prefer-file))
(position (cdr location)))
(if help-window-keep-selected
(pop-to-buffer-same-window (car location))
@@ -338,9 +340,10 @@ 'help-face-def
(require 'find-func)
;; Don't use find-function-noselect because it follows
;; aliases (which fails for built-in functions).
- (let* ((location
- (find-function-search-for-symbol fun 'defface file))
- (position (cdr location)))
+ (let* ((prefer-file (xref-preferred-source file))
+ (location
+ (find-function-search-for-symbol fun 'defface
prefer-file))
+ (position (cdr location)))
(if help-window-keep-selected
(pop-to-buffer-same-window (car location))
(pop-to-buffer (car location)))
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index 77bf3f1ed18..a59b2639b70 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -975,17 +975,16 @@ xref-backend-identifier-at-point
(cl-defmethod xref-backend-definitions ((_backend (eql 'elisp)) identifier)
(require 'find-func)
- (let ((sym (intern-soft identifier)))
- (when sym
- (let* ((pos (get-text-property 0 'pos identifier))
- (namespace (if pos
- (elisp--xref-infer-namespace pos)
- 'any))
- (defs (elisp--xref-find-definitions sym)))
- (if (eq namespace 'maybe-variable)
- (or (elisp--xref-filter-definitions defs 'variable sym)
- (elisp--xref-filter-definitions defs 'any sym))
- (elisp--xref-filter-definitions defs namespace sym))))))
+ (when-let ((sym (intern-soft identifier)))
+ (let* ((pos (get-text-property 0 'pos identifier))
+ (namespace (if pos
+ (elisp--xref-infer-namespace pos)
+ 'any))
+ (defs (elisp--xref-find-definitions sym)))
+ (if (eq namespace 'maybe-variable)
+ (or (elisp--xref-filter-definitions defs 'variable sym)
+ (elisp--xref-filter-definitions defs 'any sym))
+ (elisp--xref-filter-definitions defs namespace sym)))))
(defun elisp--xref-filter-definitions (definitions namespace symbol)
(if (eq namespace 'any)
@@ -1019,11 +1018,10 @@ elisp--xref-filter-definitions
collect d))))
(defun elisp--xref-find-definitions (symbol)
- ;; The file name is not known when `symbol' is defined via interactive eval.
+ ;; The file name is not known when SYMBOL is defined via interactive eval.
(let (xrefs)
(let ((temp elisp-xref-find-def-functions))
- (while (and (null xrefs)
- temp)
+ (while (and temp (null xrefs))
(setq xrefs (append xrefs (funcall (pop temp) symbol)))))
(unless xrefs
@@ -1051,114 +1049,99 @@ elisp--xref-find-definitions
(push (elisp--xref-make-xref 'defalias alias-symbol alias-file)
xrefs))))
(when (facep symbol)
- (let ((file (find-lisp-object-file-name symbol 'defface)))
- (when file
- (push (elisp--xref-make-xref 'defface symbol file) xrefs))))
+ (when-let ((file (find-lisp-object-file-name symbol 'defface)))
+ (push (elisp--xref-make-xref 'defface symbol file) xrefs)))
(when (fboundp symbol)
(let ((file (find-lisp-object-file-name symbol (symbol-function
symbol)))
generic doc)
- (when file
- (cond
- ((eq file 'C-source)
- ;; First call to find-lisp-object-file-name for an object
- ;; defined in C; the doc strings from the C source have
- ;; not been loaded yet. Second call will return "src/*.c"
- ;; in file; handled by t case below.
- (push (elisp--xref-make-xref nil symbol (help-C-file-name
(symbol-function symbol) 'subr)) xrefs))
-
- ((and (setq doc (documentation symbol t))
- ;; This doc string is defined in cl-macs.el cl-defstruct
- (string-match "Constructor for objects of type `\\(.*\\)'"
doc))
- ;; `symbol' is a name for the default constructor created by
- ;; cl-defstruct, so return the location of the cl-defstruct.
- (let* ((type-name (match-string 1 doc))
- (type-symbol (intern type-name))
- (file (find-lisp-object-file-name type-symbol
'define-type))
- (summary (format elisp--xref-format-extra
- 'cl-defstruct
- (concat "(" type-name)
- (concat "(:constructor " (symbol-name
symbol) "))"))))
- (push (elisp--xref-make-xref 'define-type type-symbol file
summary) xrefs)
- ))
-
- ((setq generic (cl--generic symbol))
- ;; FIXME: move this to elisp-xref-find-def-functions, in
cl-generic.el
- ;; XXX: How are we going to support using newer xref
- ;; with older versions of Emacs, though?
-
- ;; A generic function. If there is a default method, it
- ;; will appear in the method table, with no
- ;; specializers.
- ;;
- ;; If the default method is declared by the cl-defgeneric
- ;; declaration, it will have the same location as the
- ;; cl-defgeneric, so we want to exclude it from the
- ;; result. In this case, it will have a null doc
- ;; string. User declarations of default methods may also
- ;; have null doc strings, but we hope that is
- ;; rare. Perhaps this heuristic will discourage that.
- (dolist (method (cl--generic-method-table generic))
- (let* ((info (cl--generic-method-info method));; qual-string
combined-args doconly
- (specializers (cl--generic-method-specializers method))
- (non-default nil)
- (met-name (cl--generic-load-hist-format
- symbol
- (cl--generic-method-qualifiers method)
- specializers))
- (file (find-lisp-object-file-name met-name
'cl-defmethod)))
- (dolist (item specializers)
- ;; Default method has all t in specializers.
- (setq non-default (or non-default (not (equal t item)))))
-
- (when (and file
- (or non-default
- (nth 2 info))) ;; assuming only co-located
default has null doc string
- (if specializers
- (let ((summary (format elisp--xref-format-extra
'cl-defmethod symbol (nth 1 info))))
- (push (elisp--xref-make-xref 'cl-defmethod met-name
file summary) xrefs))
-
- (let ((summary (format elisp--xref-format-extra
'cl-defmethod symbol "()")))
- (push (elisp--xref-make-xref 'cl-defmethod met-name
file summary) xrefs))))
- ))
-
- (if (and (setq doc (documentation symbol t))
- ;; This doc string is created somewhere in
- ;; cl--generic-make-function for an implicit
- ;; defgeneric.
- (string-match "\n\n(fn ARG &rest ARGS)" doc))
- ;; This symbol is an implicitly defined defgeneric, so
- ;; don't return it.
- nil
- (push (elisp--xref-make-xref 'cl-defgeneric symbol file)
xrefs))
- )
-
- (t
- (push (elisp--xref-make-xref nil symbol file) xrefs))
- ))))
+ (cond
+ ((not file) nil)
+ ((eq file 'C-source)
+ ;; First call to find-lisp-object-file-name for an object
+ ;; defined in C; the doc strings from the C source have
+ ;; not been loaded yet. Second call will return "src/*.c"
+ ;; in file; handled by t case below.
+ (push (elisp--xref-make-xref
+ nil symbol (help-C-file-name (symbol-function symbol)
'subr))
+ xrefs))
+
+ ((and (setq doc (documentation symbol t))
+ ;; This doc string is defined in cl-macs.el cl-defstruct
+ (string-match "Constructor for objects of type `\\(.*\\)'"
doc))
+ ;; SYMBOL is a name for the default constructor created by
+ ;; cl-defstruct, so return the location of the cl-defstruct.
+ (let* ((type-name (match-string 1 doc))
+ (type-symbol (intern type-name))
+ (file (find-lisp-object-file-name type-symbol 'define-type))
+ (summary (format elisp--xref-format-extra
+ 'cl-defstruct
+ (concat "(" type-name)
+ (concat "(:constructor " (symbol-name
symbol) "))"))))
+ (push (elisp--xref-make-xref 'define-type type-symbol file
summary) xrefs)))
+
+ ((setq generic (cl--generic symbol))
+ ;; FIXME: move this to elisp-xref-find-def-functions, in
cl-generic.el
+ ;; XXX: How are we going to support using newer xref
+ ;; with older versions of Emacs, though?
+
+ ;; A generic function. If there is a default method, it
+ ;; will appear in the method table, with no
+ ;; specializers.
+ ;;
+ ;; If the default method is declared by the cl-defgeneric
+ ;; declaration, it will have the same location as the
+ ;; cl-defgeneric, so we want to exclude it from the
+ ;; result. In this case, it will have a null doc
+ ;; string. User declarations of default methods may also
+ ;; have null doc strings, but we hope that is
+ ;; rare. Perhaps this heuristic will discourage that.
+ (dolist (method (cl--generic-method-table generic))
+ (let* ((info (cl--generic-method-info method));; qual-string
combined-args doconly
+ (specializers (cl--generic-method-specializers method))
+ (non-default nil)
+ (met-name (cl--generic-load-hist-format
+ symbol
+ (cl--generic-method-qualifiers method)
+ specializers))
+ (file (find-lisp-object-file-name met-name
'cl-defmethod)))
+ (dolist (item specializers)
+ ;; Default method has all t in specializers.
+ (setq non-default (or non-default (not (equal t item)))))
+
+ (when (and file
+ ;; only co-located default has null doc string
+ (or non-default (nth 2 info)))
+ (if specializers
+ (let ((summary (format elisp--xref-format-extra
'cl-defmethod symbol (nth 1 info))))
+ (push (elisp--xref-make-xref 'cl-defmethod met-name
file summary) xrefs))
+
+ (let ((summary (format elisp--xref-format-extra
'cl-defmethod symbol "()")))
+ (push (elisp--xref-make-xref 'cl-defmethod met-name file
summary) xrefs))))))
+
+ (unless (and (setq doc (documentation symbol t))
+ ;; Fails when cl--generic-get-dispatcher changed.
+ (string-match-p "\n\n(fn \\(ARG \\)?&rest
ARGS[0-9]*)" doc))
+ ;; symbol is explicit defgeneric
+ (push (elisp--xref-make-xref 'cl-defgeneric symbol file) xrefs)))
+
+ (t
+ (push (elisp--xref-make-xref nil symbol file) xrefs)))))
(when (boundp symbol)
- ;; A variable
- (let ((file (find-lisp-object-file-name symbol 'defvar)))
- (when file
- (cond
- ((eq file 'C-source)
- ;; The doc strings from the C source have not been loaded
- ;; yet; help-C-file-name does that. Second call will
- ;; return "src/*.c" in file; handled below.
- (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name
symbol 'var)) xrefs))
-
- (t
- (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
-
- ))))
+ (when-let ((file (find-lisp-object-file-name symbol 'defvar)))
+ (if (eq file 'C-source)
+ ;; The doc strings from the C source have not been loaded
+ ;; yet; help-C-file-name does that. Second call will
+ ;; return "src/*.c" in file; handled below.
+ (push (elisp--xref-make-xref 'defvar symbol
+ (help-C-file-name symbol 'var))
xrefs)
+ (push (elisp--xref-make-xref 'defvar symbol file) xrefs))))
(when (featurep symbol)
- (let ((file (ignore-errors
- (find-library-name (symbol-name symbol)))))
- (when file
- (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
- );; 'unless xrefs'
+ (when-let ((file (ignore-errors
+ (find-library-name (symbol-name symbol)))))
+ (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
xrefs))
@@ -1193,7 +1176,8 @@ xref-backend-identifier-completion-table
(cl-defmethod xref-location-marker ((l xref-elisp-location))
(pcase-let (((cl-struct xref-elisp-location symbol type file) l))
- (let ((buffer-point (find-function-search-for-symbol symbol type file)))
+ (let* ((prefer-file (xref-preferred-source file))
+ (buffer-point (find-function-search-for-symbol symbol type
prefer-file)))
(with-current-buffer (car buffer-point)
(save-excursion
(save-restriction
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 4dc4762176a..86c2497e9fb 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -227,7 +227,7 @@ project-root
(cl-defmethod project-root (project
&context (project--within-roots-fallback
(eql nil)))
- (car (project-roots project)))
+ (cl-call-next-method project))
(cl-defgeneric project-roots (project)
"Return the list containing the current project root.
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 683589d71c6..95714d0488b 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -427,8 +427,36 @@ xref-auto-jump-to-first-xref
:version "28.1"
:package-version '(xref . "1.2.0"))
+(defcustom xref-prefer-source-directory nil
+ "If non-nil, jump to the file in `source-directory' that
+corresponds to the target."
+ :type 'boolean
+ :version "29.1")
+
(make-obsolete-variable 'xref--marker-ring 'xref--history "29.1")
+(defalias 'xref-preferred-message
+ (let (messaged-p)
+ (lambda (file)
+ "Heads-up to user that xref result may not reflect loaded definition."
+ (unless messaged-p
+ (setq messaged-p t)
+ (message "Showing result from %s" file)))))
+
+(defsubst xref-preferred-source (file)
+ (if-let ((preferred-p xref-prefer-source-directory)
+ (prefix (file-name-as-directory installed-directory))
+ ;; :end2 says PREFIX matches beginning of LIBRARY
+ (installed-p (cl-search prefix file
+ :end2 (length prefix)))
+ (preferred (expand-file-name
+ (cl-subseq file (length prefix))
+ source-directory))
+ (readable-p (file-readable-p preferred)))
+ (prog1 preferred
+ (funcall (symbol-function 'xref-preferred-message) preferred))
+ file))
+
(defun xref-set-marker-ring-length (_var _val)
(declare (obsolete nil "29.1"))
nil)
@@ -1193,21 +1221,15 @@ xref--auto-jump-first
(defun xref-show-definitions-buffer (fetcher alist)
"Show the definitions list in a regular window.
-
When only one definition found, jump to it right away instead."
- (let ((xrefs (funcall fetcher))
- buf)
- (cond
- ((not (cdr xrefs))
- (xref-pop-to-location (car xrefs)
- (assoc-default 'display-action alist)))
- (t
- (setq buf
- (xref--show-xref-buffer fetcher
- (cons (cons 'fetched-xrefs xrefs)
- alist)))
- (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
- buf))))
+ (when-let ((xrefs (funcall fetcher)))
+ (if (= 1 (length xrefs))
+ (xref-pop-to-location (car xrefs)
+ (assoc-default 'display-action alist))
+ (let ((buf (xref--show-xref-buffer
+ fetcher (cons (cons 'fetched-xrefs xrefs) alist))))
+ (prog1 buf
+ (xref--auto-jump-first buf (assoc-default 'auto-jump alist)))))))
(define-obsolete-function-alias
'xref--show-defs-buffer #'xref-show-definitions-buffer "28.1")
@@ -1459,10 +1481,8 @@ xref--create-fetcher
(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)))))
+ (or (funcall method backend arg)
+ (xref--not-found-error kind input))))))
(defun xref--not-found-error (kind input)
(user-error "No %s found for: %s" (symbol-name kind) input))
diff --git a/src/emacs.c b/src/emacs.c
index 43b9901e081..f83923bc6af 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -3503,12 +3503,13 @@ syms_of_emacs (void)
The value is nil if that directory's name is not known. */);
DEFVAR_LISP ("installation-directory", Vinstallation_directory,
- doc: /* A directory within which to look for the `lib-src' and
`etc' directories.
-In an installed Emacs, this is normally nil. It is non-nil if
-both `lib-src' (on MS-DOS, `info') and `etc' directories are found
-within the variable `invocation-directory' or its parent. For example,
-this is the case when running an uninstalled Emacs executable from its
-build directory. */);
+ doc: /* Should have been named build-directory.
+Counter-intuitively, this variable is nil when Emacs is invoked from
+its `make install` executable. It normally takes on the value of
+`source-directory' when Emacs is invoked from its within-repo `make`
+executable. Its primary use is locating the lib-src and etc
+subdirectories of the build. Not to be confused with
+`installed-directory'. */);
Vinstallation_directory = Qnil;
DEFVAR_LISP ("system-messages-locale", Vsystem_messages_locale,
diff --git a/src/lread.c b/src/lread.c
index 4b7d38a8e6c..e953c1dc7be 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -5108,136 +5108,73 @@ load_path_check (Lisp_Object lpath)
}
}
-/* Return the default load-path, to be used if EMACSLOADPATH is unset.
- This does not include the standard site-lisp directories
- under the installation prefix (i.e., PATH_SITELOADSEARCH),
- but it does (unless no_site_lisp is set) include site-lisp
- directories in the source/build directories if those exist and we
- are running uninstalled.
-
- Uses the following logic:
- If !will_dump: Use PATH_LOADSEARCH.
- The remainder is what happens when dumping is about to happen:
- If dumping, just use PATH_DUMPLOADSEARCH.
- Otherwise use PATH_LOADSEARCH.
-
- If !initialized, then just return PATH_DUMPLOADSEARCH.
- If initialized:
- If Vinstallation_directory is not nil (ie, running uninstalled):
- If installation-dir/lisp exists and not already a member,
- we must be running uninstalled. Reset the load-path
- to just installation-dir/lisp. (The default PATH_LOADSEARCH
- refers to the eventual installation directories. Since we
- are not yet installed, we should not use them, even if they exist.)
- If installation-dir/lisp does not exist, just add
- PATH_DUMPLOADSEARCH at the end instead.
- Add installation-dir/site-lisp (if !no_site_lisp, and exists
- and not already a member) at the front.
- If installation-dir != source-dir (ie running an uninstalled,
- out-of-tree build) AND install-dir/src/Makefile exists BUT
- install-dir/src/Makefile.in does NOT exist (this is a sanity
- check), then repeat the above steps for source-dir/lisp, site-lisp. */
+/* Dig toplevel LOAD-PATH out of epaths.h. */
static Lisp_Object
load_path_default (void)
{
if (will_dump_p ())
- /* PATH_DUMPLOADSEARCH is the lisp dir in the source directory.
- We used to add ../lisp (ie the lisp dir in the build
- directory) at the front here, but that should not be
- necessary, since in out of tree builds lisp/ is empty, save
- for Makefile. */
+ /* PATH_DUMPLOADSEARCH is the lisp dir in the source directory. */
return decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
- Lisp_Object lpath = Qnil;
-
- lpath = decode_env_path (0, PATH_LOADSEARCH, 0);
+ Lisp_Object lpath = decode_env_path (0, PATH_LOADSEARCH, 0);
+ /* Counter-intuitively Vinstallation_directory is nil for
+ invocations of the `make install` executable, and is
+ Vsource_directory for invocations of the within-repo `make`
+ executable.
+ */
if (!NILP (Vinstallation_directory))
{
- Lisp_Object tem, tem1;
-
- /* Add to the path the lisp subdir of the installation
- dir, if it is accessible. Note: in out-of-tree builds,
- this directory is empty save for Makefile. */
- tem = Fexpand_file_name (build_string ("lisp"),
- Vinstallation_directory);
- tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
- {
- if (NILP (Fmember (tem, lpath)))
- {
- /* We are running uninstalled. The default load-path
- points to the eventual installed lisp directories.
- We should not use those now, even if they exist,
- so start over from a clean slate. */
- lpath = list1 (tem);
- }
- }
- else
- /* That dir doesn't exist, so add the build-time
- Lisp dirs instead. */
- {
- Lisp_Object dump_path =
- decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
- lpath = nconc2 (lpath, dump_path);
- }
-
- /* Add site-lisp under the installation dir, if it exists. */
- if (!no_site_lisp)
+ Lisp_Object tem = Fexpand_file_name (build_string ("lisp"),
+ Vinstallation_directory),
+ tem1 = Ffile_accessible_directory_p (tem);
+
+ if (NILP (tem1))
+ /* Use build-time dirs instead. */
+ lpath = nconc2 (lpath, decode_env_path (0, PATH_DUMPLOADSEARCH, 0));
+ else if (NILP (Fmember (tem, lpath)))
+ /* Override the inchoate LOAD-PATH. */
+ lpath = list1 (tem);
+
+ /* Add the within-repo site-lisp (unusual). */
+ if (! no_site_lisp)
{
tem = Fexpand_file_name (build_string ("site-lisp"),
Vinstallation_directory);
tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
- {
- if (NILP (Fmember (tem, lpath)))
- lpath = Fcons (tem, lpath);
- }
+ if (! NILP (tem1) && (NILP (Fmember (tem, lpath))))
+ lpath = Fcons (tem, lpath);
}
- /* If Emacs was not built in the source directory,
- and it is run from where it was built, add to load-path
- the lisp and site-lisp dirs under that directory. */
-
if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
{
- Lisp_Object tem2;
-
+ /* An out-of-tree build (unusual). */
tem = Fexpand_file_name (build_string ("src/Makefile"),
Vinstallation_directory);
- tem1 = Ffile_exists_p (tem);
+ tem1 = Fexpand_file_name (build_string ("src/Makefile.in"),
+ Vinstallation_directory);
/* Don't be fooled if they moved the entire source tree
AFTER dumping Emacs. If the build directory is indeed
different from the source dir, src/Makefile.in and
src/Makefile will not be found together. */
- tem = Fexpand_file_name (build_string ("src/Makefile.in"),
- Vinstallation_directory);
- tem2 = Ffile_exists_p (tem);
- if (!NILP (tem1) && NILP (tem2))
+ if (! NILP (Ffile_exists_p (tem)) && NILP (Ffile_exists_p (tem1)))
{
tem = Fexpand_file_name (build_string ("lisp"),
Vsource_directory);
-
if (NILP (Fmember (tem, lpath)))
lpath = Fcons (tem, lpath);
-
- if (!no_site_lisp)
+ if (! no_site_lisp)
{
tem = Fexpand_file_name (build_string ("site-lisp"),
Vsource_directory);
- tem1 = Ffile_accessible_directory_p (tem);
- if (!NILP (tem1))
- {
- if (NILP (Fmember (tem, lpath)))
- lpath = Fcons (tem, lpath);
- }
+ if (! NILP (tem) && (NILP (Fmember (tem, lpath))))
+ lpath = Fcons (tem, lpath);
}
}
- } /* Vinstallation_directory != Vsource_directory */
-
- } /* if Vinstallation_directory */
+ }
+ }
return lpath;
}
@@ -5248,7 +5185,7 @@ init_lread (void)
/* First, set Vload_path. */
/* Ignore EMACSLOADPATH when dumping. */
- bool use_loadpath = !will_dump_p ();
+ bool use_loadpath = ! will_dump_p ();
if (use_loadpath && egetenv ("EMACSLOADPATH"))
{
@@ -5268,10 +5205,9 @@ init_lread (void)
load_path_check (default_lpath);
/* Add the site-lisp directories to the front of the default. */
- if (!no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
+ if (! no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
{
- Lisp_Object sitelisp;
- sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
+ Lisp_Object sitelisp = decode_env_path (0, PATH_SITELOADSEARCH,
0);
if (! NILP (sitelisp))
default_lpath = nconc2 (sitelisp, default_lpath);
}
@@ -5286,7 +5222,7 @@ init_lread (void)
Vload_path = CALLN (Fappend, Vload_path,
NILP (elem) ? default_lpath : list1 (elem));
}
- } /* Fmemq (Qnil, Vload_path) */
+ }
}
else
{
@@ -5299,11 +5235,11 @@ init_lread (void)
load_path_check (Vload_path);
/* Add the site-lisp directories at the front. */
- if (!will_dump_p () && !no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
+ if (! will_dump_p () && !no_site_lisp && PATH_SITELOADSEARCH[0] != '\0')
{
- Lisp_Object sitelisp;
- sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
- if (! NILP (sitelisp)) Vload_path = nconc2 (sitelisp, Vload_path);
+ Lisp_Object sitelisp = decode_env_path (0, PATH_SITELOADSEARCH, 0);
+ if (! NILP (sitelisp))
+ Vload_path = nconc2 (sitelisp, Vload_path);
}
}
@@ -5544,6 +5480,16 @@ syms_of_lread (void)
= Fexpand_file_name (build_string ("../"),
Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH, 0)));
+ DEFVAR_LISP ("installed-directory", Vinstalled_directory,
+ doc: /* Install path of built-in lisp libraries.
+This directory contains the `etc`, `lisp`, and `site-lisp`
+installables, and is determined at configure time in the epaths-force
+make target. Not to be confused with the legacy
+`installation-directory' nor `invocation-directory'. */);
+ Vinstalled_directory
+ = Fexpand_file_name (build_string ("../"),
+ Fcar (decode_env_path (0, PATH_LOADSEARCH, 0)));
+
DEFVAR_LISP ("preloaded-file-list", Vpreloaded_file_list,
doc: /* List of files that were preloaded (when dumping Emacs).
*/);
Vpreloaded_file_list = Qnil;
diff --git a/test/lisp/progmodes/elisp-mode-tests.el
b/test/lisp/progmodes/elisp-mode-tests.el
index 8e4dfa8bb83..cf30765df23 100644
--- a/test/lisp/progmodes/elisp-mode-tests.el
+++ b/test/lisp/progmodes/elisp-mode-tests.el
@@ -1116,5 +1116,47 @@ test-indentation
(emacs-lisp-mode)
(indent-region (point-min) (point-max)))))
+(ert-deftest xref-tests-prefer-source ()
+ "Jump to the file in `source-directory' that corresponds to the target."
+ (let* ((xref-show-definitions-function 'xref-show-definitions-buffer)
+ (xref-prefer-source-directory t)
+ (what "xref-backend-definitions")
+ (ert-directory (file-name-directory
+ (ert-resource-file "simple-shorthand-test.el")))
+ (installed-path (find-lisp-object-file-name (intern what) 'defun))
+ (preferred-path (string-replace (file-name-as-directory
+ source-directory)
+ (file-name-as-directory
+ ert-directory)
+ installed-path))
+ (installed-directory source-directory)
+ (source-directory ert-directory)
+ (buf (with-temp-buffer
+ (emacs-lisp-mode)
+ (xref-find-definitions what))))
+ (unwind-protect
+ (with-current-buffer buf
+ (mkdir (file-name-directory preferred-path) t)
+ (copy-file installed-path preferred-path t)
+ (save-excursion
+ (should (re-search-forward
+ (regexp-quote (format "cl-defmethod %s" what))
+ nil t)))
+ (should (re-search-forward
+ (regexp-quote (regexp-quote (format "cl-defgeneric %s"
what)))
+ nil t))
+ (call-interactively #'xref-goto-xref)
+ (should (equal (buffer-file-name) preferred-path)))
+ (let (kill-buffer-query-functions)
+ (delete-directory (expand-file-name
+ (reverse (file-name-nondirectory
+ (reverse (string-replace ert-directory
+ ""
preferred-path))))
+ ert-directory) t)
+ (when (buffer-live-p (get-buffer preferred-path))
+ (kill-buffer (get-buffer preferred-path)))
+ (when (buffer-live-p buf)
+ (kill-buffer buf))))))
+
(provide 'elisp-mode-tests)
;;; elisp-mode-tests.el ends here
diff --git a/test/lisp/progmodes/xref-tests.el
b/test/lisp/progmodes/xref-tests.el
index f7af5055c78..b2222d95521 100644
--- a/test/lisp/progmodes/xref-tests.el
+++ b/test/lisp/progmodes/xref-tests.el
@@ -44,7 +44,7 @@ xref-tests--locations-in-data-dir
:key #'xref-location-group)))
(ert-deftest xref-matches-in-directory-finds-none-for-some-regexp ()
- (should (null (xref-tests--matches-in-data-dir "zzz"))))
+ (should-not (xref-tests--matches-in-data-dir "zzz")))
(ert-deftest xref-matches-in-directory-finds-some-for-bar ()
(let ((locs (xref-tests--locations-in-data-dir "bar")))
@@ -99,7 +99,7 @@ xref--buf-pairs-iterator-groups-markers-by-buffers-1
(let* ((xrefs (xref-tests--matches-in-data-dir "foo"))
(iter (xref--buf-pairs-iterator xrefs))
(cons (funcall iter :next)))
- (should (null (funcall iter :next)))
+ (should-not (funcall iter :next))
(should (string-match "file1\\.txt\\'" (buffer-file-name (car cons))))
(should (= 2 (length (cdr cons))))))
@@ -108,7 +108,7 @@ xref--buf-pairs-iterator-groups-markers-by-buffers-2
(iter (xref--buf-pairs-iterator xrefs))
(cons1 (funcall iter :next))
(cons2 (funcall iter :next)))
- (should (null (funcall iter :next)))
+ (should-not (funcall iter :next))
(should-not (equal (car cons1) (car cons2)))
(should (= 1 (length (cdr cons1))))
(should (= 1 (length (cdr cons2))))))
@@ -119,10 +119,10 @@ xref--buf-pairs-iterator-cleans-up-markers
(cons1 (funcall iter :next))
(cons2 (funcall iter :next)))
(funcall iter :cleanup)
- (should (null (marker-position (car (nth 0 (cdr cons1))))))
- (should (null (marker-position (cdr (nth 0 (cdr cons1))))))
- (should (null (marker-position (car (nth 0 (cdr cons2))))))
- (should (null (marker-position (cdr (nth 0 (cdr cons2))))))))
+ (should-not (marker-position (car (nth 0 (cdr cons1)))))
+ (should-not (marker-position (cdr (nth 0 (cdr cons1)))))
+ (should-not (marker-position (car (nth 0 (cdr cons2)))))
+ (should-not (marker-position (cdr (nth 0 (cdr cons2)))))))
(ert-deftest xref--xref-file-name-display-is-abs ()
(let ((xref-file-name-display 'abs))
--
2.35.1
In Commercial Emacs 0.3.1snapshot 4cf5f33 in dev (upstream 29.0.50,
x86_64-pc-linux-gnu) built on dick
Repository revision: 4cf5f33b61635a9f55bcfb345b144d3c12396013
Repository branch: dev
Windowing system distributor 'The X.Org Foundation', version 11.0.12013000
System Description: Ubuntu 20.04.3 LTS
Configured using:
'configure --prefix=/home/dick/.local --with-tree-sitter'
Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
TREE_SITTER LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM
XINPUT2 XPM GTK3 ZLIB
Important settings:
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix
Major mode: Group
Minor modes in effect:
global-git-commit-mode: t
shell-dirtrack-mode: t
gnus-topic-mode: t
gnus-undo-mode: t
projectile-mode: t
flx-ido-mode: t
override-global-mode: t
global-hl-line-mode: t
hl-line-mode: t
winner-mode: t
tooltip-mode: t
show-paren-mode: t
mouse-wheel-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
buffer-read-only: t
column-number-mode: t
line-number-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Load-path shadows:
/home/dick/gomacro-mode/gomacro-mode hides
/home/dick/.emacs.d/elpa/gomacro-mode-20200326.1103/gomacro-mode
/home/dick/org-gcal.el/org-gcal hides
/home/dick/.emacs.d/elpa/org-gcal-0.3/org-gcal
/home/dick/.emacs.d/elpa/chess-2.0.5/_pkg hides
/home/dick/.local/share/emacs/site-lisp/_pkg
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pos hides
/home/dick/.local/share/emacs/site-lisp/chess-pos
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-module hides
/home/dick/.local/share/emacs/site-lisp/chess-module
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ucb hides
/home/dick/.local/share/emacs/site-lisp/chess-ucb
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-scid hides
/home/dick/.local/share/emacs/site-lisp/chess-scid
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-puzzle hides
/home/dick/.local/share/emacs/site-lisp/chess-puzzle
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-irc hides
/home/dick/.local/share/emacs/site-lisp/chess-irc
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-network hides
/home/dick/.local/share/emacs/site-lisp/chess-network
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-autosave hides
/home/dick/.local/share/emacs/site-lisp/chess-autosave
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-engine hides
/home/dick/.local/share/emacs/site-lisp/chess-engine
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-tutorial hides
/home/dick/.local/share/emacs/site-lisp/chess-tutorial
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-german hides
/home/dick/.local/share/emacs/site-lisp/chess-german
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-file hides
/home/dick/.local/share/emacs/site-lisp/chess-file
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-random hides
/home/dick/.local/share/emacs/site-lisp/chess-random
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-stockfish hides
/home/dick/.local/share/emacs/site-lisp/chess-stockfish
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pgn hides
/home/dick/.local/share/emacs/site-lisp/chess-pgn
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-kibitz hides
/home/dick/.local/share/emacs/site-lisp/chess-kibitz
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-eco hides
/home/dick/.local/share/emacs/site-lisp/chess-eco
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-display hides
/home/dick/.local/share/emacs/site-lisp/chess-display
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-var hides
/home/dick/.local/share/emacs/site-lisp/chess-var
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-test hides
/home/dick/.local/share/emacs/site-lisp/chess-test
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ply hides
/home/dick/.local/share/emacs/site-lisp/chess-ply
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-message hides
/home/dick/.local/share/emacs/site-lisp/chess-message
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics1 hides
/home/dick/.local/share/emacs/site-lisp/chess-ics1
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-phalanx hides
/home/dick/.local/share/emacs/site-lisp/chess-phalanx
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-game hides
/home/dick/.local/share/emacs/site-lisp/chess-game
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-log hides
/home/dick/.local/share/emacs/site-lisp/chess-log
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-plain hides
/home/dick/.local/share/emacs/site-lisp/chess-plain
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-perft hides
/home/dick/.local/share/emacs/site-lisp/chess-perft
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-glaurung hides
/home/dick/.local/share/emacs/site-lisp/chess-glaurung
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ai hides
/home/dick/.local/share/emacs/site-lisp/chess-ai
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fruit hides
/home/dick/.local/share/emacs/site-lisp/chess-fruit
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-uci hides
/home/dick/.local/share/emacs/site-lisp/chess-uci
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-epd hides
/home/dick/.local/share/emacs/site-lisp/chess-epd
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-database hides
/home/dick/.local/share/emacs/site-lisp/chess-database
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-link hides
/home/dick/.local/share/emacs/site-lisp/chess-link
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-transport hides
/home/dick/.local/share/emacs/site-lisp/chess-transport
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-none hides
/home/dick/.local/share/emacs/site-lisp/chess-none
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-polyglot hides
/home/dick/.local/share/emacs/site-lisp/chess-polyglot
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-crafty hides
/home/dick/.local/share/emacs/site-lisp/chess-crafty
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-chat hides
/home/dick/.local/share/emacs/site-lisp/chess-chat
/home/dick/.emacs.d/elpa/chess-2.0.5/chess hides
/home/dick/.local/share/emacs/site-lisp/chess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-images hides
/home/dick/.local/share/emacs/site-lisp/chess-images
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-gnuchess hides
/home/dick/.local/share/emacs/site-lisp/chess-gnuchess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fen hides
/home/dick/.local/share/emacs/site-lisp/chess-fen
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics hides
/home/dick/.local/share/emacs/site-lisp/chess-ics
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics2 hides
/home/dick/.local/share/emacs/site-lisp/chess-ics2
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-common hides
/home/dick/.local/share/emacs/site-lisp/chess-common
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-input hides
/home/dick/.local/share/emacs/site-lisp/chess-input
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-announce hides
/home/dick/.local/share/emacs/site-lisp/chess-announce
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-clock hides
/home/dick/.local/share/emacs/site-lisp/chess-clock
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sound hides
/home/dick/.local/share/emacs/site-lisp/chess-sound
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sjeng hides
/home/dick/.local/share/emacs/site-lisp/chess-sjeng
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-algebraic hides
/home/dick/.local/share/emacs/site-lisp/chess-algebraic
/home/dick/.emacs.d/elpa/transient-0.3.7snapshot/transient hides
/home/dick/.local/share/emacs/0.3.1/lisp/transient
Features:
(shadow bbdb-message footnote emacsbug flow-fill shortdoc
emms-source-file locate loadhist markdown-mode edit-indirect
magit-extras face-remap magit-patch-changelog magit-patch
magit-submodule magit-obsolete magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log which-func imenu
magit-diff git-commit log-edit pcvs-util add-log magit-core magit-margin
magit-transient magit-process with-editor server magit-mode transient
smerge-mode diff pulse find-func misearch multi-isearch vc-git diff-mode
vc vc-dispatcher bug-reference cc-mode cc-fonts cc-guess cc-menus
cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs tramp-archive
tramp-gvfs tramp-cache zeroconf gnus-html url-queue help-fns radix-tree
sort smiley shr-color qp mm-archive gnus-async gnus-ml gravatar dns
mail-extr textsec uni-scripts idna-mapping ucs-normalize uni-confusable
textsec-check gnus-notifications gnus-fun notifications gnus-kill
gnus-dup disp-table utf-7 blamer a tramp tramp-loaddefs trampver
tramp-integration cus-start files-x tramp-compat shell pcomplete ls-lisp
url-cache benchmark nnrss nnfolder nndiscourse rbenv nnhackernews
nntwitter nntwitter-api bbdb-gnus gnus-demon nntp nnmairix nnml nnreddit
gnus-topic url-http url-auth url-gw network-stream nsm request
virtualenvwrapper gud s json-rpc python gnus-score score-mode gnus-bcklg
gnus-srvr gnus-cite anaphora bbdb-mua bbdb-com bbdb bbdb-site timezone
gnus-delay gnus-draft gnus-cache gnus-agent gnus-msg gnus-art mm-uu
mml2015 mm-view mml-smime smime gnutls dig gnus-sum shr pixel-fill
kinsoku url-file url-dired svg dom nndraft nnmh gnus-group mm-url
gnus-undo use-package use-package-delight use-package-diminish
gnus-start gnus-dbus dbus xml gnus-cloud nnimap nnmail mail-source utf7
netrc nnoo parse-time iso8601 gnus-spec gnus-int gnus-range message
sendmail yank-media rmc puny dired-x dired dired-loaddefs rfc822 mml
mml-sec epa epg rfc6068 epg-config mm-decode mm-bodies mm-encode
mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils
mailheader gnus-win paredit-ext paredit subed subed-vtt subed-srt
subed-common subed-mpv subed-debug subed-config inf-ruby ruby-mode smie
company pcase haskell-interactive-mode haskell-presentation-mode
haskell-process haskell-session haskell-compile haskell-mode
haskell-cabal haskell-utils haskell-font-lock haskell-indentation
haskell-string haskell-sort-imports haskell-lexeme haskell-align-imports
haskell-complete-module haskell-ghc-support noutline outline
flymake-proc flymake warnings etags fileloop generator dabbrev
haskell-customize hydra lv use-package-ensure solarized-theme
solarized-definitions projectile lisp-mnt ibuf-ext ibuffer
ibuffer-loaddefs thingatpt magit-autorevert autorevert filenotify
magit-git magit-base magit-section format-spec crm dash rx compat-27
compat-26 compat grep compile comint ansi-color gnus nnheader range
mail-utils mm-util mail-prsvr gnus-util text-property-search time-date
flx-ido flx google-translate-default-ui google-translate-core-ui
facemenu color ido google-translate-core google-translate-tk
google-translate-backend use-package-bind-key bind-key auto-complete
easy-mmode advice edmacro kmacro popup cus-edit pp cus-load wid-edit
emms-player-mplayer emms-player-simple emms emms-compat cl-extra
help-mode xref project use-package-core derived hl-line winner ring
finder-inf json-reformat-autoloads json-snatcher-autoloads
sml-mode-autoloads tornado-template-mode-autoloads info package
browse-url url url-proxy url-privacy url-expand url-methods url-history
url-cookie url-domsuf url-util mailcap url-handlers url-parse
auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs
password-cache json map url-vars seq gv subr-x byte-opt bytecomp
byte-compile cconv cldefs cl-loaddefs cl-lib iso-transl tooltip eldoc
paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode
mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image
regexp-opt fringe tree-sitter tabulated-list replace newcomment
text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow
isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
faces cus-face macroexp files window text-properties overlay sha1 md5
base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo
move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process
emacs)
Memory information:
((conses 16 1225093 133296)
(symbols 48 47046 1)
(strings 32 212452 33657)
(string-bytes 1 6343256)
(vectors 16 136395)
(vector-slots 8 3462861 170930)
(floats 8 1238 1244)
(intervals 56 67754 1262)
(buffers 1000 45))
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.,
dick . r . chiang <=
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Po Lu, 2022/06/03
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Lars Ingebrigtsen, 2022/06/03
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Lars Ingebrigtsen, 2022/06/05
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Eli Zaretskii, 2022/06/05
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Lars Ingebrigtsen, 2022/06/05
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Eli Zaretskii, 2022/06/05
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Lars Ingebrigtsen, 2022/06/06
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Eli Zaretskii, 2022/06/06
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Lars Ingebrigtsen, 2022/06/07
- bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there., Eli Zaretskii, 2022/06/07