3

When using Emacs, I notice that words or phrases in a buffer can be annotated or highlighted by many minor modes like hi-lock-mode, flyspell-mode, flycheck-mode...

Is there any uniform way to jump to the highlighted words or phrases created by all these minor modes? Specifically, is there any package or function support jumping to the next and previous highlighted phrases?

When using Eclipse, I can do it by pressing Ctrl-. and Ctrl-,. However, when switching to Emacs, so far, I haven't found an equivalent feature.

Trung Ta
  • 1,582
  • 1
  • 16
  • 25
  • I think `^` moves the point to previous one, though I am not sure. – hjpotter92 Sep 04 '16 at 06:59
  • Which function do you mean? I tried `C-^`, `M-^` but they are not the case. – Trung Ta Sep 04 '16 at 07:44
  • For flycheck, the manual gives `C-c ! n` and `C-c ! p` for jumping back and forth between erroneous places. –  Sep 04 '16 at 07:54
  • Yeah, I know there are specific keys for each mode. However, it would be nice if there are uniform keys to go to back and forth among annotated phrases. – Trung Ta Sep 04 '16 at 08:38

3 Answers3

1

Developing a mode which aims to tackle that kind of tasks

https://github.com/andreas-roehler/werkstatt/tree/master/general-key

Facilitates the setting of a general command. Than this command gets different bindings according to modes - which needs to be edited by hand once. Afterwards it allows to set/change a key at one place for all related/bound commands.

See for example inside https://github.com/andreas-roehler/werkstatt/blob/master/general-key/general-key-python-mode.el

It's alpha still notably for the install process. Bug reports resp. feature requests welcome.

Andreas Röhler
  • 4,804
  • 14
  • 18
0

Not surprisingly, @Drew has answered something related to this.

You can programmatically use isearch with something like:

(defun foo (regexp) 
  (interactive (list (read-regexp "Regexp: ")))
  (isearch-mode t t)
  (let ((isearch-regexp  nil))
    (isearch-yank-string regexp)))

This will pull your previous regexp history, including those from hi-lock. I imagine it would be a fun exercise to modify this to use hi-lock-regexp-history.

Lorem Ipsum
  • 4,020
  • 4
  • 41
  • 67
0

If you use swiper, you can restrict the search candidates to lines with highlighted patterns by hi-lock-mode. Here is a simple wrapper of swiper:

(require 'cl-lib)

(defun swiper-over-highlights-simple ()
  (interactive)
  (let ((original-swiper--candidates (symbol-function 'swiper--candidates)))
    (cl-letf (((symbol-function 'swiper--candidates)
               (lambda ()
                 (let ((pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
                   (cl-remove-if-not (lambda (x) (string-match-p pattern x))
                                     (funcall original-swiper--candidates))))))
      (swiper))))

In addition, you can change ivy-read's preselect argument, which initializes the first matched line inside swiper. The following fuction, modified from swiper, finds the closest next line with a highlighted pattern:

(defun swiper-over-highlights (&optional initial-input)
  (interactive)
  (let ((original-swiper--candidates (symbol-function 'swiper--candidates))
        (pattern (mapconcat #'car hi-lock-interactive-patterns "\\|")))
    (cl-letf (((symbol-function 'swiper--candidates)
               (lambda ()
                 (cl-remove-if-not (lambda (x) (string-match-p pattern x))
                                   (funcall original-swiper--candidates)))))
      (let ((candidates (swiper--candidates)))
        (swiper--init)
        (setq swiper-invocation-face
              (plist-get (text-properties-at (point)) 'face))
        (let ((preselect
               (save-excursion
                 (search-forward-regexp pattern nil t)
                 (let* ((current-line-value (current-line))
                        (candidate-line-numbers (mapcar (lambda (x) (cadr (text-properties-at 0 x)))
                                                        candidates))
                        (preselect-line-num (cl-find-if (lambda (x) (<= current-line-value x))
                                                        candidate-line-numbers)))
                   (- (length candidate-line-numbers)
                      (length (member preselect-line-num candidate-line-numbers))))))
              (minibuffer-allow-text-properties t)
              res)
          (unwind-protect
               (and
                (setq res
                      (ivy-read
                       "Swiper: "
                       candidates
                       :initial-input initial-input
                       :keymap swiper-map
                       :preselect preselect
                       :require-match t
                       :action #'swiper--action
                       :re-builder #'swiper--re-builder
                       :history 'swiper-history
                       :extra-props (list :fname (buffer-file-name))
                       :caller 'swiper))
                (point))
            (unless (or res swiper-stay-on-quit)
              (goto-char swiper--opoint))
            (isearch-clean-overlays)
            (unless (or res (string= ivy-text ""))
              (cl-pushnew ivy-text swiper-history))
            (setq swiper--current-window-start nil)
            (when swiper--reveal-mode
              (reveal-mode 1))))))))
dhnam
  • 131
  • 1
  • 7