Linux – How to map CTRL+A, CTRL+E to function as Home, End system-wide

hotkeyskey-bindinglinuxUbuntuubuntu-unity

Is there a way to map CTRL+A and CTRL+E to work system-wide as move to beginning of line, and move to end of line correspondingly?

I.e. I would like these shortcuts to seamlessly work in any app, not only in the terminal (i.e. as in OSX).

My main system is Ubuntu with the Unity desktop, but it would be good to have a universal solution which would be desktop-agnostic, or at least be supported in Gnome, XFCE and LXDE.

Best Answer

xmodmap might seem to provide an answer, but it does not, because the keycodes it manipulates are existing keys on the keyboard, not modified keys. A controlA is a modified key.

xmodmap can only reassign existing keycodes or (their names) keysyms, as listed in its manual page:

keycode NUMBER = KEYSYMNAME ...
keycode any = KEYSYMNAME ...
keysym KEYSYMNAME = KEYSYMNAME ...

To see the keycodes that xmodmap knows about, run

xmodmap -pk

which shows something like this (shortened for clarity):

There are 4 KeySyms per KeyCode; KeyCodes range from 8 to 255.

    KeyCode Keysym (Keysym) ...
    Value   Value   (Name)  ...

      8     0x0061 (a)      0x0041 (A)      0x00e5 (aring)  0x00c5 (Aring)  
      9     0x0073 (s)      0x0053 (S)      0x00df (ssharp) 0x00cd (Iacute) 
     10     0x0064 (d)      0x0044 (D)      0x08ef (partialderivative)      0x00ce (Icircumflex)    
     11     0x0066 (f)      0x0046 (F)      0x08f6 (function)       0x00cf (Idiaeresis)     
     12     0x0068 (h)      0x0048 (H)      0x01ff (abovedot)       0x00d3 (Oacute) 
     13     0x0067 (g)      0x0047 (G)      0x00a9 (copyright)      0x01bd (doubleacute)    
     14     0x007a (z)      0x005a (Z)      0x07d9 (Greek_OMEGA)    0x00b8 (cedilla)
     ...

xev shows what actually happens:

KeyPress event, serial 34, synthetic NO, window 0xc00001,
    root 0x111, subw 0xc00002, time 2209364614, (27,43), root:(47,86),
    state 0x4, keycode 8 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (01) "^A"
    XmbLookupString gives 1 bytes: (01) "^A"
    XFilterEvent returns: False

KeyRelease event, serial 34, synthetic NO, window 0xc00001,
    root 0x111, subw 0xc00002, time 2209364773, (27,43), root:(47,86),
    state 0x4, keycode 8 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (01) "^A"
    XFilterEvent returns: False

The control modifier is the 0x4 in the state; the XLookupString (one of several related functions for combining key events) transforms the keysym for "a" into ^A (control/A).

Because there is no keysym for any of the control keys, reassigning keycodes using xmodmap will not be possible for OP's problem.

To solve OP's problem, one would have to have a way to tell the operating system to (essentially) refuse to deliver separate events for control and A — but Linux and X do not work that way. Limiting the scope to a particular application (xterm) or set of applications (Gtk-based programs), one might address those separately. But a solution which applies system-wide does not seem doable.