summaryrefslogtreecommitdiff
path: root/lisp/pdf-isearch.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/pdf-isearch.el')
-rw-r--r--lisp/pdf-isearch.el165
1 files changed, 95 insertions, 70 deletions
diff --git a/lisp/pdf-isearch.el b/lisp/pdf-isearch.el
index f5468eb..9ffc2e4 100644
--- a/lisp/pdf-isearch.el
+++ b/lisp/pdf-isearch.el
@@ -33,7 +33,7 @@
(require 'let-alist)
;;; Code:
-
+(defvar pdf-isearch--hl-matches-tick 0)
;; * ================================================================== *
@@ -249,42 +249,55 @@ This is a Isearch interface function."
(when (> (length string) 0)
(let ((same-search-p (pdf-isearch-same-search-p))
(oldpage pdf-isearch-current-page)
- (matches (pdf-isearch-search-page string))
+ (pages (or (image-mode-window-get 'displayed-pages (selected-window))
+ (list (pdf-view-current-page))))
+ matches
next-match)
- ;; matches is a list of list of edges ((x0 y1 x1 y2) ...),
- ;; sorted top to bottom ,left to right. Coordinates are in image
- ;; space.
- (unless isearch-forward
- (setq matches (reverse matches)))
- (when pdf-isearch-filter-matches-function
- (setq matches (funcall pdf-isearch-filter-matches-function matches)))
+ (dolist (page pages)
+ (let ((page-matches (pdf-isearch-search-page string page)))
+ ;; matches is a list of list of edges ((x0 y1 x1 y2) ...),
+ ;; sorted top to bottom ,left to right. Coordinates are in image
+ ;; space.
+ (unless isearch-forward
+ (setq page-matches (reverse page-matches)))
+ (when pdf-isearch-filter-matches-function
+ (setq page-matches (funcall pdf-isearch-filter-matches-function page-matches)))
+ (push page-matches matches)))
;; Where to go next ?
(setq pdf-isearch-current-page (pdf-view-current-page)
pdf-isearch-current-matches matches
next-match
(pdf-isearch-next-match
oldpage pdf-isearch-current-page
- pdf-isearch-current-match matches
+ pdf-isearch-current-match (car matches)
same-search-p
isearch-forward)
pdf-isearch-current-parameter
(list string isearch-regexp
isearch-case-fold-search isearch-word))
+ (cl-callf nreverse matches)
(cond
(next-match
(setq pdf-isearch-current-match next-match)
- (pdf-isearch-hl-matches next-match matches)
+ (pdf-isearch-hl-matches next-match matches nil pages)
(pdf-isearch-focus-match next-match)
;; Don't get off track.
(when (or (and (bobp) (not isearch-forward))
(and (eobp) isearch-forward))
- (goto-char (1+ (/ (buffer-size) 2))))
+ (unless pdf-view-roll-minor-mode
+ (goto-char (1+ (/ (buffer-size) 2)))))
;; Signal success to isearch.
+ ;; Moving the point is for `pdf-roll'. It ensures that
+ ;; `re-search-forward' takes us back to the starting point. Otherwise
+ ;; every call to `isearch-repeat' will increment/decrement the point
+ ;; and that causes recentering.
(if isearch-forward
- (re-search-forward ".")
+ (progn (unless (bobp) (forward-char -1))
+ (re-search-forward "."))
+ (unless (eobp) (forward-char 1))
(re-search-backward ".")))
((and (not pdf-isearch-narrow-to-page)
- (not (pdf-isearch-empty-match-p matches)))
+ (not (pdf-isearch-empty-match-p pdf-isearch-current-matches)))
(let ((next-page (pdf-isearch-find-next-matching-page
string pdf-isearch-current-page t)))
(when next-page
@@ -306,12 +319,14 @@ This is a Isearch interface function."
pdf-isearch-current-matches matches
pdf-isearch-current-match match
pdf-isearch-current-page page)
-
(pdf-view-goto-page pdf-isearch-current-page)
- (when pdf-isearch-current-match
- (pdf-isearch-hl-matches
- pdf-isearch-current-match
- pdf-isearch-current-matches))
+ (if pdf-isearch-current-match
+ (pdf-isearch-hl-matches
+ pdf-isearch-current-match
+ pdf-isearch-current-matches
+ nil (image-mode-window-get 'displayed-pages (selected-window)))
+ (when pdf-view-roll-minor-mode
+ (pdf-view-redisplay)))
(image-set-window-hscroll hscroll)
(image-set-window-vscroll vscroll))))
@@ -347,7 +362,8 @@ This is a Isearch interface function."
pdf-isearch-current-match nil
pdf-isearch-current-matches nil
pdf-isearch-current-parameter nil)
- (goto-char (1+ (/ (buffer-size) 2))))
+ (unless pdf-view-roll-minor-mode
+ (goto-char (1+ (/ (buffer-size) 2)))))
(defun pdf-isearch-same-search-p (&optional ignore-search-string-p)
"Return non-nil, if search parameter have not changed.
@@ -385,8 +401,12 @@ there was no previous search, this function returns t."
(defun pdf-isearch-redisplay ()
"Redisplay the current highlighting."
- (pdf-isearch-hl-matches pdf-isearch-current-match
- pdf-isearch-current-matches))
+ (pdf-isearch-hl-matches
+ pdf-isearch-current-match
+ pdf-isearch-current-matches
+ nil
+ (or (image-mode-window-get 'displayed-pages (selected-window))
+ (list (pdf-view-current-page)))))
(defun pdf-isearch-update ()
"Update search and redisplay, if necessary."
@@ -412,13 +432,14 @@ there was no previous search, this function returns t."
(message "%s" msg))))
(defun pdf-isearch-empty-match-p (matches)
- (and matches
+ (let ((all-matches (apply #'append matches)))
+ (and all-matches
(cl-every
(lambda (match)
(cl-every (lambda (edges)
(cl-every 'zerop edges))
match))
- matches)))
+ all-matches))))
(defun pdf-isearch-occur ()
"Run `occur' using the last search string or regexp."
@@ -564,10 +585,10 @@ is no such page."
(= incr 8)) ;;Don't bother right away.
(setq reporter
(apply
- 'make-progress-reporter "Searching"
- (if isearch-forward
- (list (car pages) (pdf-cache-number-of-pages) nil 0)
- (list 1 (cdr pages) nil 0)))))
+ 'make-progress-reporter "Searching"
+ (if isearch-forward
+ (list (car pages) (pdf-cache-number-of-pages) nil 0)
+ (list 1 (cdr pages) nil 0)))))
(when reporter
(progress-reporter-update
reporter (if isearch-forward
@@ -674,18 +695,18 @@ it is assumed to be ordered with respect to FORWARD-P."
(let ((matched (apply 'pdf-util-edges-union match)))
(pdf-util-with-edges (matched)
(cl-loop for next in matches do
- (let ((edges (apply 'pdf-util-edges-union next)))
- (pdf-util-with-edges (edges)
- (when (if forward-p
- (or (>= edges-top matched-bot)
- (and (or (>= edges-top matched-top)
- (>= edges-bot matched-bot))
- (>= edges-right matched-right)))
- (or (<= edges-bot matched-top)
- (and (or (<= edges-bot matched-bot)
- (<= edges-top matched-top))
- (<= edges-left matched-left))))
- (cl-return next))))))))
+ (let ((edges (apply 'pdf-util-edges-union next)))
+ (pdf-util-with-edges (edges)
+ (when (if forward-p
+ (or (>= edges-top matched-bot)
+ (and (or (>= edges-top matched-top)
+ (>= edges-bot matched-bot))
+ (>= edges-right matched-right)))
+ (or (<= edges-bot matched-top)
+ (and (or (<= edges-bot matched-bot)
+ (<= edges-top matched-top))
+ (<= edges-left matched-left))))
+ (cl-return next))))))))
@@ -716,41 +737,45 @@ MATCH-BG LAZY-FG LAZY-BG\)."
(car lazy)
(cdr lazy)))))))
-(defvar pdf-isearch--hl-matches-tick 0)
-
-(defun pdf-isearch-hl-matches (current matches &optional occur-hack-p)
+(defun pdf-isearch-hl-matches (current matches &optional occur-hack-p pages)
"Highlighting edges CURRENT and MATCHES."
(cl-check-type current pdf-isearch-match)
- (cl-check-type matches (list-of pdf-isearch-match))
+ (cl-check-type matches (list-of (list-of pdf-isearch-match)))
(cl-destructuring-bind (fg1 bg1 fg2 bg2)
(pdf-isearch-current-colors)
- (let* ((width (car (pdf-view-image-size)))
- (page (pdf-view-current-page))
- (window (selected-window))
+ (let* ((window (selected-window))
+ (pages (or pages
+ (image-mode-window-get 'displayed-pages (selected-window))
+ (list (pdf-view-current-page))))
(buffer (current-buffer))
- (tick (cl-incf pdf-isearch--hl-matches-tick))
- (pdf-info-asynchronous
- (lambda (status data)
- (when (and (null status)
- (eq tick pdf-isearch--hl-matches-tick)
- (buffer-live-p buffer)
- (window-live-p window)
- (eq (window-buffer window)
- buffer))
- (with-selected-window window
- (when (and (derived-mode-p 'pdf-view-mode)
- (or isearch-mode
- occur-hack-p)
- (eq page (pdf-view-current-page)))
- (pdf-view-display-image
- (pdf-view-create-image data :width width))))))))
- (pdf-info-renderpage-text-regions
- page width t nil nil
- `(,fg1 ,bg1 ,@(pdf-util-scale-pixel-to-relative
- current))
- `(,fg2 ,bg2 ,@(pdf-util-scale-pixel-to-relative
- (apply 'append
- (remove current matches))))))))
+ (tick (cl-incf pdf-isearch--hl-matches-tick)))
+ (dolist (page pages)
+ (let* ((width (car (pdf-view-image-size nil window page)))
+ (pdf-info-asynchronous
+ (lambda (status data)
+ (when (and (null status)
+ (eq tick pdf-isearch--hl-matches-tick)
+ (buffer-live-p buffer)
+ (window-live-p window)
+ (eq (window-buffer window)
+ buffer))
+ (with-selected-window window
+ (when (and (derived-mode-p 'pdf-view-mode)
+ (or isearch-mode occur-hack-p
+ (memq last-command '(isearch-repeat-forward isearch-repeat-backward)))
+ (or (eq page (pdf-view-current-page))
+ (memq page (image-mode-window-get 'displayed-pages window))))
+ (pdf-view-display-image
+ (pdf-view-create-image data :width width)
+ page window)))))))
+ (pdf-info-renderpage-text-regions
+ page width t nil nil
+ `(,fg1 ,bg1 ,@(pdf-util-scale-pixel-to-relative
+ (when (eq page (pdf-view-current-page window))
+ current)))
+ `(,fg2 ,bg2 ,@(pdf-util-scale-pixel-to-relative
+ (apply 'append
+ (remove current (pop matches)))))))))))
;; * ================================================================== *