How do I bind C-= in emacs?

旧街凉风 提交于 2019-12-09 12:48:55

问题


This s-expression in my .emacs file does not produce the desired result:

(define-key global-map (kbd "C-=") 'djhaskin987-untab-to-tab-stop)

Why can't I bind a command to Ctrl+=?

EDIT for clarification:

I am using emacs23-nox on the standard build of urxvt-256colors for Debian, except that I have recompiled with --disable-iso405776 (or something to that effect) it so that Ctrl+Shift doesn't do the weird 'insert character' thing. I don't know if this affects anything. For example, C-M-i sends M-TAB, which I don't understand.

EDIT II:

I apologize for not making this clear. The function djhaskin987-untab-to-tab-stop has the line (interactive) in it. This part works.


回答1:


In a terminal, TAB is represented by the same byte sequence as C-i. And typically the terminal has no special byte-sequence for C-=, so it will just send a =. There is nothing that Emacs can do about it. But you might be able to teach your terminal emulator to send some special byte sequence of your choice (check the documentation of your terminal emulator for that), after which you can teach Emacs to recognize it as a C-= (with something like (define-key input-decode-map "...thebytes..." [?\C-=])).




回答2:


The accepted answer in combination with the link in the first comment to it is enough to get started on a complete solution. The steps are:

  1. make your terminal output escape codes for the key
  2. make Emacs recognise the escape codes as a standard keypress
  3. bind the keypress in a mode map

The first is very terminal and/or operating system dependent.

The link in the first comment shows some examples for X Window System. The key names are available in /usr/X11R6/include/X11/keysymdef.h (or try locate keysymdef.h), prefixed with XK_ (which should be removed for our purposes). I read that symbolic names are preferred over key literals.

I don't currently run X but I think it should look like this in your case:

XTerm.VT100.Translations: #override \
Ctrl ~Meta ~Shift  <Key> equal:         string(0x1b) string("[emacs-C-=")\n

The first string is the escape, the second is of your choosing.

In iTerm you can use Preferences->Keys and choose Send Escape Sequence as the Action. For example, I have:

Emacs Wiki lists some configuration methods for other terminals.

Now you can teach Emacs to recognize it as a C-=. First define-key into input-decode-map. I have a couple of helper functions:

(defun my/global-map-and-set-key (key command &optional prefix suffix)
   "`my/map-key' KEY then `global-set-key' KEY with COMMAND.
 PREFIX or SUFFIX can wrap the key when passing to `global-set-key'."
   (my/map-key key)
   (global-set-key (kbd (concat prefix key suffix)) command))

 (defun my/map-key (key)
   "Map KEY from escape sequence \"\e[emacs-KEY\."
   (define-key function-key-map (concat "\e[emacs-" key) (kbd key)))

So then:

(my/global-map-and-set-key "C-=" 'some-function-to-bind-to)

Some keys (currently: ()\|;'`"#.,) will need escaping in the string, like C-\..




回答3:


The problem is that you use emacs in the terminal. The terminal does not allow "C-=". Try your function in the graphical emacs and it will work. You will have to find another keybinding for the terminal.




回答4:


The function you're binding must be interactive. Try:

(define-key global-map (kbd "C-=") 
    (lambda () (interactive) (djhaskin987-untab-to-tab-stop)))



回答5:


You can map C-= using the default ascii codes: ^[[61;5u. Then you can bind it in Emacs either using:

(global-set-key (kbd "C-=") 'djhaskin987-untab-to-tab-stop))

or let use-package do it, e.g.:

(use-package expand-region
  :ensure t
  :bind (("C-=" . er/expand-region)))

I do want to thank Sam Brightman, for his wonderful solution. It's a very clean, albeit heavy-handed, approach that will work for any keys that cannot be sent via normal ascii codes. I've been wanting to get C-TAB working inside iterm2 for a long time. I was able to do it by deleting the builtin preferences keys for C-TAB/C-S-TAB and using his approach. With the following, I can be ssh'd into remote Linux boxes and quickly switch through lots of open buffers in projects, just like a desktop editor.

(use-package nswbuff
  :defer 1
  :after (projectile)
  :commands (nswbuff-switch-to-previous-buffer
             nswbuff-switch-to-next-buffer)
  :config
  (progn
    (my/global-map-and-set-key "C-TAB" 'nswbuff-switch-to-previous-buffer)
    (my/global-map-and-set-key "C-S-TAB" 'nswbuff-switch-to-next-buffer))
  :init
  (setq nswbuff-display-intermediate-buffers t
        nswbuff-exclude-buffer-regexps '("^ "
                                         "^\*.*\*"
                                         "\*Treemacs.*\*"
                                         "^magit.*:.+")
        nswbuff-include-buffer-regexps '("^*Org Src")
        nswbuff-start-with-current-centered t
        nswbuff-buffer-list-function '(lambda ()
                                        (interactive)
                                        (if (projectile-project-p)
                                            (nswbuff-projectile-buffer-list)
                                          (buffer-list)))))


来源:https://stackoverflow.com/questions/10660060/how-do-i-bind-c-in-emacs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!