summaryrefslogtreecommitdiff
path: root/vim/bundle/slimv/swank-clojure/swank/core/protocol.clj
blob: 409d189b7cc745bea3cb08f9db3338838d2b9dfd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(ns swank.core.protocol
  (:use (swank util)
        (swank.util io))
  (:require swank.rpc))

;; Read forms
(def #^{:private true}
     namespace-re #"(^\(:emacs-rex \([a-zA-Z][a-zA-Z0-9]+):")

(defn- fix-namespace
  "Changes the namespace of a function call from pkg:fn to ns/fn. If
   no pkg exists, then nothing is done."
  ([text] (.replaceAll (re-matcher namespace-re text) "$1/")))

(defn write-swank-message
  "Given a `writer' (java.io.Writer) and a `message' (typically an
   sexp), encode the message according to the swank protocol and
   write the message into the writer."
  ([#^java.io.Writer writer message]
     (swank.rpc/encode-message writer message)) 
  {:tag String})

(def read-fail-exception (Exception. "Error reading swank message"))

(defn read-swank-message
  "Given a `reader' (java.io.Reader), read the message as a clojure
   form (typically a sexp). This method will block until a message is
   completely transfered.

   Note: This function will do some amount of Common Lisp -> clojure
   conversions. This is due to the fact that several slime functions
   like to treat everything it's talking to as a common lisp
   implementation.
     - If an :emacs-rex form is received and the first form contains a
       common lisp package designation, this will convert it to use a
       clojure designation.
     - t will be converted to true

   See also `write-swank-message'."
  ([#^java.io.Reader reader]
     (let [len  (Integer/parseInt (read-chars reader 6 read-fail-exception) 16)
           msg  (read-chars reader len read-fail-exception)
           form (try
                  (read-string (fix-namespace msg))
                  (catch Exception ex
                    (.println System/err (format "unreadable message: %s" msg))
                    (throw ex)))]
       (if (seq? form)
         (deep-replace {'t true} form)
         form))))