My favorites | Sign in
Project Logo
                
Search
for
Updated Sep 15, 2009 by davidcapello
Labels: Phase-Support
adoption  
Tips for adopting the ergonomic shortcuts.

Tips For Adopting ErgoEmacs Keybindings

If you are a long time emacs user, you may find it painful to adopt this setup.

This difficulty is nothing special. It's the same difficulty when you switching to dvorak after years of qwerty. Basically, it's about changing muscle memory.

shortcut to open cheatsheet

You can press F8 to open the image file showing the layout. Put the following in your emacs init file:

;; open keyboard shortcut image with F8 key
(global-set-key (kbd "<f8>")
  (lambda ()
    (interactive)
    (find-file "$HOME/ergonomic_emacs_layout_qwerty.png")))

download the image at

http://xahlee.org/emacs/ergonomic_emacs_keybinding.html
image for qwerty, dvorak, colemak are all available there.

Tips for Gradual Adoption

Here's some tips that may help you adopt.

If you find it too painful to switch, don't use the whole package. Instead, define a few very simple subset:

;; Single char cursor movement. (assuming you are on qwerty)
(global-set-key (kbd "M-j") 'backward-char)
(global-set-key (kbd "M-l") 'forward-char)
(global-set-key (kbd "M-i") 'previous-line)
(global-set-key (kbd "M-k") 'next-line)

;; kicking the habit
(global-unset-key (kbd "C-b")) ; backward-char
(global-unset-key (kbd "C-f")) ; forward-char
(global-unset-key (kbd "C-p")) ; previous-line
(global-unset-key (kbd "C-n")) ; next-line

Put the above in your “.emacs”.

With only the above change, you will increase your emacs productivity by a lot, especially if you are a touch typist. (these single char cursor moving commands are the top 4 most frequently used emacs commands by statistics, roughly accounting for 43% of commands that has a shortcut.)

You don't necessary have to unset the default bindings like the above, but it is recommended, because otherwise you'll just fall back to habit.

Once you used the above for a couple of weeks, you may add more keys to adopt.

For a visual layout of what keys are where, see: http://xahlee.org/emacs/ergonomic_emacs_keybinding.html

Code for Gradual Adoption

Here's the elisp code for qwerty users for gradual adoption. Put the code in your “.emacs”, then restart emacs. Once you are comfortable with a level, add code for the next level.

The code below does not remap keys in special modes, such as in shell, in mini-buffer, or some other modes. When in these modes, just use the arrow key. The full ergoemacs map has code that take care of these modes once you are ready to switch fully.

Level 1

;; kicking the habit
(global-unset-key (kbd "C-b")) ; backward-char
(global-unset-key (kbd "C-f")) ; forward-char
(global-unset-key (kbd "C-p")) ; previous-line
(global-unset-key (kbd "C-n")) ; next-line
(global-unset-key (kbd "C-SPC")) ; set-mark-command

;; Single char cursor movement.
(global-set-key (kbd "M-j") 'backward-char)
(global-set-key (kbd "M-l") 'forward-char)
(global-set-key (kbd "M-i") 'previous-line)
(global-set-key (kbd "M-k") 'next-line)

;; set mark
(global-set-key (kbd "M-SPC") 'set-mark-command)

Level 2

;; kicking the habit
(global-unset-key (kbd "M-f")) ; forward-word
(global-unset-key (kbd "M-b")) ; backward-word
(global-unset-key (kbd "M-d")) ; kill-word
(global-unset-key (kbd "C-<backspace>")) ; backward-kill-word
(global-unset-key (kbd "C-d")) ; delete-char

;; move by word
(global-set-key (kbd "M-u") 'backward-word)
(global-set-key (kbd "M-o") 'forward-word) ; was (prefix)

;; Delete previous/next char.
(global-set-key (kbd "M-d") 'delete-backward-char)
(global-set-key (kbd "M-f") 'delete-char)

; Delete previous/next word.
(global-set-key (kbd "M-e") 'backward-kill-word)
(global-set-key (kbd "M-r") 'kill-word)

Level 3

Try to use the full ergoemacs code.


Comment by marciomazza, Mar 15, 2009

Here is a little aid I made myself to ease my own adoption. I exchanged calls to global-unset-key for my own global-unset-key-leave-hint:

;; hash table to store the old key bindings
(setq old-key-bindings (make-hash-table :test 'equal))

;; shows a hint about the change of the key binding 
(defun show-hint-old-kbind (key)
  (let ((function-symbol (gethash key old-key-bindings)))
    (beep)
    (message "You typed: %s\n The binding for %s\n is now %s"
             key
             function-symbol
             (mapcar 'key-description (where-is-internal function-symbol)))))

;; turns off a key binding, leaving a hint for the unbound command
(defmacro global-unset-key-leave-hint (key)
  `(let ((function-symbol (global-key-binding (kbd ,key))))
     (when function-symbol
       (puthash ,key function-symbol old-key-bindings)
       (global-set-key (kbd ,key) (lambda() (interactive) (show-hint-old-kbind ,key))))))

So, instead of writing

(global-unset-key (kbd "C-y")) ; digit-argument

I now write

(global-unset-key-leave-hint "C-y") ; digit-argument

(Note the drop of the kbd call.)

Now when I hit C-y I receive a message:

You typed: C-y
 The binding for yank
 is now (<S-insert> <S-insertchar> M-v)
Comment by marciomazza, Mar 16, 2009

(... something more about the "hint" solution above)

Well, some keys will not be unset, but will simply have their commands overwritten and won't generate any such message. I made some analysis of the source code of ergonomic_keybinding_qwerty.el to list those changed keys. They are:

("C-p" "C-n" "M-f" "C-a" "M-v" "C-s" "M-d" "C-w" "M-w" "M-h" "M-;" "M-x" "M-!" "M-%")

So, I might train and memorize these first, and let the annoying warning hint teach me the rest.

Comment by xahlee, Mar 21, 2009

Hi marciomazza, great comment.

I thought about writing this myself, but then the problem is that some keys are already defined..., but your second comment hit the solution. Thanks.

Comment by rothaar, Jul 14, 2009

I've been using a setup based on this for a long time now, but 1 big problem remains in terms of adoption. I use a mac. For the most part, the existence of global-ish support for basic emacs-like bindings is a big plus. However, changing these system wide defaults to match my new settings has proven challenging, and switching back and forth is confusing (especially in Terminal). So far, the only mechanism I have found is by modifying

~/Library/KeyBindings?/DefaultKeyBinding?.dict.

This works great, as far as it goes, but only affects Cocoa apps, leaving Carbon based apps untouched. Terminal seems to be an exception. The emacs bindings were probably included independently to be helpful to unix users before the system-wide system or something.

So, I'm wondering if anyone else has run into the same problem and found a solution, or even a stab in the dark suggestion.

Comment by xahlee, Jul 15, 2009

to rothaar, i had the same problem as you. I tried to do it OS X wide, but as you described, there are many problems. On the tech side, as you said, the DefaultKeyBinding? systems don't effect Carbon apps. In practice, htere are still many carbon apps. Also, some keys are bound at low level that DefaultKeyBinding? doesn't have effect. Also, even if all this is technically possible, the problem is that one has to design bindings for all apps individually, because otherwise many apps's shortcuts are gone.

i've documented my findings on this here, might be some use for any looking into this issue:

• How To Create Your Own Keybinding In Mac Os X

http://xahlee.org/emacs/osx_keybinding.html

recently i switched to Windows Vista. So far as i can tell, similar situation here.

Comment by rothaar, Jul 17, 2009

Thanks. Some of that looks quite useful, but it sounds like there aren't any good solutions to my original problem still. The lack of consistency on this is quite frustrating, alas.

Comment by luoyonggang, Aug 29, 2009

great, I think it's even greater than emacs itself for me!!! I am an new comer. Even I thanks to the creators emacs, but they make me painful!!

Comment by gene...@vultaire.net, Sep 01, 2009

One problem for longer time users is that they may waste a lot of paper when muscle memory tells them to press C-p to move up, and instead they end up printing out pages and pages of source code.

I'd suggest, after including the ergoemacs file, to do the following:

;; Prompt on Ctrl-P (Old habits die hard, after all)
(global-unset-key (kbd "C-p")) ; print-buffer
(global-set-key (kbd "C-p")
                (lambda ()
                  (interactive)
                  (if (y-or-n-p "Are you sure you wish to print? ")
                      (print-buffer))))

Sign in to add a comment
Hosted by Google Code