swift-emacs / swift-mode

Emacs support for Apple's Swift programming language.
GNU General Public License v3.0
372 stars 47 forks source link

Repl shows unreadable characters at prompt #132

Closed sandric closed 7 years ago

sandric commented 8 years ago

While comint buffer after invoking swift-mode-run-repl looks working and I can type, evaluate and send to repl commands, at prompt it shows me some unreadable characters:

Welcome to Apple Swift version 2.2 (swiftlang-703.0.18.8 clang-703.0.30). Type :help for assistance.
^[^[[J  1>  ^[  1> ^[[1G  1> ^[[6G

The last string is invitation to prompt and is repeated at each new line enter.

JKRT commented 8 years ago

Hi! I had the same issue. The strange characters occur because It seems that the swift-repl-mode buffer does not support ansi-color.

A quick and dirty solution to the problem is to add (add-hook 'swift-repl-mode-hook 'ansi-color-apply) to your .emacs :)

taku0 commented 7 years ago

Fixed with 812d202bdf41dbc0f0e145610ee1c103071918bc.

For some reason, pop-to-buffer with Emacs 25.1 after make-comint results in corrupted prompt with strange ANSI control sequence.

For example, when feeding class Foo {} and enter key, the input is echoed with the following character sequence

class Foo {}^[[1G^[[2m  1> ^[[22m^[[18G

which would be interpreted by a terminal like this

  1>  Foo {}

This is not desirable.

FYI, each sequence means as follows:

sequence meaning
^[[1G Goto 1st column
^[[2m Use faint color
^[[22m Use normal color
^[[18G Goto 18th column

Curiously, while invoking swift command from shell mode works fine, it will be corrupted with the following steps:

  1. Start shell mode.
  2. Type M-x.
  3. Cancel the minibuffer with C-g.
  4. Invoke swift command from the shell.

I could not find the cause nor why this workaround works.

dalgong commented 4 years ago

The solution mentioned in 812d202 seems not right. The fix that I came up with is to wait until the created process produces some output:

(defun swift-mode:run-repl (cmd &optional dont-switch keep-default)
  "Run a Swift REPL process.

This function input and output via buffer `*CMD*' where CMD is replaced with
the CMD given.
If there is a process already running in `*CMD*', and DONT-SWITCH is nil,
switch to that buffer.
CMD is a string or a list, interpreted as a command line.  The default value is
`swift-mode:repl-executable'.  This function updates the buffer local variable
`swift-mode:repl-executable' with the given CMD if KEEP-DEFAULT is nil,
so it will be used as the default value for the next invocation in the current
buffer.
If KEEP-DEFAULT is non-nil, the `swift-mode:repl-executable' and the global
variable `swift-mode:repl-buffer' are not updated.  The buffer local variable
`swift-mode:repl-buffer' is always updated.
Runs the hook `swift-repl-mode-hook' \(after the `comint-mode-hook' is run).
\(Type \\[describe-mode] in the process buffer for a list of commands.)"
  (interactive
   (list (if current-prefix-arg
             (read-string
              "Run swift REPL: "
              (swift-mode:command-list-to-string swift-mode:repl-executable))
           swift-mode:repl-executable)))
  (let* ((original-buffer (current-buffer))
         (cmd-string (swift-mode:command-list-to-string cmd))
         (cmd-list (swift-mode:command-string-to-list cmd))
         (buffer-name (concat "*Swift REPL [" cmd-string "]*"))
         (buffer (get-buffer-create buffer-name))
         old-size)
    (with-current-buffer original-buffer
      (setq-local swift-mode:repl-buffer buffer)
      (unless keep-default
        (setq-local swift-mode:repl-executable cmd)
        (setq-default swift-mode:repl-buffer swift-mode:repl-buffer)))
    (with-current-buffer buffer
      (setq old-size (buffer-size))
      (swift-repl-mode)
      (setq-local swift-mode:repl-buffer buffer))
    (unless (comint-check-proc buffer)
      (apply 'make-comint-in-buffer
             cmd-string buffer (car cmd-list) nil (cdr cmd-list))
      (with-current-buffer buffer
        (while (= old-size (buffer-size))
          (sleep-for .1))))
    (unless dont-switch
      (pop-to-buffer buffer))))
taku0 commented 4 years ago

@dalgong thank you for your fix. Seems good. Could you create a PR?