* Can't we all get along? Breaking barriers between editors The nREPL project has provided a great foundation for building out portable tooling; moving towards editor-agnostic tools has reduced duplicated effort and brought some common ground for everyone to work from. But we're just getting started! Rather than simply supporting eval and stdout responses as primitive building blocks that are invoked by code written in elisp or vimscript, we can build out operations in Clojure and provide easy ways to invoke them from the editor. By defining a baseline vocabulary for Clojure to represent rich response types for the editor, we make it easy to write development tools like tracing, testing, and inspecting once in Clojure and use them as if they were implemented natively for any of the supported editors. And once anyone can extend their editor by just writing Clojure, it opens up possibilities for applications beyond simple dev tooling. ** In the Olden Days - java -cp clojure.jar clojure.main/repl - a dose of rlwrap to ease the pain - swank-clojure and slime - nailgun - custom embeddable socket repls Making some existing functionality invokeable from Emacs used to be a pain in the neck; you'd have to write and distribute a whole Emacs library for it and try to keep the elisp client code in sync with the underlying Clojure code. Did this for Slamhound, but it's a pain. And that's just for Emacs--many other editors don't even have package management repositories. ** nREPL comes along - one server for everyone! and a really good CLI client, bonus! - well-defined, documented protocol - async request/response, sort of ring-like - middleware - clients invoke ops, which are just function - you can spin off a session for another language too - clojurescript - but why not jruby? scala? ** Defining server-side ops - existing built-in ops - eval - complete - stdin - interrupt - describe - load-file - clone - javadoc but those are all boring and low-level! - new, exciting ops - toggle-trace - run-tests - unload-ns - macroexpand - doc - clojuredocs - inspector - slamhound What do these ops look like? - demo writing one - only using println for now ** Describing and Discovering Ops - a "discover" op searches all-ns for specific op metadata - metadata includes details of expected arguments an op requires - wrap-discover middleware does bootstrapping so the ops can be invoked - invoking ops from the client - hard-code all of them? - ...or compile them from server-side metadata descriptions! - how can this work? - cross-runtime metaprogramming! - about 100 lines of elisp - add argument types to our sample op ** Rich Responses - racket envy! - text/html - hyperlinked inspector - stepping debugger? - images - middleware to intercept+render return values - monitoring info? - terrible stack traces - content-disposition - inline - buffer - alert - commands to directly control the editor - reload - position - url - overlay? - add content-type to our sample op ** This lets us delete a bunch of code! - clojure-test-mode: poof - slamhound.el: poof - a bunch of cider's commands: poof ** Not just dev tools! - add a comfortable UI to your end-user Clojure application - mail client? punt the UI to the editor! - chat? search? whatever; it's all good. - caveat: this may actually be insane? - if it's for dev tools only, it's still a pretty big win ** Current status - General middleware works great - assuming the necessary namespaces are loaded; need this to be declarative - Sample ops exist for tools.trace, clojure.test - POC for all response types - Emacs discovery implementation is solid - Emacs response handling is not well-tested - Vim plugin in the works? - CCW is planned?