👩🏻‍💻 Emacs style input in Microsoft Word: A config tutorial

July 2, 2021  How to set up Microsoft Word to have Emacs style bindings in Windows

To cut to the chase: Emacs bindings are awesome and I do need to use Microsoft Word a lot. In this guide, I present a simple minimal solution to more keyboard/Emacs friendly word setup. While it is possible to have pre-fix keys and more complex behaviour with autohotkey, I only present a minimal set of functions in this guide.

You can emulate the Emacs behaviour in two ways: (1) by adjusting in-built word shortcuts and (2) with Autohotkey scripts. Previously, I had relied mainly on adjusting in-built word shortcuts (via customize ribbon dialogue). However, this approach has some significant limitations, and it is a pain to set up each time, so I try to move as much as possible to Autohotkey.

The table below shows the fullset of binds my configuration enables, with the “Configuration” column indicating whether you need to “hard fix” this in word, or setup in AHK. I use the Word Macros themselves, these are what you search in the customize shortcuts dialogue. Note C = Ctrl and M = Alt.

Macro/Command Binding Configuration
StartOfLine C-a AHK
EndOfLine C-e AHK
LineDown C-n AHK
LineUp C-p AHK
NextMisspelling C-; Word
EditSelectAll C-h AHK
FileNewDefault C-S-N AHK
WordLeft M-b AHK
DeleteWord M-d AHK
WordRight M-f AHK
SentLeft M-a Word
SentRight M-e Word
Toggle Bindings C-F11 AHK

Word Config

First, add the few Word shortcuts you would like by going to “Customize Ribbon” menu, and then click “Customize” keyboard shortcuts (as pictured below). Click “All commands”, search for the one you want, and then assign. I note that the “NextMisspelling” to C-; is useful for everyone. It will correct the misspelling closest to the cursor (normally back).

Word's customize ribbon dialouge to set custom shortcut keys

Autohotkey

This is the autohotkey script I am currently using. It’s pretty sloppy but it gets the job done.

;; Emacs Bindings for Microsoft Word
;; Author: Michael David Wilson
;; Copyright (2021)
;; Licence: Do whatever the hell you want with this

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#Warn  ; Enable warnings to assist with detecting common errors.
#SingleInstance, force
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

; Forces the use of the hook to implement all or some keyboard hotkeys.
#InstallKeybdHook
#UseHook On

; Sets the delay that will occur after each keystroke sent by Send or ControlSend
; 0 for the smallest possible delay, -1 for no delay at all, leaving blank to retain the current Delay
SetKeyDelay 0

^F11::Suspend, Toggle

;; $CapsLock::Ctrl
; function to handle re-pressing of the lctrl key after a send
; These fix issues with capslock control rebinds
cSend(sKey) {
/* useage examples (include the {}s in the passed string):
cSend("{left}")
cSend("{^left}")
*/
SendInput, {lctrl Up}%sKey%{lctrl Down}
}


Send_Control_Command(emacsKey, translationToWindowsKeystrokes) {
    cSend(translationToWindowsKeystrokes) ;passthrough original keystroke
    return
}

Send_Alt_Command(emacsKey, translationToWindowsKeystrokes) {
    SendInput, %translationToWindowsKeystrokes% ;passthrough original keystroke
    return
}

RControl & Right::selectLineEnd()
RControl & Left::selectLineHome()

;; These are fixes for my HP notebook with a completely broken keyboard design
selectLineEnd() {
    Send, {Shift Down}
    Send, {End}
    Send, {ShiftUp}
}

selectLineHome() {
    Send, {Shift Down}
    Send, {Home}
    Send, {ShiftUp}
}


;; If word open... 

#IfWinActive ahk_class OpusApp

   $^p::Send_Control_Command("^p","{Up}")

   $^n::Send_Control_Command("^n","{Down}")
   
   $!f::Send_Alt_Command("!f","^{Right}")

   $!b::Send_Alt_Command("!b","^{Left}")

   $!<::Send_Alt_Command("!<","^{Home}")

   $!>::Send_Alt_Command("!>","^{End}")


   ;==========================
   ;Line Navigation
   ;==========================

   $^a::Send_Control_Command("^a","{Home}")

   $^e::Send_Control_Command("^e","{End}")

#IfWinActive

Usage notes

You can toggle the bindings on or off with C-F11. This is useful as it means you can still access default commands (e.g., new file C-n).

See also

This solution has been derived from elsewhere, and there are other more comprehensive solutions.

https://github.com/catweazle9/emacs-everywhere

https://github.com/oneh/autohotkey_emacs_keymap

https://github.com/lynnux/emacs.ahk

https://autohotkey.com/board/topic/21786-emacs-key-bindings-for-the-outlook-2007-email-editor/