Addressed prompt duplication by printing nothing when response is prompt by itself
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 checkdocwarnings - [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!
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-connectlocalhost6000Buffer 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=>
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.
@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)?
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.
Surprisingly straightforward!
@JasonKDarby Can you rebase on top of master?
I finally took a closer look at the PR and I've added a bit of small feedback here and there.
@JasonKDarby ping :-)
!
Thanks for the ping, I'll look back into this
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.