Make Emacs ESS follow R style guide - r

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?

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.

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.

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)

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.

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.

Related

How to use console as input and output for Guile Scheme?

I understand that Scheme uses ports to perform Input and Output. While trying to learn how to get console input and output, I have come across MIT-Scheme's console-i/o-port variable.
But, the guile interpreter says it is an Unbound Variable. I would like to know how we can use ports to get input from and output to the console (Terminal in Unix) in a Guile Scheme Script. I am still a rookie in Scheme and Linux, a clear step-by-step is appreciated.
Also, how does (display <object>) work? Does it use ports inherently or is there another way.
P.S. If there is another way without using ports please let me know how to use that too.
If you want to read and write SExps, in guile you have (read), (write), (display) etc., if you want to read characters only use (read-char) and (write-char) -- they all use the input/output ports resp. you picked, by default they are stdin and stdout. Everything is rather straightforward (https://www.gnu.org/software/guile/manual/html_node/Input-and-Output.html#Input-and-Output).
You might also be interested in guile-ncurses (https://www.gnu.org/software/guile-ncurses/).
Of some more goodies check out pretty-print module from ice-9 (on very long sexps it's slow but outputs them really nicely formatted, great for e.g. code generation):
(use-modules (ice-9 pretty-print))
(pretty-print `(super cool stuff (+ 2 3) => ,(+ 2 3)))
And if you need your own parser, check out the lalr module (system base lalr).
edit a small example which reads a number, multiplies by itself and prints out the result:
#!/usr/bin/guile -s
!#
(let ((x (read)))
(display (* x x))
(newline))
(remember to chmod +x this script).
edit changed the expression to let form as Chris suggested, indeed the fewer parentheses the better
In guile you have 2 functions: current-input-port and current-output-port (the docs)
to read and put text into string (if you don't want to read s-expressions) you can use this function:
(define (read-port port)
(let iter ((result '()) (chr (read-char port)))
(if (eof-object? chr)
(list->string result)
(iter (append result (list chr)) (read-char port)))))
reading from stdin will be:
(read-port (current-input-port))
to write to stdout you can use display it also accept second argument which is port relevant docs

How to change smart assign key ("_" to "<-") binding in ESS

In emacs ESS, how do I correctly change the keybinding for ess-smart-S-assign?
What I tried is adding
(custom-set-variables
'(ess-smart-S-assign-key ":"))
to my .emacs, but that made weird things happen: When I press :, just a normal : appears. On the other hand, pressing _ once yields <- as usual, whereas pressing _ a second time then converts this to :.
The desired behavior would be to be able to use _ as a normal key, with : being converted to <-.
I am using the official emacs 24.3 for windows and the latest development version of ESS (14.06).
Here's the docstring for ess-smart-S-assign-key:
Documentation:
Key used by `ess-smart-S-assign'. By default bound to
underscore, but can be set to any key. If this key is customized,
you must add
(ess-toggle-S-assign nil)
(ess-toggle-S-assign nil)
after the line that sets the customization and evaluate these
lines or reboot emacs. The first call clears the default
`ess-smart-S-assign' assignment and the second line re-assigns
it to the customized setting.
So: put this in your .emacs file to get the desired behavior:
(setq ess-smart-S-assign-key ":")
(ess-toggle-S-assign nil)
(ess-toggle-S-assign nil)
Kind of ugly, but it works.
The accepted answer didn't work for me, but the following did:
(global-set-key (kbd "C-;") (lambda () (interactive) (insert " <- ")))
(ess-toggle-underscore nil)
Insert your shortkey choice instead of C-;.
Another solution is
(eval-after-load "ess-mode" '(define-key ess-mode-map (kbd "C-;") "<-"))
(eval-after-load "ess-mode" '(define-key inferior-ess-mode-map (kbd "C-;") "<-"))
This allows to restrict the binding change to ess-mode. Note that the second line defines the binding for the inferior R process.

any R style guide / checker?

in Python I'm used to having my code "style-checked" by an automatic but configurable tool, called pep8, after the 8th Python enhancement proposal.
in R I don't know. Google has a style guide, but:
what do most R programmers actually use?
I still didn't find any program that performs those checks.
Dirk, Alex, in your answers you pointed me at pretty printers, but in my opinion that would overdo one thing and not do another: code would be automatically edited to follow the style, while no warnings are issued for poorly chosen identifiers.
There's a formatR package with tidy.source function. I use Emacs with ESS, and follow Hadley's style recommendations. It's hard to compare R with Python, since style is kind of mandatory in Python, unlike R. =)
EDITa simple demonstration:
code <- "fn <- function(x, y) { paste(x, '+', y, '-', x+y) }"
tidy.source(text = code)
## not run
fn <- function(x, y) {
paste(x, "+", y, "-", x + y)
}
I think if you want such a tool, you may have to write it yourself. The reason is that R does not have an equivalent to Python's PEP8; that is, an "official style guide" that has been handed down from on high and is universally followed by the majority of R programmers.
In addition there are a lot of stylistic inconsistencies in the R core itself; this is a consequence of the way in which R evolved as a language. For example, many functions in R core follow the form of foo.bar and were written before the S3 object system came along and used that notation for method dispatch. In hindsight, the naming of these functions should probably be changed in the interests of consistency and clarity, but it is too late to consider that now.
In summary, there is no official "style lint" tool for R because the R Core itself contains enough style lint, of which nothing can be done about, that writing one would be very difficult. For every rule--- "don't do this" ---there would have to be a long list of exceptions--- "except in this case, and this case, and this one, and ..., where it was done for historical purposes".
As for
what do most R programmers actually use
I suspect that quite a few people follow R Core who have a
R Coding standards section in the R Internals manual.
Which in a large sense falls back to these sensible Emacs defaults to be used along with ESS. Here is what I use and it is only minimally changed:
;;; C
(add-hook 'c-mode-hook
;;(lambda () (c-set-style "bsd")))
;;(lambda () (c-set-style "user"))) ; edd or maybe c++ ?
(lambda () (c-set-style "c++"))) ; edd or maybe c++ ?
;;;; ESS
(add-hook 'ess-mode-hook
(lambda ()
(ess-set-style 'C++)
;; 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 t)
As for a general, tool Xihui's formatR pretty-printer may indeed be the closest. Or just use ESS :)
lintr - highlights possible syntax and style issues/errors
CRAN Task View: Reproducible Research - Formatting Tools section contains other useful tools, particularly formatR which can automatically formt code.
The lint package gives warnings about stylistic problems, without correcting those.
Running the lint() command (using the default parameter values) gives you a list of warnings for all R files in the current directory.
I use styler and then lintr before I check anything into version control.
styler converts your code base to match a given style - the default matches the tidyverse style described here. It modifies alignments, and some syntax (<- over =). But, it doesn't rename variables or anything like that.
lintr is non-modifying. It just identifies lines of code that are inconsistent with your style guide. I use this within vim when I'm working on a package or a project to identify things that need a bit more human input to fix (renaming variables/functions etc)
RStudio has added a style checker at some point in the past. For instance, in version 1.1.463 you can enable the feature under General Options. Here's a screenshot:

Emacs, Auto Complete Mode, CSS, pain. (illustrated!)

I've got Auto Complete Mode installed for Emacs.
First: When I'm typing declarations I get the normal auto-complete behavior:
So I hit Tab to complete — no problem. But then I hit ;:
It instantly tries to complete something! And I can't hit Enter because that'll accept the erroneous completion!
So I have to hit C-j. What a pain.
Second: Once I'm done with a declaration, I type }:
...but it doesn't get indented properly unless I type Tab.
What gives?
Update, settings:
I'm using Emacs 23. My css-electric-keys are } and ;. My Auto Complete configuration is as follows:
(ac-config-default)
(setq ac-auto-start t)
(setq ac-delay 0.1)
(setq ac-auto-show-menu nil)
(setq ac-show-menu-immediately-on-auto-complete t)
(setq ac-trigger-key nil)
Here's a few suggestions:
(setq ac-auto-start t) starts autocomplete automatically. If you change that to (setq ac-auto-start 1) (or 2 or 3) then it will only start after that many characters have been typed. This might not solve your problem though if after you type the ;, it considers the entire preceding word as part of the current auto-complete search.
Maybe the problem is that it isn't recognizing the semicolon as a delimiting character (like whitespace), so it thinks you're still adding to the last word. Perhaps adding the semicolon string to ac-ignores would do the trick? (Not sure what the syntax for that would be)
Maybe you can prevent auto-completion via the enter key by adding: (define-key ac-complete-mode-map "\t" 'ac-complete) and (define-key ac-complete-mode-map "\r" nil). I'm not sure how this will interact with DWIM though (enabled by default).
Try adding semicolon as an auto-complete key?
My .emacs knowledge on a scale of 0 to 10 is like a 1.5, but maybe this will jog some better ideas.
Old stuff I know, but try the following:
(add-hook 'css-mode-hook
(lambda ()
(make-local-variable 'ac-ignores)
(add-to-list 'ac-ignores ";")))
From the manual

How to stop emacs from replacing underbar with <- in ess-mode

ess-mode is "Emacs speaks statistics." This mode is useful for editing programs for R or Splus (two separate statistics packages).
In my buffer, when ever I type _ the character is replaced with <-, which is very frustrating. Is there an emacs lisp statement to turn off this behavior?
emacs: 22.1.1
ess-mode release (unknown)
From ESS's manual (look under "Changes/New Features in 5.2.0"):
ESS[S]: Pressing underscore ("_") once inserts " <- " (as before); pressing underscore twice inserts a literal underscore. To stop this smart behaviour, add "(ess-toggle-underscore nil)" to your .emacs after ess-site has been loaded
Since the feature is useful. You can assign it to other key which is less used by you in R it will automatically unassign it from underscore. I personally assign it to ";" by adding following line in .emacs file.
(setq ess-smart-S-assign-key ";")
My version of emacs is 24.3 All-in-one installation file by Vincent Goulet.(Installed on windows 7)
hope this helps
Edit
In emacs 25.2 above do not work instead add following in the .emacs file
(setq ess-smart-S-assign-key ";")
(ess-toggle-S-assign nil)
(ess-toggle-S-assign nil)
A more recent version which seemed to work for me, and is a lot less verbose (you essentially keep normal underscores, but can set your own key for this smart behaviour!):
(global-set-key (kbd "C-;") (lambda () (interactive) (insert " <- ")))
(ess-toggle-underscore nil)
Insert your shortkey choice instead of C-;.
From http://www.r-bloggers.com/a-small-customization-of-ess/ and
How to change smart assign key ("_" to "<-") binding in ESS
To assign ":" to "<-" and to stop the assignment of underscore (underbar) "_" to "<-" put the following in .emacs (yes, the repeated line is correct)
(setq ess-smart-S-assign-key ":")
(ess-toggle-S-assign nil)
(ess-toggle-S-assign nil)
(ess-toggle-underscore nil) ; leave underscore key alone!
Like Michał Marczyk and this R mailing list thread suggested, add this line to ~/.emacs:
(ess-toggle-underscore nil)
Then reload it with M-x load-file and type ~/.emacs.
But if you load the file again, e.g. if you add another customization, then it toggles it back to the original state. So toggle it twice, the first one forcing it to the default:
(ess-toggle-underscore t)
(ess-toggle-underscore nil)
That being said, I like Drummermean's solution better, but it also reverts back to default if you add it to ~/.emacs and load it twice. So force a toggle to the default before:
(ess-toggle-underscore t)
(global-set-key (kbd "M--") (lambda () (interactive) (insert " <- ")))
(ess-toggle-underscore nil)
I bound the smart assignment to Opt-[minus] like RStudio (on a Mac).
As a follow-up on #mmorin answer. To set keybinding for the assignment operator the same way as in Rstudio add the following in your .emacs file
(ess-toggle-underscore t)
(ess-toggle-underscore nil)
(define-key ess-mode-map (kbd "M--") (lambda () (interactive) (just-one-space 1) (insert "<-") (just-one-space 1)))
(define-key inferior-ess-mode-map (kbd "M--") (lambda () (interactive) (just-one-space 1) (insert "<-") (just-one-space 1)))

Resources