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

Addressed prompt duplication by printing nothing when response is prompt by itself

Open JasonKDarby opened this issue 3 years ago • 7 comments

This change is intended to fix the problem of the prompt being printed in line with a previously printed prompt. The issue manifests as a prompt that looks like user=> user=> and has the potential to print many more times than that.

It happens when an evaluation takes long enough for shorter requests to finish before the long one does. This has commonly come up for me when running tests or invoking load-file while completions are configured to execute through the inf-clojure process.

This pr addresses the fix in 2 steps.

First, ALL non-blanked responses are prepended by newline, as opposed to only those fulfilling (string-prefix-p "inf-clojure-" (symbol-name (or this-command last-command))). At a minimum this makes sure multiple results can't show up on the same line, which also helps to prevent the prompt from getting misaligned. I wasn't entirely certain what was going on with the string-prefix-p, in my testing it didn't appear to affect inf-clojure- evals, though they were somehow being filtered anyway.

Second, inf-clojure--previous-response-ended-with-prompt keeps track of whether the previous response ended with a prompt. If it was, and if we get only a prompt in the next request, we can replace the response with an empty string, which will leave the point at the previous prompt and appear to the user as if there was no response.

I don't consider this ready to merge, I really want to use it for a while and make sure it's enough. So far it appears to be working pretty well.


Before submitting the PR make sure the following things have been done (and denote this by checking the relevant checkboxes):

  • [x] The commits are consistent with our contribution guidelines
  • [x] The new code is not generating bytecode or M-x checkdoc warnings
  • [x] You've updated the changelog (if adding/changing user-visible functionality)
  • [x] You've updated the readme (if adding/changing user-visible functionality)

Thanks!

JasonKDarby avatar May 13 '22 23:05 JasonKDarby

I think there's a bug when first inf-clojure-connect that it does not print the first repl.

Repro:

  • start a socket repl on port 6000
  • inf-clojure-connect localhost 6000 Buffer looks blank with no indication it is ready. But if you type in it it will evaluate and then print a prompt:
(+ 1 1)
2
user=> 

dpsutton avatar Jun 03 '22 16:06 dpsutton

I think I've seen that when the repl doesn't print anything except the prompt on connect. I'm not sure why the prompt would be removed when inf-clojure--previous-response-ended-with-prompt is nil but I'll do some debugging.

JasonKDarby avatar Jun 03 '22 17:06 JasonKDarby

@dpsutton so the issue comes up when you connect to a repl that only shows the prompt 2 times. This is because inf-clojure--previous-response-ended-with-prompt gets set during the first connection, and during the second connection causes the starting prompt to get scrubbed. I can fix this by resetting inf-clojure--previous-response-ended-with-prompt to nil during repl connections.

This will still be an issue in the case of multiple simultaneous repl connections. Because inf-clojure--previous-response-ended-with-prompt tracks repl state and is only a single reference there isn't a particularly easy way to address it. I could work on tracking state of all potential repl connections, maybe just as an alist of repl buffer names to their individual inf-clojure--previous-response-ended-with-prompts but how would I know when a repl buffer changed names (according to the guide for using multiple repls with inf-clojure)?

JasonKDarby avatar Jun 07 '22 05:06 JasonKDarby

This will still be an issue in the case of multiple simultaneous repl connections. Because inf-clojure--previous-response-ended-with-prompt tracks repl state and is only a single reference there isn't a particularly easy way to address it. I could work on tracking state of all potential repl connections, maybe just as an alist of repl buffer names to their individual inf-clojure--previous-response-ended-with-prompts but how would I know when a repl buffer changed names (according to the guide for using multiple repls with inf-clojure)?

I think emacs has a native construct for this: defvar-local.

defvar-local is a Lisp macro in ‘subr.el’.

(defvar-local VAR VAL &optional DOCSTRING)

  Probably introduced at or before Emacs version 24.3.

Define VAR as a buffer-local variable with default value VAL.
Like ‘defvar’ but additionally marks the variable as being automatically
buffer-local wherever it is set.

dpsutton avatar Jun 07 '22 14:06 dpsutton

Surprisingly straightforward!

JasonKDarby avatar Jun 08 '22 03:06 JasonKDarby

@JasonKDarby Can you rebase on top of master?

bbatsov avatar Jul 15 '22 09:07 bbatsov

I finally took a closer look at the PR and I've added a bit of small feedback here and there.

bbatsov avatar Jul 18 '22 06:07 bbatsov

@JasonKDarby ping :-)

bbatsov avatar Feb 25 '23 06:02 bbatsov

!

Thanks for the ping, I'll look back into this

JasonKDarby avatar Feb 25 '23 13:02 JasonKDarby

I'm going to close this PR but leave my branch available. I haven't been able to get back to this lately, I'll resubmit once I do.

JasonKDarby avatar Mar 11 '23 14:03 JasonKDarby