From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: dick.r.chiang@gmail.com Newsgroups: gmane.emacs.bugs Subject: bug#55778: 29.0.50; [PATCH] M-. into a .gz; we've all been there. Date: Fri, 03 Jun 2022 02:27:59 -0400 Message-ID: <87k09yw9ao.fsf@dick> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="28186"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.14 (Gnus v5.14) Commercial/29.0.50 (gnu/linux) To: 55778@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jun 03 10:19:22 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nx2Wf-000784-M5 for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 03 Jun 2022 10:19:21 +0200 Original-Received: from localhost ([::1]:57872 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nx2We-0003Eg-BD for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 03 Jun 2022 04:19:20 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50378) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nx2WM-0003D1-Ra for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2022 04:19:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:33069) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nx2WM-0000El-Iu for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2022 04:19:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nx2WM-0007S5-DF for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2022 04:19:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: dick.r.chiang@gmail.com Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 03 Jun 2022 08:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 55778 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs Original-Received: via spool by submit@debbugs.gnu.org id=B.165424433528622 (code B ref -1); Fri, 03 Jun 2022 08:19:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 3 Jun 2022 08:18:55 +0000 Original-Received: from localhost ([127.0.0.1]:55197 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nx2WA-0007RU-Hl for submit@debbugs.gnu.org; Fri, 03 Jun 2022 04:18:55 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:57592) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nx0nR-0002Xz-P4 for submit@debbugs.gnu.org; Fri, 03 Jun 2022 02:28:39 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:54874) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nx0nJ-0004vA-Hc for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2022 02:28:31 -0400 Original-Received: from mail-qk1-x734.google.com ([2607:f8b0:4864:20::734]:45608) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nx0n6-0003Gm-CU for bug-gnu-emacs@gnu.org; Fri, 03 Jun 2022 02:28:23 -0400 Original-Received: by mail-qk1-x734.google.com with SMTP id x75so1867372qkb.12 for ; Thu, 02 Jun 2022 23:28:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:user-agent:mime-version; bh=nxm4u6S6gxQ43cXHracFyavPOBOQVAoEWoVnprbAR6I=; b=DLJmU3ddazhHhhKT8M77E8xygllvkygwPm1+ZdLE7Y+aL/Gx4W1B4do3rrPMwppaPu HuvDKQpcfnkjl6tvbD0G91iJJcUKjdp4WnXO1vO9gFgFbALGVRkHYt/wW7lHDPR7ydX+ 4YRDwfbWmJ9/sfEVfZ+XwW7zvKj4xUIq3L73CdtVmulfhV2zRsIgBxU5pZgEILuNMPaE X3tNxwILJbbLo8cbshfY0OMrZysjwtP61K6gZOL48ZX6VjwnCwDlqN4hmApg82reNErV PZGaReeZY3CQtzK7031SI/XoRXmPmeQDVLm2uWvzrRbOW+Ix2IEoEpCuDR7oRaV2Czwk 67zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:user-agent :mime-version; bh=nxm4u6S6gxQ43cXHracFyavPOBOQVAoEWoVnprbAR6I=; b=sbXGF2X1prJzZ1ds3OeVAFG9AlbIcRtYqaz9sHwEbQOkVFQkUVno6lZhDeCoOaZLRF 40eFag9/uYD9fxP3yY/XCqFaEsnksvhXgSmqE8WUDomdAO83cbR00K8P0GhQ/uYqleVZ AjQoYXu/ztpduOcaNlcp8CcCO5qOxPW1IyXgaX0FiDP5jBSPNYPEjjjnIbxGc5YDJCw+ 5ER4p5k2+5LtGtT3hitixzYQ+KF4h0TpoxqzxB2TDZWP6/c5/OrCjI7GnbEQGdbx4lPo pjAU3CfsDXHjsKa3unUTHy5gcSaL/jqIoSn7WId3Yfekiutx8OifTVT9u4qLY/sRUBkd cESA== X-Gm-Message-State: AOAM530hp2byio8EiwAdGMP2+flxWDiRDUVtqY+DYBOqHbP+8e/FkUyI kWrwNtaPUZ1P6gMmsbJB/G4HA+54HJY= X-Google-Smtp-Source: ABdhPJzJP51qfFA+O6lArIKJRqjERYTDgmb62pmM8Av1sDbzvbmsqAEsY2n/P7Ilb7u6TR9myQr+3A== X-Received: by 2002:a37:9401:0:b0:6a6:9a6c:978 with SMTP id w1-20020a379401000000b006a69a6c0978mr1322793qkd.384.1654237681342; Thu, 02 Jun 2022 23:28:01 -0700 (PDT) Original-Received: from localhost (pool-96-232-253-158.nycmny.fios.verizon.net. [96.232.253.158]) by smtp.gmail.com with ESMTPSA id 62-20020a370541000000b006a36b7e55b3sm4636107qkf.4.2022.06.02.23.28.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Jun 2022 23:28:00 -0700 (PDT) Received-SPF: pass client-ip=2607:f8b0:4864:20::734; envelope-from=dick.r.chiang@gmail.com; helo=mail-qk1-x734.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, SPF_HELO_NONE=0.001, T_SCC_BODY_TEXT_LINE=-0.01, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Fri, 03 Jun 2022 04:18:49 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:233593 Archived-At: --=-=-= Content-Type: text/plain 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))" --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-xref-prefer-source-directory.patch >From fb6f100bb1f588322c6a501ff2876a773189a9b9 Mon Sep 17 00:00:00 2001 From: dickmao 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 ...)". - ;; 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 ...)". + ;; 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 --=-=-= Content-Type: text/plain 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)) --=-=-=--