25

我最近试用了Sublime Text 2,我发现Goto Anything对于导航源代码非常有用(Ctrl-P file@symbol似乎工作得很好)。Emacs 有类似的东西吗?最好是可以正常工作的东西,没有大量的自定义 elisp。

到目前为止我已经尝试过:

  1. 我见过HelmAnything但据我了解,它们都不能进行实际的“即时”搜索(请参阅下面的编辑)。

  2. 我用过multi-occur-in-matching-buffers,但它似乎也无法满足“即时”标准。

  3. imenu/idomenu适用于单个文件,但不适用于跨文件。

我目前将 #2 和 #3 一起使用,作为 Goto Anything 的不良替代品。

如果不是 Goto Anything 的精确克隆,那么我可以使用一个简单的即时搜索解决方案(一种在所有打开的缓冲区中搜索给定字符串并动态显示结果的解决方案)。所以这也是可以接受的。

我使用 Emacs 24.2,所以任何仅 v24 的 elisp 也可以。

编辑:在event_jr 的建议下,我又给了 Helm 一次机会,我发现它确实支持跨所有开放缓冲区的即时搜索。helm-multi-occur+helm-follow-mode出乎意料地接近满足我的需求,唯一的小问题是(听起来很挑剔):

  • 我还没有找到运行时helm-follow-mode 自动开启的方法helm-multi-occur。我必须手动调用它C-c C-f。有人愿意用 elisp 的片段来尝试一下吗?(见下面的编辑#2)

  • 它不像 ST2 的 Goto Anything 那样“智能”(即,它不理解源代码中的“符号”,就像 Goto Anything 那样)。

编辑#2:现在我已经掌握了大部分的 Goto 任何东西,这要感谢下面 event_jr 的回答(当然,还要感谢 Helm 的创建者Thierry Volpiatto)。我衷心推荐给任何寻找类似功能的人。以下是我目前正在使用的 elisp:

;; instant recursive grep on a directory with helm
(defun instant-rgrep-using-helm ()
  "Recursive grep in a directory."
  (interactive)
  (let ((helm-after-initialize-hook #'helm-follow-mode))
    (helm-do-grep)))


;; instant search across all buffers with helm
(defun instant-search-using-helm ()
  "Multi-occur in all buffers backed by files."
  (interactive)
  (let ((helm-after-initialize-hook #'helm-follow-mode))
    (helm-multi-occur
     (delq nil
           (mapcar (lambda (b)
                     (when (buffer-file-name b) (buffer-name b)))
                   (buffer-list))))))

;; set keybindings
(global-set-key (kbd "C-M-s") 'instant-search-using-helm)
(global-set-key (kbd "C-M-S-s") 'helm-resume)
(global-set-key (kbd "C-M-g") 'instant-rgrep-using-helm)
4

5 回答 5

19

只需使用掌舵。

它可能比您要求的配置更多,但是一旦您按照自己的喜好进行配置,它应该会很舒服。非常像 Emacs ;)。

你应该向 Thierry 提交一个错误,以获得一些对新手更友好的默认值。他对问题非常敏感。

helm-multi-occurring

主要是通过提供多缓冲区交互“发生” helm-multi-occur。如果您执行该命令,您会注意到您必须首先选择一些缓冲区(用于C-SPC从列表中选择, M-SPC以选择全部)。然后您可以在下一个提示符处输入您的查询。制作自己的跳过缓冲区选择的版本很容易,如下所示:

(eval-after-load "helm-regexp"
    '(setq helm-source-moccur
           (helm-make-source "Moccur"
               'helm-source-multi-occur :follow 1)))

(defun my-helm-multi-all ()
  "multi-occur in all buffers backed by files."
  (interactive)
  (helm-multi-occur
   (delq nil
         (mapcar (lambda (b)
                   (when (buffer-file-name b) (buffer-name b)))
                 (buffer-list)))))

掌舵缓冲区列表

通常你并不关心查询字符串的确切出现,而是想要一个包含它的所有缓冲区的列表。

helm-buffers-list有一些技巧。您指定的第一个符号是按主要模式过滤,您可以使用“@”前缀将列表缩小到包含字符串的缓冲区。

也就是说,“ruby @prompt”将显示一个缓冲区列表,其主要模式包含“ruby”并且其内容包含“prompt”。或者您可以只使用“@prompt”来显示所有包含“prompt”的缓冲区。


一旦你习惯了它,它就会强大而舒适。


EDIT修改my-helm-multi-all为启用 helm-follow-mode。

编辑 2更新helm-follow-mode代码以反映掌舵更改。

EDIT 3再次更新以反映helm 更改

于 2013-02-06T14:42:24.360 回答
7

Emacs 有Projectile满足你的需求:

  • 跳转到项目中的文件
  • 在项目缓冲区中多次出现
于 2013-02-06T14:34:21.653 回答
1
  1. Heml 远非 ST3 的模糊搜索。

  2. Fiplr看起来很有希望,但在我的笔记本电脑上不起作用(请参阅 github 上的第一个问题)

  3. Simp.el看起来像 Fiplr,但对我来说也不起作用。

  4. 弹丸对我有用!这是您的解决方案!

我还使用 ido-mode 和 flx-ido 进行模糊搜索,

对于显示结果的垂直方式,我在我的 .emacs 中使用它:

;; Display ido results vertically, rather than horizontally
(setq ido-decorations (quote ("\n-> " "" "\n   " "\n   ..." "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]" " [Confirm]")))
(defun ido-disable-line-truncation () (set (make-local-variable 'truncate-lines) nil))
(add-hook 'ido-minibuffer-setup-hook 'ido-disable-line-truncation)
(defun ido-define-keys () ;; C-n/p is more intuitive in vertical layout
  (define-key ido-completion-map (kbd "C-n") 'ido-next-match)
  (define-key ido-completion-map (kbd "C-p") 'ido-prev-match))
(add-hook 'ido-setup-hook 'ido-define-keys)
于 2014-08-05T06:48:29.377 回答
0

Icicles提供了一些与您正在寻找的功能相似的功能。

  1. C-x b并且C-x C-f,要选择缓冲区或文件,允许多重完成:您可以键入模式以匹配缓冲区/文件名和/或模式以匹配缓冲区/文件中的内容。候选人在您键入时会被逐步过滤(您所说的“即时”就是 Emacs 所说的“增量”)。您可以逐步细化一个或两个搜索模式,以不同的方式缩小选择范围。您可以同时访问任意数量的匹配缓冲区/文件。您也可以使用相同的方法在 Dired: 中搜索标记的文件C-F

  2. C-c `( icicle-search) 增量搜索多个缓冲区或文件。再次,渐进式细化等。

#1 和 #2 之间的主要区别是:

  • 对于#1,您只想找到匹配的缓冲区或文件。您不会立即关心找到特定的事件 --- 任何匹配就足够了。

  • 对于 #2,您提供要搜索的缓冲区或文件,并且您希望在搜索命中之间导航。

您还可以使用 #1 来定位所需的缓冲区和文件,然后搜索它们的内容:您上次使用的内容匹配模式可用作 Isearch ( C-s) 的搜索模式。

于 2013-08-10T21:07:43.660 回答
0

对于 emacs,我自定义和修改了这个解决方案(用于安装 helm):

(defun helm-occur-from-point (initial-value)
  "Invoke `helm-occur' from point."
  (interactive)
  (let ((input initial-value)
        (bufs (list (buffer-name (current-buffer)))))
    ;; (isearch-exit)
    (helm-occur-init-source)
    (helm-attrset 'moccur-buffers bufs helm-source-occur)
    (helm-set-local-variable 'helm-multi-occur-buffer-list bufs)
    (helm-set-local-variable
     'helm-multi-occur-buffer-tick
     (cl-loop for b in bufs
              collect (buffer-chars-modified-tick (get-buffer b))))
    (helm :sources 'helm-source-occur
          :buffer "*helm occur*"
          :history 'helm-grep-history
          :input input
          :truncate-lines t)))

(defun get-point-text ()
    "Get 'interesting' text at point; either word, or region"
    (if mark-active
        (buffer-substring (mark) (point))
      (thing-at-point 'symbol)))
  (defun helm-occur-1 (initial-value)
    "Preconfigured helm for Occur with initial input."
    (helm-occur-from-point initial-value))
  (defun bk-helm-occur ()
    "Invoke helm-occur with initial input configured from text at point"
    (interactive)
    (helm-occur-1 (get-point-text)))
  (global-set-key (kbd "M-s-o") 'bk-helm-occur)

主要基于@see https://news.ycombinator.com/item?id=6872508但在最后一个掌舵版本上不起作用但我的更改已修复(只需从一些内部掌舵模块复制/粘贴)

于 2014-09-18T21:17:38.993 回答