How to enter minibuffer for editing in Emacs? - emacs

When running certain commands, the mini-buffer asks input strings, (e.g. the C-M-s).
Sometimes I need to enter complex strings into minibuffer. Therefore, I need to use movement commands such as C-f, C-b, C-a, etc. However, these does not work when I am entering string inside command C-M-s.
So, what is the general command / key-bindings for me to focus point in mini-buffer for extended movement support?
Edit:
I just discovered that M-e will work for searching commands. But I am not sure whether this command is the general command to "switch from buffer to minibuffer for dedicated editing"

Yes, M-e is what you are looking for, if you want to edit the search string. It lets you perform general editing on it. Just hit C-s or C-M-s again when you are ready to search for the edited string.
However, M-e is only for editing the search string. If you instead want to interrupt isearch to do some editing somewhere, then just end isearch to do that, and then resume isearch when done editing, by using C-s or C-M-s again.

I have been happy using these and I bind them to the function button and arrow keys on my Mac keyboard. I frequently block and copy text and move in and out of the mini-buffer. The following example frees up some of the keymap assignments in the minibuffer-local-map and minibuffer-local-completion-map (i.e., by setting them to nil) so that I can use my own custom keyboard shortcuts to enter and exit the mini-buffer.
From inside the mini-buffer, you can use C-h k and then the type the keyboard shortcut to see what function is bound.
When I switch in and out of the mini-buffer window, I use a custom function that changes the mode-line color, and mini-buffer prompt color, and default color inside the mini-buffer, but that is beyond the scope of your question. [I just add the name of my mini-buffer color change function at the tail end of the following four functions -- i.e., after the if / then statements.]
(defun lawlist-windmove-right ()
(interactive)
(if (window-in-direction 'right)
(select-window (window-in-direction 'right))
(other-window 1)))
(defun lawlist-windmove-left ()
(interactive)
(if (window-in-direction 'left)
(select-window (window-in-direction 'left))
(other-window -1)))
(defun lawlist-windmove-up ()
(interactive)
(if (window-in-direction 'above)
(select-window (window-in-direction 'above))
(other-window 1)))
(defun lawlist-windmove-down ()
(interactive)
(if (window-in-direction 'below)
(select-window (window-in-direction 'below))
(other-window -1)))
(define-key minibuffer-local-map [prior] nil)
(define-key minibuffer-local-map [next] nil)
(define-key minibuffer-local-map [home] nil)
(define-key minibuffer-local-map [end] nil)
(define-key minibuffer-local-completion-map [prior] nil)
(define-key minibuffer-local-completion-map [next] nil)
(define-key minibuffer-local-completion-map [home] nil)
(define-key minibuffer-local-completion-map [end] nil)
(global-set-key (kbd "<end>") 'lawlist-windmove-right)
(global-set-key (kbd "<home>") 'lawlist-windmove-left)
(global-set-key (kbd "<prior>") 'lawlist-windmove-up)
(global-set-key (kbd "<next>") 'lawlist-windmove-down)

Related

Evil Emacs: is there a way to disable vim-like keys in «insert» mode?

I like VIM idea of text objects, so I installed EVIL (a Emacs plugin to emulate VIM features). But I'd like «insert» mode to leave Emacs keybindings unchanged (except perhaps Escape which is to switch into «normal» mode). Any way to achieve this?
By the way: ATM «insert» mode have a mixed set of hotkeys, which isn't very comfortable either way. E.g. the «M-b» works as in Emacs, but the «C-o» works as in VIM.
In the #emacs IRC channel I was told that someone already solved a similar problem. Here's the modified version I use:
(require 'evil)
;; remove all keybindings from insert-state keymap
(setcdr evil-insert-state-map nil)
;; but [escape] should switch back to normal state
(define-key evil-insert-state-map [escape] 'evil-normal-state)
(define-key evil-normal-state-map (kbd "C-u") 'evil-scroll-up)
(define-key evil-normal-state-map (kbd "[ m") 'beginning-of-defun)
(define-key evil-normal-state-map (kbd "] m") 'end-of-defun)
(define-key evil-normal-state-map (kbd "k") 'evil-previous-visual-line)
(define-key evil-normal-state-map (kbd "j") 'evil-next-visual-line)
(evil-mode t)
(setq evil-jumps-cross-buffers nil) ;; for C-o and C-i to not cross buffers
(provide 'emvil)
The (provide 'emvil) is to allow require 'ing it in the configuration. I also found it useful to jump-to-definition in the next split screen unless the definition is in the buffer I'm currently in. Here's the code:
(defun evil-goto-definition-next-split ()
"If there's a free split, goto definition in this split,
otherwise use current one (except when a definition in the
current split)"
(interactive)
(let ((origin-spl (selected-window))
(origin-buf (current-buffer)))
(evil-goto-definition)
(when (and (eq origin-spl (selected-window)) ;; otherwise it's done
(not (eq origin-buf (current-buffer)))) ;; otherwise either definition not found, or
;; it's in the same buffer
(let ((defin-buf (current-buffer))
(defin-point (point)))
(switch-to-buffer origin-buf)
(other-window 1)
(switch-to-buffer defin-buf)
(goto-char defin-point)
))
))
(define-key evil-normal-state-map (kbd "g d") 'evil-goto-definition-next-split)

How to disable sticky highlight for repeat isearch forward / backward

Without hacking the source or creating my own isearch-repeat... function, is it possible to disable the default sticky highlight for isearch-repeat-forward and isearch-repeat-backward?
I'm using the latest developer build of Emacs Trunk --with-ns.
Here are some ideas (a work in progress), but they do not resolve the issue -- isearch-mode-end-hook does not seem to be linked to isearch-repeat-forward and isearch-repeat-backward. It would be nice if any keyboard input (escape and/or arrow keys) could momentarily be linked to lawlist-lazy-highlight-cleanup when exiting isearch-repeat.
(add-hook 'isearch-mode-end-hook 'my-isearch-end)
(defun my-isearch-end ()
"Custom behaviors for `isearch-mode-end-hook'."
(when isearch-mode-end-hook-quit
(lawlist-lazy-highlight-cleanup t)))
(defun lawlist-lazy-highlight-cleanup (&optional force)
"Stop lazy highlighting and remove extra highlighting from current buffer.
FORCE non-nil means do it whether or not `lazy-highlight-cleanup'
is nil. This function is called when exiting an incremental search if
`lazy-highlight-cleanup' is non-nil."
(interactive '(t))
(if (or force lazy-highlight-cleanup)
(while isearch-lazy-highlight-overlays
(delete-overlay (car isearch-lazy-highlight-overlays))
(setq isearch-lazy-highlight-overlays
(cdr isearch-lazy-highlight-overlays))))
(when isearch-lazy-highlight-timer
(cancel-timer isearch-lazy-highlight-timer)
(setq isearch-lazy-highlight-timer nil))
(lawlist-isearch-dehighlight))
(defun lawlist-isearch-dehighlight ()
(interactive)
(when isearch-overlay
(delete-overlay isearch-overlay)))
(defun lawlist-isearch-repeat-forward ()
"Repeat incremental search forwards."
(interactive)
(isearch-repeat 'forward)
;; need to add something that says sit-for any keyboard input before cleanup occurs.
;; (read-event) ;; read-char-exclusive | read-char | read-event
(sit-for 60)
(lawlist-lazy-highlight-cleanup))
(defun lawlist-isearch-repeat-backward ()
"Repeat incremental search backwards."
(interactive)
(isearch-repeat 'backward)
;; need to add something that says sit-for any keyboard input before cleanup occurs.
;; (read-event) ;; read-char-exclusive | read-char | read-event
(sit-for 60)
(lawlist-lazy-highlight-cleanup))
While this does not anwswer your question, it may do the thing you ultimately want to solve:
(define-key isearch-mode-map [(control up)] 'isearch-ring-retreat)
(define-key isearch-mode-map [(control down)] 'isearch-ring-advance)
After you type C-S, you may use C-up and C-down to move through search history. So C-S C-up will do what you want: repeat the last search without leaving "sticky" overlays.
See also search-ring-update, to further custom this if you like.
Using the source code of isearch.el as a guide, the following OSX additional key assignments eliminate the problem with sticky highlight as outlined in the question above.
(define-key global-map [?\s-f] 'isearch-forward)
(define-key esc-map [?\s-f] 'isearch-forward-regexp)
(define-key minibuffer-local-isearch-map [?\s-f] 'isearch-forward-exit-minibuffer)
(define-key isearch-mode-map [?\s-f] 'isearch-repeat-forward)
(define-key global-map [?\s-F] 'isearch-backward)
(define-key esc-map [?\s-F] 'isearch-backward-regexp)
(define-key minibuffer-local-isearch-map [?\s-F] 'isearch-reverse-exit-minibuffer)
(define-key isearch-mode-map [?\s-F] 'isearch-repeat-backward)

How to configure emacs' M-f and M-b to behavior like eclipse's Ctrl+right and Ctrl+left?

I'm from eclipse to emacs, and don't used to the behavior of M-f and M-b.
See the following javascript code:
module.controller('Front', ['$scope', function($scope){
When I use Ctrl+right, the cursor will jump to the | in the code:
|module|.|controller|('|Front|', |['|$scope|', |function|(|$scope|){|
and when I use Ctrl+left, the cursor will jump from right to left in these | positions.
But in emacs, M-f is different:
module|.controller|('Front|', ['$scope|', function|($scope|){
How to configure emacs to let M-f is exactly the same as eclipse's Ctrl+right, and M-b is the same as Ctrl+left?
I think these functions do what you want:
(defun eclipse-forward-word ()
(interactive)
(let ((go-back (looking-at-p "\\W")))
(forward-word)
(when go-back
(backward-word))))
(defun eclipse-backward-word ()
(interactive)
(let ((go-forward (looking-at-p "\\<")))
(backward-word)
(when go-forward
(forward-word))))
(global-set-key (kbd "<C-left>") 'eclipse-backward-word)
(global-set-key (kbd "<C-right>") 'eclipse-forward-word)

Emacs tab between buffers

Is there a way to switch between buffers without having to go through the
buffer-list, or writing the name of the buffer that I want to switch to? More specific I wonder if emacs can tab between buffers much like how it is working in notepad++
Emacs 22.1 and higher supports the previous-buffer (C-x <left arrow>) and next-buffer (C-x <right arrow>) commands.
These two commands can be added to older Emacsen using this script.
I've never ended up using C-x <right> or C-x <C-right> much, because I find them cumbersome to repeat if I want to cycle past more than one buffer, so I've just written a couple of functions to let you continue to switch to next/previous-buffer with <C-right> and <C-left> if the last command was also a next/previous-buffer command.
e.g. C-x <C-left> <C-left> <C-left> <C-right> <C-left> would take you back three buffers, forward one, and backward again.
I've made the assumption that <C-left> & <C-right> are usually bound to forward/backward-word, and am calling those explicitly as the fallback.
(defun my-forward-word-or-buffer-or-windows (&optional arg)
"Enable <C-left> to call next-buffer if the last command was
next-buffer or previous-buffer, and winner-redo if the last
command was winner-undo or winner-redo."
(interactive "p")
(cond ((memq last-command (list 'next-buffer 'previous-buffer))
(progn (next-buffer)
(setq this-command 'next-buffer)))
((memq last-command (list 'winner-redo 'winner-undo))
(progn (winner-redo)
(setq this-command 'winner-redo)))
(t ;else
(progn (forward-word arg)
(setq this-command 'forward-word)))))
(defun my-backward-word-or-buffer-or-windows (&optional arg)
"Enable <C-left> to call previous-buffer if the last command
was next-buffer or previous-buffer, and winner-undo if the last
command was winner-undo or winner-redo."
(interactive "p")
(cond ((memq last-command (list 'next-buffer 'previous-buffer))
(progn (previous-buffer)
(setq this-command 'previous-buffer)))
((memq last-command (list 'winner-redo 'winner-undo))
(progn (winner-undo)
(setq this-command 'winner-undo)))
(t ;else
(progn (backward-word arg)
(setq this-command 'backward-word)))))
(global-set-key (kbd "<C-left>") 'my-backward-word-or-buffer-or-windows)
(global-set-key (kbd "<C-right>") 'my-forward-word-or-buffer-or-windows)
(I use Icicles for buffer switching, myself, but...)
If you want to repeat the previous command any number of times, just use C-x z z z z z z... In this case, e.g., C-x left C-x z z z...
If that's too cumbersome, bind (next|previous)-buffer to other, repeatable keys, as others have suggested.
But repeatable keys are in great demand. If you don't want to waste any, you can even put such commands on a prefix key, so that, e.g., you can do, e.g., C-x left left left... Here's a trick to do that (taken from the Bookmark+ code):
(defun my-repeat-command (command)
"Repeat COMMAND."
(let ((repeat-message-function 'ignore))
(setq last-repeatable-command command)
(repeat nil)))
(defun my-next-whatever-repeat (arg) ; `C-x right'
"Jump to the Nth-next whatever.
N defaults to 1, meaning the next whatever.
Plain `C-u' means start over at the first whatever (and no repeat)."
(interactive "P")
(require 'repeat)
(my-repeat-command 'next-whatever))
(define-key ctl-x-map [right] 'my-next-whatever-repeat
Although the following suggestion does use the buffer-list, Ivy (or Helm) and evil, I think it is a nice, nearly equivalent alternative to the common Ctrl-TAB way (incl. updating the buffer list) when using e.g. Spacemacs.
Of course the commands can be adapted to your personal config (vanilla Emacs)
(evil-global-set-key 'motion (kbd "<C-tab>") 'ivy-switch-buffer)
(evil-global-set-key 'insert (kbd "<C-iso-lefttab>") 'ivy-switch-buffer)
(define-key ivy-mode-map (kbd "<C-tab>") 'ivy-next-line-and-call)
(define-key ivy-mode-map (kbd "<C-iso-lefttab>") 'ivy-previous-line-and-call)
or for the equivalent for Helm
(evil-global-set-key 'motion (kbd "<C-tab>") 'helm-buffers-list)
(evil-global-set-key 'motion (kbd "<C-iso-lefttab>") 'helm-buffers-list)
(define-key helm-map (kbd "<C-tab>") 'helm-follow-action-forward)
(define-key helm-map (kbd "<C-iso-lefttab>") 'helm-follow-action-backward)
The keystring for the last command means Ctrl-Shift-tab in my keyboard. You can find the one to use with C-h k C-S-tab.
Indeed you still need to press RET or C-l after releasing <C-tab>.
For evil users using Helm, a possibly even nicer alternative is to bind helm-buffers-list to C-j and C-k, then set helm-follow-mode-persistent to t, and in the helm-buffers-list buffer activate helm-follow-mode with C-c C-f. Now you can switch (and preview) buffers with C-j and C-k.

Emacs, switch to previous window

In Emacs, C-x o takes me to the next window.
What keyboard macro takes me to the previous window in Emacs?
You might also want to try using windmove which lets you navigate to the window of your choice based on geometry. I have the following in my .emacs file to change windows using C-x arrow-key.
(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <right>") 'windmove-right)
(global-set-key (kbd "C-x <left>") 'windmove-left)
That'd be C-- C-x o
In other words, C-x o with an argument of -1. You can specify how many windows to move by inserting a numeric argument between C-u and the command, as in C-u 2 C-x o. (C-- is a shortcut for C-u - 1)
Personally I prefer to use window-number.el
To select a different window, use Ctrl-x, Ctrl-j n
Where n is the number of the window, the modeline of each window shows it's number, as shown in the screenshot.
Just download window-number.el, place it in your emacs load-path and use the following in your .emacs
(autoload 'window-number-mode "window-number"
"A global minor mode that enables selection of windows according to
numbers with the C-x C-j prefix. Another mode,
`window-number-meta-mode' enables the use of the M- prefix."
t)
There's another similar mode called switch-window.el which gives you big numbers in the windows... (pressing the number switches the window and reverts the display.)
(source: tapoueh.org)
If you work with multiple emacs windows (>3) a lot and you will want to save some keystrokes add this to your init file and you'll be better off:
(defun frame-bck()
(interactive)
(other-window-or-frame -1)
)
(define-key (current-global-map) (kbd "M-o") 'other-window-or-frame)
(define-key (current-global-map) (kbd "M-O") 'frame-bck)
Now just cycle quickly thru the windows with M-o
There are some very good and complete answers here, but to answer the question in a minimalist fashion:
(defun prev-window ()
(interactive)
(other-window -1))
(define-key global-map (kbd "C-x p") 'prev-window)
Base on idea from #Nate but slightly modified to support backwards cycling between windows
;; Windows Cycling
(defun windmove-up-cycle()
(interactive)
(condition-case nil (windmove-up)
(error (condition-case nil (windmove-down)
(error (condition-case nil (windmove-right) (error (condition-case nil (windmove-left) (error (windmove-up))))))))))
(defun windmove-down-cycle()
(interactive)
(condition-case nil (windmove-down)
(error (condition-case nil (windmove-up)
(error (condition-case nil (windmove-left) (error (condition-case nil (windmove-right) (error (windmove-down))))))))))
(defun windmove-right-cycle()
(interactive)
(condition-case nil (windmove-right)
(error (condition-case nil (windmove-left)
(error (condition-case nil (windmove-up) (error (condition-case nil (windmove-down) (error (windmove-right))))))))))
(defun windmove-left-cycle()
(interactive)
(condition-case nil (windmove-left)
(error (condition-case nil (windmove-right)
(error (condition-case nil (windmove-down) (error (condition-case nil (windmove-up) (error (windmove-left))))))))))
(global-set-key (kbd "C-x <up>") 'windmove-up-cycle)
(global-set-key (kbd "C-x <down>") 'windmove-down-cycle)
(global-set-key (kbd "C-x <right>") 'windmove-right-cycle)
(global-set-key (kbd "C-x <left>") 'windmove-left-cycle)
Just to add to #Nate, #aspirin and #Troydm's answer I find this to be a very helpful addition if you decide to bind the windmove commands to whatever key combination you choose:
(setq windmove-wrap-around t)
With the default configuration you will get an error when you get to attempt to move to a window that doesn't exist which becomes kind of annoying after a while. However when windmove-wrap-around is set then attempting to move off the bottom of the frame for example will instead select the topmost window in the frame. This may be a more intuitive behaviour for you.
M-n and M-p makes the most sense to me, since they are analogous to C-n (next-line) and C-p (previous-line):
(define-key global-map (kbd "M-p") 'previous-multiframe-window)
(define-key global-map (kbd "M-n") 'other-window)
(inspired by to this and that)
In reference to Nate's answer, I replaced the arrow keys to use the traditional p for going up, n for going down, f for going right and b for going left. I also replaced the Ctrl with Super key as C-p, C-n, C-f and C-b are the default movement keys. This combination with M lets you jump characters and lines instead of going through just one by one after each keystroke. Thus Super key felt the best choice to keep it an easy key binding. Also, now you don't have to take your hand off the home row any more!
(global-set-key (kbd "s-p") `windmove-up)
(global-set-key (kbd "s-n") `windmove-down)
(global-set-key (kbd "s-f") `windmove-right)
(global-set-key (kbd "s-b") `windmove-left)
Hope it helps!
(global-unset-key (kbd "M-j"))
(global-unset-key (kbd "M-k"))
(global-set-key (kbd "M-j") (lambda () (interactive) (other-window 1)))
(global-set-key (kbd "M-k") (lambda () (interactive) (other-window -1)))
altj and altk will cycle through your visibles buffers. Forwards and backwards, to be exact.
There is already a package that lets you switch windows by using M-. check this website. Add this to your init file:
(require 'windmove)
(windmove-default-keybindings 'meta) ;; or use 'super to use windows key instead alt
(global-set-key (kbd "C-x a") 'ace-swap-window)
(global-set-key (kbd "C-x q") 'ace-select-window)
download ace-window from the melpa repo if you don't know how to do that
put this in your .emacs file if you don't have one create it
(package-initialize)
(require 'package)
(add-to-list 'package-archives '("melpa" , "http://melpa.org/packages/"))
(package-initialize)
then "m-x list-packages"
The fastest method I have found for switching to the previous window is to mash a couple keys together as a "key-chord". The following lets you use your left pinky+ring fingers together to go to previous window:
(key-chord-define-global "qw" 'prev-window)
(key-chord-define-global "'y" 'other-window) ; bonus for my colemak, adjust otherwise
(key-chord-define-global ";'" 'other-window) ; probably normal
(This is possible because Emacs key chords are order independent, meaning that qw is the same as wq.)