修复ESS/Stata中不良的EMACS缩进行为

8

在emacs中,ESS / Stata模式错误地缩进跟在运算符结尾的行后面的行。它似乎错误地将这些行解释为多行命令。

例如:

gen foo = 1

/* generate another variable */
  gen bar = 1

“gen bar = 1”这行代码不应该缩进。看起来EMACS将注释中的反斜杠解释为运算符,并认为此行代码跨越了两行。

实际上,Stata中的多行命令有三个反斜杠,没有三个反斜杠的换行表示语句结束。例如,以下缩进是正确的:

gen bar = 1
gen ///
  foo = 1

有没有什么我可以放在我的.emacs文件中来纠正这种行为?我不想完全放弃自动缩进 - 它对除了/* 这样的注释之外的所有内容都非常有效。

谢谢,

Pnj

1个回答

5
您说得对,ESS将尾随的/解释为换行符。这是硬编码到函数ess-continued-statement-p中的,所以要修改行为,您必须重写代码。以下代码(在您的.emacs文件中)适用于您的示例。
(eval-after-load 'ess-mode
  '(defun ess-continued-statement-p ()
   "this is modified code"
     (let ((eol (point)))
       (save-excursion
         (cond ((memq (preceding-char) '(nil ?\, ?\; ?\} ?\{ ?\]))
                nil)
               ;; ((bolp))
               ((= (preceding-char) ?\))
                (forward-sexp -2)
                (looking-at "if\\b[ \t]*(\\|function\\b[ \t]*(\\|for\\b[ \t]*(\\|while\\b[ \t]*("))
               ((progn (forward-sexp -1)
                       (and (looking-at "else\\b\\|repeat\\b")
                            (not (looking-at "else\\s_\\|repeat\\s_"))))
                (skip-chars-backward " \t")
                (or (bolp)
                    (= (preceding-char) ?\;)))
               (t
                (progn (goto-char eol)
                       (skip-chars-backward " \t")
                       (or (and (> (current-column) 1)
                                (save-excursion (backward-char 1)

        ;;;; Modified code starts here: ;;;;
                                                (or (looking-at "[-:+*><=]")
                                                    (and (looking-at "/")
                                                         (save-excursion (backward-char 1)
                                                                         (not (looking-at "*")))))))
        ;;;; End of modified code ;;;;

                           (and (> (current-column) 3)
                                (progn (backward-char 3)
                                       (looking-at "%[^ \t]%")))))))))))

Tyler,我把你的代码复制到我的.emacs文件中,但是行为没有改变。在我的Messages缓冲区中没有任何明显的错误或其他问题。有什么进一步的建议或我可以做的事情来帮助诊断吗? - pnj
如果您为重新定义的函数添加文档字符串,您可以使用 C-h f ess-continued-statement-p 检查它是否已加载。如果您没有看到文档字符串,则修改后的代码不会被评估。这将表明在 eval-after-load 命令中运行了某些内容,例如引用了错误的模式。我将在上面添加一个文档字符串。 - Tyler
我注意到当我以这种模式加载文件时,会出现错误消息“File mode specification error: (void-function run-mode-hooks)”。即使没有将上述代码插入我的.emacs中,也会发生这种情况。我认为这是版本问题,但这是否可以解释为什么被覆盖的函数没有被调用? - pnj
是的,听起来你需要更新你的Emacs、ESS或者两者都要更新。我相信run-mode-hooks是在Emacs 22中引入的(发布于2007年),而针对你的问题的修复已经添加到了ESS版本5.3.11中(发布于2009年)。你的软件已经有些老了! - Tyler
有趣。不幸的是,我没有安装它的权限; 希望能说服管理员... 再次感谢! - pnj
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接