Giter VIP home page Giter VIP logo

cider's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cider's Issues

nREPL / Emacs error "Unable to resolve symbol: if-let"

Reported on clojure-tools by Stuart Sierra.

Anybody else seeing this error (below) in an nREPL Emacs session? It starts
showing up after working in nREPL for a while. It's something to do with
auto-completion I think, because once it happens it repeats every time I
switch to the nrepl buffer. Only fix is restarting the Java process.
-S

clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable
to resolve symbol: if-let in this context, compiling:(NO_SOURCE_PATH:1)
at clojure.lang.Compiler.analyze (Compiler.java:6281)
clojure.lang.Compiler.analyze (Compiler.java:6223)
clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3497)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6457)
clojure.lang.Compiler.analyze (Compiler.java:6262)
clojure.lang.Compiler.analyze (Compiler.java:6223)
clojure.lang.Compiler$BodyExpr$Parser.parse (Compiler.java:5618)
clojure.lang.Compiler$FnMethod.parse (Compiler.java:5054)
clojure.lang.Compiler$FnExpr.parse (Compiler.java:3674)
clojure.lang.Compiler.analyzeSeq (Compiler.java:6453)
clojure.lang.Compiler.analyze (Compiler.java:6262)
clojure.lang.Compiler.eval (Compiler.java:6508)
clojure.lang.Compiler.eval (Compiler.java:6477)
clojure.core$eval.invoke (core.clj:2797)
clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
clojure.main$repl$fn__6410.invoke (main.clj:266)
clojure.main$repl.doInvoke (main.clj:266)
clojure.lang.RestFn.invoke (RestFn.java:1096)

clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__768.invoke
(interruptible_eval.clj:57)
clojure.lang.AFn.applyToHelper (AFn.java:159)
clojure.lang.AFn.applyTo (AFn.java:151)
clojure.core$apply.invoke (core.clj:601)
clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
clojure.lang.RestFn.invoke (RestFn.java:425)
clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke
(interruptible_eval.clj:42)

clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__809$fn__811.invoke
(interruptible_eval.clj:170)
clojure.core$comp$fn__4034.invoke (core.clj:2278)

clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__802.invoke
(interruptible_eval.clj:137)
clojure.lang.AFn.run (AFn.java:24)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask
(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java:908)
java.lang.Thread.run (Thread.java:680)

Details:

  • Clojure 1.4.0
  • nrepl.el 0.1.4
  • Leiningen 2.0.0-SNAPSHOT at 96bf2a20bf8305e4cc340eadf7bfd1165c08e863
  • Emacs 23.3.50.1 (Aquamacs 2.4)

Entire thread is here:
https://groups.google.com/forum/?fromgroups=#!topic/clojure-tools/RigTCB6_Ako

not all project.clj dependencies ending up on the classpath

When I am in the project directory (generated by leiningen 2), this works:

lein repl
(use '(incanter core stats charts))
(view (xy-plot))

If I do lein repl
(use '(incanter core stats charts))

and then use M-x nrepl from emacs,
(view (xy-plot))
also works as expected

However, when I use nrepl-jack-in in emacs
(use '(incanter core stats charts))
gives me an error that indicates (correctly) that incanter charts is not on the classpath.

Is there some way that I need to tell nrepl to reload the whole classpath?

by the way, this is the project.clj file
(defproject plot-metapop "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]
[org.clojure/tools.nrepl "0.2.0-beta9"]
[incanter/incanter-core "1.3.0"]
[incanter/incanter-charts "1.3.0"]])

I am using nrepl 0.1.3, emacs23, linux distribution is RHEL 6.3, and java version
Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03, mixed mode)

Persistent REPL History

When opening an nrepl session it is convenient to have the history of previous REPL sessions.

Suggestions:

  • Custom variable for file name of history, defaulting to "~/.nrepl-history.eld"
  • Custom variable for the maximum size of the history defaulting to 500
  • Saving of history would be done via kill-buffer-hook, function is attached during nrepl-mode setup in define-derived-mode ...
  • Whenever the current session history is to be saved, it is merged with the history from the file which is re-read at save-time for this.

This mimics most of the things I wrote for the persistent history of SLIME ages ago :-)

Open questions:

  • Would this need a custom variable for the coding system?
  • Is there any reasonable way to use the current project for the history? E.g. save several histories on a per project basis or sort items from the current project automatically to the top of the list?

Cleaner handler declaration

You should be able to write a handler that just handles value and have default handlers for out, err, and done.

paredit curly brace workaround

clojure-mode has a workaround to add paredit bindings for { and } when paredit is enabled, but since we have our own major mode now they don't apply any more.

REPL variables *1 and friends get corrupted by argument lists

If you wait for the display of arglists (via eldoc) your magic REPL variables get corrupted:

user> (+ 4 5) ;; wait for eldoc
9
user> *2
([] [x] [x y] [x y & more])

versus

;; type fast
(+ 1 1)
2
user> (+ 4 5)
9
user> *2
2

Don't know whether this is nrepl.el-specific.

All output should go to the *nrepl* buffer instead of the mini buffer

Hi,
I have been using swank clojure for some time now and think that a lot of users coming from slime are used to
having all output going to the repl buffer. It would be very nice and convenient if nrepl would also allow stdout to appear in the
nrepl buffer.

Many Greetings
JOhn

tab completion fails for a piggieback cljs repl

When in a cljs repl using cemerick/piggieback tab completion always returns "No match".

Quoting @cemerick

it should either (a) use a different session for tooling stuff, or (b) stop using "eval" and work towards a common introspection middleware.

piggieback hijacks "eval" for cljs, so Clojure stuff sent on the same session that is running cljs/piggieback won't work

While (a) might be a good idea, I'm not sure it will let me tab complete clojurescript.

Error message when lein not found gives little clue that this is the source of the error

Trying to set up nrepl.el a short while ago, I tried running M-x nrepl-jack-in on a buffer for a file in my project. It got this error:

Debugger entered--Lisp error: (error "Could not start nREPL server: Wrong number of arguments to repl task. 
Expected ([] [project])
")
  signal(error ("Could not start nREPL server: Wrong number of arguments to repl task. \nExpected ([] [project])\n"))
  error("Could not start nREPL server: %s" "Wrong number of arguments to repl task. \nExpected ([] [project])\n")
  nrepl-server-sentinel(#<process nrepl-server> "exited abnormally with code 1\n")

The problem is that my lein command was pointing to lein1, and not lein2. Once I renamed them, nrepl-jack-in worked.

Apropos functionality

Is someone working with apropos? I mean specifically something on par with slime-apropos-package and slime-apropos.

I'm thinking about working on these, and was looking for some pointers as to how to proceed.

Support for multiple REPLs

Currently, running M-x nrepl multiple times opens multiple REPL buffers, but all commands use only the buffer named *nrepl*.

nrepl.el should support working with multiple REPLs, like slime does. A simple function for switching between them should be enough.

Reloading

I have a branch for this in my fork, but it's pretty preliminary. It does do full reloading though, which clears out the contents of the current namespace and forces all required namespaces to be reloaded, albeit by a bit of a hack.

Inspector

I want to pull the inspector out of swank-clojure and package it up as an independent tool we can use.

datomic decode error

returning the datomic database collection results in a error in process filter: Cannot decode object: 2

minimal test is:

(def uri "datomic:mem://testdb") 
(create-database uri)
(db (connect uri))

nrepl.el breaks paredit keybindings

After nrepl-jack-in, some of paredit's keybindings in the clojure buffers are reset.
e.g. BACKSPACE is bound to 'paredit-backward-delete', but after nrepl-jack-in, the binding is reset to 'backward-delete-char-untabify'

Pukes on large structures returned

This is on "GNU Emacs 24.1.1 (i686-pc-linux-gnu, GTK+ Version 2.24.10)\n of 2012-07-25 on localhost"

Using Leiningen 2.0.0-preview7 on Java 1.6.0_22 Java HotSpot(TM) Client VM

I start the repl with this:

lein2 trampoline repl :headless

I start nrepl.el with M-x nrepl RET 7777 RET.

I type this in the repl:

(cp)

Which is a little utility that is this:

(defn cp []
  (clojure.string/split (System/getProperty "java.class.path") #":"))

And I get this stacktrace from emacs:

Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
  goto-char(nil)
  (let ((start (point)) (end (byte-to-position (+ (position-bytes (point)) (string-to-number (match-string 1)))))) (goto-char end) (buffer-substring-no-properties start end))
  (cond ((looking-at "i\\([0-9]+\\)e") (goto-char (match-end 0)) (string-to-number (match-string 1))) ((looking-at "\\([0-9]+\\):") (goto-char (match-end 0)) (let ((start (point)) (end (byte-to-position (+ (position-bytes ...) (string-to-number ...))))) (goto-char end) (buffer-substring-no-properties start end))) ((looking-at "l") (goto-char (match-end 0)) (let (result item) (while (setq item (nrepl-bdecode-buffer)) (setq result (cons item result))) (nreverse result))) ((looking-at "d") (goto-char (match-end 0)) (let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))) ((looking-at "e") (goto-char (match-end 0)) nil) (t (error "Cannot decode object: %d" (point))))
  nrepl-bdecode-buffer()
  (setq item (nrepl-bdecode-buffer))
  (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item)))
  (let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))
  (cond ((looking-at "i\\([0-9]+\\)e") (goto-char (match-end 0)) (string-to-number (match-string 1))) ((looking-at "\\([0-9]+\\):") (goto-char (match-end 0)) (let ((start (point)) (end (byte-to-position (+ (position-bytes ...) (string-to-number ...))))) (goto-char end) (buffer-substring-no-properties start end))) ((looking-at "l") (goto-char (match-end 0)) (let (result item) (while (setq item (nrepl-bdecode-buffer)) (setq result (cons item result))) (nreverse result))) ((looking-at "d") (goto-char (match-end 0)) (let (dict key item) (while (setq item (nrepl-bdecode-buffer)) (if key (setq dict (cons (cons key item) dict) key nil) (unless (stringp item) (error "Dictionary keys have to be strings: %s" item)) (setq key item))) (cons (quote dict) (nreverse dict)))) ((looking-at "e") (goto-char (match-end 0)) nil) (t (error "Cannot decode object: %d" (point))))
  nrepl-bdecode-buffer()
  (cons (nrepl-bdecode-buffer) result)
  (setq result (cons (nrepl-bdecode-buffer) result))
  (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result)))
  (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))
  (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result)))
  (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (with-current-buffer temp-buffer (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*"))) (with-current-buffer temp-buffer (unwind-protect (progn (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons ... result))) (nreverse result))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (with-temp-buffer (save-excursion (insert str)) (let ((result (quote nil))) (while (not (eobp)) (setq result (cons (nrepl-bdecode-buffer) result))) (nreverse result)))
  nrepl-decode("d2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:[\"/home/localkens/clojure/src/test-cljs3/test\" \"/home/localkens/clojure/src/test-cljs3/src\" \"/home/localkens/clojure/src/test-cljs3/dev-resources\" \"/home/localkens/clojure/src/test-cljs3/resources\" \"/home/localkens/clojure/src/test-cljs3/target/classes\" \"/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar\" \"/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar\" \"/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar\" \"/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar\" \"/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar\" \"/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar\" \"/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar\" \"/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar\" \"/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar\" \"/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar\" \"/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar\" \"/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar\" \"/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar\" \"/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar\" \"/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar\" \"/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar\" \"/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar\" \"/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar\" \"/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar\" \"/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar\" \"/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar\" \"/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar\" \"/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar\" \"/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar\" \"/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar\" \"/home/lken/.m2/repository/common")
  (let ((responses (nrepl-decode string))) (dolist (response responses) (nrepl-dispatch response)))
  nrepl-filter(#<process nrepl> "d2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:[\"/home/localkens/clojure/src/test-cljs3/test\" \"/home/localkens/clojure/src/test-cljs3/src\" \"/home/localkens/clojure/src/test-cljs3/dev-resources\" \"/home/localkens/clojure/src/test-cljs3/resources\" \"/home/localkens/clojure/src/test-cljs3/target/classes\" \"/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar\" \"/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar\" \"/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar\" \"/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar\" \"/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar\" \"/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar\" \"/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar\" \"/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar\" \"/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar\" \"/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar\" \"/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar\" \"/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar\" \"/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar\" \"/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar\" \"/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar\" \"/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar\" \"/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar\" \"/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar\" \"/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar\" \"/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar\" \"/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar\" \"/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar\" \"/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar\" \"/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar\" \"/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar\" \"/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar\" \"/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar\" \"/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar\" \"/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar\" \"/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar\" \"/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar\" \"/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar\" \"/home/lken/.m2/repository/common")
  recursive-edit()
  debug(error (error "Register doesn't contain a buffer position or configuration"))
  signal(error ("Register doesn't contain a buffer position or configuration"))
  error("Register doesn't contain a buffer position or configuration")
  jump-to-register(109 nil)
  call-interactively(jump-to-register nil nil)

However, smaller data structures do not cause nrepl.el to puke. Only these large ones do.

A network trace of the actual on-the-wire interaction between nrepl.el and lein2 is this:



ed2:id1:22:ns4:user7:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b5:value4275:["/home/localkens/clojure/src/test-cljs3/test" "/home/localkens/clojure/src/test-cljs3/src" "/home/localkens/clojure/src/test-cljs3/dev-resources" "/home/localkens/clojure/src/test-cljs3/resources" "/home/localkens/clojure/src/test-cljs3/target/classes" "/home/lken/.m2/repository/org/clojure/java.classpath/0.1.0/java.classpath-0.1.0.jar" "/home/lken/.m2/repository/clj-stacktrace/clj-stacktrace/0.2.4/clj-stacktrace-0.2.4.jar" "/home/lken/.m2/repository/ring/ring/1.1.0/ring-1.1.0.jar" "/home/lken/.m2/repository/org/mindrot/jbcrypt/0.3m/jbcrypt-0.3m.jar" "/home/lken/.m2/repository/ns-tracker/ns-tracker/0.1.1/ns-tracker-0.1.1.jar" "/home/lken/.m2/repository/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar" "/home/lken/.m2/repository/org/eclipse/jetty/orbit/javax.servlet/2.5.0.v201103041518/javax.servlet-2.5.0.v201103041518.jar" "/home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.0.0/jackson-dataformat-smile-2.0.0.jar" "/home/lken/.m2/repository/org/clojure/data.json/0.1.2/data.json-0.1.2.jar" "/home/lken/.m2/repository/ring/ring-devel/1.1.0/ring-devel-1.1.0.jar" "/home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.0.0/jackson-core-2.0.0.jar" "/home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.0-beta7/tools.nrepl-0.2.0-beta7.jar" "/home/lken/.m2/repository/clout/clout/1.0.1/clout-1.0.1.jar" "/home/lken/.m2/repository/org/clojure/clojure-contrib/1.2.0/clojure-contrib-1.2.0.jar" "/home/lken/.m2/repository/org/clojure/core.incubator/0.1.0/core.incubator-0.1.0.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpclient/4.1.2/httpclient-4.1.2.jar" "/home/lken/.m2/repository/ring/ring-core/1.1.0/ring-core-1.1.0.jar" "/home/lken/.m2/repository/clj-http/clj-http/0.3.5/clj-http-0.3.5.jar" "/home/lken/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" "/home/lken/.m2/repository/noir/noir/1.3.0-beta8/noir-1.3.0-beta8.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpcore/4.1.2/httpcore-4.1.2.jar" "/home/lken/.m2/repository/cheshire/cheshire/3.1.0/cheshire-3.1.0.jar" "/home/lken/.m2/repository/ring/ring-jetty-adapter/1.1.0/ring-jetty-adapter-1.1.0.jar" "/home/lken/.m2/repository/org/clojure/tools.logging/0.1.2/tools.logging-0.1.2.jar" "/home/lken/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar" "/home/lken/.m2/repository/org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar" "/home/lken/.m2/repository/slingshot/slingshot/0.10.2/slingshot-0.10.2.jar" "/home/lken/.m2/repository/clj-time/clj-time/0.3.7/clj-time-0.3.7.jar" "/home/lken/.m2/repository/hiccup/hiccup/1.0.0/hiccup-1.0.0.jar" "/home/lken/.m2/repository/org/clojure/clojure/1.4.0/clojure-1.4.0.jar" "/home/lken/.m2/repository/clojure-complete/clojure-complete/0.2.1/clojure-complete-0.2.1.jar" "/home/lken/.m2/repository/org/thnetos/cd-client/0.3.4/cd-client-0.3.4.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-http/7.6.1.v20120215/jetty-http-7.6.1.v20120215.jar" "/home/lken/.m2/repository/utilza/utilza/0.1.0-SNAPSHOT/utilza-0.1.0-SNAPSHOT.jar" "/home/lken/.m2/repository/compojure/compojure/1.0.4/compojure-1.0.4.jar" "/home/lken/.m2/repository/commons-codec/commons-codec/1.5/commons-codec-1.5.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-util/7.6.1.v20120215/jetty-util-7.6.1.v20120215.jar" "/home/lken/.m2/repository/bultitude/bultitude/0.1.5/bultitude-0.1.5.jar" "/home/lken/.m2/repository/joda-time/joda-time/2.0/joda-time-2.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-server/7.6.1.v20120215/jetty-server-7.6.1.v20120215.jar" "/home/lken/.m2/repository/org/clojure/tools.namespace/0.1.0/tools.namespace-0.1.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-io/7.6.1.v20120215/jetty-io-7.6.1.v20120215.jar" "/home/lken/.m2/repository/org/timmc/handy/1.2.0/handy-1.2.0.jar" "/home/lken/.m2/repository/ring/ring-servlet/1.1.0/ring-servlet-1.1.0.jar" "/home/lken/.m2/repository/org/apache/httpcomponents/httpmime/4.1.2/httpmime-4.1.2.jar" "/home/lken/.m2/repository/commons-fileupload/commons-fileupload/1.2.1/commons-fileupload-1.2.1.jar" "/home/lken/.m2/repository/com/ashafa/clutch/0.3.0/clutch-0.3.0.jar" "/home/lken/.m2/repository/org/eclipse/jetty/jetty-continuation/7.6.1.v20120215/jetty-continuation-7.6.1.v20120215.jar"]ed2:id1:27:session36:e7b89943-dd3f-4b31-92d0-b13860cbe93b6:statusl4:doneee

The same data structure does NOT crash lein2 when executed from this:

lein2 repl :connect 7777

So it seems to be a problem with nrepl.el, or perhaps with emacs itself.

Fails to print things

I was using nrepl.el in the clojail project and tried to evaluate one of the testers and got this:

error in process filter: let: Wrong type argument: integer-or-marker-p, nil
error in process filter: Wrong type argument: integer-or-marker-p, nil
error in process filter: cond: Cannot decode object: 1
error in process filter: Cannot decode object: 1

To reproduce, nrepl-jack-in to the clojail project, load clojail.testers, and then try to evaluate secure-tester. This prints fine in SLIME, but not in nrepl.el.

Excellent work on this btw. You're my new best friend.

ido-style var selection

Imagine that vars are files and namespaces are directories. If you give M-. a prefix argument (or if the point isn't on a symbol) then it should prompt for a var much like ido-find-file. Documentation lookup should work the same way, as should all commands that operate on vars.

Create jump-to-resource function

The idea here is that if you have a resource being loaded off the classpath (say by clojure.java.io/resource, but it could also be by something like enlive's deftemplate) that you should be able to jump to it with a single keystroke.

It's possible that the existing M-. functionality could be enhanced to do this as long as there's no ambiguity. Perhaps if M-. is invoked when the point is on a string, it could be interpreted as a classpath lookup? We'd also want it to work on namespaces I think, which would be on symbols, but maybe that's separate.

tab completion fails for namespaced vars when some nrepl-middleware is present

Using the middleware stack from piggieback:

:injections [(require 'cemerick.piggieback)]
:nrepl-handler (-> clojure.tools.nrepl.server/unknown-op
          clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval
                  cemerick.piggieback/wrap-cljs-repl
                  clojure.tools.nrepl.middleware.pr-values/pr-values
                  clojure.tools.nrepl.middleware.session/add-stdin
                  clojure.tools.nrepl.middleware.session/session)

then when in a normal clojure nrepl tab completing namespaced vars throws an exception.

clojure.core/su<tab> throws:

java.lang.ClassNotFoundException: clojure.core
 at java.net.URLClassLoader$1.run (URLClassLoader.java:217)
    java.security.AccessController.doPrivileged (AccessController.java:-2)
    java.net.URLClassLoader.findClass (URLClassLoader.java:205)
    clojure.lang.DynamicClassLoader.findClass (DynamicClassLoader.java:61)
    java.lang.ClassLoader.loadClass (ClassLoader.java:321)
    java.lang.ClassLoader.loadClass (ClassLoader.java:266)
    java.lang.Class.forName0 (Class.java:-2)
    java.lang.Class.forName (Class.java:264)
    clojure.lang.RT.classForName (RT.java:2039)
    clojure.lang.Compiler.maybeResolveIn (Compiler.java:6789)
    clojure.core$ns_resolve.invoke (core.clj:3883)
    clojure.core$ns_resolve.invoke (core.clj:3880)
    clojure.core$resolve.invoke (core.clj:3889)
    complete.core$resolve_class.invoke (core.clj:83)
    complete.core$eval669$fn__670.invoke (core.clj:100)
    clojure.lang.MultiFn.invoke (MultiFn.java:167)
    complete.core$completions.invoke (core.clj:124)
    user$eval2547.invoke (NO_SOURCE_FILE:1)
    clojure.lang.Compiler.eval (Compiler.java:6511)
    clojure.lang.Compiler.eval (Compiler.java:6477)
    clojure.core$eval.invoke (core.clj:2797)
    clojure.main$repl$read_eval_print__6405.invoke (main.clj:245)
    clojure.main$repl$fn__6410.invoke (main.clj:266)
    clojure.main$repl.doInvoke (main.clj:266)
    clojure.lang.RestFn.invoke (RestFn.java:1096)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__337.invoke (interruptible_eval.clj:51)
    clojure.lang.AFn.applyToHelper (AFn.java:159)
    clojure.lang.AFn.applyTo (AFn.java:151)
    clojure.core$apply.invoke (core.clj:601)
    clojure.core$with_bindings_STAR_.doInvoke (core.clj:1771)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke (interruptible_eval.clj:36)
    clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__374$fn__376.invoke (interruptible_eval.clj:164)
    clojure.core$comp$fn__4034.invoke (core.clj:2278)
    clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__367.invoke (interruptible_eval.clj:131)
    clojure.lang.AFn.run (AFn.java:24)
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1110)
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:603)
    java.lang.Thread.run (Thread.java:679)

Tracing

Slime's tracing functionality is invaluable. Supposedly clojure.tools.trace implements something similar; perhaps we can use that.

Process project's repl-options

It would be nice if the project's init and init-ns settings were processed in the same way that REPL-y processes them.

completion with :headless and full namespaces throws ClassNotFoundException

I get a ClassNotFoundException when I try to use completion with nrepl-jack-in and full namespaces.

To reproduce the problem just:

  1. Start emacs
  2. Run nrepl-jack-in
  3. Type clojure.core/rang<tab> in the repl
  4. When you hit tab, you should complete to clojure.core/range but instead you get a ClassNotFoundException for clojure.core.

I'm not skilled enough to fix this with something other than sticking (setq nrepl-server-command "lein repl") in my init.el but I've gathered some info that should help someone:

If I start lein repl :headless and connect to it with nrepl-el, completions continue to not work, but if I connect to the headless nrepl server with lein repl :connect <port>, then completions in nrepl.el will start to work.

Also, I wiresharked "lein repl :connect" connecting to a :headless repl. lein repl :connect sends a bunch of code to the nrepl server when starting up. When I ran that code into my nrepl.el session, the completion problem went away.

Convert nrepl-interaction-mode to a major mode

Perhaps nrepl-interaction-mode should be a major mode derived from clojure-mode instead of a minor mode. From the Elisp info pages:

A minor mode is not usually meant as a variation of a single major
mode. Usually they are general and can apply to many major modes. For
example, Auto Fill mode works with any major mode that permits text
insertion. To be general, a minor mode must be effectively independent
of the things major modes do.

Will it ever be useful to enable nrepl-interaction-mode on a non-clojure-mode buffer?

*nREPL error* buffer autofocus

Currently (I use nrepl-20120912.248) when a code evaluated in REPL
raises an exception, a nREPL error buffer opens and becomes
focused.

A lot of times there is no need to make anything in nREPL error
buffer, the visible data is enough. Also It seems to me inconsistent
with other Emacs behaviours when an auxiliary buffer does not get
focused automatically.

Let's remove that autofocus.

Literate programming with org-babel (ob-clojure.el) is broken under nrepl

For those people (like myself) who do a lot of Literate Programming in Emacs using Clojure and org-babel, migrating to nrepl and nrepl.el is somewhat non-trivial. This is because the existing Clojure support in org-babel (ob-clojure.el) relies on slime and swank-clojure when running org-babel-execute-src-block (which redirects to org-babel-execute:clojure in ob-clojure.el).

So clearly this is actually an issue for both nrepl.el and ob-clojure.el, not simply one or the other. All the same, I've hacked together a simple workaround that fixes the problem and makes Literate Programming under nrepl possible once again. If there is some slick way this could be worked into nrepl.el's codebase that wouldn't break its existing behavior (as this does), I'd be excited to see it.

Here we go:

;; Patch result table rendering bug in ob-clojure (NREPL version)
(defun nrepl-send-request-sync (request)
  "Send a request to the backend synchronously (discouraged).
The result is a plist with keys :value, :stderr and :stdout."
  (with-current-buffer "*nrepl-connection*"
    (setq nrepl-sync-response nil)
    (nrepl-send-request request (nrepl-sync-request-handler (current-buffer)))
    (while (not (plist-get nrepl-sync-response :done))
      (accept-process-output))
    nrepl-sync-response))

(defun org-babel-execute:clojure (body params)
  "Execute a block of Clojure code with Babel."
  (let ((result-plist (nrepl-send-string-sync (org-babel-expand-body:clojure body params) nrepl-buffer-ns))
        (result-type  (cdr (assoc :result-type params))))
    (org-babel-script-escape
     (cond ((eq result-type 'value)  (plist-get result-plist :value))
           ((eq result-type 'output) (plist-get result-plist :value))
           (t                        (message "Unknown :results type!"))))))

Multiple connections?

If we intend to allow multiple active connections, then each buffer will need to be associated with a connection, and each connection should be associated with a project root.

If we don't intend to allow multiple connections, then connecting when you're already connected should close the existing connection.

NPE for completion when ns noad yet loaded

Hi,

after nrepl-jack-in (or connecting to an already running "lein repl"), without loading the current namespace (e.g. "testproject.core) I get an NPE when trying to complete a symbol. In this case I tried to complete "bindi" which should yield "binnding".

user=> Exception in thread "nREPL-worker-1" java.lang.NullPointerException
at clojure.core$refer.doInvoke(core.clj:3779)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_lib.doInvoke(core.clj:5279)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:605)
at clojure.core$use.doInvoke(core.clj:5392)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.main$repl.doInvoke(main.clj:259)
at clojure.lang.RestFn.invoke(RestFn.java:1096)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__1311.invoke(interruptible_eval.clj:51)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:601)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1771)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.tools.nrepl.middleware.interruptible_eval$evaluate.invoke(interruptible_eval.clj:36)
at clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__1348$fn__1350.invoke(interruptible_eval.clj:162)
at clojure.core$comp$fn__4034.invoke(core.clj:2278)
at clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__1341.invoke(interruptible_eval.clj:129)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

After compilation of the file (C-c C-k), everything works fine.

Regards,
Stefan

Command to 'in-ns' into current buffer namespace

nrepl.el does not always (I actually can't grasp a full pattern here) understand what is the namespace of the buffer I'm currently in. If I evaluate *ns* for example it returns the user namespace. In this case I have to go to the top of the file and evaluate the ns declaration. From that moment this buffer clearly knows its namespace and remembers it when switching buffers back and forth.

I don't know the technology behind recognizing buffer's namespace but I'll be OK with a command that changes the nrepl-interaction-mode's namespace to current buffer's one.

Implement completion

We should have everything we need on the Clojure side from the clojure-complete library brought in by lein repl, but we should check to see if it's loaded first since it's possible folks could be using nrepl.el to connect to nrepl servers embedded in other contexts.

Once completion is in place I would feel comfortable recommending nrepl.el over slime for general use. I'd love to see reload-all support, the inspector, and swank.core/break ported too, but I consider those more as nice-to-haves rather than essentials.

Port slime-words-of-encouragement

There's nothing like being greeted with "Take this REPL, brother; may it serve you well." when you start your hacking. We should start a thread on the Clojure mailing list taking suggestions for other phrases too.

Not working under emacs 23

completion-at-point-functions variable was introduced in emacs 24. nrepl.el uses it now, so it seems to be broken for 23. If somebody confirms that then README should be updated (remove "support 23").

C-x C-e does not use the buffer's namespace

When using nrepl-interactive-eval, nrepl-interactive-eval-print from a clojure file buffer, the clojure namespace is not interpreted, and the repl namespace is used. The namespace form in the buffer should be used to interpret the buffer's namespace, so that expressions are evaluated in the correct namespace.

Send output from all threads to nrepl buffer

@metajack reported this against #81. I am not sure if/now we can support this, but I am creating this issue to track it separately.

From #81:
Say you launch a thread that outputs to stdout. In slime/swank, this output appears in the swank buffer instead of the slime repl buffer. Only output from the current thread in the repl appears in the repl buffer by default. You can override this by doing alter-var-root!, but it's quite annoying, and you see people asking where their output went occasionally.

This is also the current behavior in nrepl as well, which you can see by running:

(.start (Thread. #(println "foo")))

This will print only in the nrepl-server buffer.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.