第一个elisp尝试 - 选项卡上没有调用tab键的次要模式?

时间:2011-09-28 14:39:27

标签: emacs elisp

我决定用一些lisp来弄湿我的脚趾,因为当我点击 TAB 时,我想让emacs表现得更好一些。我的命令工作正常。它只执行indent-for-tab-command,如果没有任何反应,它会执行tab-to-tab-stop,假设我不太可能点击 TAB 只是为了让我的点拒绝让步在多行字符串或其中一些。在第一个 TAB 按下之后,它继续执行tab-to-tab-stop,直到编辑恢复,或者该点移动到其他位置。 AFAIK,我的逻辑还可以,虽然我的lisp代码可能不是!

最初我只是通过(local-set-key (kbd "TAB") 'tab-dwim)针对我想要这种行为的主要模式将其破解成我的emacs点文件。这符合预期。

然后我决定我所做的基本上是一个次要模式,所以我试图将键绑定移动到次要模式。由于某种原因,即使启用了次要模式(如模式行中所示,只是从打开和关闭它),当我点击 TAB时,我的tab-dwim函数没有被调用< / kbd>键。我仍然可以按照预期使用 M-x 调用它。

我的次要模式:keymap

我做错了什么
;;;
;; TAB DWIM

; buffer-local before/after point tracking
(setq point-before-tab nil)
(setq point-after-tab nil)
(make-local-variable 'point-before-tab)
(make-local-variable 'point-after-tab)

(defun tab-dwim ()
  "Indents normally once, then switches to tab-to-tab-stop if invoked again.

tab-dwim will always perform tab-to-tab-stop if the first TAB press does not
cause the point to move."

  (interactive)

  (print "in tab-dwim now") ; THIS LINE IS NEVER INVOKED ON TAB?

  (setq point-before-tab (point))

  (if (eq point-before-tab point-after-tab) ; pressed TAB again
      (tab-to-tab-stop)
    (indent-for-tab-command))

  (if (eq (point) point-before-tab) ; point didn't move
      (tab-to-tab-stop))
  (setq point-after-tab (point)))

(define-minor-mode tab-dwim-mode
  "Toggle tab-dwim-mode.
With a non-nil argument, turns on tab-dwim-mode. With a nil argument, turns it
off.

When tab-dwim-mode is enabled, pressing the TAB key once will behave as normal,
but pressing it subsequent times, will continue to indent, using
tab-to-tab-stop.

If tab-dwim determines that the first TAB key press resulted in no movement of
the point, it will indent according to tab-to-tab-stop instead."

  :init-value nil
  :lighter " DWIM"
  :keymap
  '(([TAB] . tab-dwim)))

(provide 'tab-dwim)

干杯,

克里斯

2 个答案:

答案 0 :(得分:2)

我认为你很亲密。

尝试使用此键盘映射:

'(("\t" . tab-dwim)))

答案 1 :(得分:2)

是,使用“\ t”或矢量格式“[(tab)]”。

您的elisp开发的一些附加说明:

  1. 避免尽可能多地制作全局变量。在这种情况下,我认为动态绑定let是合适的。另请看看*。
  2. 了解make-local-variablemake-variable-buffer-local之间的区别。编写代码的方式,缓冲区局部变量只存在于加载包的缓冲区中。
  3. 正如Nemo所提到的,极其极力地建议您对与每个包相关的所有变量/函数使用公共前缀。 Emacs只有一个命名空间,这是保持它有点组织的“hacky”方式。