Closed wmay closed 1 year ago
I have had for many years in a sfs-conf.el file which is loaded from my .default / emacs.el:
;; Only look at attached packages, not at all the 1000 installed ones :
(setq ess-r-prompt-for-attached-pkgs-only t)
(define-key inferior-ess-mode-map "\C-cw" #'ess-execute-screen-options)
(define-key ess-mode-map [?\M--] #'ess-insert-assign)
(define-key inferior-ess-mode-map [?\M--] #'ess-insert-assign)
(add-hook
'inferior-ess-mode-hook
'(lambda()
;; (message "inferior-ess-mode-hook: Increasing ess-loop-timeout..")
;; (setq ess-loop-timeout (* 2 ess-loop-timeout))
(let ((host (or (getenv "HOST")
(getenv "HOSTNAME"))))
;; double timeout for fast hosts
;; (if (and host
;; (string-match "\\(deb\\|florence\\|aryness\\|jessica\\|helen\\)"
;; host))
;; (setq ess-loop-timeout (* 2 ess-loop-timeout)))
(when (string= ess-language "S")
(add-hook 'ess-post-run-hook 'ess-execute-screen-options 'at-end)
(add-hook 'ess-r-post-run-hook 'ess-execute-screen-options 'at-end))
(cond
((string= ess-dialect "R")
(if xemacs-p
(gnuserv-start)
(unless (and emacs-23-p (fboundp 'server-running-p)
(server-running-p))
(server-start nil)))
;; now part of ESS via R-editor -> ess-editor -> inferior-ess-language-start:
;; (add-hook 'ess-post-run-hook
;; '(lambda()
;; (ess-eval-linewise "options(editor = \"emacsclient\")")))
(setq ess-dump-error-re
;; R : -- as default is only english
"[Ee]rror\\|[Ff]ehler")
)
((string= ess-dialect "S+5")
;; double timeout for Splus 5 ..
;; (setq ess-loop-timeout (* 2 ess-loop-timeout))
)
) ;end cond
)
)
); inf.ess-mode-hook
;; ess-version does *NOT* exist now
;; (when (string-lessp ess-version "16.10")
;; ESS <= 16.04 is default ess package in Fedora 24 (@d-math 2016-2017)
(add-hook
'ess-r-post-run-hook
'(lambda()
;; carefully set "pager" option "when needed":
(ess-eval-linewise
(format
"if(identical(getOption('pager'), file.path(R.home(), 'bin', 'pager')))
## rather take the ESS one
options(pager='%s')\n" inferior-ess-pager))))
this is a bit longish and has grown historically. Note that it has an "commented out" section about running a timeout. So it seems the problem about having to wait for the process is solved earlier, as indeed the two *post-run-hook"s already contain in their name that they wait for the R process to be ready ..
For me it, it currently setting the width correctly even twcice
almost surely because I had decided to add ...execute-screen-options
even to both hooks
'ess{-r}-post-run-hook` ...
I agree that the current default is really silly as not setting the width at all. I don't have time to experiment currently, but I think just doing
(add-hook 'ess-r-post-run-hook 'ess-execute-screen-options 'at-end))
might be sufficient. Can you confirm? If yes, I think we should put something like it as default into this (or the other) *-post-run-hook
I can confirm that it does not work. Those hooks are called before the buffer is visible, so they cannot get the correct settings. (Though it may end up correct anyway on some setups purely by accident.)
One easy way to confirm this is to check the source code:
(defun R (&optional start-args)
(interactive "P")
;; FIXME: Current ob-R expects current buffer set to process buffer
(set-buffer (run-ess-r start-args)))
The buffer is set here after R has been started.
A second way to check is to print the result of get-buffer-window
. When I run that from a function added to ess-r-post-run-hook
it returns nil
.
~Maybe it's possible to get a different result on another computer if things are running at different speeds.~ You should get the same result on your computer because both hooks are run by run-ess-r
. At least for my own case I've already confirmed all of this.
I think I see the issue with ess-post-run-hook
as well now. Usually it should run after the buffer is visible.
But, if you start R by executing some code, the normal ESS R
function is called within ess--with-no-pop-to-buffer
by ess-request-a-process
. Apparently ess-post-run-hook
starts up before ess-request-a-process
finishes and makes the buffer visible.
Edit: Oh, actually that's also the issue with ess-r-post-run-hook
. All of this issue is caused by ess-request-a-process
. Sorry, I'm kind of making a mess of the comments here. I subtly misunderstood the issue earlier.
Ok, thank you Will (@wmay). I've edited the issue title to match what you observe.
Yes, this is a problem for me sometimes, too.
Almost always I have at least one version of R running ("under" ESS) in my Emacs.
But in the case you mention, I occasionally observe even much worse: the whole ESSR
functionality is then not part of the search()
path, i.e.,
"ESSR" %in% search()
is FALSE instead of TRUE ... and the R-process buffer is basically useless (ESS or polymode... or .. even still tries to do things and timeouts, and it is really unusable). I have to terminate and restart R to get anything usable.
Indeed this behavior is "relatively new" i.e., only about 1-2 years old and an absolute PITA (and one of the ESS bugs that did not show for me ever in the "relatively old" times).
Now that we've clarified what the issue is, here's the workaround I put together:
(defun my-ess-wait-then-set-width ()
"Workaround for https://github.com/emacs-ess/ESS/issues/1243.
Add a wait before calling `ess-set-width' from
`window-configuration-change-hook', that way the width can still
get set if the R process is briefly busy."
(let ((proc (get-buffer-process (window-buffer))))
(when (and (process-live-p proc)
(process-get proc 'busy))
;; wait for at most 1 second if the process is busy
(when (ess-wait-for-process proc nil nil nil 1)
(ess-set-width)))))
(defun my-add-ess-window-hook ()
(add-hook 'window-configuration-change-hook #'my-ess-wait-then-set-width nil t))
(add-hook 'ess-post-run-hook #'my-add-ess-window-hook)
@wmay IIUC this blocks the UI for 1 second when the window config changes? We can't use this in ESS then because the UI should never block.
If that's only for startup, there is a bunch of R options that are set in the background on startup, so presumably we can set the width as part of that?
Regarding window-config changes, ideally the width would be set with an async command. There's some infrastructure for that but it isn't 100% reliable.
@lionel-
IIUC this blocks the UI for 1 second when the window config changes? We can't use this in ESS then because the UI should never block.
Hmm... I tested it and yes, it does block the UI for up to 1 second. To clarify, this is my user-level workaround, not necessarily what should go into ESS.
If that's only for startup, there is a bunch of R options that are set in the background on startup, so presumably we can set the width as part of that?
Um ... actually ... I'm not sure. The problem is that ess-request-a-process
displays the buffer after the hooks are started. One solution would be to call ess-set-width
at the end of ess-request-a-process
. But even at that point there's some waiting required because R is busy when the buffer becomes visible. (The existing window-configuration-change-hook
already runs ess-set-width
at this time and it fails because it doesn't wait.)
Regarding window-config changes, ideally the width would be set with an async command. There's some infrastructure for that but it isn't 100% reliable.
I was thinking there could be a buffer-local indicator variable for window changes, and then as new commands are sent, for example maybe in ess-send-string
, the width could be updated if needed.
I was thinking there could be a buffer-local indicator variable for window changes, and then as new commands are sent, for example maybe in ess-send-string, the width could be updated if needed.
Unfortunately there is no guarantee that the R interpreter is available when a string is sent. We might be in the middle of an incomplete input, or maybe a utils::menu()
, or maybe a reticulate Python repl, etc.
OK. What if we drop the waiting stuff and just run the width-setting code the same as the setwd code? I changed the last block of ess-request-a-process
to add this and it seems to work fine:
(when (or auto-started? (not noswitch))
(let ((proc-buf (ess-get-process-buffer proc)))
(if noswitch
(display-buffer proc-buf)
(pop-to-buffer proc-buf))
(with-current-buffer proc-buf
(ess-eval-linewise (ess-calculate-width ess-auto-width) t))))
ess-set-width
uses ess-command
instead. It's not clear to me if there's still a reason to prefer ess-command
in this context.
What if we drop the waiting stuff and just run the width-setting code the same as the setwd code?
Sorry I don't understand.
ess-set-width uses ess-command instead. It's not clear to me if there's still a reason to prefer ess-command in this context.
ess-command
happens in the background so that you don't see distracting input and output in the REPL. That seems preferable to me but maybe I don't understand what you mean here?
ess-command
seems to require that the process is not busy when it's called. On the other hand, ess-eval-linewise
goes ahead and sends the input to R, busy or not (as far as I can tell). So ess-set-width
requires waiting any time the process is busy because it uses ess-command
, but the setwd code run when R is started just uses ess-eval-linewise
. That's a simpler way to run code at startup.
That's because we want setwd()
to show in the console since it's very important information regarding the starting state of the REPL but the other background settings like pager
need to happen in the background.
ess-eval-linewise
has the argument invisibly
to keep it from showing in the console
ess-eval-linewise has the argument invisibly to keep it from showing in the console
This is the input not the output so you'd see an additional dangling prompt in the console.
I thought that would happen too, but I tried it and that doesn't happen. There's no extra prompt.
Maybe somehow the code being sent over changes the prompt behavior? ¯\_(ツ)_/¯
If we're ruling out all the more superficial fixes, I guess a more fundamental fix would be to hold off on running ess-post-run-hook
(or ess-r-post-run-hook
) until the end of ess-request-a-process
. Then users can use the hooks to set their width as desired
We're now setting the screen config in r-post-run-hook as well as after pop-to-buffer. IIUC this should fix your issue. Can you confirm please?
It doesn't work unfortunately.
The new function ess--execute-screen-options-bg
doesn't run because the R process is still busy after pop-to-buffer
is called. I tested it and (inferior-ess-available-p)
returns nil
at that part of the code.
window-configuration-change-hook
already runs ess-set-width
after the R buffer is made visible, and fails for the same reason.
I don't have any extra hooks set up, so this is all coming from the ESS code itself.
A second issue is that that code will only run if noswitch
is false, but it isn't false. But that's easy to fix though.
The new function ess--execute-screen-options-bg doesn't run because the R process is still busy after pop-to-buffer is called.
Shouldn't the post-run hook deal with that once R is no longer busy? I get the width correctly set with R -d lldb
which takes a long time to start.
The post-run hook isn't an option because it runs before the buffer is visible. That's what I determined earlier after detailed testing specifically to answer that question. It works if you run M-x R
directly, but not when you start R by running code, which goes through ess-request-a-process
.
I don't know why the R process is busy at the end of ess-request-a-process
. I thought it was the setwd
code but I haven't been able to answer that for sure.
I get the width correctly set with
R -d lldb
which takes a long time to start.
And to clarify, these width-setting functions can still run before the buffer is visible, and in that case they set the width to the width of the frame. (Well, that's what happens in my tests at least.) So if you're splitting your window horizontally you won't necessarily see anything wrong. I notice because my window splits vertically, so the frame and R buffer window widths are different.
I split windows vertically too.
It's not clear to me why would R be busy if it has finished running. We could try with ess-async-command
but it would be good to figure out exactly what's going on. Does the *ESS*
buffer help when ess-verbose
is t
?
Edit: Perhaps add some ess-if-verbose
calls in ess-request-a-buffer
as well.
So the setwd
code is called as part of ess-r-post-run-hook
now. I don't see any way for ESS to know if it has finished running.
I don't understand all the *ESS*
buffer output, but here is the relevant section. I added messages around
ess-set-working-directory
ess--execute-screen-options-bg
window-configuration-change-hook
The tail of this is when I manually run options('width')
and get the wrong value (212). The ordering here suggests to me that the R process is still busy with setwd
when both ess--execute-screen-options-bg
and window-configuration-change-hook
are called. That prevents both of them from setting the width.
ess-command (filter): Found prompt
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:t <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:t <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
starting `ess-set-working-directory`. inferior-ess-available-p: t
finished `ess-set-working-directory`. inferior-ess-available-p: nil
(R): inferior-ess-language-start=options(STERM='iESS', str.dendrogram.last="'", editor='emacsclient', show.error.locations=TRUE)
starting `ess--execute-screen-options-bg` (noswitch). inferior-ess-available-p: nil
finished `ess--execute-screen-options-bg` (noswitch). inferior-ess-available-p: nil
running `window-configuration-change-hook`. inferior-ess-available-p: nil
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> > <--
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:$width
[1] 212
> <--
I can also scroll up to see earlier in the log where the width was set before the buffer is even visible. I'm guessing this is from the function called by ess-r-post-run-hook
:
ess-command (filter): Found prompt
(ess-command 'options(width=212, length=99999)
' ..)
So the setwd code is called as part of ess-r-post-run-hook now.
oh yeah that's crucial. While working on this I discovered that the general post-run hook is ran too early. As things stand it should never be used to interact with the inferior process because it hasn't finished starting up yet at that point, e.g. in the case of R ESSR is not loaded when that hook runs. This is a bit tricky to solve generically without relying on the language modes to call the general hook manually. I think inferior-ess
needs to become a cl-defgeneric
.
cc @mmaechler I see that you use that hook instead of the R hook so I think this could explain some of the bad behaviour that you see on your machine. Also in a recent commit I moved the setwd
command to the ess-r post-run hook for the same reason.
The log information you provide confirms that ESS has finished starting up by the time pop-to-buffer is called. I found out that R is also busy for me at that point and this solved it: https://github.com/emacs-ess/ESS/commit/fef059c3efd89bd45e75c2a74aaadbd6e2901f5b
Can you see if that fixes it please? If not, could you please post the full log?
It fixed the setwd
issue, so we're getting somewhere now. But somehow my R process becomes busy again before the buffer becomes visible, so I still get the incorrect width. I haven't pinned down the cause yet, and I'll post again when I do.
And there's still the second issue, that your new call to ess--execute-screen-options-bg
in ess-request-a-process
doesn't run because noswitch
is true. I moved it in my local files for the sake of testing.
Anyway, here's the full log from *ESS*
:
(R): ess-dialect=R, buf=export.R, start-arg=nil
current-prefix-arg=nil
(inferior-ess: waiting for process to start (before hook)
NORMAL-FILTER:
--> busy:t busy-end:nil sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:
R version 4.2.3 (2023-03-15) -- "Shortstop Beagle .... ense()' or 'licence()' for distribution details.
<--
NORMAL-FILTER:
--> busy:t busy-end:nil sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string: Natural language support but running in an Engli .... browser interface to help.
Type 'q()' to quit R.
<--
NORMAL-FILTER:
--> busy:t busy-end:nil sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:**Consider updating packages.** To update, run
update.packages(ask = 'graphics')
saveRDS(Sys.Date(), path.expand('~/.Rupdatelog.rds'))
<--
NORMAL-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
(inferior-ess 3): waiting for process after hook
(ess-command 'if (identical(getOption('pager'), file.path(R.home(), 'bin', 'pager')))
options(pager = 'cat')
' ..)
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:nil <--
--> string:+ <--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:nil <--
--> string:> <--
ess-command (filter): Found prompt
(ess-command 'local({
source('/home/will/.emacs.d/elpa/ess-20230402.42/etc/ESSR/R/.load.R', local=TRUE) #define load.ESSR
.ess.ESSR.load('/home/will/.emacs.d/elpa/ess-20230402.42/etc/ESSR/R')
})
' ..)
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:nil <--
--> string:+ + <--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:nil <--
--> string:+ <--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:nil <--
--> string:> <--
ess-command (filter): Found prompt
(ess-command 'options(STERM='iESS', str.dendrogram.last="'", editor='emacsclient', show.error.locations=TRUE)
' ..)
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:ess-output-delimiter3 <--
--> string:ess-output-delimiter3-START
<--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:ess-output-delimiter3 <--
--> string:ess-output-delimiter3-END
> <--
ess-command (filter): Found prompt
(ess-command 'options(width=212, length=99999)
' ..)
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:ess-output-delimiter4 <--
--> string:ess-output-delimiter4-START
<--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-command-output* cmd-output-delimiter:ess-output-delimiter4 <--
--> string:ess-output-delimiter4-END
> <--
ess-command (filter): Found prompt
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:t <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
finished `ess-r-initialize-on-start`. inferior-ess-available-p: t
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:t <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
in `run-ess-r`. inferior-ess-available-p: t
(R): inferior-ess-language-start=options(STERM='iESS', str.dendrogram.last="'", editor='emacsclient', show.error.locations=TRUE)
finished `run-ess-r`. inferior-ess-available-p: nil
starting `ess--execute-screen-options-bg` (noswitch). inferior-ess-available-p: nil
finished `ess--execute-screen-options-bg` (noswitch). inferior-ess-available-p: nil
running `window-configuration-change-hook`. inferior-ess-available-p: nil
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:$width
[1] 212
> <--
TRACEBUG-FILTER:
--> busy:nil busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:t <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer:nil cmd-output-delimiter:nil <--
--> string:> <--
(ess-synchronize-dirs)
(ess-command 'getwd()
' ..)
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-get-words* cmd-output-delimiter:ess-output-delimiter5 <--
--> string:ess-output-delimiter5-START
<--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-get-words* cmd-output-delimiter:ess-output-delimiter5 <--
--> string:[1] "/home/will/Code/wethepeople"
ess-output-delimiter5-END
<--
ess-command (filter): Accumulating output
ORDINARY-FILTER:
--> busy:t busy-end:t sec-prompt:nil interruptable:nil <--
--> running-async:nil callback:nil suppress-next-output:nil <--
--> dbg-active:nil is-recover:nil <--
--> cmd-buffer: *ess-get-words* cmd-output-delimiter:ess-output-delimiter5 <--
--> string:> <--
ess-command (filter): Found prompt
|-> words= '(/home/will/Code/wethepeople)'
And there's still the second issue, that your new call to ess--execute-screen-options-bg in ess-request-a-process doesn't run because noswitch is true. I moved it in my local files for the sake of testing.
Are you sure? It should have been fixed with https://github.com/emacs-ess/ESS/commit/2ab843212d835fb7df79677c201a067d209e630b
I don't understand this part:
in `run-ess-r`. inferior-ess-available-p: t
(R): inferior-ess-language-start=options(STERM='iESS', str.dendrogram.last="'", editor='emacsclient', show.error.locations=TRUE)
finished `run-ess-r`. inferior-ess-available-p: nil
I would expect to see a lot more output during R startup, e.g. about the ess-command
that were used.
options("width")
does not get set when I start an inferior R process, even though it looks like there is ESS code that was meant to do that. And surprisingly, there is no easy way for a user to make this happen at the moment.It took a while, but I figured out the issue:
ess-set-width
is supposed to handle this, and it's added towindow-configuration-change-hook
. When the inferior R buffer is first made visible, that triggerswindow-configuration-change-hook
, but the R process is briefly busy then, so nothing happens.I saw advice to add the width-setting code to
ess-r-post-run-hook
. But this doesn't work either.ess-r-post-run-hook
is actually run before the inferior R buffer is visible, so the width can't be set correctly at that time.The result is that you can't automatically set the width when opening R, at least not without elaborate workarounds.
I saw that, in the source code for
ess-set-width
, there is a note:It seems like this needs to be implemented to solve this problem. Since R is only very briefly busy when the buffer is made visible, this problem can be solved while still including a very short timeout period to avoid causing other problems.
Or another option is, ess could store a variable to indicate that the window has been changed, and have something in
ess-presend-filter-functions
that updates the width when it's needed.If either of those solutions sounds good, I can send a pull request for it.