-
-
Notifications
You must be signed in to change notification settings - Fork 646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Something changed with printing, now syntax highlighting is confused #2628
Comments
I've noticed this as well recently. Probably it's some regression related to the REPL performance work done by @cichli in that release. We'll have to investigate this further. |
Thanks for the kind words! 🙇 |
Great. Let me know if there's anything I can do to help. |
@harold i feel like i've seen this for a while so:
|
Ok, just tried w/ puget, syntax highlighting gets lost at the exact same spot as in my first screenshot (see the first gray 'g' about halfway through the print). So puget no effect as far as I can tell. |
I get the same bug in other types of buffer (like compilation-mode, or inf-ruby) whenever there's a lot of output being produced really fast. I think it's just a matter of emacs font-locking "skipping" portions of the buffer when it can't keep-up with the speed of the output. |
Be that as it may, some recent change has exacerbated the problem for the Cider repl - since upgrading I experience this on basically every print, while before I don't recall ever having seen it. |
I'm almost certain this was broken by the streamed printing. It's like the font-locking got applied to the individual chunks that were streamed in the REPL independently, instead of to the REPL buffer as a whole. Someone will have to dig a bit deeper into that problem. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding! |
@bbatsov - Is it true that you're being paid to work on this project again? Found out today (on the anniversary of this issue Apr 23!). This must be a sign. Let's fix this issue! What can I do to help? |
Must be a sign indeed! 😆 I'll see what I can do about this, but I first have to wrap up some new nREPL middleware that I'm working on currently. |
Good, good, good. This is tremendous news. Long live CIDER. |
I didn't mention this before, but a simple workaround is to just disable font-locking in the REPL completely:
Seems I was right in the past. The potential solutions I see for this are:
|
For more context - the problem is here:
As you can see we font-lock the result in chunks (they weren't chunks before nREPL 0.6, though) and this is where the breakage is coming from. Anyways, I'll figure something out. |
After playing with the code a bit more I'll probably just remove the font-locking completely. It's going to be a big mess to keep track of the result boundaries and fontify them, so I guess we're better off without this. |
Does this imply losing syntax highlighting on printed results in the repl? |
One more neophyte question, how is the chunk-size determined? If I understand your diagnosis correctly, it seems like the likelihood of a font-locking error is inversely proportionate to this 'chunk size' (bigger chunks are more likely to be font-locked correctly because there are fewer boundaries per result). If the chunk size were enormous, or perhaps configurable, one could tune it to encounter this bug less. Thanks again for looking into this, anyone doing anything nontrivial with CIDER is hitting this every day. |
I have just received with this issue for time immemorial. I haven't ever expected repl to give pretty feedback for all but small data. You're telling me there's supposed to be another way? |
Yes. I simply don't see a simple way to preserve streaming the result in chunks and do the font-locking effectively. The current approach was meant for the case when the entire result comes in one piece.
True, but that you defeat the purpose of streaming the result in chunks, right? :-) The chunk size is configurable, but so is using streaming or not. However, without streaming if you make a mistake and print something big this will lock-up both nREPL and CIDER, which is why we introduced this feature in the first place.
Well, it's annoying for me as well, especially now that I'm actually doing some Clojure development again. :-)
In the past the result was returned from the server in one piece and this was font-locked just before it was inserted in the REPL. Now the server splits the result in 1024 byte chunks (by default) and because they are font-locked individually this breaks the font-locking on anything bigger. As noted above I don't see any reasonable way around this, as we can't really collect all results and print them in bulk - that'd undo the massive performance gains of streaming results in chunks and would make printing uninterruptible. I can write some logic that constantly goes back to the expression boundary and font-locks the code again, but that'd be super slow and quite complex. That's why it seems to me this font-locking should go away completely. I can also expose the streaming settings to the end users, so they can disable it if they want to or increase the result chunk size. |
I got it now. Thanks for the clarification. I think the screenshot in the original report is actually typical. Syntax highlighting on printed results is too good to lose. What about just cranking the default chunk size? Like, maybe 8x? Was the current size chosen carefully? Does it optimize some other concern? If font locking breaks on ginormous prints that’s definitely better than bringing Emacs and cider down (we’ve all done that). What do you think about just increasing the chunk size? Can you tell me how to do it locally so I can test for myself? Welcome back into the fold, can’t express how sweet it is to have you back. |
is it conceivable to not font-lock on messages until we get a done message and then call |
It is, but it's not very easy and it will also result in you seeing bigger results without font-locking until they are streamed until the end. The main complexity comes from the fact you can't just take everything between the previous and the next prompt, as some of it might be output. |
good point. Does the result viewer functionality give us some breathing room? Maybe the repl output isn't font-locked but you could call some type of cider-inspect-last-result and see a font-locked-version if needed? |
Frankly, I don't remember how we chose the default. :D Maybe increasing it 4/8x is fine. 1k buffer-sizes are relatively small indeed.
You can redefine the
|
Is it possible to perhaps play dynamically with the quota (looking at |
Ok! We've learned a lot. There are a couple of typos in what you shared, @bbatsov - but I got this working: (defun cider--nrepl-print-request-map (&optional right-margin)
"Map to merge into requests that require pretty-printing.
RIGHT-MARGIN specifies the maximum column-width of the printed result, and
is included in the request if non-nil."
(let* ((width-option (cider--print-option "right-margin" cider-print-fn))
(print-options (thread-last
(map-merge 'hash-table
`((,width-option ,right-margin))
cider-print-options)
(map-pairs)
(seq-mapcat #'identity)
(apply #'nrepl-dict))))
(map-merge 'list
`(("nrepl.middleware.print/stream?" "1")
("nrepl.middleware.print/buffer-size" 8192))
(when cider-print-fn
`(("nrepl.middleware.print/print" ,(cider--print-fn))))
(when cider-print-quota
`(("nrepl.middleware.print/quota" ,cider-print-quota)))
(unless (nrepl-dict-empty-p print-options)
`(("nrepl.middleware.print/options" ,print-options)))))) And with that, the original code in the report works nicely: Now, Some of the more clever solutions proposed in this issue sound interesting, but I think for simplicity my vote would currently be for just cranking this print buffer size a bit. For sure, turning off font locking by default for repl prints is bad. One other interesting tidbit I discovered in playing today is that there seems to be some kind of upper bound on the size of output that CIDER will attempt to font-lock at all. This (with a suitably large buffer) works: But this (regarless of the buffer size), just gives up: This all seems super-reasonable to me; and I think we're dialing in toward something great here. Thanks everyone. |
I like the abandoned font locking much more than inconsistent font locking
this seems like a good avenue as a first measure.
…On Sat, Apr 25, 2020 at 8:34 PM Harold ***@***.***> wrote:
Ok! We've learned a lot.
There are a couple of typos in what you shared, @bbatsov
<https://github.com/bbatsov> - but I got this working:
(defun cider--nrepl-print-request-map (&optional right-margin)
"Map to merge into requests that require pretty-printing.RIGHT-MARGIN specifies the maximum column-width of the printed result, andis included in the request if non-nil."
(let* ((width-option (cider--print-option "right-margin" cider-print-fn))
(print-options (thread-last
(map-merge 'hash-table
`((,width-option ,right-margin))
cider-print-options)
(map-pairs)
(seq-mapcat #'identity)
(apply #'nrepl-dict))))
(map-merge 'list
`(("nrepl.middleware.print/stream?" "1")
("nrepl.middleware.print/buffer-size" 8192))
(when cider-print-fn
`(("nrepl.middleware.print/print" ,(cider--print-fn))))
(when cider-print-quota
`(("nrepl.middleware.print/quota" ,cider-print-quota)))
(unless (nrepl-dict-empty-p print-options)
`(("nrepl.middleware.print/options" ,print-options))))))
And with that, the original code in the report works nicely:
[image: image]
<https://user-images.githubusercontent.com/7443/80294879-c3b4be80-872a-11ea-8ecf-925ac342d08f.png>
Now, 8192 is a number, but 16384, 32768, and 65536 are also numbers. The
last one maybe being the best choice here as Gates once said, "640K ought
to be enough for anyone." .. err maybe 1/10th that, or well, whatever.
Some of the more clever solutions proposed in this issue sound
interesting, but I think for simplicity my vote would currently be for just
cranking this print buffer size a bit. For sure, turning off font locking
by default for repl prints is bad.
One other interesting tidbit I discovered in playing today is that there
seems to be some kind of upper bound on the size of output that CIDER will
attempt to font-lock at all.
This (with a suitably large buffer) works:
[image: image]
<https://user-images.githubusercontent.com/7443/80294949-7d139400-872b-11ea-9e29-fb190c984179.png>
But this (regarless of the buffer size), just gives up:
[image: image]
<https://user-images.githubusercontent.com/7443/80294960-974d7200-872b-11ea-9171-be71448b3f44.png>
This all seems super-reasonable to me; and I think we're dialing in toward
something great here.
Thanks everyone.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2628 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABQU6TPX3JV6DUQ4Q4OPCSTROOFQXANCNFSM4HH6PZKA>
.
|
Sorry about this! I've updated my example. Code editing outside of Emacs is not my strong suit! :D
There's no limit in CIDER's font-locking function, so I'm guessing there's some Emacs limit after which font-locking doesn't kick-in at all. I'll think a bit more about the solution, but I'm leaning towards disabling this by default as I tend to value simplicity and consistency. |
To be clear, the current behavior (inconsistent font locking) is much better than having no font locking (syntax highlighting) on printed repl results. I never thought logging this issue would lead to losing syntax highlighting functionality. Increasing |
Legibility is nice when the decorating can be quick and accurate. The larger the output, the less I care about decoration. (In other words, I should refine my query.) Best would be to decorate whole outputs if small (32k?), and for anything bigger, optimize ruthlessly for speed. |
I stopped using the REPL buffer directly a long time ago. The cider-inspect tools are far quicker and more effective for browsing data, especially for nested or large results. All the other evaluation is done in the source code buffers. |
For those curious about the solution - I just opted to check if the result is a balanced expression and font-lock it only in this case. Almost always this would mean that we're doing with a single chunk result that we can safely font-lock. |
This makes it possible to stream results in bigger chunks (and as a corollary - fontify as Clojure bigger results).
I've also introduced |
Actual behavior
I often return sequences of maps to have them printed in the repl. Since upgrading to 0.21.0 I am seeing a lot of confused syntax highlighting like this:
Steps to reproduce the problem
Evaluating this form in the repl is enough to do it:
Environment & Version information
CIDER version information
Lein/Boot version
Emacs version
Operating system
Ubuntu 18.04
PS. I love Cider it's the best part of my day every day. <3
The text was updated successfully, but these errors were encountered: