Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Namespaces and vars by

I am using Emacs/Cider to launch a clj REPL. I do this by first opening my file which defines a new namespace. I then use cider-jack-in-clj to launch the REPL. The REPL namespace is “user”. I can only use fully qualified functions within the REPL. If I enter user=> (ns myns) in the REPL, this works and changes the namespace as expected. I would like to automate this so that every time I launch a REPL from a file the REPL namespace changes as well.

Alternatively, I am ok not changing the namespace as long as I can use unqualified functions.

Here is an example from the top of my file, core.clj

(ns coresync.core
(:use [tupelo.core])
(:require [clojure.core.async :refer [chan >!! <!!]]))

Within the emacs buffer for the code, I am able to get all the unqualified functions, but within the REPL, I need to use:

user=> clojure.core.async/chan

I’ve searched online and through this forum, but I haven’t been able to figure this out. I’m sorry in advance if this has already been asked and I missed it.

Thanks

2 Answers

0 votes
by
edited by

I hope someone comes along with a good answer for you. Clojure's initialisation process is a jungle with many moving parts. In this case there are at least 4 components which might be possible to configure to get good results:

  1. Might be possible to configure the repl in a project tool like Leiningen.
  2. CIDER starts an nrepl server and connects to it, maybe nrepl can be configured to use a different default namespace.
  3. CIDER itself might have an option to switch namespace on startup.
  4. Scripting in Emacs.

While we're waiting for someone who understands any of that; here is a really ugly brute forcing method using CIDER functions in an Emacs hook (ie, this is for ~/.emacs):

(add-hook
 'cider-repl-mode-hook
 (lambda ()
   (run-with-timer
    0.5 nil
    (lambda ()
      (cider-switch-to-last-clojure-buffer)
      (cider-repl-set-ns (cider-current-ns))))))
by
edited by
Thanks very much! The timer is a bit of a kluge, but I was able to get it to work! I looked for an (after! [cider-repl-loaded?] ) type structure, but couldn’t find it. Here is code that works. The idea is to launch a vertical REPL and have it take on the name of the namespace from the file.clj.

(defun run-clojure()
   (interactive)
   (+popup-mode 0)
   (delete-other-windows)
   (setq w1 (selected-window))
   (setq w1name (buffer-name))
   (cider-jack-in-clj nil)
   (set-window-buffer w1 w1name)
   (run-with-timer 5.0 nil 'cider-repl-set-ns (cider-current-ns))))
0 votes
by

In Cider you can use cider-repl-set-ns to do that.

M-x cider-repl-set-ns
or
C-c M-n n

When you run it inside a Clojure file buffer, it will switch the REPL to the current file's namespace.

If you run it from the REPL buffer, it will ask you what namespace you want to switch too.

The documentation for it is:

(cider-repl-set-ns NS)
Switch the namespace of the REPL buffer to NS.
If called from a cljc buffer act on both the Clojure and ClojureScript REPL
if there are more than one REPL present. If invoked in a REPL buffer the
command will prompt for the name of the namespace to switch to.

by
Thanks very much! My post to #owenRiddy showed the code incorporating the use of cider-repl-set-ns. Though it worked manually, I was unable to invoke it without the use of a timer. Is anyone familiar with how to invoke this after the REPL has loaded? Is there an emacs *hook* or *after!* that could be used? Thanks again.
...