Emacs:将 C-h 转换为 DEL,将 M-h 转换为 M-DEL

标签 emacs key-bindings emacs23 dot-emacs emacs24

我希望我的 C/M-h 键成为删除的绑定(bind)。

global-set-key 的通常解决方案对我不起作用,因为我希望这些键在任何地方都表现为删除,包括 minibuffer 和各种模式,并且能够在我的各种 Linux/OS X/Windows emacs 安装之间工作。

我有以下接近解决方案:

(when (>= emacs-major-version 23)
  (setq help-char (string-to-char "<f1>"))                      ;; Bind ONLY F1 to help, not C-h
  (define-key input-decode-map (kbd "C-h") (kbd "DEL"))         ;; Translate C-h to DEL ;; FIXME:  Should be in emacs 22, doens't work.
  (define-key input-decode-map (kbd "M-h") (kbd "M-<DEL>"))     ;; Translate M-h to M-DEL
  ;; (define-key input-decode-map (kbd "<backspace>") 'version) ;; Stop me using backspace for a while
)

但这显然只适用于 Emacs > 22,因为 input-decode-map .

有人能帮我找到一个适用于 22 甚至 21 的解决方案吗? (但不是优先事项)。干杯!

编辑:我的解决方案:

它还没有完成,但这已经解决了我的大部分问题:
(setq help-char [f1]) ;; I don't want help when I'm just trying to backspace!

(define-key isearch-mode-map "\C-h" 'isearch-delete-char)
;; (define-key isearch-mode-map "\M-h" 'my-isearch-delete-word)

(defvar my-overriding-binding-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [?\C-h] 'delete-backward-char)
    (define-key map [?\M-h] 'backward-kill-word)
    map))

(define-minor-mode my-overriding-binding-mode
  "Personal global key-bindings."
  :global t)

(my-overriding-binding-mode 1)

对于需要编写的一些行为不端的模式,可能有一些警告——我会在遇到它们时这样做。现在唯一真正的问题似乎是 M-h在 isearch 中,我将作为一个单独的问题发布。

再次感谢伙计们,你们帮了大忙。

最佳答案

这是答案的第一个也是最重要的部分,所有解释都在 elisp 评论中给出。这主要在 X11 环境中进行了测试,但包括使用 Mac 键盘。它已从 v19.28 开始进行测试,直至并包括 v23.3。我认为它适用于 v24,但我还没有非常多地使用 v24。

你可以找到我的完整版(虽然并不总是 100% 最新的)~/.emacs.el在以下初始化和配置文件包中:

ftp://ftp.planix.ca/pub/local/dotfiles.tar.gz

;;; first off, we do some fancy stuff to make C-h work "properly," but still
;;; have good access to the help functions!
;;;
;;; Using C-h for "help" might seem OK to some folks, but since it's also the
;;; ASCII standard value for the "backspace" character, one typically used ever
;;; since the days of the typewriter to move the cursor backwards one position
;;; and in computing normally to erase any character backed over, a vast amount
;;; of stupidity is needed in emacs to continue to (ab)use as the "help"
;;; character.  Instead it is still quite intuitive, and often much easier in
;;; zillions of environments, to use M-? for help.
;;;
;;; So, we can set C-h and C-? and friends to sensible bindings...
;;
;; Remember to call override-local-key-settings in the appropriate hooks to fix
;; up modes which violate global user preferences....
;;
(global-set-key "\C-h" 'delete-backward-char)
(global-set-key "\C-?" 'delete-char)
(global-set-key "\e\C-h" 'backward-kill-word)
(global-set-key "\e\C-?" 'kill-word)

;;; and then we diddle with help to make it work again....
;;
;; Oddly, the help interface in emacs is extremely scatter-brained, with
;; several slightly different ways of doing the same thing.  This is probably
;; due to the fact that several different programmers have implemented various
;; bits and pieces of the help systems.  See help.el and help-macro.el, but try
;; not to tear your hair out when you find out help-event-list in 19.34 is
;; essentially bogus, since it is simply an extension to a "standard" list.
;;
;; Remember to call override-local-key-settings in the appropriate hooks to fix
;; up modes which violate global user preferences....
;;
(global-set-key [f1] 'help-command)     ; first do this for 19.28.
(global-set-key "\e?" 'help-command)    ; this is the first step to set up help
(global-set-key "\e?F" 'view-emacs-FAQ) ; in 19.34 it needs more help...
;; should help-char be just ? instead?
(setq help-char ?\M-?)                  ; this should "fix" the rest.

;; one more handy help-related binding...
;;
(define-key help-map "?" 'describe-key-briefly) ; also C-x? for Jove compat

;;; Now for function key mappings...
;;;
;;; I USUALLY EXPECT THE BACKSPACE KEY TO WORK LIKE AN ASCII BACKSPACE!
;;
;; For some entirely un-fathomable reason the default function bindings make
;; the 'backspace' and 'delete' keys synonymous!
;;
;; NOTE: this *should* work by simply reading termio for current erase char.
;;
;; As of emacs-21.2 a note was added to the NEWS file which says "** On
;; terminals whose erase-char is ^H (Backspace), Emacs now uses
;; normal-erase-is-backspace-mode."  Unfortunately this does EXACTLY the WRONG
;; thing, and in a totally bizzare, disruptive, subversive, and stupid
;; backwards way.  With every major release it's gotten worse and worse and
;; worse; more convoluted, and ugly.
;;
;; So, we must do something to kill that horrible stupid broken poor
;; useless excuse for a feature, normal-erase-is-backspace-mode....
;;
;; seems 23.1 changes function-key-map radically....
;;
;; Unfortunately 23.1 also still has function-key-map so we can't make that
;; (function-key-map) an alias for the new local-function-key-map that we need
;; to use in 23.1 to modify key translations.  Sigh.
;;
;; Instead make a new alias that can be used transparently as the desired map.
;;
(eval-and-compile
  (if (functionp 'defvaralias)          ; since 22.1
      (if (boundp 'local-function-key-map)
          (defvaralias 'my-function-key-map 'local-function-key-map
            "Special variable alias to allow transparent override of
`local-function-key-map' for 23.1 vs 22.3(?).")
        (defvaralias 'my-function-key-map 'function-key-map
          "Special variable alias to allow transparent override
of `function-key-map' for 22.3(?) vs. older,"))
    ;; XXX is this right?  it works (maybe?)
    (defvar my-function-key-map function-key-map)))
;;
;; First undo (local-)function-key-map weirdness.
;;
;; luckily on Mac OS-X X11, at least with the mini-wireless keyboard and on the
;; large USB keyboard, the big "delete" key on the main block is actually
;; sending <backspace> by default, else one would have to first change the X11
;; keyboard map!
;;
(define-key my-function-key-map [delete] [?\C-?])
(define-key my-function-key-map [S-delete] [?\C-h])
(define-key my-function-key-map [M-delete] [?\C-\M-?])
(define-key my-function-key-map [kp-delete] [?\C-?])
(define-key my-function-key-map [backspace] [?\C-h])
(define-key my-function-key-map [S-backspace] [?\C-?])
;;(define-key my-function-key-map [C-backspace] [?\C-h]) ; sometimes *is* DEL....
(define-key my-function-key-map [M-backspace] [?\e?\C-h])
(define-key my-function-key-map [M-S-backspace] [?\e?\C-?])
(define-key my-function-key-map [kp-backspace] [?\C-h])
;;
;; Next, zap the keyboard translate table, set up by
;; normal-erase-is-backspace-mode (in simple.el), which can do nothing
;; but confuse!
;;
(setq keyboard-translate-table nil)
;;
;; Finally, kill, Kill, KILL! the input-decode-map added in 23.x, and set
;; up by normal-erase-is-backspace-mode (in simple.el) which can do
;; nothing but confuse!
;;
;; This is TRULY _E_V_I_L_!!!!  HORRID!!!  MASSIVELY STUPID!!!!
;;
;; input-decode-map is poorly documented, and causes things above and
;; below to fail with the most confusing errors!
;;
;; (This probably only needs to be blown away on window systems, and
;; perhaps only for X, but doing it here now is apparently early enough
;; to allow for terminal mode specific settings to be re-applied to it
;; and so it seems safe to just blow away the asinine stupid attempt to
;; transpose backspace and delete.  RMS is a pedantic idiot on this!)
;;
(if (boundp 'input-decode-map)
    (setq input-decode-map (make-sparse-keymap)))

;; finally here's a little function to help fix up modes which don't honour default
;; bindings in sensible ways.  Use this in any init hooks for modes which cause problems
;;
(defun override-local-key-settings ()
  "User defined function.  Intended to be called within various hooks to
override the value of buffer-local key map settings which may have been
overridden without consideration by the major mode."
  (local-set-key "\C-?" 'delete-char)   ; many modes
  (local-set-key "\C-h" 'delete-backward-char)  ; sh-mode
  ;; the rest are *not* overridden by cc-mode, but are by c-mode
  (local-set-key "\e\C-h" 'backward-kill-word) ; text-mode
  (local-set-key "\e?" 'help-command)   ; nroff-mode
  (local-set-key "\eh" 'mark-c-function)
  (local-set-key "\e\C-?" 'kill-word)
  (local-set-key "\e\C-e" 'compile)
  ;; try this on for size...
  (local-set-key "\C-x\e\C-e" 'recompile)
  )

(add-hook 'isearch-mode-hook
          (function
           (lambda ()
            "Private isearch-mode fix for C-h."
            (define-key isearch-mode-map "\C-h" 'isearch-delete-char))))


;;; OK, that's the end of the stuff to fix GNU Emacs' C-h brain damage.  Phew!

关于Emacs:将 C-h 转换为 DEL,将 M-h 转换为 M-DEL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13897125/

相关文章:

macos - emacs - 每行的第一个字符从窗口末尾开始

emacs - 下划线作为单词的一部分以表示前向词不起作用

emacs - 将子目录添加到加载路径

emacs - M-x 编译后在 Emacs 中运行程序的最有效方法是什么

regex - evil-mode 和正则表达式中的 Emacs

regex - 是否可以更改 emacs 的正则表达式语法?

emacs - 是什么导致 `M-S-t` (meta + shift + t) 键绑定(bind)不采取?

emacs - 如何设置键绑定(bind)以使 Emacs 像我想要的那样透明/不透明?

perl - emacs 中正确的 perl 开关格式

visual-studio - 如何在 Visual Studio 中重新绑定(bind)除 F5 以外的 "Continue"命令的键?