-(defvar ggtags-global-rerun-search-last nil)
-
-(defvar ggtags-global-rerun-search-map
- (cl-labels
- ((save ()
- (setq ggtags-global-rerun-search-last
- (ewoc-data (ewoc-locate ggtags-global-search-ewoc))))
- (next (arg)
- (interactive "p")
- (ewoc-goto-next ggtags-global-search-ewoc arg)
- (save))
- (prev (arg)
- (interactive "p")
- (ewoc-goto-prev ggtags-global-search-ewoc arg)
- (save))
- (quit ()
- (interactive)
- (quit-windows-on (ewoc-buffer ggtags-global-search-ewoc) t))
- (done ()
- (interactive)
- (let ((node (ewoc-locate ggtags-global-search-ewoc)))
- (when node
- (save)
- (quit)
- (ggtags-global-rerun-search-1 (cdr (ewoc-data node)))))))
- (let ((m (make-sparse-keymap)))
- (set-keymap-parent m special-mode-map)
- (define-key m "p" #'prev)
- (define-key m "\M-p" #'prev)
- (define-key m "n" #'next)
- (define-key m "\M-n" #'next)
- (define-key m "r" #'ggtags-save-to-register)
- (define-key m "q" #'quit)
- (define-key m "\r" #'done)
- m)))
+(defvar ggtags-view-search-history-last nil)
+
+(defvar ggtags-view-search-history-mode-map
+ (let ((m (make-sparse-keymap)))
+ (define-key m "p" 'ggtags-view-search-history-prev)
+ (define-key m "\M-p" 'ggtags-view-search-history-prev)
+ (define-key m "n" 'ggtags-view-search-history-next)
+ (define-key m "\M-n" 'ggtags-view-search-history-next)
+ (define-key m "\C-k" 'ggtags-view-search-history-kill)
+ (define-key m [remap yank] (lambda (&optional arg) (interactive "P") (yank arg)))
+ (define-key m "\C-c\C-c" 'ggtags-view-search-history-update)
+ (define-key m "r" 'ggtags-save-to-register)
+ (define-key m "\r" 'ggtags-view-search-history-action)
+ (define-key m "q" 'ggtags-kill-window)
+ m))
+
+(defun ggtags-view-search-history-remember ()
+ (setq ggtags-view-search-history-last
+ (pcase (ewoc-locate ggtags-global-search-ewoc)
+ (`nil nil)
+ (node (ewoc-data node)))))
+
+(defun ggtags-view-search-history-next (&optional arg)
+ (interactive "p")
+ (let ((arg (or arg 1)))
+ (prog1 (funcall (if (cl-minusp arg) #'ewoc-goto-prev #'ewoc-goto-next)
+ ggtags-global-search-ewoc (abs arg))
+ (ggtags-view-search-history-remember))))
+
+(defun ggtags-view-search-history-prev (&optional arg)
+ (interactive "p")
+ (ggtags-view-search-history-next (- (or arg 1))))
+
+(defun ggtags-view-search-history-kill (&optional append)
+ (interactive "P")
+ (let* ((node (or (ewoc-locate ggtags-global-search-ewoc)
+ (user-error "No node at point")))
+ (next (ewoc-next ggtags-global-search-ewoc node))
+ (text (filter-buffer-substring (ewoc-location node)
+ (if next (ewoc-location next)
+ (point-max)))))
+ (put-text-property
+ 0 (length text) 'yank-handler
+ (list (lambda (arg)
+ (if (not ggtags-global-search-ewoc)
+ (insert (car arg))
+ (let* ((inhibit-read-only t)
+ (node (unless (looking-at-p "[ \t\n]*\\'")
+ (ewoc-locate ggtags-global-search-ewoc))))
+ (if node
+ (ewoc-enter-before ggtags-global-search-ewoc
+ node (cadr arg))
+ (ewoc-enter-last ggtags-global-search-ewoc (cadr arg)))
+ (setq ggtags-view-search-history-last (cadr arg)))))
+ (list text (ewoc-data node)))
+ text)
+ (if append (kill-append text nil)
+ (kill-new text))
+ (let ((inhibit-read-only t))
+ (ewoc-delete ggtags-global-search-ewoc node))))
+
+(defun ggtags-view-search-history-update (&optional noconfirm)
+ "Update `ggtags-global-search-history' to current buffer."
+ (interactive "P")
+ (when (and (buffer-modified-p)
+ (or noconfirm
+ (yes-or-no-p "Modify `ggtags-global-search-history'?")))
+ (setq ggtags-global-search-history
+ (ewoc-collect ggtags-global-search-ewoc #'identity))
+ (set-buffer-modified-p nil)))
+
+(defun ggtags-view-search-history-action ()
+ (interactive)
+ (let ((data (ewoc-data (or (ewoc-locate ggtags-global-search-ewoc)
+ (user-error "No search at point")))))
+ (ggtags-view-search-history-remember)
+ (quit-window t)
+ (ggtags-global-rerun-search (cdr data))))