Quite often I find myself with bunch of R processes running in ESS buffers. There's a convenient Lisp function ess-request-a-process that asks for R process, and brings it to front. The only downside is that it somehow defaults to S, so each time I'm about to make a switch, I have to type R, ad nauseam.
I tried customising the ess-language variable, but even if I set value to "R", i.e. 4 for current session, or even if I save settings for future session, as soon as I type C-c C-k, automagically S appears once again. It's very annoying, and I really don't want to end up with C-x C-b and then C-s for desired R session! =)
I even tried setting (setq-default ess-language "R") in .emacs, but with no luck...
BTW, I'm running Emacs v. 23.1.1 on Linux Mint and Emacs v. 23.2 on Arch Linux, with ESS v. 5.12. If that's relevant, I run Emacs from terminal with -nw argument. Here's my .emacs:
;; start server
(server-start)
;; load ESS
(require 'ess-site)
(require 'ess-rutils)
;; set HTML help as default
(setq inferior-ess-r-help-command "help(\"%s\", help_type = \"html\")\n")
(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(ess-help-kill-bogus-buffers t)
'(ess-rutils-keys nil)
'(show-paren-mode t))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)
(put 'upcase-region 'disabled nil)
So... how to set R once and for all? (I don't use S/S+/SAS)
I did not know about this function so far. C-c C-k is bound to ess-force-buffer-current in ESS buffers.
[edit: C-c C-k is indeed bound to ess-request-a-process in iESS, in ESS it's ess-force-buffer-current]
In any case the variable you have to customize is ess-dialect
(setq-default ess-dialect "R")
It's buffer-local variable and some other stuff in ess-mode-hook might set it a different value.
Check it in each buffer with C-h v ess-dialect
Additionally, if you already running several processes then ess-switch-process (C-c C-s) might be the right way to go.
[edit: it will not jump to a process but just reset the associated process of the current ESS buffer]
[edit: After dwelling deeper on the issue it turned out that ess-request-a-process uses ess-language variable were the ess-dialect seems to be more appropriate. The problem is that each time an ess-inferior process starts it resets the global value of ess-language. This is why setting it in your case didn't work.
Here is a quick fix:
(defun ess-set-language ()
(setq-default ess-language "R")
(setq ess-language "R")
)
(add-hook 'ess-post-run-hook 'ess-set-language t)
]
Related
I am trying to get live-coding to work in lisp. i have the file t.cl which contains only this line: (loop(write(- 2 1))). Now, when i run the file in bash with sbcl --load t.cl --eval '(quit)', it runs the line, but when I try to edit the file in another terminal and save it while it runs, nothing changes ..
Why your example fails
When running sbcl --load t.cl --eval '(quit)' in a shell, what this does is spin-up a SBCL Lisp image in a process, compile the file and run it. You then modify the file and save it to your disk. This last action is of no concern to the already running SBCL process, which has already compiled the previous file. SBCL read the file once when you asked it to, once it has the compiled instructions to run, it has no reason to look at the file again unless you explicitly ask it to.
A 'live' example with Emacs+SLIME
In order to perform 'live' changes to your running program, you must interact with the already running Lisp image. This is easily doable with Emacs+Slime. You can, for example, have a loop like so:
(defun foo (x) (+ x 3))
(dotimes (it 20)
(format t "~A~%" (foo it))
(sleep 1))
and then recompile foo during execution within the REPL with a new definition:
(defun foo (x) (+ x 100))
Another thread will be used to recompile the function. The new function will be used for future calls as soon as its compilation is finished.
The output in the REPL will look like:
3
4
5
CL-USER> (defun foo (x) (+ x 100))
WARNING: redefining COMMON-LISP-USER::FOO in DEFUN
FOO
103
104
105
...
This would also work with the new definition of foo being compiled from another file as opposed to being entered directly in the REPL.
Working from the system shell
While you can already use the example above for development purposes, you might want to interact with a running SBCL Lisp image from the shell. I am not aware of how to do that. For your exact example, you want to get SBCL to reload eventual files that you have modified. A brief look at the SBCL manual doesn't seem to provide ways to pipe lisp code to an already running SBCL process.
I just started learning common lisp, so excuse me if lisp terminology is a bit off. I installed slime and am using Clozure CL. ccl is working just fine. When I enter a wrong expression, the debugger opens (slbc ccl/1 buffer). When I enter q, the debugger buffer closes, and then the inferior-lisp buffer does not respond. Why is that?
and if I want to continue work, I seem to have to restart inferior-lisp, what is it I am doing wring?
I just wanted to say put out the solution I found.
I had followed the instructions in the slime's user manual (from here), I used MALPA repository to install slime.
As PuercoPop's says in the comments, i should land in a slime-repl buffer, which I didn't have by default. I did some further digging and learnt that i have to add a few more line to my .emacs file for the slime-repl buffer to load. The line needed was
(slime-setup '(slime-fancy))
My final .emacs file looks like this:
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/"))
(when (< emacs-major-version 24)
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize)
(setq package-enable-at-startup nil)
(setq inferior-lisp-program "F:/Binaries/ccl/wx86cl64.exe")
(setq slime-auto-connect 'ask)
(setq slime-net-coding-system 'utf-8-unix)
(require 'slime)
(slime-setup
'(slime-fancy slime-asdf slime-references slime-indentation slime-xref-browser)
)
My workflow:
Hack away at an .R or test_*.R file
Save buffer.
Switch to window with *R* process
hit C-p, RET. to re-evaluate devtools::test()
To me, this seems far too arduous. Why can't I get R to run devtools::test() automatically when I save the buffer? Please help, my fingers can barely take the strain of the seven extra keystrokes!
This worked for a similar setup (switching to a shell buffer):
(defun devtools-test ()
(interactive)
(when (string-match (rx-to-string `(: ".R" eos) t) (buffer-name))
(switch-to-buffer "*R*")
(end-of-buffer)
(insert "devtools::test()")
(comint-send-input)))
(add-hook 'after-save-hook 'devtools-test)
Does that work for you?
For completeness, there are easier way to do this in recent versions of ESS.
The function/command ess-r-devtools-test now runs devtools::test.
So you could achieve this with (untested):
(add-hook 'ess-r-mode-hook
(lambda ()
(add-hook 'after-save-hook 'devtools-test nil 'local)))
In addition, there are many other useful functions under ess-r-devtools-* for build, install etc.
It's worth noting that calling ess-r-devtools-test with the universal argument will filter tests by the current file.
So calling C-u M-x ess-r-devtools from a file my-file.R will run devtools::test(filter="my-file").
This can be useful to bear in mind when choosing names for test files, or when rerunning only the current test file.
There is a ess-eval-linewise function which you can use.
Something like this (not tested):
(defun devtools-test ()
(interactive)
(when (and (equal ess-dialect "R")
(string-match "^test.*\\.[Rr]$" (buffer-name)))
(ess-eval-linewise "devtools::test()")))
(add-hook 'after-save-hook 'devtools-test)
I would not recommend this though, as for some packages tests take quite a while to run. You don't want them running on every save.
There will be a dedicated devtools functionality in ess soon. Follow this issue.
To use ess-rdired to browse objects, I followed the ESS manual and added the following to my .emacs:
(autoload 'ess-rdired "ess-rdired"
"View *R* objects in a dired-like buffer." t)
When I do M-x ess-rdired, a buffer listing the objects in your current environment appears.
However, when I press shortcuts like p, v I get this error:
"no ESS process is associated with this buffer now."
Besides, can ess-rdired update info of objects when they are changed?
I had the same problem and sure enough C-c C-s solves it. I added the following function to my dot emacs file to automate this. I mapped the function to C-c o which will load rdired or refresh it. Any improvements would be very welcome!
(defun ess-R-show-objects ()
"Calls rdired and associates with R process"
(interactive)
(if (get-buffer "*R*") ;;Only run if R is running
(progn
(ess-rdired)
(ess-rdired-switch-process))
(message "No R process")
)
)
(global-set-key (kbd "\C-co") 'ess-R-show-objects)
The following fragment of CL code does not work as I expected with CCL running SLIME. If I
first compile and load the file using C-c C-k, and then run
(rdirichlet #(1.0 2.0 3.0) 1.0)
in the SLIME/CCL REPL, I get the error
value 1.0 is not of the expected type DOUBLE-FLOAT.
[Condition of type TYPE-ERROR]
It works with SBCL. I expected the (setf *read-default-float-format* 'double-float)) to allow me to use values like 1.0. If I load this file into CCL using LOAD at the REPL it works. What am I missing?
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :asdf) (require :cl-rmath) (setf *read-default-float-format* 'double-float))
(defun rdirichlet (alpha rownum)
;;(declare (fixnum rownum))
(let* ((alphalen (length alpha))
(dirichlet (make-array alphalen :element-type '(double-float 0.0 *) :adjustable nil :fill-pointer nil :displaced-to nil)))
(dotimes (i alphalen)
(setf (elt dirichlet i) (cl-rmath::rgamma (elt alpha i) rownum)))
;; Divide dirichlet vector by its sum
(map 'vector #'(lambda (x) (/ x (reduce #'+ dirichlet))) dirichlet)))
UPDATE: I forgot to mention my platform and versions. I'm using Debian squeeze x86. The version of SLIME is from Debian unstable, 1:20120525-2.
CCL is the 1.8 release. I tried it both with the upstream binaries from http://svn.clozure.com/publicsvn/openmcl/release/1.8/linuxx86/ccl, and a binary package created by me - see Package ccl at mentors.debian.net. The result was the same in each case.
It seems probable that this issue is SLIME specific. It would be helpful if people could comment whether they see this behavior or not. Also,
what is the equivalent of C-c C-k in SLIME, if one is running CCL in basic command line mode? (LOAD filename), or something else? Or, to ask a slightly different question, what CCL function is C-c C-k calling?
I notice that calling C-c C-k on the following code
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :asdf) (require :cl-rmath) (setf *read-default-float-format* 'double-float))
(print *read-default-float-format*)
produces DOUBLE-FLOAT, though even though *read-default-float-format* at the REPL immediately afterwards gives SINGLE-FLOAT.
UPDATE 2: It looks like, as Rainer said, that the compilation occurs in a separate thread.
Per the function all-processes in Threads Dictionary
printing all-processes from the buffer using C-c C-k gives
(#<PROCESS worker(188) [Active] #x18BF99CE> #<PROCESS repl-thread(12) [Semaphore timed wait] #x187A186E> #<PROCESS auto-flush-thread(11) [Sleep] #x187A1C9E> #<PROCESS swank-indentation-cache-thread(6) [Semaphore timed wait] #x186C128E> #<PROCESS reader-thread(5) [Active] #x186C164E> #<PROCESS control-thread(4) [Semaphore timed wait] #x186BE3BE> #<PROCESS Swank Sentinel(2) [Semaphore timed wait] #x186BD0D6> #<TTY-LISTENER listener(1) [Active] #x183577B6> #<PROCESS Initial(0) [Sleep] #x1805FCCE>)
CL-USER> (all-processes)
and in the REPL gives
(#<PROCESS repl-thread(12) [Active] #x187A186E> #<PROCESS auto-flush-thread(11) [Sleep] #x187A1C9E> #<PROCESS swank-indentation-cache-thread(6) [Semaphore timed wait] #x186C128E> #<PROCESS reader-thread(5) [Active] #x186C164E> #<PROCESS control-thread(4) [Semaphore timed wait] #x186BE3BE> #<PROCESS Swank Sentinel(2) [Semaphore timed wait] #x186BD0D6> #<TTY-LISTENER listener(1) [Active] #x183577B6> #<PROCESS Initial(0) [Sleep] #x1805FCCE>)
so it seems #<PROCESS worker(188) [Active] #x18BF99CE> is the thread that is doing the compilation. Of course, there still remains the question of why these variables are local to a thread, and also why SBCL does not behave the same way.
I can see that with CCL and some older (which I use) SLIME, too. Haven't tried it with a newer SLIME.
It does not happen with SBCL or LispWorks.
*read-default-float-format* is one of the I/O variables of Common Lisp. Something like WITH-STANDARD-IO-SYNTAX binds them to the standard values and, on exit, restores the previous values. So I suspect that CCL's SLIME code has such a binding in effect. This is confirmed by setting other I/O variables like *read-base* - they are also bound.
CCL, Emacs and SLIME has some layers of code which makes it slightly complex to debug this.
Emacs runs the ELISP code of SLIME and talks to SWANK.
SWANK is the backend of SLIME and is Common Lisp code running in CCL.
SWANK has portable code and some CCL-specific code.
On the Emacs side the SLIME/ELISP function SLIME-COMPILE-AND-LOAD-FILE is used.
On the SWANK side the Common Lisp function swank:compile-file-for-emacs gets called.
Later SWANK:LOAD-FILE gets called.
I don't see where the I/O variables are bound - maybe it is in the CCL networking code?
This seems to be the answer:
If CCL has thread-local I/O variables, then the compilation happens in another thread and won't change the I/O bindings in the REPL thread and also not in any other thread.
This is a difference between various CL implementations. Since the CL standard does not specify threads or processes, it is also not specified if special bindings are global or have a thread-local binding by default...
If you think about it, protecting a thread's I/O variables against changes from other threads makes sense...
So, the correct way to deal with it should be to make sure in each thread independently that the right I/O variable values are in effect.
Let me expand a bit why things are like they are.
Typically a Common Lisp implementation can run more than one thread. Some implementations also allow concurrent threads running at the same time on different cores. These threads can do very different things: one could run a REPL, another one could answer an HTTP request, one could load data from the disk and another one could read the contents of an Email. Lisp in this case runs several different tasks inside one Lisp system.
Lisp has several variables which determine the behavior of I/O operations. For example which format floats are when read or which base integer numbers are in when read. The letter is done by `read-base.
Now imagine that the above disk reading thread has set its *read-base* to 16 for some purpose. Now you change the global in another thread to 8 and then suddenly all other threads have base 8. The consequence: the disk reading thread will suddenly see *read-base* 8 instead of 16 and work differently.
So it makes sense to prevent this in some way. The simplest is that in each thread the running code has their own bindings for the I/O values and then changing the *read-base* won't have effects on other threads. These bindings are usually introduced by LET or a function call. Typically the code would be responsible to bind the variables.
Another way to prevent it is to give each thread a number of initial bindings, which should for example include the I/O bindings. CCL does that. LispWorks for example does that, too. But not for the I/O variables.
Now each Lisp might give you a non-portable way to change the thread-local top binding (CCL has that, too - for example (setf ccl:symbol-value-in-process) ). Still it would not mean that it might change the binding in effect in the REPL. Since the REPL itself is a piece of Lisp code, running in a thread and it could have been setting up its own bindings.
In CCL you can also set the global static binding: (CCL::%SET-SYM-GLOBAL-VALUE sym value). But if you use such functionality you are probably doing something wrong or you have a good reason.
Some background for CCL: http://clozure.com/pipermail/openmcl-devel/2011-June/012882.html
Lore
Don't try to change global bindings from one thread visible for other threads.
Shield your code from changes in other threads by binding the crucial variables to the correct values.
Write a function which sets up the variable values to some values in a controllable fashion.