How can I emulate Vim's * search in GNU Emacs?

前端 未结 9 1530
星月不相逢
星月不相逢 2020-12-23 16:57

In Vim the * key in normal mode searches for the word under the cursor. In GNU Emacs the closest native equivalent would be:

C-s C-w

But th

相关标签:
9条回答
  • 2020-12-23 17:25

    I have not tried it but there is some code here called Grep-O-Matic.

    0 讨论(0)
  • 2020-12-23 17:26

    The highlight symbol emacs extension provides this functionality. In particular, the recommend .emacsrc setup:

    (require 'highlight-symbol)
    
    (global-set-key [(control f3)] 'highlight-symbol-at-point)
    (global-set-key [f3] 'highlight-symbol-next)
    (global-set-key [(shift f3)] 'highlight-symbol-prev)
    

    Allows jumping to the next symbol at the current point (F3), jumping to the previous symbol (Shift+F3) or highlighting symbols matching the one under the cursor (Ctrl+F3). The commands continue to do the right thing if your cursor is mid-word.

    Unlike vim's super star, highlighting symbols and jumping between symbols are bound to two different commands. I personally don't mind the separation, but you could bind the two commands under the same keystroke if you wanted to precisely match vim's behaviour.

    0 讨论(0)
  • 2020-12-23 17:32

    With this you should be able to do C-* while in isearch mode.

    (define-key isearch-mode-map [?\C-*] 'kmk-isearch-yank-thing)
    
    (defun kmk-isearch-yank-thing ()
      "Pull next thing from buffer into search string."
      (interactive)
      (let ((string (regexp-quote (thing-at-point 'word))))
        (setq isearch-string 
          (concat isearch-string "\\")
          isearch-message
          (concat isearch-message
              (mapconcat 'isearch-text-char-description
                     string ""))
          ;; Don't move cursor in reverse search.
          isearch-yank-flag t))
      (setq isearch-regexp t isearch-word nil isearch-success t isearch-adjusted t)
      (isearch-search-and-update))
    
    0 讨论(0)
  • 2020-12-23 17:33
    ;Here is my version: Emulates Visual Studio/Windows key bindings 
    ; C-F3 - Start searching the word at the point
    ; F3 searches forward and Shift F3 goes reverse
    
    (setq my-search-wrap nil)
    
    (defun my-search-func (dir)
      (interactive)
      (let* ((text (car search-ring)) newpoint)
            (when my-search-wrap  
                 (goto-char (if (= dir 1) (point-min) (point-max)))
                 (setq my-search-wrap nil))
            (setq newpoint (search-forward text nil t dir))
            (if newpoint
              (set-mark (if (= dir 1) (- newpoint (length text))
                             (+ newpoint (length text))))
              (message "Search Failed: %s" text) (ding)
              (setq my-search-wrap text))))
    
    (defun my-search-fwd () (interactive) (my-search-func 1))
    (defun my-search-bwd () (interactive) (my-search-func -1))
    
    (defun yank-thing-into-search ()
       (interactive)
       (let ((text (if mark-active
              (buffer-substring-no-properties (region-beginning)(region-end))
                     (or (current-word) ""))))
         (when (> (length text) 0) (isearch-update-ring text) (setq my-search-wrap nil)
                (my-search-fwd))))
    (global-set-key (kbd "")    'my-search-fwd)            ; Visual Studio like search keys
    (global-set-key (kbd "")  'my-search-bwd)
    (global-set-key (kbd "")  'yank-thing-into-search)
    
    
    0 讨论(0)
  • 2020-12-23 17:35

    Mickey of Mastering Emacs blog reintroduced a cool "Smart Scan" lib that gives global bindings of M-n and M-p for navigating symbols under the cursor in the buffer. Doesn't affect search register so it's not a * replacement as is, but a clever and usable alternative to the navigation problem.

    0 讨论(0)
  • 2020-12-23 17:37

    scottfrazer's answer works well for me, except for words that end in '_' (or perhaps other non-word characters?). I found that the code for light-symbol mode was using a different regex for word boundary depending on the version of emacs, and that fixed it for me. Here is the modified code:

    (defconst my-isearch-rx-start
      (if (< emacs-major-version 22)
          "\\<"
        "\\_<")
      "Start-of-symbol regular expression marker.")
    
    (defconst my-isearch-rx-end
      (if (< emacs-major-version 22)
          "\\>"
        "\\_>")
      "End-of-symbol regular expression marker.")
    
    (defun my-isearch-word-at-point ()
      (interactive)
      (call-interactively 'isearch-forward-regexp))
    
    (defun my-isearch-yank-word-hook ()
      (when (equal this-command 'my-isearch-word-at-point)
        (let ((string (concat my-isearch-rx-start
                              (buffer-substring-no-properties
                               (progn (skip-syntax-backward "w_") (point))
                               (progn (skip-syntax-forward "w_") (point)))
                              my-isearch-rx-end)))
          (if (and isearch-case-fold-search
                   (eq 'not-yanks search-upper-case))
              (setq string (downcase string)))
          (setq isearch-string string
                isearch-message
                (concat isearch-message
                        (mapconcat 'isearch-text-char-description
                                   string ""))
                isearch-yank-flag t)
          (isearch-search-and-update))))
    
    (add-hook 'isearch-mode-hook 'my-isearch-yank-word-hook)
    
    0 讨论(0)
提交回复
热议问题