English 中文(简体)
How to turn off alternative Enter with Ctrl+M in Linux
原标题:

Why is Ctrl+M bound to Enter in Ubuntu Jaunty? How to turn it off?

I m using Emacs and would like to bind Ctrl+M to some other command.

问题回答

I think your question is backwards. It is not C-m that is bound to Enter, it is Enter that is bound to C-m. And C-m is the same as RET.

If you run C-h k C-m, you will see something like "RET runs the command ...". C-m sends RET because it is a control code, see http://en.wikipedia.org/wiki/Control_character.

The Enter key is bound to C-m; if you run C-h k Enter, you will see something like "RET (translated from <return>) runs the command ...". See, Enter is being interpreted by emacs as <return> and then that key is getting translated to C-m.

What you want to do is first remove the translation from <return> to RET by binding it directly to what it s currently indirectly bound, e.g. (global-set-key (kbd "<return>") newline). Then you re free to bind C-m to whatever you want without affecting Enter.

This assumes you re using the graphical emacs. If you re running it in a terminal, this won t work, because Enter will send C-m, not <return>. You can check that using the window-system variable though.

Note: The issue isn t limited to Linux, it exists on Windows (and presumably Mac) as well. Read the other (non stack-overflow) source of all knowledge: Wikipedia on Carriage Return.

If you want to rebind C-m, be sure to all bind <return> otherwise you run the risk of no longer being able to use the Enter/Return key. Also, in a terminal, Emacs cannot distinguish between the two (C-m and <return>).

In a plain Emacs, the Enter/Return key is bound to <return>, which is (by default) translated to RET (same thing as C-m). If you only rebound the C-m, you d also be affecting the Enter/Return key.

Try C-h k <return> and you ll see

RET (translated from <return>)

So, rebind both in the appropriate keymap to make sure you get the behavior you want.

It might be instructive to play with the following code:

(defun my-return ()
  (interactive)
  (message "return"))
(defun my-ret ()
  (interactive)
  (message "RET"))
(defun my-c-m ()
  (interactive)
  (message "C-m"))
(global-set-key (kbd "<return>")  my-return)
(global-set-key (kbd "C-m")  my-c-m)
(global-set-key (kbd "RET")  my-ret)

Put that in your *scratch* buffer and press C-j after each line (to evaluate the sexp). Then play with the Enter/Return keys and C-m.

input-decode-map does the trick. Quote from the emacs manual:

This keymap has the same structure as other keymaps, but is used differently: it specifies translations to make while reading key sequences, rather than bindings for key sequences.

It s the same principle like I ve presented above, transforming Ctrl+m to something, say Ctrl+1 and map Ctrl+1 to your command. I use Ctrl+m for backward-kill-word.

Here you go:

(global-set-key (read-kbd-macro "C-1")  backward-kill-word)
(define-key input-decode-map "C-m" [?C-1])

It s unclear whether the previous answers have solved this question, so here s another spin on it:

Historically, "return" frequently meant two things: Carriage Return, and Line Feed.

Quoting wikipedia:

Originally, carriage return was the term for a mechanism or lever on a typewriter that would cause the cylinder on which the paper was held (the carriage) to return to the left side of the paper after a line of text had been typed, and would usually move the paper to the next line as well. Later it was used for the control character in Baudot code on a teletypewriter for end of line return to beginning of line and did not include line feed.

Long story short, there are two ASCII codes that are relevant to end-of-line (and, therefore, potentially to the return key): CR (ASCII decimal 13, or Ctrl-m) and LF (ASCII decimal 10, or Ctrl-J).

I think the general convention these days is for the return or enter keys to map to ASCII 13, and thus be "return" (RET in emacs messaging). But if you re running emacs from a terminal emulator, this may mean that you don t have the option of having a C-m binding that s different from RET. When I try running emacs in a terminal (GNU Emacs 23.2.1 on MacOS X in Terminal.app), and I try typing C-h c <return> (i.e. pressing my return/enter key), I get:

RET runs the command newline

If I type, instead, C-h c C-m (i.e. holding down control and pressing M), I get:

RET runs the command newline

In other words, the exact same thing. Emacs (nor any other program run from the terminal) can t tell the difference between the two. (Knowing this can sometimes be handy -- if you re logged in to a system that maps things differently than the system you re coming from, you can type C-m or C-j to get the thing you want, depending on the way the mapping is screwed up.)

And speaking of having the mapping screwed up, I ll just mention that there are some stty settings that can be relevant to such things: inlcr, inlcr, and igncr (these three are related to how input is processed -- there are also some output-related ones). I doubt that making stty changes is going to be useful to this particular problem, but I thought it worth mentioning.

In the end, I think your choices are:

  1. Live with not having C-m that means anything different than return/enter

  2. Run a graphical version of emacs, instead of the terminal version. This should have access to the distinct keycodes, which the terminal emulator isn t passing along (because it s emulating a terminal, which didn t have such things in the same way as modern computers do).

(global-set-key (kbd "C-m") cmd) ;

Where cmd is your command should remap control m...

As for why ctrl+m is bound to enter. I believe it had something to do with some older keyboard not having enter,tab, backspace, etc... ( I could be grossly mistaken)

For example ctrl+h is backspace, some unix operating systems will output ^H when you hit backspace on them!

The main source of the problem is that Enter and Ctrl-M both map to the same ASCII code (13). You would only be able to map them distinctly on a system that can distinguish them.

Actually, this is a very tricky question, you won t get it right with: (global-set-key (kbd "") newline)

because that return (RET) is newline in just some particular cases. You will see the weirdness I m talking about if you try that in your .emacs

I ve found an ugly but working solution by using some KDE events application, and bound Ctrl+m to Ctrl+1 . I ve chosen that because I wouldn t use that combination (Ctrl+1) but you can choose something else. This way, in emacs (but in my X environment) I don t get the RET (or linefeed character) when I press Ctrl+m, instead I get Ctrl+1. And then, I did something like: (global-set-key "C-1" mycmd)

The problem is, that now I use awesome window manager, and I don t know how to do that X mapping again. If you don t use KDE, you search for something similar in Gnome.

Some very good explanations here as to the nature of the problem, and I won t expound on those issues. However, I want to address the original question directly. I solved the problem for changing the (control m) sequence bound to newline command by the following code in my ~/.xemacs/custom.el file:

(defun my-compile-hook-for-c-and-cpp-mode ()
  "My compile hook for C and C++ mode" 
  (local-set-key [(control m)]  compile)
  )

(add-hook  c-mode-hook  my-compile-hook-for-c-and-cpp-mode)
(add-hook  c++-mode-hook  my-compile-hook-for-c-and-cpp-mode)

In the above example, I have changed (control m) to run the compile command (M-x compile) when the c-mode or c++-mode is active.

Note that you can change the behavior of (control m) globally as well, without the mode related bindings. In that case, just add the following to your ~/.xemacs/custom.el file:

(global-set-key [(control m)]  compile)




相关问题
suppress additional braces in emacs electric mode

I started using ruby-electric-mode. I like it except that I am used to closing open brackets myself (the other pairing are still useful to me). How can I make emacs suppress additional brackets when ...

Setting up an emacs environment in windows?

I am currently constrained to a windows dev box and I want to migrate my projects from eclipse to emacs. What are some good references on setting up an emacs dev environment for windows? Anything ...

Emacs Setting which-function-mode

I would like to have which-function-mode on by default when I open up Emacs. I ve added the following lines to my .emacs file. (setq which-func-mode t) (setq which-function-mode t) When I open ...

Enabling go mode for emacs

I don t seem to be able to enable a go mode for emacs. C mode doesn t work without semicolons. The best I have found is the JavaScript mode by Karl Landstrom, since JavaScript also doesn t require ...

Custom Emacs key bindings are not working

The key bindings I ve defined in my .emacs file aren t working. Here s the file: ;init modes (menu-bar-mode 0) (tool-bar-mode 0) (cua-mode) (column-number-mode) (fset perl-mode cperl-mode) (cperl-...

eval during emacs lisp macro expansion

How can I fix the simple macro foo in (elisp)Eval During Expansion? None of the followings work: (defmacro foo1 (a) `(setq (eval ,a) t)) (defmacro foo2 (a) `(setq ,(eval a) t)) (defmacro foo3 (...

Get local cvs comment history when committing file/s in emacs

I often commit files with similar cvs comment but not in a single operation. I would like to able to bring up previous comments I ve used in a previous commit when I am in the process of writing a ...

热门标签