Sometimes, I press the wrong combination of keys and get the wrong minibuffer. I'd like to kill my current minibuffer and open a new one by just pressing the key-combination for the desired minibuffer option. How do I do that?
Not sure if this is a good idea or not.
(setq enable-recursive-minibuffers t)
(add-hook 'minibuffer-setup-hook 'my-minibuffer-unrecursion)
(defun my-minibuffer-unrecursion ()
(when (> (minibuffer-depth) 1)
(run-with-timer 0 nil 'my-interactive-command
this-command current-prefix-arg)
(abort-recursive-edit)))
(defun my-interactive-command (cmd arg)
(let ((current-prefix-arg arg))
(call-interactively cmd)))
Related
And I dont want this behavior. Actually, not everytime is focus switched. For example, buffers like *Help* or *Message* does not have this behavior, this unwanted feature is active only when closing regular file buffers.
How to disable this feature completelly ?
My solution for this problem is simply write my own handler for buffer kill. Hope it will help someone in future.
(global-set-key (kbd "C-w")
(lambda ()
(interactive)
(if (string= (substring (buffer-name) 0 2) " *")
(progn
(message "You can not kill protected BUFFER"))
(progn
(if (string= (substring (buffer-name) 0 1) "*")
(progn
(call-interactively 'kill-buffer))
(progn
(call-interactively 'kill-buffer)
(run-at-time "0.5 sec" nil
(lambda ()
(call-interactively 'windmove-right)))))))))
You need to have installed ace-window package for windmove-right, that feature with protected buffers is not relevant to this answer so you can freely remove it.
I'd like to make a simple change to Emacs so that the next-buffer and previous-buffer commands (which I have bound to C-x <RIGHT> and C-x <LEFT> will skip over the *Messages* buffer.
I'm using Emacs 24 and the Emacs Starter Kit.
I've read the following related questions and answers, but they are not what I want:
Buffer cycling in Emacs: avoiding scratch and Messages buffer
Emacs disable *Messages* buffer
Emacs Lisp Buffer out of focus function?
Here are some of the reasons why they don't work:
I'd like to keep it as simple as possible. Fewer configuration changes are better.
I don't want to kill or prevent *Messages* altogether.
(add-to-list 'ido-ignore-buffers "^\*Messages\*" helps with my C-x b (ido-switch-buffer) but does not change how next-buffer and previous-buffer behave.
This way you can avoid the infinite loop:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(string-match-p "^\*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
This code loops over non-starred buffers ("^\*"). For your case (only avoid *Messages*) it would be:
(defun next-code-buffer ()
(interactive)
(let (( bread-crumb (buffer-name) ))
(next-buffer)
(while
(and
(equal "*Messages*" (buffer-name))
(not ( equal bread-crumb (buffer-name) )) )
(next-buffer))))
(global-set-key [remap next-buffer] 'next-code-buffer)
You can write previous-code-buffer just replacing every next-buffer with previous-buffer.
The simplest I can think of is defining an advice for both functions. Here it is for next-buffer. Similarly would be for previous-buffer. You can also define a configuration variable to enable/disable the behavior (or activating/deactivating the advice):
(defadvice next-buffer (after avoid-messages-buffer-in-next-buffer)
"Advice around `next-buffer' to avoid going into the *Messages* buffer."
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
;; activate the advice
(ad-activate 'next-buffer)
Maybe you can compare buffers in some other way instead of its string name, but that will work. The code for previous buffer is almost the same. I don't know either if there is a way of calling the original function without triggering the advice once inside the advice itself, but again, the code will work even if the name of the buffer is tested afterwards (will fail if you just have one buffer, and it is the messages buffer; some code can check if there is just one buffer and don't call next-buffer again).
If you want to use a standalone function that does the same thing:
(defun my-next-buffer ()
"next-buffer, only skip *Messages*"
(interactive)
(next-buffer)
(when (string= "*Messages*" (buffer-name))
(next-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-next-buffer)
This is what I'm using, based on Diego's answer:
(setq skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-next-buffer ()
"next-buffer that skips certain buffers"
(interactive)
(next-buffer)
(while (member (buffer-name) skippable-buffers)
(next-buffer)))
(defun my-previous-buffer ()
"previous-buffer that skips certain buffers"
(interactive)
(previous-buffer)
(while (member (buffer-name) skippable-buffers)
(previous-buffer)))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
It is not great yet, because it will hang if there are no buffers other than the skippable-buffers I list. I use C-g to break out of the loop when it happens as a hackaround.
As RubenCaro's answer points out, the other answers can enter infinite loops. I thought David James' approach of a skippable buffers list was a bit nicer, though, so here's a variant of that.
(setq my-skippable-buffers '("*Messages*" "*scratch*" "*Help*"))
(defun my-change-buffer (change-buffer)
"Call CHANGE-BUFFER until current buffer is not in `my-skippable-buffers'."
(let ((initial (current-buffer)))
(funcall change-buffer)
(let ((first-change (current-buffer)))
(catch 'loop
(while (member (buffer-name) my-skippable-buffers)
(funcall change-buffer)
(when (eq (current-buffer) first-change)
(switch-to-buffer initial)
(throw 'loop t)))))))
(defun my-next-buffer ()
"`next-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'next-buffer))
(defun my-previous-buffer ()
"`previous-buffer' that skips `my-skippable-buffers'."
(interactive)
(my-change-buffer 'previous-buffer))
(global-set-key [remap next-buffer] 'my-next-buffer)
(global-set-key [remap previous-buffer] 'my-previous-buffer)
I have most of my bookmarks prefixed by a letter in a way that
the first letter almost always uniquely determines the bookmark.
This way I can, for instance,
jump to my source folder (bookmarked as "s: source") with M-x bookmark-jump RET s RET.
I have it on a shortcut, so it's actually ~ s RET.
I'd like to get rid of RET in the end,
i.e. get M-x bookmark-quick-jump RET s or ~ s
to do the aforementioned job.
I'd also like it to fall back to the default behavior: to show me all bookmarks
that start with the given letter, in case there's not just one variant.
So far, I've got:
(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's still two hiccups:
Firstly, I need to jump into minibuffer somehow and stick in there this map (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 do a call
(bookmark-do-quick-jump "o")
It comes back with 3 variants (org-capture-last-stored, org-capture-last-stored-marker...).
I'm in minibuffer now, but I still need to press RET RET
to see these 3 variants. I'd like this to be done automatically.
I'd appreciate any responses that either directly answer my two sub-problems,
or an altogether different approach, as long as I can get the behavior and usability
that I described.
UPD:
I've 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)))))
Btw, I forgot to mention that I use bookmark+. I'm not sure if jumping to dired
is supported by the default bookmark-jump.
We can remap self-insert-command during the completing-read to trigger the auto-completion and auto-acceptance behaviour.
I originally used (or (minibuffer-complete-and-exit) (minibuffer-completion-help)) which at first glance worked very nicely but, as noted in the comments, is less than ideal when one bookmark's name is the prefix of another, as it will immediately accept the shorter name, hence making the longer one inaccessible.
Calling minibuffer-complete and minibuffer-completion-help together breaks the completion functionality, however, so instead I've copied the relevant part of minibuffer-complete-and-exit to a new function. Using this resolves all of the earlier problems.
(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 stab at this using ido. It's a little unfortunate that you don't get the next 'important character' highlighted the way that you do with the regular minibuffer completion (as that was a nice indicator of what to type next), but this seems to work nicely 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 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
Here's 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 yet 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))
Sounds like you're doing a lot of extra work. Just use Icicles.
User option icicle-incremental-completion non-nil and non-t means show all matches as soon as you type input.
Option icicle-top-level-when-sole-completion-flag non-nil means accept a solitary match without your needing to hit a key (e.g. RET).
Instead of customizing the options to have these values in general, you can just bind them to the values in your own command.
I have some custom scrolling functions in Emacs, which help me get around a bug where a single scroll event sends two <mouse-4> or <mouse-5> actions. I have:
(setq scroll-down-this-time t)
(defun my-scroll-down-line ()
(interactive "#")
(if scroll-down-this-time
(progn
(scroll-down-line)
(setq scroll-down-this-time nil))
(setq scroll-down-this-time t)))
(setq scroll-up-this-time t)
(defun my-scroll-up-line ()
(interactive "#")
(if scroll-up-this-time
(progn
(scroll-up-line)
(setq scroll-up-this-time nil))
(setq scroll-up-this-time t)))
(global-set-key (kbd "<mouse-4>") 'my-scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'my-scroll-up-line)
This works perfectly, except that the (interactive "#") isn't exactly what I want. This causes whatever buffer that is under the mouse to scroll and to gain the keyboard focus. I want a way to make it scroll, but not steal the keyboard focus (like (setq mouse-wheel-follow-mouse 't) does for the normal scrolling library). How might I achieve this?
I am using the development version of Emacs, so don't be afraid to give me any new features.
You should not redefine <mouse-4> and <mouse-5>, but instead:
(mouse-wheel-mode 1)
(defvar alternating-scroll-down-next t)
(defvar alternating-scroll-up-next t)
(defun alternating-scroll-down-line (&optional arg)
(when alternating-scroll-down-next
(scroll-down-line (or arg 1)))
(setq alternating-scroll-down-next (not alternating-scroll-down-next)))
(defun alternating-scroll-up-line (&optional arg)
(when alternating-scroll-up-next
(scroll-up-line (or arg 1)))
(setq alternating-scroll-up-next (not alternating-scroll-up-next)))
(setq mwheel-scroll-up-function 'alternating-scroll-up-line)
(setq mwheel-scroll-down-function 'alternating-scroll-down-line)
I want to make the compilation window in Emacs to always appear at the bottom of a window, and always be a certain height. So far I put the following lines in my .emacs file:
(setq split-height-threshold 0)
(setq compilation-window-height 10)
...and it does work for when I have only one window open, but as soon as I split the screen into two windows horizontally (that is, the dividing line in the middle goes from the top to the bottom), the compilation window stops respecting the height variable, and splits the window right in the middle.
How do I fix this?
I would use something like this, freely adapted from the EmacsWiki:
(defun my-compilation-hook ()
(when (not (get-buffer-window "*compilation*"))
(save-selected-window
(save-excursion
(let* ((w (split-window-vertically))
(h (window-height w)))
(select-window w)
(switch-to-buffer "*compilation*")
(shrink-window (- h compilation-window-height)))))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)
If the *compilation* buffer is not visible, this will split the window vertically, resize the newly opened window to 10 lines height, and open the *compilation* buffer in it.
You can customize the variable compilation-window-height.
Combining code from How can I prevent emacs from opening new window for compilation output? and code from http://www.emacswiki.org/emacs/CompilationMode, this is all my code for compile, it provides you 4 features:
1). Use compile-again to run the same compile as the last time automatically, no prompt. If there is no last time, or there is a prefix argument, it acts like M-x compile.
2). compile will split the current window(always be a certain size), it will not affect the other windows in this frame.
3). it will auto-close the *compilation* buffer (window) if there is no error, keep it if error exists.
4). it will highlight the error line and line number of the source code in the *compilation* buffer, use M-n/p to navigate every error in *compilation* buffer, Enter in the error line to jump to the line in your code code.
(require 'compile)
(setq compilation-last-buffer nil)
(defun compile-again (ARG)
"Run the same compile as the last time.
If there is no last time, or there is a prefix argument, this acts like M-x compile."
(interactive "p")
(if (and (eq ARG 1)
compilation-last-buffer)
(progn
(set-buffer compilation-last-buffer)
(revert-buffer t t))
(progn
(call-interactively 'compile)
(setq cur (selected-window))
(setq w (get-buffer-window "*compilation*"))
(select-window w)
(setq h (window-height w))
(shrink-window (- h 10))
(select-window cur))))
(global-set-key (kbd "C-x C-m") 'compile-again)
(defun my-compilation-hook ()
"Make sure that the compile window is splitting vertically."
(progn
(if (not (get-buffer-window "*compilation*"))
(progn
(split-window-vertically)))))
(add-hook 'compilation-mode-hook 'my-compilation-hook)
(defun compilation-exit-autoclose (STATUS code msg)
"Close the compilation window if there was no error at all."
;; If M-x compile exists with a 0
(when (and (eq STATUS 'exit) (zerop code))
;; then bury the *compilation* buffer, so that C-x b doesn't go there
(bury-buffer)
;; and delete the *compilation* window
(delete-window (get-buffer-window (get-buffer "*compilation*"))))
;; Always return the anticipated result of compilation-exit-message-function
(cons msg code))
(setq compilation-exit-message-function 'compilation-exit-autoclose)
(defvar all-overlays ())
(defun delete-this-overlay(overlay is-after begin end &optional len)
(delete-overlay overlay)
)
(defun highlight-current-line ()
"Highlight current line."
(interactive)
(setq current-point (point))
(beginning-of-line)
(setq beg (point))
(forward-line 1)
(setq end (point))
;; Create and place the overlay
(setq error-line-overlay (make-overlay 1 1))
;; Append to list of all overlays
(setq all-overlays (cons error-line-overlay all-overlays))
(overlay-put error-line-overlay
'face '(background-color . "red"))
(overlay-put error-line-overlay
'modification-hooks (list 'delete-this-overlay))
(move-overlay error-line-overlay beg end)
(goto-char current-point))
(defun delete-all-overlays ()
"Delete all overlays"
(while all-overlays
(delete-overlay (car all-overlays))
(setq all-overlays (cdr all-overlays))))
(defun highlight-error-lines(compilation-buffer process-result)
(interactive)
(delete-all-overlays)
(condition-case nil
(while t
(next-error)
(highlight-current-line))
(error nil)))
(setq compilation-finish-functions 'highlight-error-lines)
There's an excellent package for these situations named Shackle. https://github.com/wasamasa/shackle
Easy to set up and works on pretty much any type of buffer