【问题标题】:Use key as both prefix and command使用 key 作为前缀和命令
【发布时间】:2013-12-30 08:19:06
【问题描述】:

我想知道如何使用一个键作为其他键的前缀和命令本身。

  1. 我可以用key-chord.el 来做这件事,通过将键和弦绑定到第一个键之后的命令,但它有几个问题

    • 只能与字母数字键一起使用
    • 这不是真的,因为我必须在按键超时之前快速敲击它们
  2. easy-killexpand-region 等一些软件包支持此功能,但它们具有复杂的代码库,而且我的 lisp 技能并不出色...

我将如何做到这一点?我真的很想将<menu> 绑定到evil-ex,但我还想绑定<menu> 作为所有动作(如箭头键)的前缀,这些动作设置标记就像无弦cua-selection-mode

因为 evil-ex 后面没有移动,也没有移动自身插入,所以这将是一个完美的用例。 <menu> 非常完美,因为它就在箭头键和其他动作键(例如结束、主页等)旁边,并且没有被修改。

【问题讨论】:

  • 我不确定我是否遵循...您想在键入 <menu> 时运行命令,但如果您接下来键入移动命令,您想...撤消上一个命令并做一些不同的事情???
  • 或者你是说evil-ex(请问是什么?)本身需要额外的击键,所以你可以安全地等待后续的键(移动或非移动)在决定调用哪个函数之前?
  • 这个帖子包含一个类似的概念:stackoverflow.com/questions/20026083/…

标签: emacs elisp


【解决方案1】:

如果我明白你想要什么,我建议最好忘记计时器并等待一点延迟(即,将<menu> 作为命令的意图与其作为前缀键的用途区分开来)。

我推荐并经常使用的方法是定义一个前缀键(在您的情况下,例如<menu>),然后将您想用于<menu> 的命令放在@987654326 @。这就像点击一次<menu> 并尝试依赖一些微小的延迟等一样快。

并且它允许您认为在<menu>(实际上是在<menu> <menu>)上的命令可重复

通常使这样的命令可重复,以便<menu> <menu> <menu> 重复该命令一次,<menu> <menu> <menu> <menu> 重复两次,依此类推。 IOW,我倾向于将这个技巧用于我真正想轻松重复的命令,只需按住一个键即可。

这是一个简单的例子,我在 2009 年向emacs-devel@gnu.org 提出了一个更普遍的建议,HERE。在该邮件列表消息中,如果向下滚动到#9,您将看到使用此类键的建议,#12 显示相同的示例,#15 直接解决您的问题。主题是“有蛋糕会吃,吃蛋糕会有 - krazy key koncept kontroversy”,主题是正是你提出的问题.


;; This function builds a repeatable version of its argument COMMAND.
(defun repeat-command (command)
  "Repeat COMMAND."
 (interactive)
 (let ((repeat-previous-repeated-command  command)
       (last-repeatable-command           'repeat))
   (repeat nil)))

Here is how you could then define `C-x', which is already a prefix
key, as also a repeatable key for an action command, in this case,
`backward-char':

(defun backward-char-repeat ()
  "Like `backward-char', but repeatable even on a prefix key."
  (interactive)
  (repeat-command 'backward-char))

(define-key ctl-x-map "\C-x" 'backward-char-repeat)

Now just holding down `C-x' invokes `backward-char' repeatedly - once
you've gotten past the first `C-x' (the prefix).

正如我所说,我长期以来一直使用这种技术来 (a) 具有“重复前缀键”并且 (b) 在它们上仍然定义其他键。

【讨论】:

  • 前缀映射是打开键绑定可能性的绝佳方式。将重复命令功能添加到原始命令可以让您两全其美 - 快速访问原始命令,以及在键盘映射中使用一组全新的未绑定键。
  • @Tyler -- 我也这么认为。事实上,我一直在使用这个“技巧”。一个典型的用途是在Bookmark+,我在同一个前缀键上有很多书签命令(例如,C-x p),但我在该地图上的可重复键上有各种类型的书签循环命令(e.g., Cx p down, Cx p right`)。
  • 谢谢,我发现这非常有用(我还从<C-menu> <something> 启动了很多命令。)现在我可以重复它们了!
  • @PythonNut -- 那么请随意对答案进行投票。 ;-)
  • 当然! (我不知道我可以)。
【解决方案2】:

您似乎想要smartrep 之类的东西,它可以将键指定为多个命令的公共前缀。开箱即用您唯一缺少的是将命令绑定到公共前缀键,因此您需要稍微弄脏smartrep 内部结构。你追求的功能是

(smartrep-read-event-loop
  '((KEY1 command)
    (KEY2 command)
    ...))

这里有一段代码可以帮助你入门:

(defun my-command-with-prefix ()
  (interactive)

  (invoke-prefix-command)

  (initialize-event-loop)

  ;; The form
  ;;
  ;;   (condition-case ERR FORM (quit QUIT-HANDLER))
  ;;
  ;; is there to catch C-g key presses and make sure that
  ;; finalization code is run.
  (condition-case e
      (smartrep-read-event-loop
       '(("a" . command1)
         ("b" . command2)
         ("c" . command3)))

    (quit nil))

  ;; finalize loop
  (finalize-event-loop))

上面的 sn-p 本质上是 here 代码的提炼版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-02
    • 2020-10-27
    • 2019-11-09
    • 2016-10-26
    • 2013-01-10
    • 2023-04-04
    • 1970-01-01
    • 2021-09-11
    相关资源
    最近更新 更多