emacs的智能替换键绑定

时间:2014-07-07 18:26:15

标签: emacs

我正在尝试使用不同的键绑定来进行emacs中的基本移动和删除。 我想使用的是以下键绑定:

  • Ctrl + i / k / j / l :up /向下/向左/向右
  • Ctrl + u / o :后退/前进词
  • Ctrl + d / f :删除左/右
  • Ctrl + e / r :删除左/右字
  • Ctrl + Alt + e / r :删除行/开头
  • Ctrl + c / x / v :复制/剪切/粘贴
  • Ctrl + m Alt + m :向后/向前搜索历史记录

我在大多数情况下成功完成了工作。然而,我仍然面临两个问题:

  • 某些主要模式键绑定优先于我的设置。例如,某些python模式可能会将 C-j 设置为换行符,并且我必须弄清楚我正在使用的每个次要模式的每个问题,找到正确的键映射并释放我的键。乏味。
  • 某些主要模式使用略微修改的命令进行基本运动。例如,org-mode可能使用org-end-of-line代替行尾的 C-e 。这允许跳转到行尾,而不考虑右侧的标记。或者某些模式会将删除后退命令更改为自定义命令,更适合所需任务。对于经常通过模式改变表示的 C-n C-p 也是如此。这些是我想要使用的一些正弦特征,没有明确地搜索它们,找到它们的命令名称,为我使用的每个主要模式重新绑定它们。我希望我的 C-k 与我使用的每种模式中的 C-n 一样工作,而不必做任何事情。

所以我的问题是,如何创建一个包含所有其他键绑定的次要模式,该模式将在所有其他模式的键绑定之前,并且可以执行以下操作: Cn :“请将 Ck (我喜欢向下移动)绑定到任何命令 Cn 意味着在此模式下绑定”

我想我必须为此创建一个次要模式,可能必须在每个主要模式之前通过钩子加载它,并使用一些emacs函数返回绑定到给定键绑定的函数。

关于如何做到这一点的任何想法?

1 个答案:

答案 0 :(得分:1)

  1. 首先,您应该看一下evil mode,它为Emacs带来了许多Vim风格的键盘快捷键,其中许多都符合您自己的偏好。

  2. 如果您仍然想要一个通用次要模式,它将动态重新绑定任何给定的主要或次要模式的函数,您可能希望使用find-function-on-key之类的函数来嗅出你的绑定然后可以根据需要重新绑定。

  3. 一种不太雄心勃勃的方法可能是定义个人键盘映射并将其绑定到一个键。这样可以节省每次切换模式时重新绑定密钥的麻烦。例如,我使用以下内容:

    (define-prefix-command 'ty-keymap)
    (global-set-key "\M- " ty-keymap)
    (define-key ty-keymap " " 'just-one-space) 
    
  4. 重新绑定M-<space>供我自己使用,然后将just-one-space重新绑定到M-<space><space>。这让我很自由地做了这样奇怪的事情:

    (define-key ty-keymap "j" #'(lambda () (interactive) (ty-move-mode ?j)))
    (define-key ty-keymap ";" #'(lambda () (interactive) (ty-move-mode ?\;)))
    (define-key ty-keymap "k" #'(lambda () (interactive) (ty-move-mode ?k)))
    (define-key ty-keymap "l" #'(lambda () (interactive) (ty-move-mode ?l)))
    
    (defun ty-move-mode (mv)
      "Move over windows with right homerow keys."
      (interactive "k")
      (case mv
        (?j (windmove-left)
            (ty-move-mode (read-event)))
        (?; (windmove-right)
            (ty-move-mode (read-event)))
        (?k (windmove-down)
            (ty-move-mode (read-event)))
        (?l (windmove-up)
            (ty-move-mode (read-event)))
        (?\r (message "done!"))
        (t (push last-input-event unread-command-events))))
    

    这使我可以访问j,k,l和;在我的窗户周围定向移动。修改它可以很容易地为你提供一个单个字符移动的迷你模式:

    (defun ty-move-mode (mv)
      "Move over windows with right homerow keys."
      (interactive "k")
      (case mv
        (?j (backward-char 1)
            (ty-move-mode (read-event)))
        (?; (forward-char 1)
            (ty-move-mode (read-event)))
        (?k (previous-line 1)
            (ty-move-mode (read-event)))
        (?l (next-line 1)
            (ty-move-mode (read-event)))
        (?\r (message "done!"))
        (t (push last-input-event unread-command-events))))
    

    也许其他人会更好地了解如何做到你想要的。