-
Notifications
You must be signed in to change notification settings - Fork 160
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
Change how 'Disable Formatting' works #4496
base: master
Are you sure you want to change the base?
Conversation
Thanks for the PR, I can confirm that this makes indentation work regardless of the formatting status and makes I noticed one additional issue which I assume is related to stdout being opened multiple times: If I put
in a file (or my gaprc), call gap with the filename and then check |
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.
I have to teach, will comment more later
@@ -1866,8 +1857,6 @@ static Obj FuncSET_PRINT_FORMATTING_STDOUT(Obj self, Obj val) | |||
TypOutputFile * output = IO()->Output; | |||
if (!output) | |||
ErrorMayQuit("SET_PRINT_FORMATTING_STDOUT called while no output is opened\n", 0, 0); | |||
while (output->prev) |
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.
This change is wrong, it should affect stdout, not the top open file, which may be different from stdout.
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.
I agree this isn't currently right.
There is currently a problem, whereby we end up with two copies of stdout on the stack. By chucking in some prints I see the stack of Outputs is two "stdout". The old code would change the bottom one, but then the top (currently active) one would not have printing disabled.
I could explicitly search down the stack for the first "stdout" (which would mean file=1), and change the formatting of that, or investigate why we get multiple stdout on the output stack.
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.
We get multiple stdout (and stderr) on the stack because that's the whole point of the stack: we start with stdout open and run code; that code opens a file and runs some more code; which opens stdout again. Now we have a stack with three levels: stdout, that file, again stdout. If the currently running code closes its output, the active output should again point at the file -- the bottommost "stdout" should still stay open, though.
The problematic part thus is not that stdout (and stderr) can be multiple times on the stack; rather it is that they do not share data: neither the formatting hints nor the line cache. This already causes issues with printing to stderr: if your terminal is 80 chars wide, and you print 50 chars to stdout, then open stderr and print another 45 chars, GAP fails to realize that a wraparound has occurred, because the stderr output stream is not aware of the 50 chars printed before it. And when stderr is closed, then stdout still thinks that 50 chars were printed to the terminal, when really it was 95. See also issue #1197.
There are several ways to address this. One crude but easy to implement approach would be to detect whenever we open/close stdout or stderr, and add some special treatment: when opening a new one, make sure to copy the content of the TypOutputFile
struct of the any previously opened stdout/stderr over (well, at least part of it; maybe pos/hint/indent/...?). Conversely, when closing, copy it back to the previously opened stdout/stderr. Of course variations are possible, e.g. there could be a static TypOutputFile Stdout
in io.c
, and we simply sync with that resp. use that whenever output goes to stdout or stderr.
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.
I agree that might well be a better fix. I've tweaked this PR so it now walks the stack of open Outputs and changes the formatting on each one which is *stdout*
. That still doesn't fix the other problems you discuss of course.
b341e68
to
3796ef2
Compare
Since indentation is now always on, this breaks the changes @ChrisJefferson recently made in PR #4458, as those specifically relied on indentation turning off in this case. We may need a more elaborate way to control the "formatting settings" of output streams than just a single boolean. That said, Or we leave it as it is, and instead add a way to let the user separately turn off "line wrapping" and "indentation". |
I believe SetPrintFormattingStatus always worked, except for stdout was it has been broken (at least sometimes). Personally, I've never seen a good reason to disable indentation, so I'd be happy to just remove the ability to disable it, but I realise some people might have a use case where they want to disable indentation. For that, we could split indenting and line wrapping into two options (I'd personally then suggest we disable line wrapping by default when writing to files, which would be another change of behaviour, but one I think, again, most users would want). |
Sorry for the late reply, I lost track of the PR over the weekend. This is much more intricate than I expected, so I thought a bit about what the simplest interface for my use case would be. My use case is: I never want line wrapping (because I prefer to let my terminal wrap lines and do not want "random" backslashes when printing to strings/files) and I always want indentation, regardless of the print target (stdout, file, string). So I think the easiest solution would be to introduce a function |
This PR changes GAP so when formatting is disabled we still indent functions (and other objects), just disable line wrapping.
This also fixes a bug which where
SetPrintFormattingStatus
wouldn't work if stdout was opened twice (it might be we should also stop that happening, separately).I'm not saying this should be final (we certainly want a whole bunch of tests), but I'm exploring options. Comments welcome.