[ESS] Yet another indentation question: indentation after parenthese

Vitalie Spinu spinuvit at gmail.com
Sat Dec 17 13:35:21 CET 2011

Mathieu Basille <basille at ase-research.org> writes:

> Le 16/12/2011 14:54, Rodney Sparapani a écrit :
>> Mathieu Basille wrote:
>>> Alright, I think I start to understand the problem, and what seemed easy to
>>> me might not be possible. I thought that taking parentheses into account
>>> would be easier than ignoring them, thus my question!
>>> I will stick to 'C++' or 'RRR' styles and manually adjust them when needed
>>> (using e.g. 'source' with 'options(keep.source = FALSE)'). This makes,
>>> however, the use of 'auto-fill-mode' virtually impossible to me, because
>>> such statements:
>>> toto <- someFunction(arg1 = bli, arg2 = bla, arg3 = blo, arg2 = c("a",
>>> "bla", c(1, 2, 3, 4), "blo", "blu", "bli"))
>>> will render awfully with a column width of 70. I can live with this (well,
>>> I did for many years now!), I just hoped that there was a way to follow
>>> what R uses internally to format R code. I find it a pity that such a great
>>> editor like Emacs (which is, by far, the best tool I tried to edit R/Rnw
>>> scripts, with the result that I couldn't work without it now) can't
>>> reproduce R behaviour.
>>> Vitalie and Richard, many thanks go to you for your efforts to 1)
>>> understand (!) and 2) trying to find a solution to my little problems!
>>> All the best,
>>> Mathieu.
>> Hi Mathieu:
>> Making it into a style might be a challenge.  Mode grammar/syntax is not
>> much fun to play with.  Look at the definition of parentheses to see if
>> they are a word or punctuation.  Otherwise, you could probably create an
>> elisp function that calls R to replace a function with its re-formmatted
>> equivalent.  ESS has several functions that work like that.  For example,
>> take a look at ess-ebcdic-to-ascii-search-and-replace which replaces EBCDIC
>> passages in the buffer with their ASCII equivalents. You might also be able
>> to use ESS primitives that find the function definitions and repeatedly
>> replace them (just like you can search and replace multiple EBCDIC blurbs
>> in one go).

Taking Rodney's idea further, you can actually call deparse(parse()) on
the region:

(defun ess-indent-region-as-R-function (beg end)
  (let ((string (replace-regexp-in-string
		 "\"" "\\\\\\&"
		 (replace-regexp-in-string ;; how to avoid this double matching?
		  "\\\\\"" "\\\\\\&" (buffer-substring-no-properties beg end))))
	(buf (get-buffer-create "*ess-command-output*")))
    (ess-command (format "local({oo<-options(keep.source=FALSE);
options(oo)})\n"  string) buf)
    (with-current-buffer buf
      (goto-char (point-max))
      ;; (skip-chars-backward "\n")
      (let ((end (point)))
	(goto-char (point-min))
	(goto-char (1+ (point-at-eol)))
	(setq string (buffer-substring-no-properties (point) end))
    (delete-region beg end)
    (insert string)

(add-hook 'ess-mode-hook '(lambda () (set (make-local-variable 'indent-region-function)
Now you can select a region and pres C-M-/ to get it indented as R
thinks it should. Pay attention that the code in the region should be
syntactically correct.

Now a question for programmers out there. In the above code I have
parse(text="%s") where "%s" is a string from the buffer. In order that
to work one have at least to substitute all " and \" in %s (there might
be other problems with escaped chars which I don't see now).

I assume this is a common task but I cannot find a function in emacs
which would escape all problematic chars for me. Any ideas?


> Dear Rodney,
> That looks interesting! I have no knowledge of elisp and probably not much
> time to dig into it, but I'll keep this on my todo list, in case I find
> time for it! An interactive function could actually be quite useful...
> Thanks!
> Mathieu.
>> ______________________________________________
>> ESS-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/ess-help

More information about the ESS-help mailing list