1

我知道 TAB 想在 Emacs 中变得聪明。然而,它对我的​​口味还不够聪明。而且因为它是“智能”的,所以扩展起来似乎很复杂。

我希望 Clojure 模式下的 TAB 完全按照它的行为行事,除非我在位于第defn, defmacro0 列的 a 等的第一个括号中。

当它在那里时,我希望它改为从hs-minor-mode调用hs-toggle-hiding

但是,我越来越疯狂地试图让它发挥作用。

我首先尝试修改分配给 TAB 的快捷方式,以便仅在 Clojure 模式下时,它会首先调用我的函数,然后调用indent-for-tab-command但更改 TAB 快捷方式似乎非常复杂。并且由于 Emacs 已经计划了模式可以在 lisp-indent-function 中注册其 TAB 函数的情况,我希望修改clojure-indent-function,它说:

(defun clojure-indent-function (indent-point state)
  "This function is the normal value of the variable `lisp-indent-function'.

然而,这个函数显然只在光标位于函数内部时才被调用。当光标位于“(defn ...”) 的第一个 '(' 上时不会。

hs-toggle-hiding在 Clojure 模式下并在括号上指向第 0 列时,如何让 TAB 调用?

我不希望这影响 org-mode 或任何其他模式。只是 Clojure 模式。

4

2 回答 2

3

一般的答案是:

(eval-after-load 'clojure-mode
  '(define-key clojure-mode-map [tab] 'my-tab-command))

正如您所描述的,定义:

(defun my-tab-command (&optional arg)
  (interactive "P")
  (if (and (zerop (current-column)) (eq (char-after) ?\())
      (hs-toggle-hiding)
    (indent-for-tab-command arg)))
于 2013-01-31T19:11:20.667 回答
3

clojure-indent-function是 的一个实现lisp-indent-function,它应该缩进而是计算缩进。任何对可能的缩进感兴趣的代码都可以随时调用它,因此我们当然不想将我们想要的TAB行为挂钩到这个地方。

考虑到TAB在一个有趣的点上它的智能可能不是你想要的,最好重新绑定TAB以将我们的逻辑放在所有可能的智能之前:

(defun clojure-hs-tab (arg)
  (interactive "P")
  (if (and (<= (current-column) 1)
           (save-excursion
             (beginning-of-line)
             (looking-at "\(")))
      (hs-toggle-hiding)
    (indent-for-tab-command arg)))

(define-key clojure-mode-map (kbd "TAB") 'clojure-hs-tab)    

我冒昧地修改了您的要求并允许第 1 列,因为这是 hs-toggle-hiding 在隐藏后放置点的地方。您不想通过第二次TAB按键取消隐藏吗?

“标签智能”的下一个级别是indent-line-function 变量。当完成或缩进选项卡确定缩进而不是完成时,这就是所谓的。有一个强烈的理由不在这里使用它:indent-line-function可能会被多次调用以缩进region。即使我们决定只覆盖 indenting 和 complete 的缩进行为, TAB最好还是建议indent-for-tab-command (全局建议并检查major-mode仅在该模式下执行我们想要的操作)。

于 2013-01-31T19:25:47.800 回答