Ejemplo n.º 1
0
        static void HandleMessage(BDictionary message, TcpClient client)
        {
            var opValue  = message["op"];
            var opString = opValue as BString;

            if (opString != null)
            {
                var session = GetSession(message);
                switch (opString.ToString())
                {
                case "clone":
                    var newSession = CloneSession(session);
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "status", new BList {
                              "done"
                          } },
                        { "new-session", newSession.ToString() }
                    }, client);
                    break;

                case "describe":
                    // TODO include arcadia version
                    var clojureVersion     = (IPersistentMap)RT.var("clojure.core", "*clojure-version*").deref();
                    var clojureMajor       = (int)clojureVersion.valAt(Keyword.intern("major"));
                    var clojureMinor       = (int)clojureVersion.valAt(Keyword.intern("minor"));
                    var clojureIncremental = (int)clojureVersion.valAt(Keyword.intern("incremental"));
                    var clojureQualifier   = (string)clojureVersion.valAt(Keyword.intern("qualifier"));
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done"
                          } },
                        {
                            "ops",
                            new BDictionary
                            {
                                { "eval", 1 },
                                { "describe", 1 },
                                { "clone", 1 },
                            }
                        },
                        {
                            "versions",
                            new BDictionary
                            {
                                {
                                    "clojure", new BDictionary
                                    {
                                        { "major", clojureMajor },
                                        { "minor", clojureMinor },
                                        { "incremental", clojureIncremental },
                                        { "qualifier", clojureQualifier }
                                    }
                                },
                                {
                                    "nrepl", new BDictionary
                                    {
                                        { "major", 0 },
                                        { "minor", 2 },
                                        { "incremental", 3 }
                                    }
                                }
                            }
                        }
                    }, client);
                    break;

                case "eval":
                    var fn = new EvalFn(message, client);
                    addCallbackVar.invoke(fn);
                    break;

                default:
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done", "error", "unknown-op"
                          } }
                    }, client);
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        static void HandleMessage(BDictionary message, TcpClient client)
        {
            var opValue  = message["op"];
            var opString = opValue as BString;
            var autoCompletionSupportEnabled = RT.booleanCast(((IPersistentMap)configVar.invoke()).valAt(Keyword.intern("nrepl-auto-completion")));

            if (opString != null)
            {
                var session = GetSession(message);
                switch (opString.ToString())
                {
                case "clone":
                    var newSession = CloneSession(session);
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "status", new BList {
                              "done"
                          } },
                        { "new-session", newSession.ToString() }
                    }, client);
                    break;

                case "describe":
                    // TODO include arcadia version
                    var clojureVersion     = (IPersistentMap)RT.var("clojure.core", "*clojure-version*").deref();
                    var clojureMajor       = (int)clojureVersion.valAt(Keyword.intern("major"));
                    var clojureMinor       = (int)clojureVersion.valAt(Keyword.intern("minor"));
                    var clojureIncremental = (int)clojureVersion.valAt(Keyword.intern("incremental"));
                    var clojureQualifier   = (string)clojureVersion.valAt(Keyword.intern("qualifier"));
                    var supportedOps       = new BDictionary {
                        { "eval", 1 },
                        { "load-file", 1 },
                        { "describe", 1 },
                        { "clone", 1 },
                        { "info", 1 },
                        { "eldoc", 1 },
                        { "classpath", 1 },
                    };
                    // Debug.Log("Autocomplete support is enabled?: " + autoCompletionSupportEnabled);
                    if (autoCompletionSupportEnabled)
                    {
                        supportedOps.Add("complete", 1);
                    }
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done"
                          } },
                        { "ops", supportedOps },
                        {
                            "versions",
                            new BDictionary
                            {
                                {
                                    "clojure", new BDictionary
                                    {
                                        { "major", clojureMajor },
                                        { "minor", clojureMinor },
                                        { "incremental", clojureIncremental },
                                        { "qualifier", clojureQualifier }
                                    }
                                },
                                {
                                    "nrepl", new BDictionary
                                    {
                                        { "major", 0 },
                                        { "minor", 2 },
                                        { "incremental", 3 }
                                    }
                                }
                            }
                        }
                    }, client);
                    break;

                case "eval":
                    var fn = new EvalFn(message, client);
                    addCallbackVar.invoke(fn);
                    break;

                case "load-file":
                    message["code"] = new BString("(do " + message["file"].ToString() + " )");
                    var loadFn = new EvalFn(message, client);
                    addCallbackVar.invoke(loadFn);
                    break;

                case "eldoc":
                case "info":

                    String symbolStr = message["symbol"].ToString();

                    // Editors like Calva that support doc-on-hover sometimes will ask about empty strings or spaces
                    if (symbolStr == "" || symbolStr == null || symbolStr == " ")
                    {
                        break;
                    }

                    IPersistentMap symbolMetadata = null;
                    try
                    {
                        symbolMetadata = (IPersistentMap)metaVar.invoke(nsResolveVar.invoke(
                                                                            findNsVar.invoke(symbolVar.invoke(message["ns"].ToString())),
                                                                            symbolVar.invoke(symbolStr)));
                    } catch (TypeNotFoundException) {
                        // We'll just ignore this call if the type cannot be found. This happens sometimes.
                        // TODO: One particular case when this happens is when querying info for a namespace.
                        //       That case should be handled separately (e.g., via `find-ns`?)
                    }


                    if (symbolMetadata != null)
                    {
                        var resultMessage = new BDictionary {
                            { "id", message["id"] },
                            { "session", session.ToString() },
                            { "status", new BList {
                                  "done"
                              } }
                        };

                        foreach (var entry in symbolMetadata)
                        {
                            if (entry.val() != null)
                            {
                                String keyStr = entry.key().ToString().Substring(1);
                                String keyVal = entry.val().ToString();
                                if (keyStr == "arglists")
                                {
                                    keyStr = "arglists-str";
                                }
                                if (keyStr == "forms")
                                {
                                    keyStr = "forms-str";
                                }
                                resultMessage[keyStr] = new BString(keyVal);
                            }
                        }
                        SendMessage(resultMessage, client);
                    }
                    else
                    {
                        SendMessage(
                            new BDictionary
                        {
                            { "id", message["id"] },
                            { "session", session.ToString() },
                            { "status", new BList {
                                  "done", "no-info"
                              } }
                        }, client);
                    }
                    break;

                case "complete":

                    // When autoCompletionSupportEnabled is false, we don't advertise auto-completion support.
                    // some editors seem to ignore this and request anyway, so we return an unknown op message.
                    if (!autoCompletionSupportEnabled)
                    {
                        SendMessage(
                            new BDictionary
                        {
                            { "id", message["id"] },
                            { "session", session.ToString() },
                            { "status", new BList {
                                  "done", "error", "unknown-op"
                              } }
                        }, client);
                        break;
                    }

                    Namespace ns = Namespace.find(Symbol.create(message["ns"].ToString()));
                    var       sessionBindings  = _sessions[session];
                    var       completeBindings = sessionBindings;
                    if (ns != null)
                    {
                        completeBindings = completeBindings.assoc(RT.CurrentNSVar, ns);
                    }

                    // Make sure to eval this in the right namespace
                    Var.pushThreadBindings(completeBindings);
                    BList completions = (BList)completeVar.invoke(message["symbol"].ToString());
                    Var.popThreadBindings();

                    SendMessage(new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done"
                          } },
                        { "completions", completions }
                    }, client);
                    break;

                case "classpath":
                    BList classpath = new BList();
                    foreach (String p in Environment.GetEnvironmentVariable("CLOJURE_LOAD_PATH").Split(System.IO.Path.PathSeparator))
                    {
                        if (p != "")
                        {
                            classpath.Add(Path.GetFullPath(p));
                        }
                    }

                    SendMessage(new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done"
                          } },
                        { "classpath", classpath },
                    }, client);
                    break;

                default:
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done", "error", "unknown-op"
                          } }
                    }, client);
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        static void HandleMessage(BDictionary message, TcpClient client)
        {
            var opValue  = message["op"];
            var opString = opValue as BString;

            if (opString != null)
            {
                var session = GetSession(message);
                switch (opString.ToString())
                {
                case "clone":
                    var newSession = CloneSession(session);
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "status", new BList {
                              "done"
                          } },
                        { "new-session", newSession.ToString() }
                    }, client);
                    break;

                case "describe":
                    // TODO include arcadia version
                    var clojureVersion     = (IPersistentMap)RT.var("clojure.core", "*clojure-version*").deref();
                    var clojureMajor       = (int)clojureVersion.valAt(Keyword.intern("major"));
                    var clojureMinor       = (int)clojureVersion.valAt(Keyword.intern("minor"));
                    var clojureIncremental = (int)clojureVersion.valAt(Keyword.intern("incremental"));
                    var clojureQualifier   = (string)clojureVersion.valAt(Keyword.intern("qualifier"));
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done"
                          } },
                        {
                            "ops",
                            new BDictionary
                            {
                                { "eval", 1 },
                                { "load-file", 1 },
                                { "describe", 1 },
                                { "clone", 1 },
                                { "info", 1 },
                            }
                        },
                        {
                            "versions",
                            new BDictionary
                            {
                                {
                                    "clojure", new BDictionary
                                    {
                                        { "major", clojureMajor },
                                        { "minor", clojureMinor },
                                        { "incremental", clojureIncremental },
                                        { "qualifier", clojureQualifier }
                                    }
                                },
                                {
                                    "nrepl", new BDictionary
                                    {
                                        { "major", 0 },
                                        { "minor", 2 },
                                        { "incremental", 3 }
                                    }
                                }
                            }
                        }
                    }, client);
                    break;

                case "eval":
                    var fn = new EvalFn(message, client);
                    addCallbackVar.invoke(fn);
                    break;

                case "load-file":
                    message["code"] = new BString("(do " + message["file"].ToString() + " )");
                    var loadFn = new EvalFn(message, client);
                    addCallbackVar.invoke(loadFn);
                    break;

                case "info":
                    var symbolMetadata = (IPersistentMap)metaVar.invoke(nsResolveVar.invoke(
                                                                            findNsVar.invoke(symbolVar.invoke(message["ns"].ToString())),
                                                                            symbolVar.invoke(message["symbol"].ToString())));

                    if (symbolMetadata != null)
                    {
                        var resultMessage = new BDictionary {
                            { "id", message["id"] },
                            { "session", session.ToString() },
                            { "status", new BList {
                                  "done"
                              } }
                        };
                        foreach (var entry in symbolMetadata)
                        {
                            if (entry.val() != null)
                            {
                                resultMessage[entry.key().ToString().Substring(1)] =
                                    new BString(entry.val().ToString());
                            }
                        }
                        SendMessage(resultMessage, client);
                    }
                    else
                    {
                        SendMessage(
                            new BDictionary
                        {
                            { "id", message["id"] },
                            { "session", session.ToString() },
                            { "status", new BList {
                                  "done", "no-info"
                              } }
                        }, client);
                    }
                    break;

                default:
                    SendMessage(
                        new BDictionary
                    {
                        { "id", message["id"] },
                        { "session", session.ToString() },
                        { "status", new BList {
                              "done", "error", "unknown-op"
                          } }
                    }, client);
                    break;
                }
            }
        }