sagemath / sage-shell-mode

Emacs front end for SageMath
GNU General Public License v3.0
98 stars 16 forks source link

Create `sage-shell:restart-sage` #15

Closed johanrosenkilde closed 6 years ago

johanrosenkilde commented 7 years ago

I quite often restart the Sage shell. Sometimes its to flush all the globals I've created during experiments to double-check that my functions don't rely on them, and sometimes it's because I accidentally evaluate an infinite loop or something.

For this use case it would be nice with a handy restart function.

johanrosenkilde commented 7 years ago

I tried my hand at creating this function, but it relies very nastily on the time it takes the existing process to finish:

(defun sage-restart (cmd)
  (interactive (list (sage-shell:read-command)))
  (with-current-buffer sage-shell:process-buffer
    (end-of-buffer)
    (ignore-errors
      (progn
        (comint-delchar-or-maybe-eof nil)
        (sleep-for 3)))
    (sage-shell:run cmd nil)
  ))

Note the ugly (sleep-for 3): If that's not there, then sage-shell:run doesn't seem to do anything because it hasn't discovered that the existing process has ended yet.

The advantage of reusing the existing buffer is that history in the buffer is preserved, so you can go back and read what went on previously. The disadvantage is that I don't know how to get back from the process when it has ended, replacing the sleep-for by something robust.

stakemori commented 7 years ago

The advantage of reusing the existing buffer is that history in the buffer is preserved, so you can go back and read what went on previously. The disadvantage is that I don't know how to get back from the process when it has ended, replacing the sleep-for by something robust.

As for the input history, you can set sage-shell:input-history-cache-file. You can reuse input history even if Emacs exits.

For such an asynchronous job, you can use deferred or the macro sage-shell:as-soon-as which needs lexical-binding and is not documented (sorry). Or maybe I should add a hook which runs when the proces exits.

johanrosenkilde commented 7 years ago

As for the input history, you can set sage-shell:input-history-cache-file. You can reuse input history even if Emacs exits.

Yes, but you lose the output history. And the input history is not conveniently listed so you can search backward through it.

For such an asynchronous job, you can use deferred or the macro sage-shell:as-soon-as which needs lexical-binding and is not documented (sorry). Or maybe I should add a hook which runs when the proces exits.

That sounds interesting. I'm afraid I won't have time to look further on this for some days. It sounds like the hook would be an Emacsy and convenient way of accomplishing this.

stakemori commented 7 years ago

I added sage-shell:process-exit-hook and sage-shell:restart-sage in fix-branch. Thanks.

johanrosenkilde commented 7 years ago

Thanks!

johanrosenkilde commented 7 years ago

sage--shell:restart-sage works correctly and with the nice behaviour of staying in the same buffer. But it works only if *Sage* is the current buffer? Perhaps a more convenient semantics is:

stakemori commented 7 years ago

Thanks for your suggestion. I modified sage-shell:restart-sage (15ee1e6c2bec83e01b73e1b7e6462831e8e9c5d9).

johanrosenkilde commented 7 years ago

Thanks! I've verified that it works

johanrosenkilde commented 7 years ago

New problem: sage-shell:restart-sage forgets to store the input of the session in the history cache file, even when this is non-nil.

stakemori commented 7 years ago

Thanks. I pushed further fix. I will test commits more carefully.