Meikel  Brandmeyer avatar Meikel Brandmeyer committed 528d805

Change interface to not read from stdin

Reading from stdin is not possible with nrepl. So we have to pass
everything as properly quoted string literals in some code which
is to be invoked.

For nailgun we still pass on the code via stdin. For nrepl it will
be via the :code key.

Comments (0)

Files changed (5)

nailgun-connector/src/main/clojure/vimclojure/connector/nailgun.clj

 (defn nailgun-driver
   "Entry point for the nailgun connector."
   [#^NGContext ctx]
-  (let [args         (.getArgs ctx)
-        nail         (aget args 0)
-        nail         (let [slash (.indexOf nail "/")
-                           [nspace nail] (if (neg? slash)
-                                           ["vimclojure.nails" nail]
-                                           [(subs nail 0 slash) (subs nail slash)])]
-                       @(resolve (symbol nspace nail)))
-        out          (ByteArrayOutputStream.)
+  (let [out          (ByteArrayOutputStream.)
         err          (ByteArrayOutputStream.)
         encoding     (System/getProperty "clojure.vim.encoding" "UTF-8")
         [clj-in clj-out clj-err] (make-stream-set (.in ctx) out err encoding)
                                *out* clj-out
                                *err* clj-err]
                        (try
-                         (nail (next args))
+                         (eval (read))
                          (catch Throwable e
                            (.printStackTrace e))))]
     (.flush clj-out)

server/src/main/clojure/vimclojure/nails.clj

   'nailContext'."
   [nail usage arguments & body]
   `(defn ~nail
-     [args#]
+     [& args#]
      (util/with-command-line args#
        ~usage
        ~arguments
        ~@body)))
 
 (defnail DocLookup
-  "Usage: ng vimclojure.nails.DocString [options] symbol ..."
-  [[nspace n "Lookup the symbols in the given namespace." "user"]]
-  (let [nspace  (util/resolve-and-load-namespace nspace)]
-    (backend/doc-lookup nspace (read))))
+  "Usage: ng vimclojure.nails.DocString [options] symbol"
+  [[nspace n "Lookup the symbols in the given namespace." "user"]
+   sym]
+  (let [nspace  (util/resolve-and-load-namespace nspace)
+        sym     (symbol (first sym))]
+    (backend/doc-lookup nspace sym)))
 
 (defnail FindDoc
-  "Usage: ng vimclojure.nails.FindDoc"
-  []
-  (backend/find-documentation (.readLine *in*)))
+  "Usage: ng vimclojure.nails.FindDoc pattern"
+  [pattern]
+  (backend/find-documentation (first pattern)))
 
 (defnail JavadocPath
-  "Usage: ng vimclojure.nails.JavadocPath [options]"
-  [[nspace n "Lookup the symbols in the given namespace." "user"]]
+  "Usage: ng vimclojure.nails.JavadocPath [options] class"
+  [[nspace n "Lookup the symbols in the given namespace." "user"]
+   class]
   (let [nspace         (util/resolve-and-load-namespace nspace)
-        our-ns-resolve #(ns-resolve nspace %)]
-    (-> (read)
+        our-ns-resolve #(ns-resolve nspace %)
+        class          (symbol (first class))]
+    (-> class
       our-ns-resolve
       backend/javadoc-path-for-class)))
 
 (defnail SourceLookup
-  "Usage: ng vimclojure.nails.SourceLookup [options]"
-  [[nspace n "Lookup the symbols in the given namespace." "user"]]
+  "Usage: ng vimclojure.nails.SourceLookup [options] symbol"
+  [[nspace n "Lookup the symbols in the given namespace." "user"]
+   source]
   (let [nspace         (util/resolve-and-load-namespace nspace)
-        our-ns-resolve #(ns-resolve nspace %)]
-    (-> (read)
+        our-ns-resolve #(ns-resolve nspace %)
+        source         (symbol (first source))]
+    (-> source
       our-ns-resolve
       backend/get-source
       println)))
 
 (defnail MetaLookup
-  "Usage: ng vimclojure.nails.MetaLookup [options]"
-  [[nspace n "Lookup the symbols in the given namespace." "user"]]
+  "Usage: ng vimclojure.nails.MetaLookup [options] symbol"
+  [[nspace n "Lookup the symbols in the given namespace." "user"]
+   sym]
   (let [nspace         (util/resolve-and-load-namespace nspace)
-        our-ns-resolve #(ns-resolve nspace %)]
-    (-> (read)
+        our-ns-resolve #(ns-resolve nspace %)
+        sym            (symbol (first sym))]
+    (-> sym
       our-ns-resolve
       meta
       util/pretty-print)))
 
 (defnail SourceLocation
-  "Usage: ng vimclojure.nails.SourceLocation [options]"
-  [[nspace n "Lookup the symbols in the given namespace." "user"]]
+  "Usage: ng vimclojure.nails.SourceLocation [options] symbol"
+  [[nspace n "Lookup the symbols in the given namespace." "user"]
+   sym]
   (let [nspace         (util/resolve-and-load-namespace nspace)
-        our-ns-resolve #(ns-resolve nspace %)]
-    (-> (read)
+        our-ns-resolve #(ns-resolve nspace %)
+        sym            (symbol (first sym))]
+    (-> sym
       our-ns-resolve
       backend/source-position)))
 
 (defnail DynamicHighlighting
-  "Usage: ng vimclojure.nails.DynamicHighlighting"
-  []
-  (let [nspace    (read)
+  "Usage: ng vimclojure.nails.DynamicHighlighting namespace"
+  [nspace]
+  (let [nspace    (symbol (first nspace))
         c-c       (the-ns 'clojure.core)
         the-space (util/resolve-and-load-namespace nspace)
         refers    (remove #(= c-c (-> % second meta :ns)) (ns-refers the-space))
               "Variable" (map first vars))))
 
 (defnail NamespaceOfFile
-  "Usage: ng vimclojure.nails.NamespaceOfFile"
-  []
+  "Usage: ng vimclojure.nails.NamespaceOfFile file"
+  [file]
   (let [of-interest '#{in-ns ns clojure.core/in-ns clojure.core/ns}
-        in-seq      (util/stream->seq *in*)
+        in-seq      (-> file
+                      first
+                      util/in-reader
+                      util/stream->seq)
         candidate   (first
                       (drop-while #(or (not (instance? clojure.lang.ISeq %))
                                        (not (contains? of-interest (first %))))
                                                          second
                                                          second))))
 
-(defnail NamespaceInfo
-  "Usage: ng vimclojure.nails.NamespaceInfo"
-  []
-  (println (util/clj->vim (map #(-> % symbol find-ns backend/ns-info)
-                               (line-seq (BufferedReader. *in*))))))
-
 (defnail MacroExpand
-  "Usage: ng vimclojure.nails.MacroExpand [options]"
+  "Usage: ng vimclojure.nails.MacroExpand [options] form"
   [[nspace n "Lookup the symbols in the given namespace." "user"]
-   [one?   o "Expand only the first macro."]]
+   [one?   o "Expand only the first macro."]
+   form]
   (let [nspace (util/resolve-and-load-namespace nspace)
         expand (if one
                  #(macroexpand-1 %)
-                 #(macroexpand %))]
+                 #(macroexpand %))
+        form   (read-string (first form))]
     (binding [*ns* nspace]
-      (-> (read)
+      (-> form
         expand
         util/pretty-print-code))))
 
    [nspace  n "Change to namespace before executing the input." ""]
    [file    f "The filename to be set." "REPL"]
    [line    l "The initial line to be set." "0"]
-   [ignore? I "Ignore the command with respect to *1, *2, *3"]]
+   [ignore? I "Ignore the command with respect to *1, *2, *3"]
+   code]
   (let [id     (Integer/parseInt id)
         line   (Integer/parseInt line)
         nspace (when (not= nspace "")
     (cond
       start {:id (repl/start nspace)}
       stop  (repl/stop id)
-      run   (repl/run id nspace file line ignore))))
+      run   (repl/run (first code) id nspace file line ignore))))
 
 (defnail ReplNamespace
   "Usage: ng vimclojure.nails.Repl [options]"
     (get (get @repl/*repls* id {:ns "user"}) :ns)))
 
 (defnail CheckSyntax
-  "Usage: ng vimclojure.nails.CheckSyntax"
-  [[nspace  n "Change to namespace before executing the input." "user"]]
-  (let [nspace (util/resolve-and-load-namespace nspace)]
+  "Usage: ng vimclojure.nails.CheckSyntax [options] code"
+  [[nspace  n "Change to namespace before executing the input." "user"]
+   code]
+  (let [nspace (util/resolve-and-load-namespace nspace)
+        code   (util/in-reader (first code))]
     (binding [*ns* nspace]
       (try
         (let [eof (Object.)]
           (loop [x nil]
             (if (identical? x eof)
               true
-              (recur (read *in* false eof)))))
+              (recur (read code false eof)))))
         (catch clojure.lang.LispReader$ReaderException exc
           (let [e (.getCause exc)]
             (if (.startsWith (.getMessage e) "EOF while reading")
               (throw exc))))))))
 
 (defnail Complete
-  "Usage: ng vimclojure.nails.Complete"
+  "Usage: ng vimclojure.nails.Complete [options]"
   [[nspace n "Start completion in this namespace." "user"]
    [prefix p "Prefix used for the match, ie. the part before /." ""]
    [base   b "Base pattern to be matched."]]
     (map #(apply util/make-completion-item %) completions)))
 
 (defnail RunTests
-  "Usage: ng vimclojure.nails.RunTests"
+  "Usage: ng vimclojure.nails.RunTests [options]"
   [[nspace n "Run tests in the given namespace." "user"]
    [all?   a "Reload all or only the namespace under test"]]
   (when (not= "user" nspace)

server/src/main/clojure/vimclojure/repl.clj

     clojure.test)
   (:use
     [vimclojure.util :only [resolve-and-load-namespace safe-var-get stream->seq
-                            pretty-print pretty-print-causetrace]])
+                            pretty-print pretty-print-causetrace in-reader]])
   (:import
     clojure.lang.Var
     clojure.lang.Compiler
   Repl is retrieved using the given id. Output goes to *out* and *err*.
   The initial input line and the file are set to the supplied values.
   Ignore flags whether the evaluation result is saved in the star Vars."
-  [id nspace file line ignore]
+  [code id nspace file line ignore]
   (with-repl id nspace file line
     (try
-      (doseq [form (stream->seq *in*)]
+      (doseq [form (stream->seq (in-reader code))]
         (let [result (eval form)]
           ((if vimclojure.repl/*print-pretty* pretty-print prn) result)
           (when-not ignore

vim/src/main/vim/autoload/vimclojure.vim

 		return
 	endif
 
-	let doc = g:vimclojure#Connector.execute("DocLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
+	let doc = g:vimclojure#Connector.execute("DocLookup",
+				\ "-n", b:vimclojure_namespace, a:word)
 	let buf = g:vimclojure#ResultBuffer.New()
 	call buf.showOutput(doc)
 	wincmd p
 
 function! vimclojure#JavadocLookup(word)
 	let word = substitute(a:word, "\\.$", "", "")
-	let path = g:vimclojure#Connector.execute("JavadocPath", word,
-				\ "-n", b:vimclojure_namespace)
+	let path = g:vimclojure#Connector.execute("JavadocPath",
+				\ "-n", b:vimclojure_namespace, word)
 
 	if path.stderr != ""
 		let buf = g:vimclojure#ResultBuffer.New()
 endfunction
 
 function! vimclojure#SourceLookup(word)
-	let source = g:vimclojure#Connector.execute("SourceLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
+	let source = g:vimclojure#Connector.execute("SourceLookup",
+				\ "-n", b:vimclojure_namespace, a:word)
 	let buf = g:vimclojure#ClojureResultBuffer.New(b:vimclojure_namespace)
 	call buf.showOutput(source)
 	wincmd p
 endfunction
 
 function! vimclojure#MetaLookup(word)
-	let meta = g:vimclojure#Connector.execute("MetaLookup", a:word,
-				\ "-n", b:vimclojure_namespace)
+	let meta = g:vimclojure#Connector.execute("MetaLookup",
+				\ "-n", b:vimclojure_namespace, a:word)
 	let buf = g:vimclojure#ClojureResultBuffer.New(b:vimclojure_namespace)
 	call buf.showOutput(meta)
 	wincmd p
 endfunction
 
 function! vimclojure#GotoSource(word)
-	let pos = g:vimclojure#Connector.execute("SourceLocation", a:word,
-				\ "-n", b:vimclojure_namespace)
+	let pos = g:vimclojure#Connector.execute("SourceLocation",
+				\ "-n", b:vimclojure_namespace, a:word)
 
 	if pos.stderr != ""
 		let buf = g:vimclojure#ResultBuffer.New()
 	let [unused, sexp] = vimclojure#ExtractSexpr(0)
 	let ns = b:vimclojure_namespace
 
-	let cmd = ["MacroExpand", sexp, "-n", ns]
+	let cmd = [ "MacroExpand", "-n", ns ]
 	if a:firstOnly
-		let cmd = cmd + [ "-o" ]
+		call add(cmd, "-o")
 	endif
+	call add(cmd, sexp)
 
 	let expanded = call(g:vimclojure#Connector.execute, cmd)
 
 	let all = a:all ? "-all" : ""
 
 	let require = "(require :reload" . all . " :verbose '". ns. ")"
-	let result = g:vimclojure#Connector.execute("Repl", require, "-r")
+	let result = g:vimclojure#Connector.execute("Repl", "-r", require)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	let ns = b:vimclojure_namespace
 
 	let result = call(g:vimclojure#Connector.execute,
-				\ [ "RunTests", "", "-n", ns ] + (a:all ? [ "-a" ] : []))
+				\ [ "RunTests", "-n", ns ] + (a:all ? [ "-a" ] : []))
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	wincmd p
 	let file = vimclojure#BufferName()
 	let ns = b:vimclojure_namespace
 
-	let result = g:vimclojure#Connector.execute("Repl", content,
-				\ "-r", "-n", ns, "-f", file)
+	let result = g:vimclojure#Connector.execute("Repl",
+				\ "-r", "-n", ns, "-f", file, content)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	let file = vimclojure#BufferName()
 	let ns = b:vimclojure_namespace
 
-	let result = g:vimclojure#Connector.execute("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", theLine)
+	let result = g:vimclojure#Connector.execute("Repl",
+				\ "-r", "-n", ns, "-f", file, "-l", theLine, content)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	let ns = b:vimclojure_namespace
 
 	let content = getbufline(bufnr("%"), line("'<"), line("'>"))
-	let result = g:vimclojure#Connector.execute("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", line("'<") - 1)
+	let result = g:vimclojure#Connector.execute("Repl",
+				\ "-r", "-n", ns, "-f", file, "-l", line("'<") - 1, content)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	let ns = b:vimclojure_namespace
 	let [pos, expr] = vimclojure#ExtractSexpr(1)
 
-	let result = g:vimclojure#Connector.execute("Repl", expr,
-				\ "-r", "-n", ns, "-f", file, "-l", pos[0] - 1)
+	let result = g:vimclojure#Connector.execute("Repl",
+				\ "-r", "-n", ns, "-f", file, "-l", pos[0] - 1, expr)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 	let endPosition = vimclojure#util#WithSavedPosition(closure)
 
 	let content = getbufline(bufnr("%"), startPosition, endPosition)
-	let result = g:vimclojure#Connector.execute("Repl", content,
-				\ "-r", "-n", ns, "-f", file, "-l", startPosition - 1)
+	let result = g:vimclojure#Connector.execute("Repl",
+				\ "-r", "-n", ns, "-f", file, "-l", startPosition - 1, content)
 
 	let resultBuffer = g:vimclojure#ClojureResultBuffer.New(ns)
 	call resultBuffer.showOutput(result)
 " FIXME: Ugly hack. But easier than cleaning up the buffer
 " mess in case something goes wrong with repl start.
 function! vimclojure#Repl.New(namespace) dict
-	let replStart = g:vimclojure#Connector.execute("Repl", "", "-s",
+	let replStart = g:vimclojure#Connector.execute("Repl", "-s",
 				\ "-n", a:namespace)
 	if replStart.stderr != ""
 		call vimclojure#ReportError(replStart.stderr)
 	let instance = call(self.__superBufferNew, [a:namespace], self)
 	let instance._id = replStart.value.id
 	call g:vimclojure#Connector.execute("Repl",
-				\ "(require 'clojure.stacktrace)",
-				\ "-r", "-i", instance._id)
+				\ "-r", "-i", instance._id, "(require 'clojure.stacktrace)")
 
 	return instance
 endfunction
 
 function! vimclojure#Repl.doReplCommand(cmd) dict
 	if a:cmd == ",close"
-		call g:vimclojure#Connector.execute("Repl", "", "-S", "-i", self._id)
+		call g:vimclojure#Connector.execute("Repl", "-S", "-i", self._id)
 		call self.close()
 		stopinsert
 	elseif a:cmd == ",st"
 		let result = g:vimclojure#Connector.execute("Repl",
-					\ "(vimclojure.util/pretty-print-stacktrace *e)", "-r",
-					\ "-i", self._id)
+					\ "-r", "-i", self._id,
+					\ "(vimclojure.util/pretty-print-stacktrace *e)")
 		call self.showOutput(result)
 		call self.showPrompt()
 	elseif a:cmd == ",ct"
 		let result = g:vimclojure#Connector.execute("Repl",
-					\ "(vimclojure.util/pretty-print-causetrace *e)", "-r",
-					\ "-i", self._id)
+					\ "-r", "-i", self._id,
+					\ "(vimclojure.util/pretty-print-causetrace *e)")
 		call self.showOutput(result)
 		call self.showPrompt()
 	elseif a:cmd == ",toggle-pprint"
 		let result = g:vimclojure#Connector.execute("Repl",
-					\ "(set! vimclojure.repl/*print-pretty* (not vimclojure.repl/*print-pretty*))", "-r",
-					\ "-i", self._id)
+					\ "-r", "-i", self._id,
+					\ "(set! vimclojure.repl/*print-pretty* (not vimclojure.repl/*print-pretty*))")
 		call self.showOutput(result)
 		call self.showPrompt()
 	endif
 		return
 	endif
 
-	let result = g:vimclojure#Connector.execute("CheckSyntax", cmd,
-				\ "-n", b:vimclojure_namespace)
+	let result = g:vimclojure#Connector.execute("CheckSyntax",
+				\ "-n", b:vimclojure_namespace, cmd)
 	if result.value == 0 && result.stderr == ""
 		call vimclojure#ReplDoEnter()
 	elseif result.stderr != ""
 		let buf = g:vimclojure#ResultBuffer.New()
 		call buf.showOutput(result)
 	else
-		let result = g:vimclojure#Connector.execute("Repl", cmd,
-					\ "-r", "-i", self._id)
+		let result = g:vimclojure#Connector.execute("Repl",
+					\ "-r", "-i", self._id, cmd)
 		call self.showOutput(result)
 
 		let self._historyDepth = 0
 		let self._history = [cmd] + self._history
 
-		let namespace = g:vimclojure#Connector.execute("ReplNamespace", "",
+		let namespace = g:vimclojure#Connector.execute("ReplNamespace",
 					\ "-i", self._id)
 		let b:vimclojure_namespace = namespace.value
 		let self._prompt = namespace.value . "=>"
 			return []
 		endif
 
-		let completions = g:vimclojure#Connector.execute("Complete", "",
+		let completions = g:vimclojure#Connector.execute("Complete",
 					\ "-n", b:vimclojure_namespace,
 					\ "-p", prefix, "-b", base)
 		return completions.value

vim/src/main/vim/autoload/vimclojure/connector/nailgun.vim

 	let vimclojure#connector#nailgun#Port = "2113"
 endif
 
-function! vimclojure#connector#nailgun#Execute(nail, input, ...)
-	if type(a:input) == type("")
-		let input = split(a:input, '\n', 1)
+function! vimclojure#connector#nailgun#Execute(nail, ...)
+	let args = join(map(copy(a:000), 'vimclojure#util#Literalize(v:val)'), " ")
+	if stridx(a:nail, "/") >= 0
+		let nail = a:nail
 	else
-		let input = a:input
+		let nail = "vimclojure.nails/" . a:nail
 	endif
+	let code = "(". nail . " " . args . ")"
 
 	let inputfile = tempname()
 	try
-		call writefile(input, inputfile)
+		call writefile([code], inputfile)
 
 		let cmdline = vimclojure#util#ShellEscapeArguments(
 					\ [g:vimclojure#connector#nailgun#Client,
 					\   g:vimclojure#connector#nailgun#Server,
 					\   '--nailgun-port',
 					\   g:vimclojure#connector#nailgun#Port,
-					\   'vimclojure.Nail', a:nail]
-					\ + a:000)
+					\   'vimclojure.Nail'])
 		let cmd = join(cmdline, " ") . " <" . inputfile
 		" Add hardcore quoting for Windows
 		if has("win32") || has("win64")
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.