emacs-ess / ESS

Emacs Speaks Statistics: ESS
https://ess.r-project.org/
GNU General Public License v3.0
613 stars 160 forks source link

Error in .External2(C_savehistory, file) : no history available to save in #970

Open abigmo opened 4 years ago

abigmo commented 4 years ago

I am using ESS version 18.10.2 and R version 3.6.1 (2019-07-05) -- "Action of the Toes" in standard Ubuntu LTS 18.04.3 LTS. Everything is downloaded from the official ubuntu repository. Even if I have a .Last file in my .Rprofile I get this error.

> q()
Save workspace image? [y/n/c]: y
Error in .External2(C_savehistory, file) : no history available to save

Process R finished at Mon Dec  2 09:18:13 2019

I have it on two different machines, using the same setup... No way to find a solution on stackoverflow... How is it possible that I am the only one? To me, this seems a bug...

Thanks, ABigMO

nverno commented 4 years ago

The history should be saved by ESS (via comint) when the process is killed. Personally, I add a function to kill-buffer-hook to kill buffer processes before killing the buffer so modes like comint have a chance to do cleanup, including saving history.

I don't know if these qualify as proper solutions, but here are a couple of simpler alternatives:

  1. (setq inferior-R-args "--no-save")
  2. Add an alias to your .Rprofile for q
    q <- function() { 
    quit(save=ifelse(Sys.getenv("INSIDE_EMACS") == "", "default", "no")
    }
vspinu commented 4 years ago

@abigmo what is the value of your inferior-R-args?

nverno commented 4 years ago

@vspinu what is your normal procedure for killing an ess inferior process when you want the history to be saved? Do you add a hook to kill-buffer-hook, or something else?

I add one in my comint-mode-hook, but I have no idea if that is a standard procedure.

what is the value of your inferior-R-args?

Should this by default include the "--no-save" flag? Maybe that would be an easy solution if it doesn't have negative side effects.

vspinu commented 4 years ago

@nverno

what is your normal procedure for killing an ess inferior process

Normal is C-c C-q, but often the process is just killed, so what you do (adding history saving to kill buffer hook) seems the right approach. Not sure what we can do on ESS side here though. Shall we add the history saving function there?

Should this by default include the "--no-save" flag?

I expect that every single ESS user sets this flag, so maybe indeed we should consider setting it by default. What others think? @mmaechler, @lionel-, @jabranham

But I don't think either of the above relateds to the OP though. OP seems not to have any history at all, so it's a corner case error from R. I bet it should b happening with plain R in terminal. @abigmo

abigmo commented 4 years ago

Goodmorning,

actually in plain terminal R the history is saved.

My .Rprofile is

options(stringsAsFactors=FALSE)

.First <- function(){
  if(interactive()){
    library(utils)
    timestamp(,prefix=paste("##------ [",getwd(),"] ",sep=""))

  }
}

.Last <- function() {
    if (interactive()) {
        hist_file <- Sys.getenv("R_HISTFILE")
        if (hist_file != ".Rhistory") hist_file <- ".Rhistory"
        try(savehistory())
    }
}

And my ~.emacs I have:

(setq ess-history-directory "./") ; makes sure that .history file is saved
in the current working dir
(setq ess-history-file t) ; makes sure that .history file is saved

The behaviour is the following:

When I close my R session in ESS using

>q()

there is no .Rhistory saved.

And as long as I have the two lines above in .emacs I also get the error message:

> q()
Save workspace image? [y/n/c]: n
Error in .External2(C_savehistory, file) : no history available to save

Without those lines in .emacs, I don't have that error and there is no Rhistory.

In the terminal in plain R the history is always saved.

Thanks for your support, ABigMo

Il giorno dom 8 dic 2019 alle ore 00:01 Vitalie Spinu < notifications@github.com> ha scritto:

@nverno https://github.com/nverno

what is your normal procedure for killing an ess inferior process

Normal is C-c C-q, but often the process is just killed, so what you do (adding history saving to kill buffer hook) seems the right approach. Not sure what we can do on ESS side here though. Shall we add the history saving function there?

Should this by default include the "--no-save" flag?

I expect that every single ESS user sets this flag, so maybe indeed we should consider setting it by default. What others think? @mmaechler https://github.com/mmaechler, @lionel- https://github.com/lionel-, @jabranham https://github.com/jabranham

But I don't think either of the above relateds to the OP though. OP seems not to have any history at all, so it's a corner case error from R. I bet it should b happening with plain R in terminal. @abigmo https://github.com/abigmo

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/emacs-ess/ESS/issues/970?email_source=notifications&email_token=AHLYNNSEII32LCM46OLXXIDQXQTLPA5CNFSM4JTSEGP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEGGRMDQ#issuecomment-562894350, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHLYNNX277UWRQWDDT3HWQTQXQTLPANCNFSM4JTSEGPQ .

nverno commented 4 years ago

That does seem surprising that you would get that error even with the "--no-save" flag (or calling quit(save = "no") or defining the shortcut above). When you exit the ESS process this way, there should be a .Rhistory file saved in the ess-history-directory. Can you confirm you tried either of those options? Also, I think you should remove that call to savehistory from your .Last function, as I believe that will be called anyway when appropriate.

In general, you can check if you are inside emacs from with .Rprofile (or anywhere) with Sys.getenv("INSIDE_EMACS") == "", which will be define when true.

nverno commented 4 years ago

Adding the following to your init should allow you to simply kill ESS R buffers (or any other comint-related buffers) with C-x k, negating the need to manual stop R with eg. q(), and still let comint write the history files (which should end up in ess-history-directory in the case of R).

(defun my-kill-proc-before-buffer ()
  (let ((proc (get-buffer-process (current-buffer))))
    (when (processp proc)
      (and (derived-mode-p 'comint-mode)
           (comint-write-input-ring))
      (delete-process proc))))

(defun my-comint-hook ()
  (add-hook 'kill-buffer-hook #'my-kill-proc-before-buffer nil 'local))

(add-hook 'comint-mode-hook #'my-comint-hook)
abigmo commented 4 years ago

That does seem surprising that you would get that error even with the "--no-save" flag (or calling quit(save = "no") or defining the shortcut above). When you exit the ESS process this way, there should be a .Rhistory file saved in the ess-history-directory. Can you confirm you tried either of those options? Also, I think you should remove that call to savehistory from your .Last function, as I believe that will be called anyway when appropriate.

In general, you can check if you are inside emacs from with .Rprofile (or anywhere) with Sys.getenv("INSIDE_EMACS") == "", which will be define when true.

@nverno 1st: pardon me for the late reply. I removed the ".last" function in my .Rprofile. When exiting from an R session in ESS using quit (save = "no"), I got the history saved, without the error "Error in .External2(C_savehistory, file) : no history available to save"

Then for your following suggestion:

Adding the following to your init should allow you to simply kill ESS R buffers (or any other comint-related buffers) with C-x k, negating the need to manual stop R with eg. q(), and still let comint write the history files (which should end up in ess-history-directory in the case of R).

(defun my-kill-proc-before-buffer () (let ((proc (get-buffer-process (current-buffer)))) (when (processp proc) (and (derived-mode-p 'comint-mode) (comint-write-input-ring)) (delete-process proc))))

(defun my-comint-hook () (add-hook 'kill-buffer-hook #'my-kill-proc-before-buffer nil 'local))

(add-hook 'comint-mode-hook #'my-comint-hook)

I added to my .emacs init file and now it does save my history, although I still get the error Error in .External2(C_savehistory, file) : no history available to save (note that I have no more the .Last function in my .Rprofile).

So for me the solution is ok, I would prefer not have this error. Now I am using elpa-ess 18.10.2-2 bionic0, emacs 25.2, R 3.6.2 on ubuntu 18.04

Thanks! ABig

nverno commented 4 years ago

@abigmo that should be removed if you add (setq inferior-R-args "--no-save") I believe

abigmo commented 4 years ago

@nverno pardon me, but I was not fully correct before:

without your fix here in the .emacs and using q(save="no") the Rhistory is "saved", but only if I don't close emacs. If I restart ESS within the same window, then I have the history of the commands, but no file is written...so if I close emacs and I restart emacs+ess I have actually no history of the commands.

Exactly the same happens if I include your fix in my init file.

Note that in R, Sys.getenv I have R_HISTFILE .Rhistory , so it should be saved in the working directory...

Pardon me, but I was not 100% correct before. Thanks! ABig

jabranham commented 4 years ago

I think the issue here IIUC is that you're trying to combine R's history saving feature and Emac's history saving feature. They don't currently play well together (#291), so I'd suggest using either one or the other but not both.

abigmo commented 4 years ago

Thanks! Unfortunately my modest ESS-Emacs skills are not sufficient to catch your suggestion... I have the impression that I am not doing anything different from what I have done in the last ... decade...(?) I added (and now removed) a .Last function for writing history, only because I was a little desperate about this issue with the history... But apparently it's just something specific to my systems (it occurs on two pcs of mine), so it must be something I did somewhere, since I can't find many more similar cases... :-(

jonbaron1944 commented 4 years ago

For what it is worth, I have the same problem. For the about the last 20 years, up to May 15 (date of the most recent .Rhistory file I have), .Rhistory was saved in the working directory when I said q(), using ESS with no special configuration about this issue. I use Fedora 31. The R package was last updated on May 14, to version 3.6.3-2 (the "2" is the Fedora build). It is possible that the May 15 file was started the day before, so this may have something to do with R. Since this issue occurs with Ubuntu as well, I doubt is a bug specific to Fedora.

almoralesmo commented 3 years ago

I am new to emacs-ess and I have the same problem: no .Rhistory file saved. Next my data:

Creating global Emacs toolbar[ess-site:] very end ... (R): ess-dialect=nil, buf=GNU Emacs, start-arg=nil current-prefix-arg=nil (inf-ess 1): lang=nil, dialect=nil, tmp-dialect=R, buf=GNU Emacs (inf-ess 1.1): procname=R temp-dialect=R, buf-name=R (inf-ess 2.0) Method #3 start=/home/mori/R/ buf=R (inf-ess 2.1): ess-language=S, ess-dialect=R buf=R (i-ess 1): buf=R, lang=S, comint..echo=t, comint..sender=inferior-ess-input-sender, (i-ess end): buf=R, lang=S, comint..echo=t, comint..sender=inferior-ess-input-sender, (inf-ess 3.0): prog=R, start-args=--no-readline , echoes=t Making Process...Buf R, :Proc R, :Prog R :Args= --no-readline
Start File=nil (inferior-ess: waiting for process to start (before hook) (inferior-ess 3): waiting for process after hookload-ESSR cmd: local({ source('/usr/share/emacs/site-lisp/elpa/ess-18.10.2/etc/ESSR/R/.load.R', local=TRUE) #define load.ESSR load.ESSR('/usr/share/emacs/site-lisp/elpa/ess-18.10.2/etc/ESSR/R') })

(R): inferior-ess-language-start=options(STERM='iESS', str.dendrogram.last="'", editor='emacsclient', show.error.locations=TRUE)

Emacs : GNU Emacs 26.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.5) of 2019-09-22, modified by Debian Package: ess-mode 18.10.2 [Released git: d4cd65da6dbf]

current state:

(setq ess-language "S" ess-dialect "R" ess-ask-for-ess-directory t ess-ask-about-transfile nil default-directory "/home/mori/R/" ess-keep-dump-files t ess-source-directory "/tmp/" ess-use-ido t ess-use-eldoc t ess-use-tracebug t ess-use-auto-complete t ess-use-company t ess-eval-visibly-p t ess-can-eval-in-background t ess-local-process-name "R" )

jonbaron1944 commented 3 years ago

FWIW, ess has been working almost "correctly" for at least a few weeks now. I did nothing to make this happen. The history gets saved automatically when I quit R. I say "almost" because it works only when .Rhistory already exists in the working directory. Thus, in order to be sure that it works, I must say "touch .Rhistory" before starting emacs or R. The following line in .bashrc seems to work: alias er='touch .Rhistory; emacs -f R'.

I'm using emacs-ess-18.10.2-2.fc31.noarch, R-3.6.3-2.fc31.x86_64, and emacs-26.3-1.fc31.x86_64, on Fedora 31. I don't think any of this has changed recently.

almoralesmo commented 3 years ago

Thanks, jonbaron1944. Your procedure is confirmed, it works.

jonbaron1944 commented 1 year ago

Addendum: I just upgraded to Fedora 37, but still using the Fedora 35 version of emacs and the fedora 36 version of emacs.ess. (Maybe I should try the new one.) My fix still works, but I had to remove .last from .Rprofile (as suggested here by someone else.)