Does Emacs scan a bookmark faster?

I have most of my bookmarks with a letter prefix such that the first letter almost always uniquely identifies the bookmark. Thus, I can, for example, go to the source folder (with the "s: source" tab) using Mx bookmark-jump RET s RET . I have a shortcut, so actually ~ s RET .

I would like to get rid of RET at the end, i.e. get Mx bookmark-quick-jump RET s or ~ s to do the above work. I would also like to return to the default behavior: show me all bookmarks that start with a given letter, if not one option.

So far I have had:

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

There are two more hiccups:

Firstly, I need to somehow jump into the minibuffer and insert this card there (I don’t know how to do this):

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

Secondly, when I call

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

It comes back with three options (org-capture-last-stored, org-capture-last-stored-marker ...). I'm in the minibuffer now, but I still need to press RET RET to see these 3 options. I would like it to be done automatically.

I would appreciate any answers that either directly answer my two problems, or a completely different approach if I can get the behavior and usability that I described.

UPD:

I solved the second thing by switching from completing-read to 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))))) 

By the way, I forgot to mention that I use bookmark+ . I'm not sure if jump is supported by default bookmark-jump .

+4
source share
3 answers

We can reassign self-insert-command during read completion to trigger autocompletion and auto-accept behavior.

I initially used (or (minibuffer-complete-and-exit) (minibuffer-completion-help)) , which at first glance worked very well, but, as noted in the comments, is less ideal when one bookmark name is a prefix of another, so how it will immediately take a shorter name, a longer inaccessible.

Calling minibuffer-complete and minibuffer-completion-help together violates the completion functionality, however instead I copied the corresponding part of minibuffer-complete-and-exit to a new function. Using this, resolve all previous issues.

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

Edit:

I took another hit using ido. It’s a little annoying that you won’t get the next “important character" underlined by how you do it with the usual completion of the minibuffer (since it was a good indicator of what to enter next), but it seems to work well in other respects.

 (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 tt)) (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 
+2
source

Here is another take:

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

Or another (even more guaranteed untested):

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

It looks like you are doing a lot of extra work. Just use icicles .

  • The custom option icicle-incremental-completion not nil and not t means to display all matches as soon as you enter the input.

  • The icicle-top-level-when-sole-completion-flag option not nil means accepting a single match without having to press a key (for example, RET ).

Instead of adjusting the parameters to have these values ​​in general, you can just bind them to the values ​​in your own command.

0
source

Source: https://habr.com/ru/post/1489966/


All Articles