1

我是 elisp 的新手,所以如果以下方法完全笨拙,请原谅我。

在我目前正在使用的团队中,通常的惯例是用pass语句关闭 python 块(如果它们不是通过关闭关键字 like elseor来结束的话except)。indent-region虽然不寻常,但这样做的好处是,如果程序被无意更改(使用 emacs ),总是可以恢复程序的原始缩进。

为了使现有代码符合这个约定,我编写了一个小的 elisp 函数:

(defun python-check-indent ()
 "Check if automatic indentation changes current indent, insert pass keyword if it does."
 (interactive)
 (move-beginning-of-line 1)
 (skip-chars-forward " ")
 (if
  (< 0
     (let (original)
      (setq original (point))
      (indent-for-tab-command)
      (- (point) original)
      )
     )
  (progn
   (insert "pass")
   (newline)
   (indent-for-tab-command)
   )
 )
 (next-line)
)


(global-set-key (kbd "C-`") 'python-check-indent)

这个想法只是测试按 TAB 是否会改变缩进,并pass在这种情况下插入一条语句。为了便于处理较长的代码块,它会前进到下一行。

当我使用 运行它时M-x python-check-indent,它会做我想要的(除了它会稍微围绕空行移动),在重复运行它以处理多行时也是如此。但是,当我使用 C-` 键绑定重复运行它时,它会从第二次调用开始弄乱代码。

M-x ...所以这是我的问题:调用命令和使用它的键绑定有什么区别?我怎样才能改变功能不受这种差异的影响?

emacs-version: GNU Emacs 23.3.1 (x86_64-apple-darwin, NS apple-appkit-1038.35) of 2011-03-10 on black.porkrind.org

(编辑)当前解决方法:我现在将它包装在键盘宏中,因此它“绑定”到 Cx e,并且行为正常。

4

1 回答 1

3

一般规则是最好避免在函数中使用复杂的交互式命令,因为它们可能会受到各种选项的影响。

(defun python-check-indent ()
  "Check if automatic indentation changes current indent, insert pass keyword if it does."
  (interactive)
  (goto-char (line-beginning-position))
  (skip-chars-forward " ")
  (when (< 0
           (let (original)
             (setq original (point))
             (python-indent-line)
             (- (point) original)))
    (insert "pass\n")
    (python-indent-line))
  (forward-line))

但是,即使这样也可能不好,因为python-indent-line的行为取决于last-commandpython-indent-trigger-commands。我认为最好将第一次调用替换为python-indent-line计算目标缩进而不是实际缩进的代码,例如(nth python-indent-current-level python-indent-levels).

PS。如果还是有问题,建议您使用edebug并单步执行该功能。

于 2013-07-12T14:51:40.927 回答