unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
@ 2022-06-03  6:27 dick.r.chiang
  2022-06-03 10:45 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: dick.r.chiang @ 2022-06-03  6:27 UTC (permalink / raw)
  To: 55778

[-- Attachment #1: Type: text/plain, Size: 329 bytes --]


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))"

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-xref-prefer-source-directory.patch --]
[-- Type: text/x-diff, Size: 48203 bytes --]

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


[-- Attachment #3: Type: text/plain, Size: 12777 bytes --]




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))

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
@ 2022-06-03 10:45 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-06-03 10:52 ` Lars Ingebrigtsen
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 18+ messages in thread
From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2022-06-03 10:45 UTC (permalink / raw)
  To: dick.r.chiang; +Cc: 55778

Thanks, but this does not look acceptable, if not for anything else,
then for the simple fact that so much text (comments and doc strings)
was changed for the worse.

dick.r.chiang@gmail.com writes:

> * 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.

"English."  "Style." and "Was crashing on this missing entry in
find-function-regexp-alist" do not describe what changed, and why it was
changed.

> +LIBRARY can be an absolute or relative path."

Say "file name" instead of "path".

> -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."

Whitespace and formatting change.

> +(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")
> +

Did implementing this feature really require so many changes, in
project.el, elisp-mode.el, help-fns.el, help-mode.el, emacs.c, and
lread.c?

>    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;

Useless doc change.

> -/* 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.  */

Comment deleted and replaced with something much less meaningful.

>  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;
>  }

What you did was change the behavior of code that has worked well enough
for decades.  Is that really needed to make finding a definition prefer
the source directory to the compressed Lisp code?  Not to mention that
you can avoid jumping into the compressed source by specifying
--without-compress-install at configure time.

> +  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);
>          }
>      }

Whitespace changes, comment aimlessly deleted.

> +  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)));

Why is yet another one of these variables needed?  And was this change
tested on every possible installation type, such as an NS self-contained
bundle or MS-DOS?





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
  2022-06-03 10:45 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2022-06-03 10:52 ` Lars Ingebrigtsen
  2022-06-05 13:49   ` Lars Ingebrigtsen
  2022-06-03 11:41 ` Eli Zaretskii
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-03 10:52 UTC (permalink / raw)
  To: dick.r.chiang; +Cc: 55778

dick.r.chiang@gmail.com writes:

> 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.

Your patch is (as usual) full of totally irrelevant things, so it's not
applicable.

The idea of the feature is good, though, but can probably be implemented
as a simple file name regexp substitution in the xref machinery that
says "if we were going to jump to
/usr/share/emacs/27.1/lisp/gnus/gnus.el.gz, then jump to
/usr/src/emacs/27.1/lisp/gnus/gnus.el" instead.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
  2022-06-03 10:45 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2022-06-03 10:52 ` Lars Ingebrigtsen
@ 2022-06-03 11:41 ` Eli Zaretskii
  2022-06-04 16:52   ` dick
  2022-06-03 13:24 ` Dmitry Gutov
  2022-06-14 12:42 ` Lars Ingebrigtsen
  4 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-03 11:41 UTC (permalink / raw)
  To: dick.r.chiang; +Cc: 55778

> From: dick.r.chiang@gmail.com
> Date: Fri, 03 Jun 2022 02:27:59 -0400
> 
> * 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.

Please separate the real changes from refactoring of existing code and
from documentation changes that are unrelated to code changes.  They
each should be reviewed and judged separately and with different
criteria in mind.

> @@ -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))))

This seems to be some effort to use 'when' and 'unless' instead of
'if'?  If so, please don't: I see no reason for such changes.

> +(defcustom xref-prefer-source-directory nil
> +  "If non-nil, jump to the file in `source-directory' that
> +corresponds to the target."

"if that exists", right?  And what does "jump" mean? who is it that
will "jump"?

Also, the first line of a doc string should be a complete sentence,
for the benefit of 'apropos' commands.

>    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'.  */);

Please keep your controversial opinions out of the Emacs sources, and
definitely out of the doc strings.  Your intuition is wrong here.

> -/* 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.  */

Fat chance we will ever accept such "changes".  These details might
bore you, but they are there for a reason: so that people who need to
make changes in this tricky code could be aware of all the pitfalls
that others in their good time fell into.

>  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);

And this.

> -  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.
> +  */

And this.  (The comment style is also not our style.)

> +  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)));

This won't work reliably, because it assumes PATH_LOADSEARCH is
determined at build time.  That is only true for some builds, but not
for others.  It also disregards EMACSLOADPATH.  To be reliable, the
variable's value needs to be recalculated at startup, each time anew.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
                   ` (2 preceding siblings ...)
  2022-06-03 11:41 ` Eli Zaretskii
@ 2022-06-03 13:24 ` Dmitry Gutov
  2022-06-03 13:41   ` Eli Zaretskii
  2022-06-14 12:42 ` Lars Ingebrigtsen
  4 siblings, 1 reply; 18+ messages in thread
From: Dmitry Gutov @ 2022-06-03 13:24 UTC (permalink / raw)
  To: dick.r.chiang, 55778

On 03.06.2022 09:27, dick.r.chiang@gmail.com wrote:
> emacs -Q --eval "(custom-set-variables '(xref-prefer-source-directory t))"

Unrelated changes aside, this new option seems to be designed for and 
only affect the elisp backend, right?

Then it should reside in elisp-mode.el, shouldn't it?

The way xref-preferred-source breaks the abstraction doesn't look great 
either. Maybe that logic could live in help-fns.el or find-func.el.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03 13:24 ` Dmitry Gutov
@ 2022-06-03 13:41   ` Eli Zaretskii
  0 siblings, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-03 13:41 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: 55778, dick.r.chiang

> Date: Fri, 3 Jun 2022 16:24:26 +0300
> From: Dmitry Gutov <dgutov@yandex.ru>
> 
> On 03.06.2022 09:27, dick.r.chiang@gmail.com wrote:
> > emacs -Q --eval "(custom-set-variables '(xref-prefer-source-directory t))"
> 
> Unrelated changes aside, this new option seems to be designed for and 
> only affect the elisp backend, right?
> 
> Then it should reside in elisp-mode.el, shouldn't it?

Yes, I think so.  I don't see how it could be related to anything else
but the way Emacs installs the *.el files.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03 11:41 ` Eli Zaretskii
@ 2022-06-04 16:52   ` dick
  2022-06-04 17:29     ` Eli Zaretskii
  0 siblings, 1 reply; 18+ messages in thread
From: dick @ 2022-06-04 16:52 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 55778

EZ> to make changes in this tricky code could be aware of all the

If by "tricky" you mean "written by a recent graduate", you may have a point.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-04 16:52   ` dick
@ 2022-06-04 17:29     ` Eli Zaretskii
  0 siblings, 0 replies; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-04 17:29 UTC (permalink / raw)
  To: dick; +Cc: 55778

> From: dick <dick.r.chiang@gmail.com>
> Cc: 55778@debbugs.gnu.org
> Date: Sat, 04 Jun 2022 12:52:12 -0400
> 
> EZ> to make changes in this tricky code could be aware of all the
> 
> If by "tricky" you mean "written by a recent graduate", you may have a point.

I think you simply don't understand what that code does and why.  Your
mistake in initializing the installed-directory variable is a clear
evidence that you have a lot to learn about the various aspects of the
Emacs startup, before your conclusions about the code which supports
that could be taken seriously.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03 10:52 ` Lars Ingebrigtsen
@ 2022-06-05 13:49   ` Lars Ingebrigtsen
  2022-06-05 13:57     ` Eli Zaretskii
  0 siblings, 1 reply; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-05 13:49 UTC (permalink / raw)
  To: dick.r.chiang; +Cc: 55778, Stefan Monnier

Lars Ingebrigtsen <larsi@gnus.org> writes:

> The idea of the feature is good, though, but can probably be implemented
> as a simple file name regexp substitution in the xref machinery that
> says "if we were going to jump to
> /usr/share/emacs/27.1/lisp/gnus/gnus.el.gz, then jump to
> /usr/src/emacs/27.1/lisp/gnus/gnus.el" instead.

This reminded me of something Stefan M said the other day(ish) -- it'd
be nice to be able to jump to "another file" that's somehow tied to the
current file.  For instance, jump to files-tests.el from files.el, or to
emacs-28/lisp/files.el when you're in trunk/lisp/files.el, or jump to
foo.h when you're in foo.c.

And this is basically the same -- if you're in
/usr/share/emacs/27.1/lisp/abbrev.el.gz, then you want to jump to the
development sources.

So I've now added a new command `find-sibling-file' to Emacs 29.  This
setting does what the latter:

(setq find-sibling-rules
      '(("\\(/usr/share/emacs.*/\\(lisp/.*.el\\).gz\\)"
	 "/home/larsi/src/emacs/trunk/\\2\\'")))

Something like this does the Emacs development sibling dance:

(setq find-sibling-rules
      '(("src/emacs/trunk/[^/]+/\\(.*\\)\\'" "src/emacs/emacs-28/.*/\\1\\'")
	("emacs/trunk/\\(.*\\)\\.\\(c\\|el\\)\\'"
	 "emacs/trunk/test/\\1-tests.el\\'")))

And this is foo.c -> foo.h:

(setq find-sibling-rules
      '(("\\([^/]+\\)\\.c\\'" "\\1.h")))

I'm not 100% sure about the semantics of the match/expansions here --
there may well be use cases I haven't considered, so this should
probably be tweaked a bit.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-05 13:49   ` Lars Ingebrigtsen
@ 2022-06-05 13:57     ` Eli Zaretskii
  2022-06-05 14:02       ` Lars Ingebrigtsen
  0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-05 13:57 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 55778, dick.r.chiang, monnier

> Cc: 55778@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
> From: Lars Ingebrigtsen <larsi@gnus.org>
> Date: Sun, 05 Jun 2022 15:49:04 +0200
> 
> So I've now added a new command `find-sibling-file' to Emacs 29.  This
> setting does what the latter:
> 
> (setq find-sibling-rules
>       '(("\\(/usr/share/emacs.*/\\(lisp/.*.el\\).gz\\)"
> 	 "/home/larsi/src/emacs/trunk/\\2\\'")))

We already have ff-find-related-file, why not expand that facility
instead?  the new command sounds like a subset of what
ff-find-related-file can do.






^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-05 13:57     ` Eli Zaretskii
@ 2022-06-05 14:02       ` Lars Ingebrigtsen
  2022-06-05 14:15         ` Eli Zaretskii
  0 siblings, 1 reply; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-05 14:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 55778, dick.r.chiang, monnier

Eli Zaretskii <eliz@gnu.org> writes:

> We already have ff-find-related-file, why not expand that facility
> instead?  the new command sounds like a subset of what
> ff-find-related-file can do.

I thought that one was quite centred on knowing a lot of magical rules
for C files, so it doesn't really seem general enough...

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-05 14:02       ` Lars Ingebrigtsen
@ 2022-06-05 14:15         ` Eli Zaretskii
  2022-06-06 12:25           ` Lars Ingebrigtsen
  0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-05 14:15 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 55778, dick.r.chiang, monnier

> From: Lars Ingebrigtsen <larsi@gnus.org>
> Cc: dick.r.chiang@gmail.com,  55778@debbugs.gnu.org,  monnier@iro.umontreal.ca
> Date: Sun, 05 Jun 2022 16:02:40 +0200
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > We already have ff-find-related-file, why not expand that facility
> > instead?  the new command sounds like a subset of what
> > ff-find-related-file can do.
> 
> I thought that one was quite centred on knowing a lot of magical rules
> for C files, so it doesn't really seem general enough...

That it supports C files doesn't mean it cannot support others: the
feature is quite general, not tied to C mode in any way.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-05 14:15         ` Eli Zaretskii
@ 2022-06-06 12:25           ` Lars Ingebrigtsen
  2022-06-06 12:51             ` Eli Zaretskii
  0 siblings, 1 reply; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-06 12:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 55778, dick.r.chiang, monnier

Eli Zaretskii <eliz@gnu.org> writes:

> That it supports C files doesn't mean it cannot support others: the
> feature is quite general, not tied to C mode in any way.

It just seems like a really awkward fit -- the features aren't
dissimilar in concept, but they're very different in feeling.
`ff-get-other-file' tries to magically guess at stuff, while
`find-sibling-file' explicitly leaves it all to the user.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-06 12:25           ` Lars Ingebrigtsen
@ 2022-06-06 12:51             ` Eli Zaretskii
  2022-06-07  9:13               ` Lars Ingebrigtsen
  0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-06 12:51 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 55778, dick.r.chiang, monnier

> From: Lars Ingebrigtsen <larsi@gnus.org>
> Cc: dick.r.chiang@gmail.com,  55778@debbugs.gnu.org,  monnier@iro.umontreal.ca
> Date: Mon, 06 Jun 2022 14:25:34 +0200
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > That it supports C files doesn't mean it cannot support others: the
> > feature is quite general, not tied to C mode in any way.
> 
> It just seems like a really awkward fit -- the features aren't
> dissimilar in concept, but they're very different in feeling.
> `ff-get-other-file' tries to magically guess at stuff, while
> `find-sibling-file' explicitly leaves it all to the user.

Maybe I'm missing something, but isn't ff-other-file-alist equivalent
to your find-sibling-rules?





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-06 12:51             ` Eli Zaretskii
@ 2022-06-07  9:13               ` Lars Ingebrigtsen
  2022-06-07 11:31                 ` Eli Zaretskii
  0 siblings, 1 reply; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-07  9:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 55778, dick.r.chiang, monnier

Eli Zaretskii <eliz@gnu.org> writes:

> Maybe I'm missing something, but isn't ff-other-file-alist equivalent
> to your find-sibling-rules?

No?  "Alist of extensions to find given the current file's extension."
`find-sibling-rules' isn't about extensions.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-07  9:13               ` Lars Ingebrigtsen
@ 2022-06-07 11:31                 ` Eli Zaretskii
  2022-06-08 11:39                   ` Lars Ingebrigtsen
  0 siblings, 1 reply; 18+ messages in thread
From: Eli Zaretskii @ 2022-06-07 11:31 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 55778, dick.r.chiang, monnier

> From: Lars Ingebrigtsen <larsi@gnus.org>
> Cc: dick.r.chiang@gmail.com,  55778@debbugs.gnu.org,  monnier@iro.umontreal.ca
> Date: Tue, 07 Jun 2022 11:13:31 +0200
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > Maybe I'm missing something, but isn't ff-other-file-alist equivalent
> > to your find-sibling-rules?
> 
> No?  "Alist of extensions to find given the current file's extension."
> `find-sibling-rules' isn't about extensions.

It isn't?  Then why did you show these examples:

> So I've now added a new command `find-sibling-file' to Emacs 29.  This
> setting does what the latter:
> 
> (setq find-sibling-rules
>       '(("\\(/usr/share/emacs.*/\\(lisp/.*.el\\).gz\\)"
> 	 "/home/larsi/src/emacs/trunk/\\2\\'")))
> 
> Something like this does the Emacs development sibling dance:
> 
> (setq find-sibling-rules
>       '(("src/emacs/trunk/[^/]+/\\(.*\\)\\'" "src/emacs/emacs-28/.*/\\1\\'")
> 	("emacs/trunk/\\(.*\\)\\.\\(c\\|el\\)\\'"
> 	 "emacs/trunk/test/\\1-tests.el\\'")))
> 
> And this is foo.c -> foo.h:
> 
> (setq find-sibling-rules
>       '(("\\([^/]+\\)\\.c\\'" "\\1.h")))

AFAIU, almost all of them are about extensions.  find-file.el
separates the directory search from the file-name search, while you
keep them together, but the approaches are equivalent, and each one
has its advantages.

Anyway, I'm not saying that find-file.el can support everything you
wanted to support OOTB.  But it can support most of it, and it can be
extended to support the rest.  So it sounds strange to me to come up
with an entirely new feature, implemented from scratch and with an
incompatible API, when these two have such a significant functionality
overlap.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-07 11:31                 ` Eli Zaretskii
@ 2022-06-08 11:39                   ` Lars Ingebrigtsen
  0 siblings, 0 replies; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-08 11:39 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 55778, dick.r.chiang, monnier

Eli Zaretskii <eliz@gnu.org> writes:

>> No?  "Alist of extensions to find given the current file's extension."
>> `find-sibling-rules' isn't about extensions.
>
> It isn't?  Then why did you show these examples:
>
>> So I've now added a new command `find-sibling-file' to Emacs 29.  This
>> setting does what the latter:
>> 
>> (setq find-sibling-rules
>>       '(("\\(/usr/share/emacs.*/\\(lisp/.*.el\\).gz\\)"
>> 	 "/home/larsi/src/emacs/trunk/\\2\\'")))

That's not about extensions, but finding a related file in a different
directory.

> Anyway, I'm not saying that find-file.el can support everything you
> wanted to support OOTB.  But it can support most of it, and it can be
> extended to support the rest.  So it sounds strange to me to come up
> with an entirely new feature, implemented from scratch and with an
> incompatible API, when these two have such a significant functionality
> overlap.

I understand your point, but I don't feel there's much to be gained
trying to merge these two things that have somewhat different use cases.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there.
  2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
                   ` (3 preceding siblings ...)
  2022-06-03 13:24 ` Dmitry Gutov
@ 2022-06-14 12:42 ` Lars Ingebrigtsen
  4 siblings, 0 replies; 18+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-14 12:42 UTC (permalink / raw)
  To: dick.r.chiang; +Cc: 55778

Anyway, there was some discussion about whether to fold
find-sibling-file into ff-find-file and friends (I still don't think
that's a good idea), but in any case, I think this functionality is more
generally useful than the proposed changes here (even if it requires an
optional step to get from .gz to .el), so I'm closing this bug report.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no






^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-06-14 12:42 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-03  6:27 bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there dick.r.chiang
2022-06-03 10:45 ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-06-03 10:52 ` Lars Ingebrigtsen
2022-06-05 13:49   ` Lars Ingebrigtsen
2022-06-05 13:57     ` Eli Zaretskii
2022-06-05 14:02       ` Lars Ingebrigtsen
2022-06-05 14:15         ` Eli Zaretskii
2022-06-06 12:25           ` Lars Ingebrigtsen
2022-06-06 12:51             ` Eli Zaretskii
2022-06-07  9:13               ` Lars Ingebrigtsen
2022-06-07 11:31                 ` Eli Zaretskii
2022-06-08 11:39                   ` Lars Ingebrigtsen
2022-06-03 11:41 ` Eli Zaretskii
2022-06-04 16:52   ` dick
2022-06-04 17:29     ` Eli Zaretskii
2022-06-03 13:24 ` Dmitry Gutov
2022-06-03 13:41   ` Eli Zaretskii
2022-06-14 12:42 ` Lars Ingebrigtsen

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).