How to bind text insertion in isearch - emacs

I'd like to have M-u to insert an underscore when I am in isearch (isearch-regexp and also the reverse variants).
Neither
(define-key isearch-mode-map (kbd "M-u") 'insert-underscore)
nor
(add-hook 'isearch-mode-hook
(lambda ()
(local-set-key (kbd "M-u") 'insert-underscore)
))
insert-underscore is my function that simply inserts "_". It works in the main frame and also in minibuffer, but I can't get it working in isearch...
Thank you!

Isearch doesn't use regular commands. (kbd "_") along with every other
printable character is bound to a special command in isearch-mode-map. It's
not obvious, but a lot of things happen in "isearch-mode" when you press a
key. Display is refreshed with new results, wrapping is a possibility, etc, etc,
You'd have to manipulate raw keyboard events to get this to work.
(defun underscore ()
(interactive)
(isearch-unread-key-sequence (list ?_)))
(define-key isearch-mode-map (kbd "M-u") 'underscore)
Note that this code is not robust; for example, numeric prefix does not work.
EDIT: After letting percolate in my mind for a while, it occured to me that this is the exact use-case for translation keymaps
(define-key key-translation-map (kbd "M-u") (kbd "_"))
Ain't Emacs grand?

Related

Emacs elisp: How to change a keybind for a specific mode in evil's evil-insert-state-map

I've been using emacs for a little while now and am still trying to get the hang of elisp. In my init.el, I have the following lines:
(define-key evil-insert-state-map (kbd "RET") 'newline-and-indent)
(add-hook 'org-mode-hook (lambda () (define-key evil-insert-state-map (kbd "RET") 'newline)))
The intended effect of these two lines of elisp is to disable automatic indentation in org-mode only, but keep automatic indentation for every other mode. However, while this code does disable automatic indentation for org-mode, it has the unintended effect of disabling it for everything else as well. Does anyone know of a way to achieve the desired effect?
You're looking for evil-define-key:
(evil-define-key 'insert org-mode-map (kbd "RET") 'newline)
This will define return to call newline in insert state only in org-mode. What your hook was doing was redefining the global insert state map every time you opened an org buffer.

emacs, flyspell, deactivate "C-." key binding

I have this little problem, I have some key bindings like so C-. C-x or C-. C-m. After I activate the flyspell-mode, I cannot use these commands. In my .emacs file I have the next 2 lines before
(global-unset-key (kbd "C-."))
(define-key (current-global-map) (kbd "C-.") nil)
(global-set-key (kbd "C-. C-l") 'global-linum-mode)
Then, my C-. C-l works, but it does not when the flyspell-mode is activated. The command bound to C-. is flyspell-auto-correct-word. I tried to deactivate it as follows:
;; first try
(defun flyspell-auto-correct-word-disable() (define-key (current-local-map) (kbd "C-.") nil))
(add-hook 'flyspell-mode-hook 'flyspell-auto-correct-word-disable)
;; second try
(define-key (current-global-map) [remap flyspell-auto-correct-word] nil)
None of the tries work, what can I do? I tried in Emacs 23 and 24 and I have the same issue.
What about:
(eval-after-load "flyspell"
'(define-key flyspell-mode-map (kbd "C-.") nil))
Your first solution is almost correct, but you have to remember that the current local map is set up by the major mode, not minor modes. The best option you have it to directly access flyspell-mode-map and modify it (another option would be to find it in minor-mode-map-alist but I think it would be needlessly complicated).
Also, I prefer putting such mode-specific settings within eval-after-load (which means they will be evaluated once) rather than in a hook (in which case the settings are evaluated multiple times: each time one buffer activates flyspell-mode). But this is a matter of preference and either way is fine.

Emacs multi keyboard shortcut

I'm trying to create a combination keybinding.
Here's an example:
(define-key my-minor-mode-map (kbd "x f") "\C-x\C-f")
(edit: Thanks you Stefan for pointing out the space between \C-x and \C-f.)
This however takes me to a random file and describe-key says this:
Macro: C-x C-f
Keyboard macro.
So I'm not really sure what that means.
It seems that trying to bind s to C-s doesn't work either (As well as other interactive commands like C-r and M-x).
This does work:
(define-key my-minor-mode-map (kbd "x f") "\M-f")
So basically I want to be able to run C-x C-f (find-file) without having to type 'find-file as a function itself.
In other words; I don't want this:
(define-key my-minor-mode-map (kbd "x f") 'find-file)
I hope someone could help me out with this. My emacs knowledge is very limited.
Thanks in advance.
Complete code:
(defvar my-minor-mode-map (make-keymap) "my-minor-mode keymap")
(define-key my-minor-mode-map (kbd "x f") "\C-x\C-f")
(define-minor-mode my-minor-mode
"My minor-mode"
t "My minor mode" 'my-minor-mode-map)
(defun my-minibuffer-setup-hook ()
(my-minor-mode 0))
"My minor-mode"
Edit:
What would even be better is if I could do this:
(define-key my-minor-mode-map (kbd "x") "\C-x")
(define-key my-minor-mode-map (kbd "f") "\C-f")
And then if I would type "x f" that it would exectue "\C-x C-f" aka find file.
That way I wouldn't have to write out every possible key combination.
"\C-x \C-f" has 3 elements: C-x, SPC, and C-f. You probably did not mean for that space to be there.
I'm not entirely certain what you believe should be happening here, but I suspect what you actually want is:
(define-key my-minor-mode-map (kbd "x f") (key-binding (kbd "C-x C-f")))
which is the same thing as the code you said you didn't want to use:
(define-key my-minor-mode-map (kbd "x f") 'find-file)
except that it obtains the function dynamically, based on the key binding.
p.s. It's also slightly odd that you're using a mixture of kbd and non-kbd syntax in the same form.

Defining key binding with arguments

I want to map C-f C-b as moving forward and backward by a fixed amount of lines in a file.
I did this:
(global-set-key (kbd "C-f") 'next-line)
(global-set-key (kbd "C-b") 'previous-line)
but I don't know how to specify an argument before the next-line command. I guess I should use digit-argument but I am unable to write the command in a correct way.
You've changed your question to be about how to bind directly to key sequences
This binds C-c l to C-u 5 C-n
(global-set-key (kbd "C-c l") (kbd "C-u 5 C-n"))
One of the possible alternatives would be define a new function:
(defun my-next-line ()
(interactive)
(next-line 5))
(global-set-key (kbd "C-f") 'my-next-line)
Otherwise, if it is just something you can accomplish with the keyboard you might want to use
M-x name-last-kbd-macro
and save it in your .emacs file
M-x insert-kbd-macro
and have emacs implement the function for you.
It will just get the name you gave in your call to name-last-kbd-macro

Setting shortcuts keys in specific modes in Emacs (e.g. ido)

I have two problems which are somewhat related I believe:
1) In IDO I'd like to change ido-restrict-to-matches to samething else than C-SPC or C-#. Unfortunately I do not know how to tell emacs that I want a different shortcut (say C-0).
2) I'd like to protect my C-; but whenever flyspell-mode is running it overtakes C-;. My definition is in .emacs as:
(global-set-key (kbd "C-;") 'mark-paragraph)
but apparently flyspell overwrites this... (although even then, if I look in the help M-h k C-; it does say mark-paragraph)
Could somebody please tell me how to bind/unbind keys in these conditions? It has to work without modifying ido.el and flyspell.el and re-building, right?
Thanks very much!
Flyspell provides a customization for the C-; binding, so you can either M-x customize RET flyspell-auto-correct-binding RET or put something like this in your ~/.emacs:
(setq flyspell-auto-correct-binding (kbd "C-~")) ; or a binding of your choice
As for ido, your question is slightly confusing, because it implies there are times when you're using ido outside the minibuffer...
The documentation in ido.el contains the following advice:
;; To modify the keybindings, use the ido-setup-hook. For example:
;;(add-hook 'ido-setup-hook 'ido-my-keys)
;;
;;(defun ido-my-keys ()
;; "Add my keybindings for ido."
;; (define-key ido-completion-map " " 'ido-next-match)
;; )
Using that knowledge, you can change the key bindings like this in your own "ido-my-keys" function:
(define-key ido-completion-map (kbd "C-SPC") nil)
(define-key ido-completion-map (kbd "C-#") nil)
(define-key ido-completion-map (kbd "C-0") 'ido-restrict-to-matches)
There's an additional ido hook specifically for the minibuffer, too, but it's not clear why you would need that: ido-minibuffer-setup-hook.