Redundant empty lines after FCTL_SETUSERSCREEN
Consider such code:
local function print (str)
panel.GetUserScreen()
win.WriteConsole(str.."\n")
panel.SetUserScreen()
end
print(1)
print(2)
print(3)
Output is:
1
2
3
Perhaps it would be better to add extra newline only when Far gets control back. It it possible?
Even worser case:
panel.GetUserScreen()
print 1
print 2
print 3
panel.SetUserScreen()
Output:
1
2
3
Presumably broken between 6360 (good) and 6373 (bad)
Are you sure 6360 was good?
Well, bisect was performed by Shmuel, here is the picture from him:
Update from Shmuel: bad is 6368
drkns 2024-09-10 19:37:57+01:00 - build 6368
- Minor visual correction of 6348.
Thanks, it looks like the right place indeed, but, as already mentioned, I cannot reproduce it.
What I did:
- Put your code into a file, e.g. 957.lua
- Downloaded a version < 6368 from the releases page
- Unpacked it to a new directory
- Created Far.exe.ini with UseSystemProfiles = 0 there
- Started it
- Invoked
lua:@<path>\957.lua
If steps to reproduce are different, then please specify them, I cannot read minds.
@alabuzhev , my file for testing was as follows:
mf.printconsole(1)
mf.printconsole(2)
mf.printconsole(3)
@johnd0e gave me several test examples yesterday but I used only one of them (as I was busy with other things).
Thanks, that one works.
6482
- As I can see now Far does not add empty line after receiving control back. That is acceptable, but still I would prefer to get the empty line automatically
- Consider the case from the last post: https://github.com/FarGroup/FarManager/issues/957#issuecomment-2909192357
Or this equivalent
panel.GetUserScreen()
mf.printconsole(1)
mf.printconsole(2)
mf.printconsole(3)
panel.SetUserScreen()
1
2
3
In my opinion the output in both cases should not differ.
In my opinion the output in both cases should not differ
Was it the same in 6367 (or whatever is considered 'good')?
Ugh, I'm tempted to wash it all away and rewrite.
How it should work, in my opinion:
- A FCTL_GETUSERSCREEN shows the canvas and adds an empty line after the previous text (if param1 is 0 and if it is actually needed).
- A FCTL_SETUSERSCREEN adds an empty line after whatever plugin has written (if param1 is 0 and if it is actually needed) and one or two more empty lines to make space for the command line and the keybar (if needed) and takes a snapshot.
- A nested FCTL_GETUSERSCREEN does not show the canvas (as it is already shown), just optionally adds an empty line if needed.
- A nested FCTL_SETUSERSCREEN optionally adds an empty line if needed. It knows that it is nested so it doesn't try to make space for for the command line and the keybar.
Examples:
mf.printconsole("1\n")
mf.printconsole("2\n")
mf.printconsole("3\n")
will produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
mf.printconsole("1")
mf.printconsole("2")
mf.printconsole("3")
will produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
panel.GetUserScreen()
mf.printconsole("1")
mf.printconsole("2")
mf.printconsole("3")
panel.SetUserScreen()
will produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
panel.GetUserScreen(-1, 1)
mf.printconsole("1")
mf.printconsole("2")
mf.printconsole("3")
panel.SetUserScreen(-1, 1)
will produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
panel.GetUserScreen()
mf.printconsole("1\n")
mf.printconsole("2\n")
mf.printconsole("3\n")
panel.SetUserScreen()
will produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
panel.GetUserScreen()
win.WriteConsole("1")
win.WriteConsole("2")
win.WriteConsole("3")
panel.SetUserScreen()
will produce
...whatever...
123
C:\...
1Help 2UserMn
panel.GetUserScreen(-1, 1)
win.WriteConsole("1")
win.WriteConsole("1")
win.WriteConsole("1")
panel.SetUserScreen(-1, 1)
will produce
...whatever...
123
C:\...
1Help 2UserMn
mf.printconsole("1")
I believe that this should add new line on its own, without explicit "\n", so
--panel.GetUserScreen()
mf.printconsole("1")
mf.printconsole("2")
mf.printconsole("3")
--panel.SetUserScreen()
should produce
...whatever...
1
2
3
C:\...
1Help 2UserMn
regardless of explicit (and nested) [GS]etUserScreen calls.
If user really needs "123", he should use win.WriteConsole directly (and take care of explicit [GS]etUserScreen)
panel.GetUserScreen() should not add anything.
panel.SetUserScreen() should not add anything itself, but when it isused in script run from command line, then Far is responsible to add extra line.
If that is possible, then no extra arguments required.
printconsole is [getuserscreen + writeconsole + setuserscreen], I used it here as a convenient example.
When calls are not nested we for obvious reasons do not know that after "1" you might write "2", so we have to assume that it's over and move the output up to make space for the UI. In other words, empty lines are inevitable. If you don't want them - use nesting or pass 1 as Param1.
How it should work, in my opinion
When calls are not nested we for obvious reasons do not know that after "1" you might write "2"
But we could defer empty line adding until Far finally gets control back, couldn't we? In my imagination this is so simple:
panel.SetUserScreen()only sets some flag- Far checks that flag and makes sure that there is empty line, otherwise adds it.
"Far gets control back" is not so simple. It can get it back after the plugin exits the exported function (they are legion), or when a plugin calls a function from Far (they are also legion). I don't feel like checking this flag in a hundred places and see no point in general: as mentioned, you can disable them altogether and add (or not) your own breaks wherever you like.
6483
panel.GetUserScreen!
mf.printconsole("1")
mf.printconsole("2")
mf.printconsole("3")
panel.SetUserScreen!
> 123
Roughly mf.printconsole should be equivalent of standard print, which always adds newline.
Here it can be easily fixed locally for mf.printconsole alone.
But I would prefer to have more general solution, that would work for cases like this:
local function print (str)
panel.GetUserScreen()
win.WriteConsole(str.."\n")
panel.SetUserScreen()
end
panel.GetUserScreen()
print(1)
print(2)
print(3)
panel.SetUserScreen()
> 123
Good news: it is consistent with my example. Bad news: my example is inconsistent with my description. Updated & 5484.
with my description.
Your description still looks confusing to me. Please define meaning of Get/SetUserScreen 2nd argument.
meaning of Get/SetUserScreen 2nd argument.
So it roughly means "do not ensure empty line at the end of output".
But wouldn't that be enough for SetUserScreen alone?
Backwards compatibility.
Ok, than what are your suggestions regarding mf.printconsole?
https://github.com/FarGroup/FarManager/blob/f23ad5f43b202453fe7d3c233983ca36246f6806/plugins/luamacro/api.lua#L624-L631
How to make it output without empty lines (considering that we still need empty line before prompt)?
How to make it output without empty lines
- Pass 1 to Get and Set
- Add \n wherever it makes sense for you.
The ideal solution would be if user not required to care about final \n.
Any idea how to implement this?
Edit
In either case currently we cannot make use of the second argument GET/SETUSERSCREEN for mf.printconsole.
After upgrading to b6488 from before the changes for this issue, when I run a CLI command from AltHistory (e.g. ver), the command itself is not printed, only its output, which makes the scrollback much less useful. Can this scenario be fixed within FAR?
P.S. AFAICS AltHistory uses macros somehow to run the commands.
Any idea how to implement this?
As I explained earlier, it's hard to tell which one is "final".
Can this scenario be fixed within FAR?
Thanks for reporting. 6490.
Thanks for reporting. 6490.
Thank you! With regular CLI commands, this is fixed. But I noticed that (regardless of AltHistory) commands with plugin prefixes (such as edit: < cmd /? or lm:load) are not printed. Far's own far:about and far:config are fine but far:regex is not — it's messy.
commands with plugin prefixes (such as
edit: < cmd /?orlm:load) are not printed
It's always (or at least for a very long time) been like that. The reason is simple: calling plugin by prefix just calls a plugin's function, and this usually does not print anything, so no need to prepare the canvas etc.
it's messy
Same logic applies: if a command prints something, it should echo, otherwise not.
far:about
This one does print, so it should echo as well.
far:regex
This doesn't print anything.
far:config
This also doesn't print anything, so it should not hide panels, print echo etc., same as far:regex. Probably a bug. 6491.
logic applies: if a command prints something, it should echo, otherwise not
First and foremost, I question that this logic is useful. I'd like to be able to recollect from the scrollback what silent commands I ran among the verbose ones and with what arguments I called them. After all, many nix-style commands print nothing when successful (and print something otherwise).
Next, there's still an inconsistency: if I run some well-behaved GUI program (such as notepad.exe MyFile.txt or just notepad), the program does not print anything to the console, yet the command is printed by Far. It is exactly what I expect from commands-with-prefixes too.
P.S. It looks like any (not just GUI) external program invocation command is printed, regardless of its output. I see no reason why the plugin prefixed commands should be of less value, especially considering that they can have complex arguments.
@HamRusTal I was about to explain why it won't work, but then I realized that it might, so 6492. Please raise a new issue if you have further comments or observations.