When reading through the code at times, its a pain to keep pressing ctrl key or alt key in addition to n or p or other combination to keep moving around in the code.
I was wondering if there is a way to lock these keys for a while and then be able to just use combination keys to navigate around
NOTE : I don't want answers like use vim. I don't have time to read stupid answers please.
You could for example define a minor mode for which the keymap assigns navigation commands to just letters, without the C- or M- modifier.
For example:
(define-minor-mode my-minor-mode
"Navigate with easy key bindings"
; Make this a global mode (i.e. active in all buffers)
:global t
; "foo" will be printed in the modeline when this mode is active
:lighter " foo"
; Setup the keymap
:keymap (let ((map (make-sparse-keymap)))
(define-key map (kbd "n") 'next-line)
map))
Then, you can assign this mode to a key binding to easily switch it on and off:
(global-set-key (kbd "<f5>") 'my-minor-mode)
You might want to look at the documentation to better understand how define-minor-mode works:
C-hfdefine-minor-modeRET
Try M-x view-mode. That binds lots of single characters to various navigation commands. Type C-h f view-mode to see the entire list.
Related
I'm trying to redefine the keys used to navigate the history when inside several commands accepting regexps and offering C-p / C-n history navigation. I'd like to use other keys, in addition to C-p / C-n. For example when using occur or replace-regexp, C-p and C-n can be used to go to previous and next elements.
I've tried several things but can't make it work. I think I'm missing the "big picture" here.
Which mode-map do I need to modify, when and how? Everything I tried failed.
P.S: Note that I've got my own minor mode with all my keymaps as adviced here.
I'm assuming you just needed minibuffer-local-map. Subsequent definitions using keys previously assigned to that key map will trump the prior definitions. To disable a prior key assignment, then just create a new definition and set the last portion to nil instead of 'function-name.
(define-key minibuffer-local-map (kbd "<f6>") 'help-for-help)
Here is an excerpt from Emacs Trunk .../lisp/bindings.el:
(let ((map minibuffer-local-map))
(define-key map "\en" 'next-history-element)
(define-key map [next] 'next-history-element)
(define-key map [down] 'next-history-element)
(define-key map [XF86Forward] 'next-history-element)
(define-key map "\ep" 'previous-history-element)
(define-key map [prior] 'previous-history-element)
(define-key map [up] 'previous-history-element)
(define-key map [XF86Back] 'previous-history-element)
(define-key map "\es" 'next-matching-history-element)
(define-key map "\er" 'previous-matching-history-element)
;; Override the global binding (which calls indent-relative via
;; indent-for-tab-command). The alignment that indent-relative tries to
;; do doesn't make much sense here since the prompt messes it up.
(define-key map "\t" 'self-insert-command)
(define-key map [C-tab] 'file-cache-minibuffer-complete))
To add to what #lawlist said (which was to bind the key in minibuffer-local-map):
There are multiple minibuffer keymaps, depending on what is being read in the minibuffer, and how. And which of those keymaps you might want to use can depend on which Emacs version you are using.
In addition, there is also the keymap for interaction with buffer *Completions*: completion-list-mode-map.
For completion in the minibuffer, the main keymap is minibuffer-local-completion-map.
Here is a list of the minibuffer keymaps. Some of these might not be available (used) in your Emacs version.
minibuffer-local-map
minibuffer-local-ns-map
minibuffer-local-isearch-map
minibuffer-local-completion-map
minibuffer-local-must-match-map
minibuffer-local-filename-completion-map
minibuffer-local-filename-must-match-map
minibuffer-local-must-match-filename-map
In addition, you can use minibuffer-with-setup-hook (or minibuffer-setup-hook directly) to add key bindings on the fly, for the duration of a single minibuffer reading.
I will add this info, since it can be really helpful when you are manipulating minibuffer keymaps: You can use C-h M-k (command describe-keymap), from library help-fns+.el, to see all of the bindings of a given minibuffer keymap in human-readable form.
I’m on a Mac and would like to use the function key F19 as meta.
(There’s a good reason, although it's a bit of a hack: My built (the otherwise excellent port by Yamamoto Mitsuharu) doesn’t support using only the left alt key as meta while preserving the native behavior (inserting special characters) of the right alt key.. So I remapped the left alt key to an unused key - F19 - on the system level with PCKeyboardHack (xmodmap is sorely missed) and would like to tell Emacs to use that as meta.)
So, how do I: use a function key (F19 in my case) as meta key in Emacs?
(I’m fairly new to Emacs and, after some googling, tried out something like
(define-key global-map [f19] \M)
but that, of course, doesn’t do the trick (Symbol’s value as variable is void: M)
Well, with
(setq x-alt-keysym symbol)
you can tell emacs what key is to be understood as meta, but afaik it only accepts 'meta, 'alt, 'super and 'hyper as symbol. Maybe try it with f19.
An alternative option that will work but which will require adaption to a new way of working would be to use F19 as a prefix key (like you use C-h or F1 to invoke help commands):
(define-prefix-command 'f19-map)
(global-set-key (kbd "<f19>") 'f19-map)
(global-set-key (kbd "<f19> x") 'execute-extended-command)
(global-set-key (kbd "<f19> u") 'upcase-word)
...
Writing the configuration shouldn't be too hard. Just press C-h b to get all existing keybindings and edit the help buffer. Get rid of all lines that don't start with M-, then use rectangles to replace all occurrences of ^M- by (global-set-key (kbd ", and so on.
Yet another option would be to bind the key to Esc instead of F19, as long as that's supported by your system, and use the esc prefix instead of the f19 prefix. That way you don't have to change the emacs configuration at all.
I'm trying ParEdit mode and this is something that it does not the way I'd want: it shadows the original binding for C-M-F and replaces it with C-M-f. I.e. it forwards sexp instead of selecting it :| I couldn't find the place where the bindings are defined at the first glance.
Any way to cancel this behaviour? Or what would be the analogue command in ParEdit for selecting an sexp?
EDIT:
To give you a better idea of what happens, if I do C-h k while ParEdit is active, and then C-M-S-f this is what I get:
C-M-f (translated from C-M-S-f) runs the command paredit-forward,
which is an interactive compiled Lisp function in `paredit.el'.
It is bound to C-M-f.
(paredit-forward)
Move forward an S-expression, or up an S-expression forward.
If there are no more S-expressions in this one before the closing
delimiter, move past that closing delimiter; otherwise, move forward
past the S-expression following the point.
C-M-f
(foo |(bar baz) quux)
->
(foo (bar baz)| quux)
(foo (bar)|)
->
(foo (bar))|
[back]
I don't want it to translate anything, this is absolutely undesired behaviour.
You can use:
(eval-after-load "paredit"
'(progn
(define-key paredit-mode-map (kbd "C-M-f") nil)))
Strictly speaking the progn is unnecessary, but you might want to redefine/remove more keys afterwards
EDIT
Unlike forward-sexp, paredit-forward doesn't check whether shift is pressed. You could try using this
(eval-after-load "paredit"
'(progn
(define-key paredit-mode-map (kbd "C-M-S-f")
(lambda ()
(interactive)
(unless (region-active-p)
(set-mark (point)))
(paredit-forward)))))
EDIT
An alternative way to do the same thing (select the following sexp), would be C-M-space. Then, should you want to do so, you can swap point and mark with C-x C-x (or C-x (no delay here) C-x C-x if you use CUA)
EDIT (last?)
The proper way to make a function also mark when shift is pressed is this:
(put 'paredit-forward 'CUA 'move)
Paredit isn't translating the keys. Emacs is. It's the same in every mode. If there's no binding for C-M-F, Emacs will try C-M-f instead.
If you want to select the S-expression after the point, the standard Emacs key for this is C-M-SPC.
Resurrecting a very old question, but I think I know a more general solution to this.
paredit is a very old package that predates modern packaging hygiene. i.e. aggressive setting of default keybindings.
To undo that, run this after loading the paredit package:
(paredit-do-commands (spec keys _fn _examples) nil
(dolist (key keys)
(define-key paredit-mode-map (read-kbd-macro key) nil)))
now you're back to no keybindings, and you can use the regular mechanisms. Read the value (not the documentation) on paredit-commands to see which commands are available and what their default bindings are, some of which you might want to retain.
I'm giving ErgoEmacs mode a try to see if I can use Emacs more comfortably. Some of its keybindings are fairly intuitive, but in many cases I don't want to outright replace the defaults.
For example, in the context of ErgoEmacs' navigation shortcut structure, M-h makes sense as a replacement for C-a--but I want to be able to use both, not just M-h. I tried simply duplicating the commands:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "C-a")) ; original
(defconst ergoemacs-move-end-of-line-key (kbd "C-e")) ; original
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h")) ; ergoemacs
(defconst ergoemacs-move-end-of-line-key (kbd "M-H")) ; ergoemacs
But Emacs simply overwrites the first keybinding with the second. What's the best way to address this?
To re-post reply from ergo-emacs mailing list:
Xah Lee said:
that's very easy.
in the
ergoemacs-mode.el file, there's this
line (load "ergoemacs-unbind") just
comment it out. That should be all
you need to do. However, note that
ErgoEmacs keybinding defines those
common shortcuts such as Open, Close,
New, Save... with keys Ctrl+o,
Ctrl+w, Ctrl+n, Ctrl+s etc. About 7 of
them or so. So, i think some of these
will hit on emacs traditional
bindings with Ctrl. if you are new to
ErgoEmacs and trying to explore it,
you might just try starting with few
keys. this page might have some
useful info:
http://code.google.com/p/ergoemacs/wiki/adoption
thanks for checking out ErgoEmacs!
Xah ∑ http://xahlee.org/
As it turns out, ErgoEmacs uses two files to define the keybinding. One is the main ergoemacs-mode.el file, and the other is the specific keyboard layout you select (e.g. ergoemacs-layout-us.el). The latter document creates a constant, which the former uses to create the keybinding. So while I thought I was duplicating the keybinding, I was actually changing the constant which was subsequently used for that purpose.
Solution:
In ergomacs-mode.el:
;; Move to beginning/ending of line
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key 'move-beginning-of-line)
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key 'move-end-of-line)
(define-key ergoemacs-keymap ergoemacs-move-beginning-of-line-key2 'move-beginning-of-line) ; new
(define-key ergoemacs-keymap ergoemacs-move-end-of-line-key2 'move-end-of-line) ; new
In ergoemacs-layout-us.el:
;; Move to beginning/ending of line
(defconst ergoemacs-move-beginning-of-line-key (kbd "M-h"))
(defconst ergoemacs-move-end-of-line-key (kbd "M-H"))
(defconst ergoemacs-move-beginning-of-line-key2 (kbd "C-a")) ; new
(defconst ergoemacs-move-end-of-line-key2 (kbd "C-e")) ; new
Huh? Is having one and only one way for every function some golden principle of ErgoEmacs? Because normal keybinding works exactly the opposite way: you name one key at a time and specify what it should do. If a mode defines a global variable to mean "the key that end-of-line is bound to", then of course there can be only one value, but with the normal binding commands you can bind the same function to as many combinations as you like. In fact, every keybinding I have ever seen used looked either like this
(global-set-key [(meta space)] 'just-one-space)
or like this
(add-hook 'c-mode-hook 'my-c-mode-hook)
(defun my-c-mode-hook ()
(define-key c-mode-map [(control c) b] 'c-insert-block))
if it's only for a specific mode.
Most emacs modes include some sort of prefix to activate their features. For example, when using GUD "next" is "C-c C-n". Of these modes, many provide special buffers where one can use a single key to activate some functionality (just 'n' or 'p' to read next/previous mail in GNUS for example).
Not all modes provide such a buffer, however, and repeatedly typing the prefix can be tiresome. Is there a well-known bit of elisp that will allow for ad-hoc specification of prefix keys to be perpended to all input for some time? (Until hitting ESC or some other sanctioned key, for example)
I agree with Joe Casadonte's answer that the way to go is to define your own minor (or major) mode.
That being said, your question is interesting.
Here's a solution that prompts you for a key sequence and it takes the prefix keystrokes and promotes that keymap to the top level.
e.g. Assume the following keymap:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
When you run M-x semi-modal-minor-mode, it will prompt you for some keystrokes. If you enter M-g n, then the following keybindings are set:
ESC Prefix Command (same as M-g ESC)
g goto-line
n next-error
p previous-error
So now n doesn't self-insert, but jumps to the next error. See the code below.
Note: when this minor mode is enabled, <f12> is bound to a command which disables the minor mode. This is because the keybindings might very well disable your Emacs (for instance, what if there was a new keybinding for M-x).
Edited to add these thoughts: the minor mode variable was originally made buffer local, but that doesn't work unless you also make the minor-mode-alist variable buffer local (duh). But, you also (probably) don't want these bindings in the minibuffer... So, I'm not going to test it b/c it really depends on what you want, but I've added a comment to the code reflecting this thought.
Without further ado:
(defvar semi-modal-minor-mode-keymap (make-sparse-keymap)
"keymap holding the prefix key's keymapping, not really used")
(defvar semi-modal-minor-mode-disable-key (kbd "<f12>")
"key to disable the minor mode")
(defun semi-modal-minor-mode-disable ()
"disable the minor mode"
(interactive)
(semi-modal-minor-mode 0))
(define-minor-mode semi-modal-minor-mode
"local minor mode that prompts for a prefix key and promotes that keymap to the toplevel
e.g. If there are bindings like the following:
M-g ESC Prefix Command
M-g g goto-line
M-g n next-error
M-g p previous-error
And you enter 'M-g n' when prompted,
then the minor mode keymap has the bindings
g -> goto-line
n -> next-error
p -> previous-error
ESC -> Prefix Command (same as M-g ESC)
The variable semi-modal-minor-mode-disable-key is bound to disable the minor mode map.
This is provided because often the mappings make the keyboard unusable.
Use at your own risk."
nil " Semi" semi-modal-minor-mode-keymap
(make-local-variable 'semi-modal-minor-mode)
(make-local-variable 'minor-mode-map-alist)
(let ((pair-holding-keymap-to-modify (assq 'semi-modal-minor-mode minor-mode-map-alist)))
(setcdr pair-holding-keymap-to-modify (make-sparse-keymap))
(if semi-modal-minor-mode
(let (key
keymap)
;; all but last (b/c we want a prefix
(setq key (substring (read-key-sequence "Enter a full key combination, the prefix will be used: ") 0 -1))
(if (and (not (equal "" key))
(not (equal (kbd "C-g") key))
(let ((semi-modal-minor-mode nil))
(keymapp (setq keymap (key-binding key)))))
(progn
(setcdr pair-holding-keymap-to-modify (copy-keymap keymap))
(when semi-modal-minor-mode-disable-key
(define-key (cdr pair-holding-keymap-to-modify)
semi-modal-minor-mode-disable-key 'semi-modal-minor-mode-disable)))
(semi-modal-minor-mode 0))))))
The mode-specific (modal?) part of key-bindings in Emacs is realized by the various local maps that overshadow the universal global-map. Most major and minor modes define their own local maps; for example, there is a gud-mode-map. Key bindings in a local keymap will be activated only when the current-buffer is in the respective mode. You can customize a mode specific keymap through the mode's hook. For example, you may put this snippet into your ~/.emacs
(add-hook 'gud-mode-hook
(lambda ()
(local-set-key (kbd "C-n")
(lookup-key (current-local-map) (kbd "C-c C-n")))))
More details about keymaps can be found in Elisp reference manual.
The basic issue here is that there is no current keymap per-se. There's the global keymap which is overridden by the major mode's keymap which in turn is overridden by one or more minor mode keymaps (and they can step on each other in some defined way, I'm sure). Defining a new major mode will still leave the minor mode keys functional, and defining a new minor mode will only affect whatever keys you define in the minor mode's keymap.
For example, you could define a minor mode that will do what you want as long as the minor mode is active. You define a new minor mode my-gud-mode which will have its own keymap. You would then have to define all of your key mappings for it (e.g. n, p, etc) and you would also have to define all of the keys that you didn't want to work to be bound to the function ignore. That's the real pain of this, remapping all of the other keys. The minor mode is easy to switch on and off, though; that's the advantage.
Defining a new major mode would be easier at first blush, as it will let you override more of the "current keymap" in one shot. It should note the current major mode in a buffer-local variable so it can be restored later when the temporary major mode is turned off. But you'll still have other minor modes intruding into your keymap, so it won't be "pure".
What I do in this situation is define an easier prefix! For stuff I use all of the time, all day every day, I give them a function key all on their own (e.g. I have F1 set aside as my jabber-mode key). For less immediately useful things, I have two other function keys set aside, F3 and F12 (I'm sure there was some reason I picked them long ago, but I no longer remember why). F3 defines keys that are always available, regardless of major mode. F12 defines keys that are major-mode-dependent. Some examples:
I have set up F3-m- as a prefix to switch major modes (e.g. F3-m-p switches to cperl-mode) and F3-M- as a prefix for minor modes (e.g. F3-M-v toggles view-mode). These are always available, so you could do something like bind F3-g- to be your gud prefix, and type F3-g-p for previous and so on.
My F12 key is mode-dependent. So, in dired mode F12-e will call dired-nt-open-in-excel on the current file, and in emacs-lisp-mode F12-e will call elint-current-buffer. Somehow I never get them confused.
If you need help in defining keymaps like this, let me know.
Viper mode allows you to map commands to keys or key sequences while in the visual mode (entered using the "esc" key). Go back to insert mode with "i".
Have a look at viper-in-more-modes.elIt uses viper-modify-major-mode.
I also like to use the viper-vi-global-user-map: a snippet from my .emacs file.