让Emacs ESS遵循R风格指南

时间:2011-09-21 15:35:05

标签: r emacs coding-style elisp ess

我一直在使用Emacs / ESS,我熟悉Hadley's R style recommendations。我想在ESS中遵循这些约定,比如运算符周围的空格,逗号后的空格和if语句之后,花括号之前等等。

有人甚至不愿意遵循这种风格指南吗?恕我直言,官方风格的建议相当谦虚,他们对风格一无所知。 Google R style guide与我在JavaScript中编码时使用的版本太相似,所以这是一个禁忌。

长话短说: 是否有人(e)LISP技能愿意为ESS实施(哈德利)风格指南?

5 个答案:

答案 0 :(得分:24)

我不写Elisp,我不同意Hadley关于下划线的风格优点。此外,哈德利仍然在不使用OneTrueEditor的沙漠中迷失,所以在这个问题上我们可以期待他没有这方面的帮助。

但是如果你愿意跟随R Core而不是Hadley,那么下面是R Internals manual, section 8. "R Coding Standards"推荐的内容。对我而言,R Core首先定义R风格。谷歌和哈德利的风格是很好的次要推荐。

无论如何,回到Elisp。以下这些已经很好地服务了很多年,我确实喜欢这样一个事实:基本的R行为类似于Emacs C ++风格,因为我碰巧在两种模式下都会看到代码。

  

[...]

     

以允许的方式编写代码也很重要   其他人了解它。这对于修复特别有用   问题,包括使用自描述变量名称,   评论代码,并正确格式化。 R核心团队   建议对R和C使用4的基本缩进(和大多数   也可能是Perl)代码,2代表Rd格式的文档。 Emacs的   (21或更高版本)用户可以通过put实现这种缩进样式   其中一个启动文件中的以下内容,并使用自定义   设置c-default-style' to“bsd”和c-basic-offset' to 4'。)

 ;;; ESS
 (add-hook 'ess-mode-hook
           (lambda ()
             (ess-set-style 'C++ 'quiet)
             ;; Because
             ;;                                 DEF GNU BSD K&R  C++
             ;; ess-indent-level                  2   2   8   5  4
             ;; ess-continued-statement-offset    2   2   8   5  4
             ;; ess-brace-offset                  0   0  -8  -5 -4
             ;; ess-arg-function-offset           2   4   0   0  0
             ;; ess-expression-offset             4   2   8   5  4
             ;; ess-else-offset                   0   0   0   0  0
             ;; ess-close-brace-offset            0   0   0   0  0
             (add-hook 'local-write-file-hooks
                       (lambda ()
                         (ess-nuke-trailing-whitespace)))))
 (setq ess-nuke-trailing-whitespace-p 'ask)
 ;; or even
 ;; (setq ess-nuke-trailing-whitespace-p t)
 ;;; Perl
 (add-hook 'perl-mode-hook
           (lambda () (setq perl-indent-level 4)))
     

(Emacs的C和R模式的`GNU'样式使用的基本缩进   2,已确定不清楚显示结构   使用窄字体时足够了。)

我认为我经常添加的唯一内容是关注最后一个已注释掉的代码段:

;; or even
(setq ess-nuke-trailing-whitespace-p t)

如果你真的需要用下划线编码,你当然可以关闭下划线切换。

答案 1 :(得分:15)

使用ESS的开发版(将于2015年9月发布),只需添加到ess-mode-hook

(ess-set-style 'RStudio)

RStudio还有一个默认设置的“垂直对齐参数”复选框。如果要在未选中此设置时重现行为(如Hadley的代码中所示),则需要将ess-offset-arguments更改为prev-line

(setq ess-offset-arguments 'prev-line)

如果您发现ESS和RStudio缩进之间存在重大差异,请在https://github.com/emacs-ess/ESS上提出问题。

答案 2 :(得分:4)

哈德利指南的优点是围绕操作员(除了可能在/附近)

有一个smart-operator包可以为几乎每个运营商实现它。

这是我的设置(你想要使用的uncoment运算符):

(setq smart-operator-mode-map
  (let ((keymap (make-sparse-keymap)))
    (define-key keymap "=" 'smart-operator-self-insert-command)
    ;; (define-key keymap "<" 'smart-operator-<)
    ;; (define-key keymap ">" 'smart-operator->)
    ;; (define-key keymap "%" 'smart-operator-%)
    (define-key keymap "+" 'smart-operator-+)
    ;; (define-key keymap "-" 'smart-operator--)
    ;; (define-key keymap "*" 'smart-operator-*)
    ;; (define-key keymap "/" 'smart-operator-self-insert-command)
    (define-key keymap "&" 'smart-operator-&)
    (define-key keymap "|" 'smart-operator-self-insert-command)
    ;; (define-key keymap "!" 'smart-operator-self-insert-command)
    ;; (define-key keymap ":" 'smart-operator-:)
    ;; (define-key keymap "?" 'smart-operator-?)
    (define-key keymap "," 'smart-operator-,)
    ;; (define-key keymap "." 'smart-operator-.)
    keymap)
  "Keymap used my `smart-operator-mode'.")

另见R样式here的讨论。

[edit]我也在使用全局变量的事实上的raacto camelCase样式。局部变量的下划线分隔名称 - 很容易区分。

emacs中有一种特殊的subword模式,它重新定义了用于大写子词的所有编辑和导航命令

(global-subword-mode)

答案 3 :(得分:2)

与OP具有相同的风格偏好,我跳到这里并感谢@lionel提供了有效的建议,但我在~/emacs.d/init.el中设置RStudio样式时出现了问题:

(ess-set-style 'RStudio)

Emacs / ESS拒绝应用这种风格(4空格缩进而不是2空格,而不是讨论风格:))。

我对新手的建议,使用~/emacs.d/init.el中的以下挂钩:

(add-hook 'find-file-hook 'my-r-style-hook)
(defun my-r-style-hook ()
  (when (string-match (file-name-extension buffer-file-name) "[r|R]$")
    (ess-set-style 'RStudio)))

会做到这一点。

答案 4 :(得分:1)

迄今为止尚未涵盖的风格指南的另一个组成部分 当函数在多行上运行时是缩进。风格指南 说要使用像

这样的缩进
long_function_name <- function(a = "a long argument", 
                               b = "another argument",   # X
                               c = "another long argument") {
  # As usual code is indented by two spaces.
}

但是使用任何默认样式似乎都会将行X缩进一些固定的行 空格数而不是(。解决方案是set ess-arg-function-offset to some non-number,例如

(set 'ess-arg-function-offset t)

这应该放在类似于@Dirk Eddelbuettel的答案的模式钩子中。此外,它必须在之后ess-set-style进行任何调用,否则它将被覆盖。