【问题标题】:Emacs: Translating C-h to DEL, M-h to M-DELEmacs:将 C-h 转换为 DEL,将 M-h 转换为 M-DEL
【发布时间】:2012-12-15 23:22:59
【问题描述】:

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

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)

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

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

【问题讨论】:

  • 为什么?是因为你喜欢点击C-h 来删除字符,还是因为你的backspace 键发送了C-h?如果是后者,那么您最好修复它(即更改终端仿真器,使其发送其他内容)。
  • 是前者。为答案干杯。
  • 你不需要延迟(define-key isearch-mode-map ...),你可以在顶层调用它们而不使用isearch-mode-hook
  • 太好了,干杯。我编辑了解决方案。
  • @Daniel 你最后有没有做过isearch-backward-kill-word

标签: emacs key-bindings emacs23 dot-emacs emacs24


【解决方案1】:

这是答案的第一个也是最重要的部分,所有解释都在 elisp cmets 中给出。这主要在 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!

【讨论】:

  • 哇,一个比我更讨厌 C-h 的人。非常感谢,尽管我需要一些时间来为我挑选相关的部分。我会这样做,发布我使用的位,然后希望关闭问题。
  • 谢谢! :-) 我想你会发现你需要 all 这些位,甚至更多。例如,我目前有 8 次调用或添加到我的 override-local-key-settings 函数的钩子。
  • 也许应该注意的是,这场 C-h/Backspace vs. DEL/Delete 之战与最古老的 ASCII 终端一样古老,甚至更古老,而且这两个派系通常被描述为东海岸 vs . 西海岸,虽然起源比那稍微复杂一些。
  • 好的,所以一些测试表明这对于 C-h 来说非常有效,但我的 M-h 要求仍然有点棘手。例如,'isearch-delete-word 对于isearch-mode-hook 会很方便,但该函数不存在。我试过backward-kill-word,我认为我上面的代码正在调用(作为M-Del),但没有骰子。
  • 刚刚重新测试了我的旧代码。似乎我的解决方案无论如何都不适用于 isearch - 我必须只使用 find-file 等进行测试。
【解决方案2】:

那么我建议你使用次要模式:

(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)

【讨论】:

  • 我刚刚在 emacs 22 和 24 中尝试了该代码,它们仍然将 C-h 翻译为 help-char 并将 M-h 翻译为 mark-paragraph。
  • 嗯,这是保证 100% 未经测试的代码,所以你需要对它持保留态度。我刚刚修复了一个明显的错误(键盘映射名称末尾缺少-map),但可能还有其他错误。
  • 不用担心未经测试的代码位。虽然我的 lisp 正在改进 - 实际上我确实发现并纠正了这个错误 - 我认为我目前无法进一步调试。
  • FWIW,我刚刚尝试了上面的代码并且“它有效”。所以,一定是对你想要什么有一些误解。
  • 我又试了一次,成功了。我一定是引入了另一个错误,我很抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 2018-10-07
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多