From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#46859: 28.0.50; [PATCH]: Add option to truncate long lines in xref.el Date: Wed, 03 Mar 2021 17:13:58 +0100 Message-ID: References: <87im69uzlt.fsf@mail.linkov.net> <25782781-4baa-5d44-99a1-2e57552ab3a0@yandex.ru> Reply-To: Theodor Thornhill Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31660"; mail-complaints-to="usenet@ciao.gmane.io" To: Dmitry Gutov , juri@linkov.net, 46859@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Wed Mar 03 17:17:42 2021 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 1lHUBw-000873-K0 for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 03 Mar 2021 17:17:40 +0100 Original-Received: from localhost ([::1]:60136 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lHUBv-0004h3-LN for geb-bug-gnu-emacs@m.gmane-mx.org; Wed, 03 Mar 2021 11:17:39 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:34902) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lHU9V-0002c2-9f for bug-gnu-emacs@gnu.org; Wed, 03 Mar 2021 11:15:10 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:45192) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lHU9O-0005gF-Hc for bug-gnu-emacs@gnu.org; Wed, 03 Mar 2021 11:15:08 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lHU9O-0004LF-DI for bug-gnu-emacs@gnu.org; Wed, 03 Mar 2021 11:15:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Theodor Thornhill Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 03 Mar 2021 16:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46859 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 46859-submit@debbugs.gnu.org id=B46859.161478804716546 (code B ref 46859); Wed, 03 Mar 2021 16:15:02 +0000 Original-Received: (at 46859) by debbugs.gnu.org; 3 Mar 2021 16:14:07 +0000 Original-Received: from localhost ([127.0.0.1]:56725 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lHU8U-0004In-P1 for submit@debbugs.gnu.org; Wed, 03 Mar 2021 11:14:07 -0500 Original-Received: from out0.migadu.com ([94.23.1.103]:20484) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lHU8Q-0004ID-Ct for 46859@debbugs.gnu.org; Wed, 03 Mar 2021 11:14:05 -0500 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. In-Reply-To: <25782781-4baa-5d44-99a1-2e57552ab3a0@yandex.ru> X-Migadu-Flow: FLOW_OUT X-Migadu-Auth-User: theo@thornhill.no 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:201288 Archived-At: Hi again! Dmitry Gutov writes: > On 03.03.2021 00:14, Theodor Thornhill via Bug reports for GNU Emacs, > the Swiss army knife of text editors wrote: >> I'm interested in seeing if I could gain some more >> performance by short circuiting after the first iteration of a match on >> the same line. In my test scenario there are a lot of matches on the >> same huge line. What do you think? I couldn't really find any approaches that yielded better results with short-circuiting in mind, so I dropped that idea. > You probably mean to short-circuit as soon as you reach the target > > ...of course, ideally we would keep all contents of the line somewhere > in memory and truncate with (setq truncate-line t). But IIRC Juri said > this didn't give us as much of a speedup as we'd want. > > Another question: how many hits do you usually have in that huge > one-line file? If it's more than 2-3, it might be that our current > algorithm which creates "match objects" will duplicate this string > unnecessarily N times (which is the number of hits), in > xref--collect-matches-1, to then cut it up and merge into one line again > when printing the buffer. In which case the patch above should also show > a healthy improvement, but we could figure out something better instead. > This long line has 25 matches, so yeah, that takes some time. With your hint here I tried another approach which yielded some nice results. Ok, some benchmarks: ;; With nothing (benchmark-run 10 (project-find-regexp "UrlChange")) ;; (11.748253 14 0.23526199999999997) ;; With -M 500 (benchmark-run 10 (project-find-regexp "UrlChange")) ;; (0.293626 0 0.0) ;; My first patch (benchmark-run 10 (project-find-regexp "UrlChange")) ;; (1.230833 8 0.13783999999999996) ;; Dmitrys patch (benchmark-run 10 (project-find-regexp "UrlChange")) ;; (1.007787 0 0.0) ;; Latest diff (attached at the bottom) (benchmark-run 10 (project-find-regexp "UrlChange")) ;; (1.0351299999999999 0 0.0) So there are some interesting findings here: - There are some improvements to gain - None so far kills "-M 500" - Pretty close between Dmitrys and my last patch However, only my patch actually renders the long file as a match in the output buffer. All the others seem to drop it altogether. IMO that is one point in favour of my approaches. In addition, we could add another defcustom for the xref--collect-matches-1 function, "xref--collect-all-matches-p" or something like that. Retrofitting the current variable seems a little off. That means you could customize xref to render the whole long line if you want, while not bothering about multiple matches. Not sure if that has a great benefit, though. What do you think? Are any of these approaches worth pursuing further? -- Theo diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 18fdd963fb..fb422dcffa 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -872,6 +872,18 @@ beginning of the line." (xref--search-property 'xref-item)) (xref-show-location-at-point)) +(defcustom xref-truncate-line-to 500 + "Max number of columns to display in xref buffer." + :type '(choice + (fixnum :tag "Number of lines") + (null :tag "Don't truncate")) + :version "28.1" + :package-version '(xref . "1.0.5")) + +(defun xref--truncate-long-lines-p (summary) + (and (numberp xref-truncate-line-to) + (> (length summary) xref-truncate-line-to))) + (defun xref--insert-xrefs (xref-alist) "Insert XREF-ALIST in the current-buffer. XREF-ALIST is of the form ((GROUP . (XREF ...)) ...), where @@ -902,14 +914,22 @@ GROUP is a string for decoration purposes and XREF is an " "))) ;; 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)) + (if (xref--truncate-long-lines-p summary) + (delete-region + (save-excursion (forward-line -1) (point)) + (point)) + (when-let ((column (xref-location-column location))) + (delete-region + (save-excursion + (forward-line -1) + (move-to-column (+ (length prefix) column)) + (point)) (point)) - (point)) - (setq new-summary (substring summary column) prefix ""))) + (setq new-summary (substring summary column) prefix "")))) + (when (xref--truncate-long-lines-p new-summary) + (setq new-summary + (concat (substring new-summary 0 xref-truncate-line-to) + " (...truncated)"))) (xref--insert-propertized (list 'xref-item xref 'mouse-face 'highlight @@ -1678,7 +1698,7 @@ 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 (matches prev-line) (when syntax-needed (syntax-propertize line-end)) ;; FIXME: This results in several lines with the same @@ -1688,14 +1708,18 @@ Such as the current syntax table and the applied syntax properties." (or (null matches) (> (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)) - (loc (xref-make-file-location file line beg-column)) - (summary (buffer-substring line-beg line-end))) - (add-face-text-property beg-column end-column 'xref-match - t summary) - (push (xref-make-match summary loc (- end-column beg-column)) - matches))) + + (unless (and (eq prev-line line) + (numberp xref-truncate-line-to)) + (let* ((beg-column (- (match-beginning 0) line-beg)) + (end-column (- (match-end 0) line-beg)) + (loc (xref-make-file-location file line beg-column)) + (summary (buffer-substring line-beg line-end))) + (add-face-text-property beg-column end-column 'xref-match + t summary) + (push (xref-make-match summary loc (- end-column beg-column)) + matches))) + (setq prev-line line)) (nreverse matches))) (defun xref--find-file-buffer (file)