Emacs Ctrl modifiers don't work in console

2020-04-08 13:50发布

问题:

I have 2 hotkeys for dired, that work in GUI mode in Emacs:

(add-hook 'dired-mode-hook
  (lambda ()
        (define-key dired-mode-map (kbd "C-<up>")
              (lambda () (interactive) (find-alternate-file "..")))))

(add-hook 'dired-mode-hook
  (lambda ()
        (define-key dired-mode-map (kbd "C-<right>") 'diredp-find-file-reuse-dir-buffer)))

But when I click CTRL+ or CTRL+ in console the cursor just moves as if the arrow was pressed.

When I try CTRL+H K and then CTRL+, it gives me the right key docs as if CTRL wasn't pressed at all.

How to fix this strange behaviour in console?

I am using Linux Slackware 14, Emacs 24.2.1.

回答1:

Here is the algorithm, how to make modifier keys work in Emacs in terminal.

1.Create a file funcskeys with content:

control keycode 105 = F100
string F100 = "\033[1;5D"
control keycode 106 = F101
string F101 = "\033[1;5C"
control keycode 103 = F102
string F102 = "\033[1;5E"
altgr keycode 105 = F103
string F103 = "\033[1;5F"

At the end must be an empty line!

2.Under root load the file:

#loadkeys funcskeys

3.Put this into the beginning of .emacs:

(unless (display-graphic-p)
  (progn
    (define-key input-decode-map "\e[1;5C" [(control right)])
    (define-key input-decode-map "\e[1;5D" [(control left)])
    (define-key input-decode-map "\e[1;5E" [(control up)])
    (define-key input-decode-map "\e[1;5F" [(meta left)])))

End of algorythm

After this hotkeys will work:

(global-set-key (kbd "C-<right>") 'forward-word)
(global-set-key (kbd "C-<left>") 'backward-word)


回答2:

Look out for loadkeys. At least in Debian/Ubuntu it's in the package kbd. With it, you can modify your keyboard layout and probably also some more "exotic" key combinations.



回答3:

Your terminal likely doesn't produce different escape sequences for CTRL-right‬ versus just right.

You can easily verify this by typing CTRL-v CTRL-right‬ and CTRL-v right‬. Here, CTRL-v tells the terminal to print the escape sequence for the key that follows. If these two produce the same sequences then your terminal sends the exact same information to Emacs whether you press CTRL or not.

For instance, if I type these shortcuts in a Gnome terminal, I get:

  • ^[[C for CTRL-v right‬
  • ^[[1;5C for CTRL-v CTRL-right‬

When I do the same on one of the Linux consoles, I get:

  • ^[[C for CTRL-v right‬
  • ^[[C for CTRL-v CTRL-right‬

As you can see, in the latter case it's exactly the same result for both key sequences, hence there's no way Emacs can distinguish the two.

The only way to fix this is to convince your terminal to send a different sequence when you hold down the CTRL key - see this question for more information.

An easier work-around would be to simply use different key bindings in Emacs.