12

Within Visual Studio and Notepad++, when I select a symbol (using the shift key or mouse), other occurrences of it within the buffer are also highlighted in another color.

When editing JavaScript or AutoHotkey or any other dynamic language where you can use variables without defining them, it is very useful to be able to select some text and find all occurances of that string.

I am struggling particularly with Notepad++ and AutoHotkey, which highlights word matches, but I want to be able to select half of a symbol, for example within Suggest_ShowToolTip, I can even just select ToolTip and it should show the matches of ToolTip anywhere in the buffer, even if it part of a larger symbol.

Does such a feature exist? Is it easy to implement?

4
  • 2
    This may seem like a silly question, but are you asking about how to do this in Emacs or in Notepad++? I ask because I am trying to understand the statement "I am struggling particularly with Notepad++ and AutoHotkey..."
    – nispio
    Apr 21, 2016 at 16:34
  • Sorry I meant that Notepad++ is no longer an option because I can't select a piece of text - it only allows words for this behaviour. Therefore I am sure that Emacs being the flexible editor that it is, should allow it. Apr 21, 2016 at 16:48
  • You can try msearch. There is a video about it on that page. Let me mention in advance that this video is an external link to my web pages. If you do not like external links then do not click it.
    – Tobias
    Apr 21, 2016 at 16:52
  • Sorry, that was the code. The description is there emacswiki.org/emacs/msearch and the video is there tn-home.de/Tobias/Soft/Elisp/msearch.avi
    – Tobias
    Apr 21, 2016 at 16:56

4 Answers 4

15

Functionality built-in to emacs:

With point on the word in question, type

M-s h .

to highlight all occurrences. Note that this matches the entire word, not substrings. Repeat this multiple times, each is assigned a unique color.

M-s h u

allows you to select which word to un-highlight. There are a few other highlighting commands, type M-s h C-h for a list.

For what it's worth, here is how I search for occurrences of a word.

  1. For a quick overview, use swiper. It's quick and very good at giving you a overview of the word across the entire document, but is transient: once you use it to traverse to another occurrence, you have to engage swiper again to traverse elsewhere.

  2. I-search. Still the most flexible search tool, and built-in to boot. Can easily search for substrings. Once you've found another occurrence, is quicker than swiper to find next (or prior) occurrence. You're still only seeing matches that currently fit on the screen, however. Has plenty of time-saving commands, which I only found out after years of using it, when I bothered to read the manual.

  3. occur-mode. Pretty awesome, and built-in: M-s o. Provides a persistent record of all matches for any regexp. May be the best option if you want to see and traverse through a list of all occurrences in a buffer. Easy to go back M-g pand forward M-g n, or jump to another occurrence.

Honorable mention goes to iedit. I don't use it often, but always enjoy it when I do. Hit the shortcut, and all matching occurrences are highlighted. Here's the bonus: start typing, and all occurrences are changed, not just the one where the cursor is. That's its basic idea. There are some fancy options, but I've not found the readme very clear about those.

I'll also mention idle-highlight. I've not used it, but it does advertise as doing what you describe. (Highlights other occurrences when cursor has been idle for a time.) Though I don't know if it handles substrings.

2
  • 2
    Note also that typing M-s o or M-s h r whilst isearching triggers occur or highlight-regexp using your current active isearch pattern, so it's trivial to transition from isearch to either of those other options.
    – phils
    Apr 22, 2016 at 5:49
  • The words for this is highlight-symbol-at-point, and here's the documentation, if that helps others
    – RyanWilcox
    Nov 20, 2022 at 18:11
3

C-s then type what you want to see matched. Or C-s followed by C-w (possibly repeated), to match words at the cursor. See the Emacs manual (C-h r), node Incremental Search.

3
  • As a slight tweak, if you replace isearch with phi-search (available through Melpa), then when you press C-s the search begins with the selected word.
    – nispio
    Apr 21, 2016 at 16:52
  • This will match any occurrence of the substring, which is useless for e.g. when I'm looking for all occurrences of i in a for loop
    – Romário
    Nov 23, 2021 at 0:06
  • @Romário: Did you follow the link to the doc? This page. An extract: "To begin a forward incremental word search, type M-s w. If incremental search is not already active, this runs the command isearch-forward-word. If incremental search is already active (whether a forward or backward search), M-s w runs the command isearch-toggle-word, which switches to a word search while keeping the direction of the search and the current search string unchanged. You can toggle word search back off by typing M-s w again.".
    – Drew
    Nov 23, 2021 at 4:13
0

Here's some code to make isearch smarter about regions.

(defun isearch-region-dwim-helper ()
  (when (region-active-p)
    (let* ((beg (min (mark) (point)))
           (end (max (mark) (point)))
           (search-text (buffer-substring-no-properties beg end))
           (symbol-bounds (bounds-of-thing-at-point 'symbol)))
      (when (and search-text
                 ;; Assume that multi-line regions should be extended,
                 ;; not searched literally.
                 (= (line-number-at-pos beg)
                    (line-number-at-pos end)))
        (deactivate-mark)
        (setq isearch-regexp t
              ;; If region is a subregion of the current symbol, then
              ;; limit it to the contents of symbols in the current buffer
              isearch-string (if (and (car symbol-bounds)
                                      (>= beg (car symbol-bounds))
                                      (<= end (cdr symbol-bounds)))
                                 (concat "\\_<"
                                         ;; If the region matches the
                                         ;; beginning or end of a symbol
                                         ;; anchor it there.
                                         (if (= beg (car symbol-bounds)) ""
                                           "\\(\\s_\\|\\sw\\)*")
                                         (regexp-quote search-text)
                                         (if (= end (cdr symbol-bounds)) ""
                                           "\\(\\s_\\|\\sw\\)*")
                                         "\\_>")
                               (regexp-quote search-text))
              isearch-message (mapconcat #'isearch-text-char-description
                                         isearch-string
                                         ""))))))

(add-hook 'isearch-mode-hook #'isearch-region-dwim-helper)
  • Multiline regions are always extended
  • Within-line regions are searched
  • Regions within symbols (inclusive) are constrained to be within symbols
  • Regions at the beginning/end of symbols are anchored to the beg/end of symbols

Combining this with expand-region turns out to be pretty awesome.

0

The current answers mention only highlighting, which isn't very useful on it's own. Why not modify all occurrences of the highlighted thing in the whole buffer at once?

Here's how to do it: install iedit and bind it to e.g. M-i:

(global-set-key (kbd "M-i") 'iedit-mode)

If you want to highlight modify only withing the current function, use C-u M-i.

Then simply edit within any of the green fields and the changes will propagate everywhere. You can also cycle between the fields with TAB and S-TAB.

One last thing: to toggle the highlight off, press M-i again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.