From 49bc8586b7abc8e1e36027ca5eec0d0488a27474 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Fri, 23 Oct 2020 16:29:46 +0200 Subject: Move some test data to follow our conventions * test/data/emacs-module/mod-test.c: Move from here... * test/src/emacs-module-resources/mod-test.c: ...to here. * test/src/emacs-module-tests.el (ert-x): Require. (mod-test-file, module/describe-function-1): * test/Makefile.in (test_module_dir): Adjust for move. * test/data/files-bug18141.el.gz: Move from here... * test/lisp/files-resources/files-bug18141.el.gz: ... to here. * test/lisp/files-tests.el (ert-x): Require. (files-test-bug-18141-file): Use ert-resource-file. * test/data/mailcap/mime.types: Move from here... * test/lisp/net/mailcap-resources/mime.types: ...to here. * test/lisp/net/mailcap-tests.el (ert-x): Require. (mailcap-tests-path): Use ert-resource-file. * test/data/somelib.el: * test/data/somelib2.el: Move from here... * test/src/lread-resources/somelib.el: * test/src/lread-resources/somelib2.el: ...to here. * test/src/lread-tests.el (ert, ert-x): Require. (lread-test-bug26837): Use ert-resource-directory. * test/data/syntax-comments.txt: Move from here.... * test/src/syntax-resources/syntax-comments.txt: ...to here. * test/src/syntax-tests.el (ert-x): Require. (syntax-comments, syntax-br-comments, syntax-pps-comments): Use ert-resource-file. * test/data/xref/file1.txt: * test/data/xref/file2.txt: Move from here... * test/lisp/progmodes/xref-resources/file1.txt: * test/lisp/progmodes/xref-resources/file2.txt: ...to here. * test/lisp/progmodes/xref-tests.el (ert, ert-x): Require. (xref-tests-data-dir): Use ert-resource-directory. --- test/lisp/progmodes/xref-resources/file1.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/lisp/progmodes/xref-resources/file1.txt (limited to 'test/lisp/progmodes/xref-resources/file1.txt') diff --git a/test/lisp/progmodes/xref-resources/file1.txt b/test/lisp/progmodes/xref-resources/file1.txt new file mode 100644 index 00000000000..5d7cc544443 --- /dev/null +++ b/test/lisp/progmodes/xref-resources/file1.txt @@ -0,0 +1,2 @@ +foo foo +bar -- cgit v1.2.3 From 8e103ebef12bb723723c7e6ec8e1053e86878a5b Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Mon, 8 Mar 2021 04:25:15 +0200 Subject: Speed up xref rendering for matches on very long lines * lisp/progmodes/xref.el (xref--insert-xrefs): Cut up the current line into pieces here for multiple matches's summaries, so that xref--insert-xrefs can do less work (bug#46859). (xref--insert-xrefs): Do less work. (xref--outdated-p): Update accordingly to how the summary creation logic changed. (xref--buf-pairs-iterator): Update to the new calling convention. (xref-location-column): Effectively rename back to xref-file-location-column since the generic version is now unused. * test/lisp/progmodes/xref-tests.el (xref-matches-in-directory-finds-two-matches-on-the-same-line) (xref-matches-in-directory-finds-an-empty-line-regexp-match): Adjust to the xref-location-column change. (xref-matches-in-files-trims-summary-for-matches-on-same-line): New test. * test/lisp/progmodes/xref-resources/file1.txt: Change contents slightly to test the new xref--outdated-p code. --- lisp/progmodes/xref.el | 110 ++++++++++++++++----------- test/lisp/progmodes/xref-resources/file1.txt | 2 +- test/lisp/progmodes/xref-resources/file3.txt | 1 + test/lisp/progmodes/xref-tests.el | 15 +++- 4 files changed, 78 insertions(+), 50 deletions(-) create mode 100644 test/lisp/progmodes/xref-resources/file3.txt (limited to 'test/lisp/progmodes/xref-resources/file1.txt') diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 18fdd963fb1..af46365325b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -97,10 +97,6 @@ This is typically the filename.") "Return the line number corresponding to the location." nil) -(cl-defgeneric xref-location-column (_location) - "Return the exact column corresponding to the location." - nil) - (cl-defgeneric xref-match-length (_item) "Return the length of the match." nil) @@ -130,7 +126,7 @@ in its full absolute form." (defclass xref-file-location (xref-location) ((file :type string :initarg :file) (line :type fixnum :initarg :line :reader xref-location-line) - (column :type fixnum :initarg :column :reader xref-location-column)) + (column :type fixnum :initarg :column :reader xref-file-location-column)) :documentation "A file location is a file/line/column triple. Line numbers start from 1 and columns from 0.") @@ -713,10 +709,7 @@ references displayed in the current *xref* buffer." (push pair all-pairs) ;; Perform sanity check first. (xref--goto-location loc) - (if (xref--outdated-p item - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position))) + (if (xref--outdated-p item) (message "Search result out of date, skipping") (cond ((null file-buf) @@ -733,18 +726,38 @@ references displayed in the current *xref* buffer." (move-marker (car pair) nil) (move-marker (cdr pair) nil))))))) -(defun xref--outdated-p (item line-text) - ;; FIXME: The check should probably be a generic function instead of - ;; the assumption that all matches contain the full line as summary. - (let ((summary (xref-item-summary item)) - (strip (lambda (s) (if (string-match "\r\\'" s) - (substring-no-properties s 0 -1) - s)))) +(defun xref--outdated-p (item) + "Check that the match location at current position is up-to-date. +ITEMS is an xref item which " + ;; FIXME: The check should most likely be a generic function instead + ;; of the assumption that all matches' summaries relate to the + ;; buffer text in a particular way. + (let* ((summary (xref-item-summary item)) + ;; Sometimes buffer contents include ^M, and sometimes Grep + ;; output includes it, and they don't always match. + (strip (lambda (s) (if (string-match "\r\\'" s) + (substring-no-properties s 0 -1) + s))) + (stripped-summary (funcall strip summary)) + (lendpos (line-end-position)) + (check (lambda () + (let ((comparison-end + (+ (point) (length stripped-summary)))) + (and (>= lendpos comparison-end) + (equal stripped-summary + (buffer-substring-no-properties + (point) comparison-end))))))) (not - ;; Sometimes buffer contents include ^M, and sometimes Grep - ;; output includes it, and they don't always match. - (equal (funcall strip line-text) - (funcall strip summary))))) + (or + ;; Either summary contains match text and after + ;; (2nd+ match on the line)... + (funcall check) + ;; ...or it starts at bol, includes the match and after. + (and (< (point) (+ (line-beginning-position) + (length stripped-summary))) + (save-excursion + (forward-line 0) + (funcall check))))))) ;; FIXME: Write a nicer UI. (defun xref--query-replace-1 (from to iter) @@ -886,30 +899,24 @@ GROUP is a string for decoration purposes and XREF is an (length (and line (format "%d" line))))) for line-format = (and max-line-width (format "%%%dd: " max-line-width)) - with prev-line-key = nil + with prev-group = nil + with prev-line = nil do (xref--insert-propertized '(face xref-file-header xref-group t) group "\n") (cl-loop for (xref . more2) on xrefs do (with-slots (summary location) xref (let* ((line (xref-location-line location)) - (new-summary summary) - (line-key (list (xref-location-group location) line)) (prefix - (if line - (propertize (format line-format line) - 'face 'xref-line-number) - " "))) + (cond + ((not line) " ") + ((equal line prev-line) "") + (t (propertize (format line-format line) + 'face 'xref-line-number))))) ;; Render multiple matches on the same line, together. - (when (and line (equal prev-line-key line-key)) - (when-let ((column (xref-location-column location))) - (delete-region - (save-excursion - (forward-line -1) - (move-to-column (+ (length prefix) column)) - (point)) - (point)) - (setq new-summary (substring summary column) prefix ""))) + (when (and (equal prev-group group) + (not (equal prev-line line))) + (insert "\n")) (xref--insert-propertized (list 'xref-item xref 'mouse-face 'highlight @@ -917,9 +924,10 @@ GROUP is a string for decoration purposes and XREF is an 'help-echo (concat "mouse-2: display in another window, " "RET or mouse-1: follow reference")) - prefix new-summary) - (setq prev-line-key line-key))) - (insert "\n")))) + prefix summary) + (setq prev-line line + prev-group group)))) + (insert "\n"))) (defun xref--analyze (xrefs) "Find common filenames in XREFS. @@ -1678,20 +1686,30 @@ Such as the current syntax table and the applied syntax properties." syntax-needed))))) (defun xref--collect-matches-1 (regexp file line line-beg line-end syntax-needed) - (let (matches) + (let (match-pairs matches) (when syntax-needed (syntax-propertize line-end)) - ;; FIXME: This results in several lines with the same - ;; summary. Solve with composite pattern? (while (and ;; REGEXP might match an empty string. Or line. - (or (null matches) + (or (null match-pairs) (> (point) line-beg)) (re-search-forward regexp line-end t)) - (let* ((beg-column (- (match-beginning 0) line-beg)) - (end-column (- (match-end 0) line-beg)) + (push (cons (match-beginning 0) + (match-end 0)) + match-pairs)) + (setq match-pairs (nreverse match-pairs)) + (while match-pairs + (let* ((beg-end (pop match-pairs)) + (beg-column (- (car beg-end) line-beg)) + (end-column (- (cdr beg-end) line-beg)) (loc (xref-make-file-location file line beg-column)) - (summary (buffer-substring line-beg line-end))) + (summary (buffer-substring (if matches (car beg-end) line-beg) + (if match-pairs + (caar match-pairs) + line-end)))) + (when matches + (cl-decf beg-column (- (car beg-end) line-beg)) + (cl-decf end-column (- (car beg-end) line-beg))) (add-face-text-property beg-column end-column 'xref-match t summary) (push (xref-make-match summary loc (- end-column beg-column)) diff --git a/test/lisp/progmodes/xref-resources/file1.txt b/test/lisp/progmodes/xref-resources/file1.txt index 5d7cc544443..85b92f11566 100644 --- a/test/lisp/progmodes/xref-resources/file1.txt +++ b/test/lisp/progmodes/xref-resources/file1.txt @@ -1,2 +1,2 @@ -foo foo + foo foo bar diff --git a/test/lisp/progmodes/xref-resources/file3.txt b/test/lisp/progmodes/xref-resources/file3.txt new file mode 100644 index 00000000000..6283185910d --- /dev/null +++ b/test/lisp/progmodes/xref-resources/file3.txt @@ -0,0 +1 @@ + match some words match more match ends here diff --git a/test/lisp/progmodes/xref-tests.el b/test/lisp/progmodes/xref-tests.el index 028c43db43e..9982c32d41d 100644 --- a/test/lisp/progmodes/xref-tests.el +++ b/test/lisp/progmodes/xref-tests.el @@ -59,15 +59,15 @@ (should (string-match-p "file1\\.txt\\'" (xref-location-group (nth 1 locs)))) (should (equal 1 (xref-location-line (nth 0 locs)))) (should (equal 1 (xref-location-line (nth 1 locs)))) - (should (equal 0 (xref-location-column (nth 0 locs)))) - (should (equal 4 (xref-location-column (nth 1 locs)))))) + (should (equal 1 (xref-file-location-column (nth 0 locs)))) + (should (equal 5 (xref-file-location-column (nth 1 locs)))))) (ert-deftest xref-matches-in-directory-finds-an-empty-line-regexp-match () (let ((locs (xref-tests--locations-in-data-dir "^$"))) (should (= 1 (length locs))) (should (string-match-p "file2\\.txt\\'" (xref-location-group (nth 0 locs)))) (should (equal 1 (xref-location-line (nth 0 locs)))) - (should (equal 0 (xref-location-column (nth 0 locs)))))) + (should (equal 0 (xref-file-location-column (nth 0 locs)))))) (ert-deftest xref-matches-in-files-includes-matches-from-all-the-files () (let ((matches (xref-matches-in-files "bar" @@ -78,6 +78,15 @@ (lambda (match) (equal (xref-item-summary match) "bar")) matches)))) +(ert-deftest xref-matches-in-files-trims-summary-for-matches-on-same-line () + (let ((matches (xref-matches-in-files "match" + (directory-files xref-tests--data-dir t + "\\`[^.]")))) + (should (= 3 (length matches))) + (should + (equal (mapcar #'xref-item-summary matches) + '(" match some words " "match more " "match ends here"))))) + (ert-deftest xref--buf-pairs-iterator-groups-markers-by-buffers-1 () (let* ((xrefs (xref-tests--matches-in-data-dir "foo")) (iter (xref--buf-pairs-iterator xrefs)) -- cgit v1.2.3