-
Notifications
You must be signed in to change notification settings - Fork 52
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
Pretty print code blocks according to widget size #1897
Conversation
I am not sure that |
It's true that |
Ah, OK, that's better than I thought. In that case I think we can merge this, since it's definitely better than the status quo. However, I think we should leave #1794 open. The pretty-printer is carefully written to insert appropriate line breaks depending on how much horizontal space is available (the reason it looks so bad right now is that for some reason it thinks there is very little horizontal space so it inserts every possible line break). So what I had in mind is to query brick for the amount of horizontal space we have to work with, and then render the code block with a layout configured specifically for the given width. Of course this will require some refactoring. |
Let me sleep over it and revisit tomorrow. Probably there is a better solution that this. Even I'm a little uncomfortable with |
There's also this usage of swarm/src/swarm-lang/Swarm/Language/Pretty.hs Line 173 in 4e7b2f4
which causes the newline break right after |
9d12ca6
to
bb92c9a
Compare
I made a few changes in my latest commit:
This seems like a better solution imo than As far as code blocks are rendered, I don't think there is way to make that widget size aware? I'm talking about this:
It just allows the width from defaultLayoutOptions to take effect as part of prettyText .
|
src/swarm-tui/Swarm/TUI/View.hs
Outdated
[ hBox | ||
[ padRight (Pad 1) (txt . syntax $ constInfo c) | ||
, padRight (Pad 1) (txt ":") | ||
, withAttr magentaAttr . txt $ prettyTextWidth (inferConst c) w |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the width w
of the widget to pretty-print the type signature here is not quite right, because w
is the width of the entire widget, but the type signature is not going to be printed starting in the first column of the widget; there is a command name and colon that come before it. You can see the issue in the following screenshots. In the first screenshot, you can see that the type of installKeyHandler
is cut off, because the pretty-printer thought it had the entire width of the widget to work with, so it laid out the type on a single line:
In the next screenshot, you can see that in a much narrower window, the pretty-printer does actually insert some newlines into the type, but it still gets cut off on the right:
I can imagine two things to do here.
- The obvious thing would just be to subtract the width of the constant name + colon (+ two spaces) from
w
before passing it toprettyTextWidth
. - The nicer, slightly more complex approach would be:
- first try printing the type on a single line with
prettyTextLine
and see whether the command name, colon, + pretty-printed type will fit withinw
; if so, great. - If not, instead use
prettyTextWidth
to print the type with a width ofw - 2
and then print the type indented by 2 spaces on a new line(s) after the command + colon.
- first try printing the type on a single line with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update on this:
I managed to get rendering a little bit better but need to test the implemented a bit more. Here's how the above screenshot renders now:
Hopefully this is what you had in mind @byorgey ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that looks nice!
@nitinprakash96, thanks for taking on this issue. 👍 I remember getting the layout right in #1464 was tricky and the layout issues persisted. |
@xsebek yeah I agree that getting layout right is a bit tricky 😅 still trying to figure out how this can be done nicely. But I think I should be able to get this done given I was able to figure out a few things in my last commit. I'll see if I can implement what Brent suggested in one of his reviews. |
I think this should now be ready ( - unit tests). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! I ran it and resized a terminal window continuously while looking at a complex type in the info box --- it flawlessly adapted to the width.
I don't really know how to make unit tests for this (in general it is hard to make tests for TUI things). If you can think of a way, go for it, but I think we can merge this as is!
let w = ctx ^. availWidthL | ||
constType = inferConst c | ||
info = constInfo c | ||
requiredWidthForTypes = textWidth (syntax info <> " : " <> prettyTextLine constType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Today I learned about textWidth
! I didn't know about this before. There are probably some other places in the codebase where we ought to be using it instead of length
! https://hackage.haskell.org/package/brick-2.3.1/docs/Brick-Widgets-Core.html#t:TextWidth , for anyone else reading this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@byorgey it will be more noticeable with Unicode and different terminals; see:
https://github.com/jtdaugherty/vty?tab=readme-ov-file#multi-column-character-support
Closes #1794
Changes include:
prettyTextWidth
that takes in number of allowed characters in a line as an argument.pparens'
which is mostly similar topparens
except that it only encloses a documentin parantheses and does not do anything else.
hardline
withsoftline
for multiline pretty printing.