technomancy / swank-clojure

Swank/slime support for clojure
Eclipse Public License 1.0
412 stars 83 forks source link

A unicode character which blows up the Slime connection #57

Closed maxweber closed 13 years ago

maxweber commented 13 years ago

Hi,

I use swank-clojure 1.4.0-SNAPSHOT. At the moment I'm using Clojure to fetch some emails from a Google Mail account via the JavaMail API. In one of the standard Google welcome emails is a unicode character which blows up my Slime connection, for example when I use the function slurp to get the text data from an InputStream of a javax.mail.BodyPart. However this also happens if I read the character from a text file. The Unicode character is: C2AA Nevertheless I would like to mention that I have also experienced a similar error last week, while I were fetching JSON data from the Google Calendar API. It would be great if this error would be fixed, at the moment I have to write the corresponding result into a file each and every time, if I like to look at its content.

Best regards

Max

The error log:

Debugger entered--Lisp error: (end-of-file) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("000025(:write-string \"\"ª\"\n\" :repl-result)000016(:return (:ok nil) 13)" 0 72 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("000025(:write-string \"\"ª\"\n\" :repl-result)000015(:return (:ok nil) 6)" 0 71 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("000025(:write-string \"\"�\"\n\" :repl-result)000015(:return (:ok nil) 8)" 0 72 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000023(:write-string \"nil\n\" :repl-result)000016(:return (:ok nil) 18)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000016(:return (:ok nil) 17)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("000334(:write-string \"\"You can import your contacts and mail from Yahoo!, Hotmail, AOL, and many\r\nother web mail or POP accounts. If you want, we'll even keep importing your\r\nmail for the next 30 days.\r\n Import contacts and mail\r\n�https://mail.google.com/mail/#settings/accounts\r\n\r\nWe know it can be a pain to switch email accounts, and we hope this makes\r\nthe transition to Google Mail a bit easier.\r\n\r\n- The Google Mail Team\r\n\r\nPlease note that importing is not available if you're using Internet\r\nExplorer 6.0. To take advantage of the latest Google Mail features,\r\nplease upgrade\r\nto a fully supported\r\nbrowserhttp://mail.google.com/support/bin/answer.py?answer=6557&hl=en&utm_source=wel-eml&utm_medium=eml&utm_campaign=en\r\n.\r\n\"\n\" :repl-result)" 0 828 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("0001e5(:write-string \"\" [image: Access Google Mail on your mobile phone]\r\nhttp://www.google.com/intl/en/mobile/default/mail.html\r\n\r\nThe days of needing your computer to get to your inbox are long gone. You\r\ncan now use Google Mail on your mobile phone to access your email from\r\nanywhere.\r\n Get Google Mail for your phone\r\n»http://www.google.com/intl/en/mobile/default/mail.html#utm_source=wel-eml&utm_medium=eml&utm_campaign=en\r\n\"\n\" :repl-result)000016(:return (:ok nil) 73)" 0 520 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("0001e5(:write-string \"\" [image: Access Google Mail on your mobile phone]\r\nhttp://www.google.com/intl/en/mobile/default/mail.html\r\n\r\nThe days of needing your computer to get to your inbox are long gone. You\r\ncan now use Google Mail on your mobile phone to access your email from\r\nanywhere.\r\n Get Google Mail for your phone\r\n»http://www.google.com/intl/en/mobile/default/mail.html#utm_source=wel-eml&utm_medium=eml&utm_campaign=en\r\n\"\n\" :repl-result)000016(:return (:ok nil) 84)" 0 520 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000052(:write-string \"#<core$future_call$reify__5500@2b5d70ae: :pending>\n\" :repl-result)000017(:return (:ok nil) 128)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000017(:return (:ok nil) 127)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000023(:write-string \"nil\n\" :repl-result)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "000052(:write-string \"#<core$future_call$reify__5500@343abc87: :pending>\n\" :repl-result)000017(:return (:ok nil) 126)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# "00002f(:write-string \"#'postal.pop3/m\n\" :repl-result)000017(:return (:ok nil) 125)") recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("0001e5(:write-string \"\" [image: Access Google Mail on your mobile phone]\r\nhttp://www.google.com/intl/en/mobile/default/mail.html\r\n\r\nThe days of needing your computer to get to your inbox are long gone. You\r\ncan now use Google Mail on your mobile phone to access your email from\r\nanywhere.\r\n Get Google Mail for your phone\r\n»http://www.google.com/intl/en/mobile/default/mail.html#utm_source=wel-eml&utm_medium=eml&utm_campaign=en\r\n\"\n\" :repl-result)000017(:return (:ok nil) 124)" 0 521 (charset iso-8859-1))) recursive-edit() byte-code("\306 @\307=\203!\310\311\312\"\210\313\311!\211A@)\242\314=\203!\310\315\312\"\210\316 !\210\317 \210\320 !\210\f\203d\321ed\" V\203Web\210\322 \245y\210db\210\322 \245 Zy\210|\210)\323c\210eb\210\324\325\326 \"\210\327\306!\210\324\330!\210\331\312\324\330!\210\212\332 \210+\331\207" [unread-command-char debugger-args x debugger-buffer noninteractive debugger-batch-max-lines -1 debug backtrace-debug 4 t backtrace-frame lambda 5 pop-to-buffer debugger-mode debugger-setup-buffer count-lines 2 "...\n" message "%s" buffer-string kill-emacs "" nil recursive-edit middlestart buffer-read-only standard-output] 4) debug(error (end-of-file)) byte-code("\302\300\"\210\303 \304\"\210\300\305\"\207" [error process debug slime-net-close t "net-read error: %S"] 3) slime-net-read-or-lose(#) slime-process-available-input(#) slime-net-filter(# #("0001e5(:write-string \"\" [image: Access Google Mail on your mobile phone]\r\nhttp://www.google.com/intl/en/mobile/default/mail.html\r\n\r\nThe days of needing your computer to get to your inbox are long gone. You\r\ncan now use Google Mail on your mobile phone to access your email from\r\nanywhere.\r\n Get Google Mail for your phone\r\n»http://www.google.com/intl/en/mobile/default/mail.html#utm_source=wel-eml&utm_medium=eml&utm_campaign=en\r\n\"\n\" :repl-result)000017(:return (:ok nil) 123)" 0 521 (charset iso-8859-1)))

purcell commented 13 years ago

How are you starting your clojure backend?

You'll want to make sure that 'slime-net-coding-system in your Emacs matches the encoding used by the swank backend.

For example, I do this in my Emacs:

(setq slime-net-coding-system 'utf-8-unix)

and I start clojure via elein-swank, which then starts lein swank with the :encoding option set to "utf-8".

-Steve

maxweber commented 13 years ago

Hi Steve,

thank you very much that did the trick. And it also works if I start "lein swank" on the command line.

Best regards

Max

technomancy commented 13 years ago

Realized this wasn't documented, so I added it to the readme.

purcell commented 13 years ago

On a related note, I filed the following pull request for elein so that M-x elein-swank should work out of the box:

https://github.com/remvee/elein/pull/7

-Steve

joachimdb commented 12 years ago

Hi all,

I have a similar problem but the above solution does not work for me, probably because I have to deal with strings that contain UTF-16 characters? I wanted to give an example but apparently there is an error when posting my comment if I do that (but there is an example string at http://groups.google.com/group/clojure/browse_thread/thread/5f55d5f9a8695b37)

Joachim.

purcell commented 12 years ago

@joachimdb What are the steps to duplicate the error?

joachimdb commented 12 years ago

Well, the only thing I need to do for blowing up the slime connection is call a clojure function (I used type) on a string containing UTF-16 characters from a repl started with elein-swank. I give such an example string here (look for "capricorn"): http://groups.google.com/group/clojure/browse_thread/thread/5f55d5f9a8695b37)

purcell commented 12 years ago

Sure, but I guess I'm wondering about some of the following things:

In essence, how could I take the problematic string in the mailing list message and produce the same error?

-Steve

joachimdb commented 12 years ago

1.3.4

(defproject twat "1.0.0-SNAPSHOT" :description "FIXME: write description" :dependencies [[org.clojure/clojure "1.3.0"] [org.clojure/data.json "0.1.1"] ;; replacement for clojure.contrib.json [http.async.client "0.4.0"] [twitter-api "0.6.4"] [clucy "0.2.3"] [org.apache.solr/solr-solrj "1.4.0"] [org.apache.lucene/lucene-core "3.5.0"] [org.apache.lucene/lucene-highlighter "3.5.0"] [self/guava "11.0.1"] [self/mahout-core "0.6-SNAPSHOT"] [self/mahout-collections "1.0"] [self/mahout-math "0.6-SNAPSHOT"] [cascalog "1.8.5"] [org.apache.solr/solr-solrj "1.4.0"] [org.slf4j/slf4j-simple "1.5.5"]] :dev-dependencies [[swank-clojure "1.3.4"] [clojure-hadoop "1.2.0"] [lein-multi "1.0.0"]])

I'm not sure, but the value of slime-net-coding-system is 'unix-utf-8

I copy it from the mailinglist by selecting it with the mouse, paste it in the repl with C-y and press enter.

The result is "Lisp connection closed unexpectedly: connection broken by remote peer"

Jm.

purcell commented 12 years ago

Thanks Joachim. My set-up is similar, and I can reproduce the error in my Emacs 24 on OS X by copying the quoted string from the link you posted, pasting it into the slime-repl buffer and pressing RET:

user> "Michelle Obama is a Capricorn !!! Jan 17th. ?? ---&gt; 
http://t.co/1moZ4IUZ"
unreadable message: (:emacs-rex (swank:listener-eval "\"Michelle Obama is a Capricorn !!! Jan 17th. @@ ---&gt; 
http://t.co/1moZ4IUZ\"
") "user" :repl-thread 5
exception in read loop
java.lang.RuntimeException: EOF while reading
    at clojure.lang.Util.runtimeException(Util.java:156)
    at clojure.lang.LispReader.readDelimitedList(LispReader.java:1115)
    at clojure.lang.LispReader$ListReader.invoke(LispReader.java:962)
    at clojure.lang.LispReader.read(LispReader.java:180)
    at clojure.lang.RT.readString(RT.java:1681)
    at clojure.core$read_string.invoke(core.clj:3359)
    at swank.core.protocol$read_swank_message$fn__278.invoke(protocol.clj:46)
    at swank.core.protocol$read_swank_message.invoke(protocol.clj:45)
    at swank.core.connection$read_from_connection.invoke(connection.clj:59)
    at swank.core$read_loop.invoke(core.clj:363)
    at swank.swank$connection_serve$fn__1873$fn__1874.invoke(swank.clj:33)
    at clojure.lang.AFn.applyToHelper(AFn.java:159)
    at clojure.lang.AFn.applyTo(AFn.java:151)
    at clojure.core$apply.in

Inside the repl buffer, which itself has a buffer-file-coding-system of UTF-8, using describe-char on one of the 2 offending characters reports:

        character: ? (128527, #o373017, #x1f60f)
preferred charset: unicode (Unicode (ISO10646))
       code point: 0x1F60F
           syntax: w    which means: word
         category: .:Base
      buffer code: #xF0 #x9F #x98 #x8F
        file code: #xF0 #x9F #x98 #x8F (encoded by coding system utf-8)
          display: no font available

Character code properties: customize what to show
  name: SMIRKING FACE
  old-name: 
  general-category: So (Symbol, Other)
  decomposition: (128527) ('?')

(Note: for github's sake, I've had to replace the chars with '?' in the snippets above.)

So at that point you have a mixture of UTF-8 and UTF-16 chars in the REPL buffer, and it's hard to know what the correct behavior should be. If you tried to write the contents of the REPL buffer to a file, Emacs would correctly ask you for a coding system to use, but in the case of Slime, you've already (effectively) said that you want everything sent across the wire in UTF-8.

In this case, Slime tosses raw byte data across the wire to the swank backend, saying "Here's some UTF-8 source text for you to handle with read," and the backend (understandably) mistakes the UTF-16 chars for an EOF.

The resulting error and disconnection is ugly, and can likely be fixed, but I'm not sure that sending the mixed-encoding data can be made to work, because I'm not sure it's easy to unify the encodings of the Slime REPL input before sending it across the wire. I spent half an hour or more hacking at it and got nowhere (hint: encode-coding-region is a useful function).

You note that it works in a terminal REPL, and I can reproduce that too: I can paste the string into the REPL in a terminal which has LC_CTYPE="en_US.UTF-8", and the string displays correctly, and is echoed back. I think this is because Java (and therefore the clojure reader) is defaulting to a file.encoding of ISO-8859-1 (or MacRoman, for me), in which any byte sequence is kinda legal; although the resulting string gets echoed back intact, I'm not convinced it's doing the right thing under the covers.

Slime doesn't support transferring UTF-16 over the network connection, so you might consider trying the following in order to replicate the terminal behaviour under slime: set 'slime-net-coding-system to 'binary (an alias for 'iso-latin-1-unix), and then launch the swank backend configured to use iso-8859-1.

-Steve

joachimdb commented 12 years ago

@purcell Thanks a lot!

purcell commented 12 years ago

@joachimdb So did that work for you?

joachimdb commented 12 years ago

@purcell Well, sort of (although I had to use 'iso-8859-1-unix and not 'iso-8859-1): now the connection stays up, which is definitely good, but I get the following error:

slime-net-send: Coding system iso-8859-1-unix not suitable for "00007c(:emacs-rex (swank:pprint-eval \"\"Michelle Obama is a Capricorn !!! Jan 17th. ?? ---> http://t.co/1moZ4IUZ\\"\") nil t 13)

Anyway, as said, the connection isn't blown anymore, which was my main concern. Thanks again!

purcell commented 12 years ago

That's a more helpful message, at least. Note that even when the connection blows up, you can usually just M-x slime-connect, and continue from where you left off.

joachimdb commented 12 years ago

Really? That's awesome! I'm just getting to know clojure (it's great!), I'm more familiar with common-lisp where this would not be the case. I guess I'm still missing quite some things about the way clojure works...