Emacs更快的书签跳?

时间:2013-07-05 19:53:18

标签: emacs elisp bookmarks

我的大多数书签都以字母为前缀 第一个字母几乎总是唯一地确定书签。 这样我可以,例如, 使用 M-x书签 - 跳转RET s RET 跳转到我的源文件夹(标记为“s:source”)。 我有一个快捷方式,所以它实际上是 ~s RET

我想最后摆脱 RET , 即获取 M-x书签 - 快速跳转RET ~s 做上述工作。 我也希望它回到默认行为:向我显示所有书签 从给定的字母开始,如果不是只有一个变体。

到目前为止,我已经:

(defun bookmark-do-quick-jump (str)
  (let ((completions (all-completions str bookmark-alist)))
    (bookmark-jump
     (if (eq 1 (length completions))
         (car completions)
       (completing-read "Jump to bookmark: " bookmark-alist nil t str)))))

还有两个小问题:

首先,我需要以某种方式跳入迷你缓冲区并坚持使用此地图(不知道该怎么做):

(setq bookmark-quick-jump-map
      (let ((map (make-sparse-keymap)))
        (mapcar (lambda (key) 
                  (define-key map key 
                    (lambda()
                      (interactive)
                      (bookmark-do-quick-jump key))))
                (loop for c from ?a to ?z
                      collect (string c)))
        map))

其次,当我打电话时

(bookmark-do-quick-jump "o")

它带有3个变体(org-capture-last-stored,org-capture-last-stored-marker ...)。 我现在在使用迷你缓冲区,但我仍然需要按 RET RET 看到这3个变种。我想这是自动完成的。

我很感激任何直接回答我的两个子问题的回复, 或者完全不同的方法,只要我能得到行为和可用性 我描述过。

UPD:

我已经通过从completing-read切换到ido-completing-read来解决了第二件事:

(defun bookmark-do-quick-jump (str)
  (let ((completions (all-completions str bookmark-alist)))
    (bookmark-jump
     (if (eq 1 (length completions))
         (car completions)
       (ido-completing-read "Jump to bookmark: " completions nil t str)))))
是的,我忘了提到我使用bookmark+。我不确定是否会跳到最低点 默认bookmark-jump支持。

3 个答案:

答案 0 :(得分:2)

我们可以在完成阅读期间重新映射self-insert-command以触发自动完成和自动接受行为。

我最初使用的(or (minibuffer-complete-and-exit) (minibuffer-completion-help))乍一看工作非常好但是,如评论中所述,当一个书签的名称是另一个书签的前缀时,它不太理想,因为它会立即接受较短的名称,因此使较长的一个不可访问。

同时调用minibuffer-completeminibuffer-completion-help会破坏完成功能,因此我将minibuffer-complete-and-exit的相关部分复制到新功能中。使用它可以解决所有早期的问题。

(require 'bookmark)

(defvar bookmark-do-quick-jump-map (copy-keymap minibuffer-local-must-match-map)
  "Keymap for `bookmark-do-quick-jump'.

`minibuffer-local-must-match-map' is used by `completing-read' when its
REQUIRE-MATCH argument is t.

In `bookmark-do-quick-jump' we bind this modified copy to use in its place.")

(define-key bookmark-do-quick-jump-map
  [remap self-insert-command] 'my-self-insert-complete-and-exit)

(defun bookmark-do-quick-jump ()
  "Jump to specified bookmark with auto-completion and auto-acceptance."
  (interactive)
  (bookmark-maybe-load-default-file)
  (let ((minibuffer-local-must-match-map bookmark-do-quick-jump-map))
    (bookmark-jump
     (completing-read "Jump to bookmark: " bookmark-alist nil t))))

(defun my-self-insert-complete-and-exit (n)
  "Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains, and displaying the
completion options otherwise."
  (interactive "p")
  (self-insert-command n)
  (my-minibuffer-complete)
  (let ((my-completions (completion-all-sorted-completions)))
    (if (and my-completions (eq 0 (cdr my-completions)))
        (exit-minibuffer)
      (minibuffer-completion-help))))

(defun my-minibuffer-complete ()
  "Copied from `minibuffer-complete-and-exit'."
  (interactive)
  (condition-case nil
      (completion--do-completion nil 'expect-exact)
    (error 1)))

修改

我使用偶像再次刺伤了这个。有点不幸的是,你没有像常规迷你缓冲区完成那样强调下一个“重要角色”(因为这是下一步输入内容的一个很好的指示),但这似乎在其他方面很有效。

(require 'bookmark)
(require 'ido)

(defvar bookmark-ido-quick-jump-map (copy-keymap minibuffer-local-map)
  "Keymap for `bookmark-ido-quick-jump'.

Every time `ido-completing-read' is called it re-initializes
`ido-common-completion-map' and sets its parent to be `minibuffer-local-map'.

In `bookmark-ido-quick-jump' we provide this modified copy as a replacement
parent.")

(define-key bookmark-ido-quick-jump-map
  [remap self-insert-command] 'my-self-insert-and-ido-complete)

(defun bookmark-ido-quick-jump ()
  "Jump to selected bookmark, using auto-completion and auto-acceptance."
  (interactive)
  (bookmark-maybe-load-default-file)
  (let ((minibuffer-local-map bookmark-ido-quick-jump-map)
        (ido-enable-prefix t))
    (bookmark-jump
     (ido-completing-read "Jump to bookmark: " 
                          (loop for b in bookmark-alist collect (car b))))))

(defun my-self-insert-and-ido-complete (n)
  "Insert the character, then attempt to complete the current string,
automatically exiting when only one option remains."
  (interactive "p")
  (self-insert-command n)
  ;; ido uses buffer-local pre- and post-command hooks, so we need to
  ;; co-operate with those. We append our post-command function so that
  ;; it executes after ido has finished processing our self-insert.
  (add-hook 'post-command-hook
            'my-self-insert-and-ido-complete-post-command t t))

(defun my-self-insert-and-ido-complete-post-command ()
  (remove-hook 'post-command-hook
               'my-self-insert-and-ido-complete-post-command t)
  ;; Now that ido has finished its normal processing for the current
  ;; command, we simulate a subsequent `ido-complete' command.
  (ido-tidy) ;; pre-command-hook
  (ido-complete)
  (ido-exhibit)) ;; post-command-hook

答案 1 :(得分:2)

这是另一个想法:

(defun bookmark-do-quick-jump (str)
  (let ((completions (all-completions str bookmark-alist)))
    (if (null (cdr completions))
        (bookmark-jump (car completions))
      (minibuffer-with-setup-hook
          (lambda () (insert str)
                     (minibuffer-completion-help))
        (call-interactively 'bookmark-jump)))))

或者另一个(甚至更有保证未经测试):

(defadvice bookmark-jump (around quick-bookmarks activate)
  (minibuffer-with-setup-hook
      (lambda ()
        (add-hook 'post-self-insert-hook
                  (lambda ()
                    (let ((completions
                           (all-completions (minibuffer-contents)
                                            bookmark-alist)))
                      (if (cdr completions)
                          (minibuffer-completion-help)
                        (minibuffer-complete-and-exit))))
                  nil t))
    ad-do-it))

答案 2 :(得分:0)

听起来你正在做很多额外的工作。只需使用 Icicles 即可。

  • 用户选项icicle-incremental-completion非 - nil和非 - t表示您输入后立即显示所有匹配项。

  • 选项icicle-top-level-when-sole-completion-flag非 - nil表示接受单独匹配而无需点击密钥(例如 RET )。

您可以将它们绑定到您自己命令中的值,而不是自定义选项以获得这些值。