33

在 Vim 中,正常模式下的 * 键搜索光标下的单词。在 GNU Emacs 中,最接近的原生等价物是:

C-s C-w

但这不完全一样。它打开增量搜索迷你缓冲区并从当前缓冲区中的光标复制到单词的末尾。在 Vim 中,您会搜索整个单词,即使您在按 * 时位于单词的中间。

我已经做了一些 elisp 来做类似的事情:

(defun find-word-under-cursor (arg)
  (interactive "p")
  (if (looking-at "\\<") () (re-search-backward "\\<" (point-min)))
  (isearch-forward))

在启动 isearch 之前,它会倒退到单词的开头。我已经将它绑定到 C-+,它很容易在我的键盘上键入并且类似于 *,所以当我键入C-+ C-w它时,它会从单词的开头复制到搜索迷你缓冲区。

然而,这仍然不完美。理想情况下,它会正则表达式搜索"\<" word "\>"不显示部分匹配(搜索单词“bar”不应该匹配“foobar”,只匹配“bar”)。我尝试使用 search-forward-regexp 和 concat'ing \<> 但这不会包含在文件中,不会突出显示匹配项并且通常很蹩脚。isearch-* 函数似乎是最好的选择,但这些函数在编写脚本时表现不佳。

有任何想法吗?任何人都可以对 elisp 提供任何改进吗?还是有其他我忽略的方法?

4

9 回答 9

15

根据您对我的第一个答案的反馈,这个怎么样:

(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 "\\<"
                          (buffer-substring-no-properties
                           (progn (skip-syntax-backward "w_") (point))
                           (progn (skip-syntax-forward "w_") (point)))
                          "\\>")))
      (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)
于 2009-02-26T15:07:01.857 回答
7

高亮符号emacs 扩展提供了这个功能。特别是,推荐的.emacsrc设置:

(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)

允许跳到当前点的下一个符号 (F3)、跳到上一个符号 (Shift+F3) 或突出显示与光标下的符号匹配的符号 (Ctrl+F3)。如果您的光标位于单词中间,这些命令将继续执行正确的操作。

与 vim 的超级明星不同,高亮符号和符号之间的跳转绑定了两个不同的命令。我个人不介意这种分离,但如果你想精确匹配 vim 的行为,你可以将这两个命令绑定在同一个击键下。

于 2011-06-11T05:55:23.010 回答
5

有很多方法可以做到这一点:

http://www.emacswiki.org/emacs/SearchAtPoint

于 2009-02-26T12:41:43.530 回答
3

scottfrazer 的答案对我来说效果很好,除了以 '_' 结尾的单词(或者可能是其他非单词字符?)。我发现轻符号模式的代码根据 emacs 的版本对单词边界使用了不同的正则表达式,这对我来说是固定的。这是修改后的代码:

(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)
于 2009-09-02T19:19:07.090 回答
2

内置命令 Mb Cs Cw 怎么样(单词开头,搜索,单词搜索)

于 2010-05-11T18:49:57.453 回答
2

Mastering Emacs博客的Mickey重新引入了一个很酷的“ Smart Scan ”库,它提供了全局绑定M-nM-p用于在缓冲区中的光标下导航符号。不影响搜索寄存器,因此它不是原样的*替代品,而是导航问题的聪明且可用的替代品。

于 2013-11-05T09:02:59.957 回答
1

我还没有尝试过,但是这里有一些代码叫做Grep-O-Matic。

于 2009-02-26T09:14:03.013 回答
0

有了这个,您应该能够在 isearch 模式下执行 C-*。

(定义键 isearch-mode-map [?\C-*] 'kmk-isearch-yank-thing)

(defun kmk-isearch-yank-thing ()
  “将下一件事从缓冲区拉到搜索字符串中。”
  (交互的)
  (let ((string (regexp-quote (thing-at-point 'word))))
    (setq isearch-string
      (连接 isearch 字符串“\\”)
      isearch 消息
      (连接 isearch 消息
          (mapconcat 'isearch-text-char-description
                 细绳 ””))
      ;; 不要在反向搜索中移动光标。
      isearch-yank-flag t))
  (setq isearch-regexp t isearch-word nil isearch-success t isearch-adjusted t)
  (isearch-搜索和更新))
于 2009-02-26T09:30:17.313 回答
0
;这是我的版本:模拟 Visual Studio/Windows 键绑定
; C-F3 - 开始搜索该点的单词
; F3 向前搜索,Shift F3 向后搜索

(setq my-search-wrap nil)

(defun my-search-func (dir)
  (交互的)
  (let* ((text (car search-ring)) newpoint)
        (当我的搜索换行  
             (goto-char (if (= dir 1) (point-min) (point-max)))
             (setq my-search-wrap nil))
        (setq newpoint (search-forward text nil t dir))
        (如果新点
          (set-mark (if (= dir 1) (- newpoint (length text))
                         (+ newpoint (长度文本))))
          (消息“搜索失败:%s”文本)(叮)
          (setq my-search-wrap 文本))))

(defun my-search-fwd () (交互式) (my-search-func 1))
(defun my-search-bwd () (交互式) (my-search-func -1))

(defun yank-thing-into-search ()
   (交互的)
   (让((文本(如果标记激活
          (缓冲区子字符串无属性(区域开始)(区域结束))
                 (或(当前词)“”))))
     (when (> (length text) 0) (isearch-update-ring text) (setq my-search-wrap nil)
            (我的搜索转发))))
(global-set-key (kbd "") 'my-search-fwd) ; Visual Studio 之类的搜索键
(global-set-key (kbd "") 'my-search-bwd)
(global-set-key (kbd "") 'yank-thing-into-search)

于 2010-01-24T21:59:32.710 回答