使 Emacs ESS 遵循 R 风格指南

发布于 2024-12-05 12:16:51 字数 487 浏览 0 评论 0原文

我已经使用 Emacs/ESS 有一段时间了,并且我熟悉 Hadley 的 R 风格建议。我想遵循 ESS 中的这些约定,例如运算符周围的那些漂亮空格、逗号后面和 if 语句之后、大括号之前的空格等。

有没有人愿意遵循这个风格指南?恕我直言,官方的风格推荐相当谦虚,他们对风格只字未提。 Google R 风格指南 与我的指南太相似当我用 JavaScript 编码时使用,所以这是一个禁忌。

长话短说:是否有任何具有 (e)LISP 技能的人愿意为 ESS 实施(Hadley 的)风格指南?

I've been using Emacs/ESS for quite a while, and I'm familiar with Hadley's R style recommendations. I'd like to follow these conventions in ESS, like those nice spaces around operators, space after comma and after if statement, before curly braces, etc.

Did anyone even bothered to follow this style guide at all? IMHO, official style recommendations are quite modest, and they say nothing about the style whatsoever. Google R style guide are too similar with the ones I use when I code in JavaScript, so it's a no-no.

Long story short: is there anyone with (e)LISP skills willing to implement (Hadley's) style guide for ESS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤蝉 2024-12-12 12:16:51

我不写 Elisp,而且我不同意 Hadley 关于下划线风格优点的观点。此外,Hadley 仍然迷失在不使用 OneTrueEditor 的沙漠中,所以我们不能指望他在这个问题上提供任何帮助。

但如果您愿意关注 R Core 而不是 Hadley,下面是 R 内部手册,第 8 节“R 编码标准” 建议。对我来说,R Core 首先定义了 R 风格。 Google 和 Hadley 的风格是很好的次要推荐。

无论如何,回到 Elisp。以下内容多年来一直为我们提供了良好的服务,而且我确实喜欢这样一个事实:基本的 R 行为与 Emacs C++ 风格类似,因为我碰巧经常查看这两种模式下的代码。

[...]

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

<前><代码> ;;; ESS
(添加钩子'ess-模式钩子
(拉姆达()
(ess-set-style 'C++' 安静)
;;因为
;; DEF GNU BSD K&R C++
;; ess 缩进级别 2 2 8 5 4
;; ess-继续语句-偏移量 2 2 8 5 4
;; ess 大括号偏移 0 0 -8 -5 -4
;; ess-arg-函数偏移 2 4 0 0 0
;; ess 表达式偏移量 4 2 8 5 4
;; ess-else-偏移 0 0 0 0 0
;; ess-闭括号-偏移 0 0 0 0 0
(添加钩子'本地写入文件钩子
(拉姆达()
(ess-nuke-尾随空白)))))
(setq ess-nuke-trailing-whitespace-p '询问)
;;甚至
;; (setq ess-nuke-trailing-whitespace-p t)
;;;珀尔
(add-hook 'perl-mode-hook
(lambda () (setq perl 缩进级别 4)))

(Emacs 的 C 和 R 模式的“GNU”样式使用基本缩进
2、已确定无法清晰显示结构
使用窄字体时就足够了。)

我认为我经常做的唯一添加是遵循最后一个注释掉的片段:

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

如果您确实需要使用下划线进行编码,您当然可以关闭下划线切换。

I don't write Elisp, and I disagree with Hadley about the stylistic merits of underscores. Moreover, Hadley is still lost in the desert of not using the OneTrueEditor so we can expect no help from him on this on this issue.

But if you are open to follow R Core rather than Hadley, below is what the R Internals manual, section 8. "R Coding Standards" recommends. To me, it is R Core who defines R style first and foremost. Google's and Hadley's styles are nice secondary recommendations.

Anyway, back to Elisp. The following has served we well for many years, and I do like the fact that the basic R behaviour is similar to the Emacs C++ style as I happen to look at code in both modes a lot.

[...]

It is also important that code is written in a way that allows
others to understand it. This is particularly helpful for fixing
problems, and includes using self-descriptive variable names,
commenting the code, and also formatting it properly. The R Core Team
recommends to use a basic indentation of 4 for R and C (and most
likely also Perl) code, and 2 for documentation in Rd format. Emacs
(21 or later) users can implement this indentation style by putting
the following in one of their startup files, and using customization
to set the c-default-style' to"bsd"' and c-basic-offset' to4'.)

 ;;; 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)))

(The `GNU' styles for Emacs' C and R modes use a basic indentation of
2, which has been determined not to display the structure clearly
enough when using narrow fonts.)

I think the only additions I regularly make are to follow the last commented-out snippet:

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

You can of course turn off the underscore toggle if you really need to code with underscores.

国产ˉ祖宗 2024-12-12 12:16:51

对于 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 缩进。

With the development version of ESS (to be released in September 2015), just add to your ess-mode-hook:

(ess-set-style 'RStudio)

RStudio also has a 'Vertically align arguments' checkbox that is set by default. If you want to reproduce the behaviour when this setting is unchecked (as in Hadley's code), you'll need to change ess-offset-arguments to prev-line:

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

Please file an issue on https://github.com/emacs-ess/ESS if you find an important discrepancy between ESS and RStudio indentation.

哆兒滾 2024-12-12 12:16:51

Hadley 指南的优点是在运算符周围留出空间(除了 / 周围)

有一个 smart -operator 包几乎为每个操作员实现了它。

这是我的设置(取消注释您要使用的运算符):

(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 样式的精彩讨论 此处

[编辑] 我还对全局变量使用 R 代码事实上的驼峰命名风格。局部变量的名称用下划线分隔 - 很容易区分。

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

(global-subword-mode)

The good point of Hadley's guide is spaceing around operators (except maybe around /)

There is a smart-operator package which implements it for almost every operator.

This is my setup (uncoment operators which you want to use):

(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'.")

See also a nice discussion on R styles here.

[edit] I am also using the defacto camelCase style of R code for globals. The underscore-separated names for local variables - it's easy to differentiate.

There is a special subword mode in emacs which redefines all editing and navigation commands to be used on capitalized sub-words

(global-subword-mode)
夕嗳→ 2024-12-12 12:16:51

与 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)))

即可解决问题。

Having the same style preference of the OP, I jumped here and I thank @lionel for your valid suggestions, but I had an issue coming from setting RStudio style in ~/emacs.d/init.el with:

(ess-set-style 'RStudio)

Emacs/ESS refused to apply the style (4-space indent instead of the 2-space, not discussing style here :) ).

My advice for the novice, using the following hook in your ~/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)))

will do the trick.

别想她 2024-12-12 12:16:51

风格指南的另一个组成部分到目前为止还没有涉及到
是函数跨多行运行时的缩进。风格指南
说要使用缩进,

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 缩进一些固定的值
空格数而不是最多 (。解决方案是 设置
ess-arg-function-offset 到一些非数字
,例如,

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

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

One more component of the style guide which hasn't been covered here so far
is indentation when a function runs over multiple lines. The style guide
says to use indentation like

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

but using any of the default styles seems to indent line X by some fixed
number of spaces rather than up to the (. The solution is to set
ess-arg-function-offset to some non-number
, e.g.

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

This should be placed in a mode hook similar to @Dirk Eddelbuettel's answer. Also it must go after any calls to ess-set-style or it will be overridden.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文