[英]How can I emulate Vim's * search in GNU Emacs?
在 Vim 中,正常模式下的 * 键搜索 cursor 下的单词。 在 GNU Emacs 中,最接近的本机等效项是:
C-s C-w
但这不完全一样。 它打开增量搜索迷你缓冲区并从当前缓冲区中的 cursor 复制到字的末尾。 在 Vim 中,您将搜索整个单词,即使您在按 * 时位于单词中间。
我已经做了一些 elisp 来做类似的事情:
(defun find-word-under-cursor (arg)
(interactive "p")
(if (looking-at "\\<") () (re-search-backward "\\<" (point-min)))
(isearch-forward))
在启动 isearch 之前,它会倒退到单词的开头。 我已经将它绑定到 C-+,它很容易在我的键盘上键入并且类似于 *,所以当我键入C-+ Cw
时,它会从单词的开头复制到搜索迷你缓冲区。
然而,这仍然不完美。 理想情况下,它会正则表达式搜索"\<" word "\>"
以不显示部分匹配(搜索单词“bar”不应匹配“foobar”,仅匹配“bar”)。 我尝试使用 search-forward-regexp 和 concat'ing \<> 但这不会包含在文件中,不会突出显示匹配项并且通常很蹩脚。 isearch-* function 似乎是最好的选择,但这些在编写脚本时表现不佳。
有任何想法吗? 任何人都可以对 elisp 提供任何改进吗? 还是有其他我忽略的方法?
根据您对我的第一个答案的反馈,这个怎么样:
(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)
突出显示符号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) 或突出显示与 cursor 下的符号匹配的符号 (Ctrl+F3)。 如果您的 cursor 处于单词中间,这些命令将继续执行正确的操作。
与 vim 的超级明星不同,高亮符号和符号之间的跳转绑定了两个不同的命令。 我个人不介意这种分离,但如果你想精确匹配 vim 的行为,你可以将这两个命令绑定在同一个击键下。
有很多方法可以做到这一点:
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)
Mickey of Mastering Emacs博客重新引入了一个很酷的“智能扫描”库,它提供了Mn
和Mp
的全局绑定,用于在缓冲区中的 cursor 下导航符号。 不影响搜索寄存器,因此它不是*
替换原样,而是导航问题的聪明且可用的替代方案。
内置命令 Mb Cs Cw 怎么样(单词开头,搜索,单词搜索)
我还没有尝试过,但是这里有一些代码叫做 Grep-O-Matic。
;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)
有了这个,您应该能够在 isearch 模式下执行 C-*。
(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))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.