New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
swiper.el: Don't highlight multiline matches #1600
swiper.el: Don't highlight multiline matches #1600
Conversation
This corrects an inconsistency between the search results and the highlighting which happens when a regexp can match newlines.
swiper.el
Outdated
swiper-faces) | ||
wnd i) | ||
(cl-incf i))))))))))) | ||
;; Don't highlight a match if it goes across |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: how about "spans" instead of "goes across"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
swiper.el
Outdated
;; Don't highlight a match if it goes across | ||
;; multiple lines. | ||
(unless (> (line-number-at-pos (match-end 0)) | ||
(line-number-at-pos (match-beginning 0))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not
(when (> 2 (count-lines (match-beginning 0) (match-end 0))) ...)
or similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know about count-lines
. But that actually seems less clear to me. One has to figure out why 2
instead of 1
, and the docstring does not seem all too obvious to me:
Return number of lines between START and END.
This is usually the number of newlines between them,
but can be one more if START is not equal to END
and the greater of them is not at the start of a line.
I think using line-number-at-pos
makes it obvious that what we are checking is if the beginning and ending are on different lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, line-number-at-pos
is super slow, since it recomputes the line number from the beginning of the buffer. Checking if the match has a newline should be faster.
In these cases it is customary to
Yes, which is why I suggested calling
This is also a possibility, but are you sure that:
? |
FWIW, here's a toy benchmark suggesting allocating strings is only a tiny bit slower, but uses a lot more memory: (defun my-a ()
(string-match-p "\n" (match-string 0)))
(defun my-b ()
(<= 2 (count-lines (match-beginning 0) (match-end 0))))
(defun my-c ()
(save-excursion (search-backward "\n" (match-beginning 0) t)))
(defun my-run (pred)
(goto-char (point-min))
(let (matches)
(while (re-search-forward (rx "sit" (+? anything) "tellus") nil t)
(when (funcall pred)
(push (point) matches)))
matches))
(byte-compile #'my-run)
(with-temp-buffer
(dotimes (_ 500)
(insert "\
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Donec hendrerit tempor tellus.
Proin quam nisl, tincidunt et, mattis eget, convallis nec, purus.\n"))
(let ((fns '(my-c my-b my-a)))
;; Check equivalence of predicates.
(cl-assert (= 1 (length (delete-dups (mapcar #'my-run fns)))))
(dolist (fn fns)
(byte-compile fn)
(garbage-collect)
(message "%s: %s" fn (benchmark-run 1000 (my-run fn)))))) The result is:
Premature optimisation FTW! :) |
OK, I have no real objection to using |
Thanks to both of you, as this was very instructive. I didn't know about count-lines either, or that it has a cache. May I suggest a blog article? =) |
It's not For some recent discussion about these things (which is how I found out about them), see the
You may, but I don't blog; perhaps someone else will want to. |
Thanks. |
This corrects an inconsistency between the search results and the highlighting which happens when a regexp can match newlines.