Tell me more ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

Yes, the OSX already supports + and + for moving the cursor word-backward and word-forward, but reaching for arrow keys is annoying. So, why not rather have +B and +F do this? I mean, not once have I (intentionally) wrote the integral sign ∫ with +B (apart from now).

In short, I'd rather have Emacs-like behavior (not just, say, ^+F for character-forward) throughout the OSX.


Related question: Stop using Mac keyboard Option as a modifier to character

share|improve this question

1 Answer

up vote 5 down vote accepted

One option would be to create ~/Library/KeyBindings/ and save a property list like this as DefaultKeyBinding.dict:

{
    "~b" = moveWordBackward:;
    "~f" = moveWordForward:;
    "~F" = moveWordForwardAndModifySelection:;
    "~B" = moveWordForwardAndModifySelection:;
    "~d" = deleteWordForward:;
    "~u" = (uppercaseWord:, moveForward:, moveForward:);
    "~l" = (lowercaseWord:, moveForward:, moveForward:);
    "~c" = (capitalizeWord:, moveForward:, moveForward:);
    "~v" = pageUp:;
    "~V" = pageUpAndModifySelection:;
    "^V" = pageDownAndModifySelection:;
    "^ " = setMark:;
    "^w" = deleteToMark:;

    "^x" = {
        "^x" = swapWithMark:;
        "^m" = selectToMark:;
    };
}

It's based on http://www.hcs.harvard.edu/~jrus/site/KeyBindings/Emacs%20Opt%20Bindings.dict. transposeWords: doesn't work in most applications. openDocument: and saveDocument: don't work in applications that use auto-save, and performClose: doesn't work everywhere either.

DefaultKeyBinding.dict doesn't work in Xcode or Firefox or in some text views like AppleScript dialogs. The mark methods aren't really usable with rich text or in TextMate 1. Key combinations that enter dead key states can't be reassigned, but you can remove them by creating a new keylayout with Ukelele.

KeyRemap4MacBook has a predefined Emacs mode group, but for example the setting for changing ⌥F also changes ⌥⌘F to ⌥⌘→. Here's an alternative private.xml:

<?xml version="1.0"?>
<root>
<item>
<name>emacs</name>
<identifier>private.emacs</identifier>
<not>{{EMACS_MODE_IGNORE_APPS}}</not>
<autogen>__KeyToKey__ KeyCode::P, VK_CONTROL | ModifierFlag::NONE, KeyCode::CURSOR_UP</autogen>
<autogen>__KeyToKey__ KeyCode::N, VK_CONTROL | ModifierFlag::NONE, KeyCode::CURSOR_DOWN</autogen>
<autogen>__KeyToKey__ KeyCode::B, VK_CONTROL | ModifierFlag::NONE, KeyCode::CURSOR_LEFT</autogen>
<autogen>__KeyToKey__ KeyCode::F, VK_CONTROL | ModifierFlag::NONE, KeyCode::CURSOR_RIGHT</autogen>
<autogen>__KeyToKey__ KeyCode::P, VK_CONTROL | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_UP, VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::N, VK_CONTROL | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_DOWN, VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::B, VK_CONTROL | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_LEFT, VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::F, VK_CONTROL | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_RIGHT, VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::B, VK_OPTION | ModifierFlag::NONE, KeyCode::CURSOR_LEFT, VK_OPTION</autogen>
<autogen>__KeyToKey__ KeyCode::F, VK_OPTION | ModifierFlag::NONE, KeyCode::CURSOR_RIGHT, VK_OPTION</autogen>
<autogen>__KeyToKey__ KeyCode::B, VK_OPTION | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_LEFT, VK_OPTION | VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::F, VK_OPTION | VK_SHIFT | ModifierFlag::NONE, KeyCode::CURSOR_RIGHT, VK_OPTION | VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::D, VK_OPTION | ModifierFlag::NONE, KeyCode::FORWARD_DELETE, VK_OPTION</autogen>
<autogen>__KeyToKey__ KeyCode::V, VK_OPTION | ModifierFlag::NONE, KeyCode::PAGEUP</autogen>
<autogen>__KeyToKey__ KeyCode::V, VK_OPTION | VK_SHIFT | ModifierFlag::NONE, KeyCode::PAGEUP, VK_SHIFT</autogen>
<autogen>__KeyToKey__ KeyCode::V, VK_CONTROL | VK_SHIFT | ModifierFlag::NONE, KeyCode::PAGEDOWN, VK_SHIFT</autogen>
</item>
</root>

The key codes have to be changed for keyboard layouts like Dvorak or Colemak. EMACS_MODE_IGNORE_APPS includes terminal emulators, Emacs applications, and VMs, but you can also add custom appdef elements.

share|improve this answer
Amazing. Changing relatively low-level behavior and yet so easy. A leap closer to a OS paradise. Hopefully there is even better, 100 % working solution, otherwise this is the answer. – courteous Nov 11 '12 at 10:20
As you say, it doesn't work in all apps. Xcode, for one, won't budge to this .dict (but that can be "solved" with a custom keybinding, say, ⌘+B and ⌘+F). Still, very powerful to have Emacs-like behavior (almost) throughout the OS. – courteous Nov 11 '12 at 15:38
KeyRemap4MacBook has an emacs mode group that changes for example ⌥F to ⌥→, but not when Terminal or Emacs is frontmost. You can customize it by creating a private.xml based on it. I think the real solution is to just get a keyboard with the arrow keys and modifier keys at better positions. – Lauri Ranta Nov 12 '12 at 19:36
1  
@courteous The emacs mode in KeyRemap4MacBook does that. It's not possible in a keylayout file or with DefaultKeyBinding.dict. – Lauri Ranta Nov 18 '12 at 14:52
1  
@courteous I added that to the answer as well. I have "~w" = selectWord:; in my DefaultKeyBinding.dict. – Lauri Ranta Nov 19 '12 at 5:46
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.