Clojure's vars maintain bindings in ThreadLocals[1].  I'm pretty sure
accessing ThreadLocals of other threads can't be done.  Looking at
ThreadLocal and Thread sources, you might be able to dig around
private and package-private fields to get at them.  Generally a bad
idea.

FWIW, the Enclojure REPL is available as a standalone Swing
component[2], which may or may not be a good basis for your work.

Also FWIW, you might want to take a look at nREPL[3], which is an
attempt to provide a common network-capable Clojure REPL (currently
used by ccw and vimclojure AFAIK).  The benefit for you there would be
that the thread-local state of each REPL connection (its "session",
for lack of a better term) can be queried at will, asynchronously from
code that your users might want to send to the REPL.

Cheers,

- Chas

[1] http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
[2] http://www.enclojure.org/The+Enclojure+REPLs+%28Not+just+for+Netbeans!%29
[3] https://github.com/clojure/tools.nrepl

On Dec 30 2010, 11:34 am, Mike <cki...@gmail.com> wrote:
> I'm doing something kind of tricky...I'm running a REPL in my Java
> Swing application.  I do something like:
>
> public class MyConsoleClass extends OurEmbeddedInterpreterClass {
>   // ...
>
>   // inner class
>   private class ReplRunner extends Thread {
>     public void run() {
>       Namespace MYNS = Namespace.findOrCreate(Symbol.create("myns"));
>       Var ACCESS_ME =  Var.intern(MYNS, Symbol.create("*me*"));
>       Var.pushThreadBindings(RT.map(RT.IN, myIn, RT.OUT, myOut,
> RT.ERR, myErr, ACCESS_ME, MyConsoleClass.this);
>       BufferedReader script = getMagicInitScript();
>       Compiler.load(script, getScriptPath(), getScriptFile());
>     }
>   }
>   // ...somewhere, make a ReplRunner and launch it when you're
> supposed to
>
> }
>
> The "magic init script" is what runs the repl.  The ins and outs are
> mapped into Swing components so you can type commands, it passes to
> the repl, and then output comes back to a text pane or the equivalent.
>
> Now, my GUI app puts a KeyListener on the input component so that when
> the TAB key is pressed, it runs a completion routine (Java callback)
> to try to complete your command.  I wrote a function (in Clojure,
> inside the magic init script) that returns all the completions based
> on the current command.  My Java callback looks like:
>
> // a method in MyConsoleClass...CodeCompletion is our own little
> helper struct...
> public List<CodeCompletion> getCompletions(String cmd) {
>   Var getFn = RT.var("myns", "get-completions");
>   try {
>     List<CodeCompletion> result = (List<CodeCompletion>)
> getFn.invoke(cmd);
>     return result;
>   catch(Exception e) { /* handle e omitted */ }
>   return null;
>
> }
>
> The problem is, get-completions uses dir-fn and ns-map to gather
> bindings based on the context of the command.  But it's being invoked
> in the AWT event thread (which calls this getCompletions method), NOT
> the ReplRunner thread that I launch (which is of course just looping
> infinitely waiting on input).  So all the local bindings (including
> *me* that I bound in ReplRunner.run()) are missing from the results.
>
> Does anybody have any ideas how I can jack into the repl thread to
> grab the bindings from it?  I don't think any of Clojure's concurrency
> constructs will help me here, because I need to interfere with a
> thread that's essentially blocked at the time of the (synchronous)
> completion call.
>
> Sorry if this isn't fully specified and hurried...I can't paste the
> code directly here because of NDA.  If you need more details I can
> provide them.
>
> Thanks in advance for any ideas...
> Mike

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to