inf-clojure icon indicating copy to clipboard operation
inf-clojure copied to clipboard

Pressing enter doesn't returns the user=> prompt.

Open andradefil opened this issue 1 year ago • 4 comments

From Slack's thread in Clojurians #inf-clojure

Expected behavior

Press enter to return the prompt => like in clj repl.

$ clj
Clojure 1.11.3
user=> 
user=> 
user=> 
user=> 
user=> 
user=> 
user=>

Actual behavior

Pressing enter doesn't make a new line with the user=> prompt. image

A variation of the issue pressing control-j instead enter; it doesn't return, but after putting some value, it returns multiple times user =>

user=> 





2
user=> user=> user=> user=> user=> user=> 2

Steps to reproduce the problem

Start a new repl and press enter.

Environment & Version information

inf-clojure version information

3.2.1

Clojure version

1.11.3

Emacs version

29.3

Operating system

MacOS Sonoma 14.5

andradefil avatar Jul 22 '24 11:07 andradefil

The reason is this function:

(defun inf-clojure--sanitize-command (command)
  "Sanitize COMMAND for sending it to a process.
An example of things that this function does is to add a final
newline at the end of the form.  Return an empty string if the
sanitized command is empty."
  (let ((sanitized (string-trim-right command)))
    (if (string-blank-p sanitized)
        ""
      )))

If input is an empty string it doesn't add a newline character. If I change it to:

(defun inf-clojure--sanitize-command (command)
  "Sanitize COMMAND for sending it to a process.
An example of things that this function does is to add a final
newline at the end of the form.  Return an empty string if the
sanitized command is empty."
  (let ((sanitized (string-trim-right command)))
    (concat sanitized "\n")))

it works as expected.

From the Git history I see that it was done intentionally. Here's the relevant commit: https://github.com/clojure-emacs/inf-clojure/commit/39e794c169c331a43c52b62e546ddd612ef020d7

rrudakov avatar May 25 '25 08:05 rrudakov

I think it's fine to send blank strings to the REPL, so let's change it back.

bbatsov avatar May 25 '25 08:05 bbatsov

Looking at the bigger change my guess is that it was trying to avoid sending blank strings that result from transforming the input. (I recall in certain situations evaluating multi-line expressions resulted in several blank prompts which looked weird) Haven't used inf-clojure in a while, so I've started to forget the details here.

bbatsov avatar May 25 '25 08:05 bbatsov

I tried to evaluate multiline string and get surprising results. Seems not only inf-clojure--sanitize-command has an issue, but may be inf-clojure--forms-without-newlines also has an issue. Let's evaluate a code

(concat "
   
   
   
")

here 3 spaces in each line , in emacs whitespace-mode it looks as

(concat "
...$
...$
...$
$")

If we evaluate it in clojure repl(without emacs ind-clojure) we get

user=> (concat "
   
   
   
")
(\newline \space \space \space \newline \space \space \space \newline \space \space \space \newline)
user=> 

which is of course correct result.

if we evaluate it from emacs with inf-clojure-eval-last-sexp we get

(\newline \newline \newline \newline)

It is unexpected and incorrect.

If we copy the code and paste into inf clojure repl we get

(\newline \space \space \space \newline \space \space \space \newline \space \space \space \newline)

It is correct result.

if we try to type expression

user=> (concat "
   
   
   
")

then click enter, nothing happening, even if we put ";\n"(it usually raise print prompt because ; is not whitespace from inf-clojure--sanitize-command pint of view), nothing happened. Looks as infinite loop, the only way which I found interrupt it is quit from inf clojure repl.

Btw CIDER doesn't have any of above issues and always returns

(\newline
 \space
 \space
 \space
 \newline
 \space
 \space
 \space
 \newline
 \space
 \space
 \space
 \newline)

as expected.

Here is workaround for issues with prompt, "remove space from multiline", "infinite loop" described above, but it prints multiple prompt when send multiple "\n" to comint process , for example when evaluate buffer.

  (with-eval-after-load 'inf-clojure
    (message "Override some inf-clojure functions")

    (defun inf-clojure--sanitize-command (command)
      (let ((sanitized (string-trim-right command "\n+")))
        (concat sanitized "\n"))
      )
    
    (defun inf-clojure--forms-without-newlines (str)
      (string-trim str "\n+" "\n+")
      )
    
  )

vkocubinsky avatar Oct 22 '25 09:10 vkocubinsky