huijunchen9260 / fm.awk

File manager written in awk
GNU General Public License v3.0
125 stars 3 forks source link

Preview "Move too fast!" error. #1

Closed magpie514 closed 3 years ago

magpie514 commented 3 years ago

Hello. I've been very interested in trying out fm.awk to have as a backup file manager when nothing else is available, and so far I'm rather happy about it existing (saying as user and awk enthusiast). I only noticed a weird thing. In current (69a738d) version, moving around files with the up and down keys will produce a "Move too fast!" error message if previews are active. Previews work if pressing v twice again. What's more puzzling is that it does work fine if pressing k/j instead of uparrow/downarrow. My terminal is konsole (v.21.04.3) and I have tried using gawk (5.1.0) and mawk (1.3.4) (and busybox awk but that went as expected). If you need any additional information please let me know.

Thanks for making this. Best regards.

huijunchen9260 commented 3 years ago

This is a "feature" that is not yet implemented well. I wish there's a better solution.

The Move too fast! error is because awk cannot parallelize the computation between preview and cursor movement. So if you keep pressing j with preview on, and you are in a image directory, then chafa will start to slow down the selection, because it takes time for chafa to generate new image preview.

The way I avoid unnecessary image preview generation is by having that error message.

The arrow key problem you've mentioned can be figured out by the following code:

awk '
BEGIN{
system("stty -isig -icanon -echo")
printf "\033\1332J\033\133H" >> "/dev/stderr" # clear screen
printf "\033\133?1049h" >> "/dev/stderr" # alternate buffer
printf "\033\1337" >> "/dev/stderr" # save cursor
printf "\033\133?25l" >> "/dev/stderr" # hide cursor
printf "\033\133?7l" >> "/dev/stderr" # line wrap
while (1) {
    RS = "\a"
    cmd = "dd ibs=1 count=1 2>&1"
    cmd | getline record;
    close(cmd)
    print record
    if (record ~ /\003/) break
}
printf "\033\1332J\033\133H" >> "/dev/stderr" # clear screen
printf "\033\133?7h" >> "/dev/stderr" # line wrap
printf "\033\1338" >> "/dev/stderr" # restore cursor
printf "\033\133?25h" >> "/dev/stderr" # hide cursor
printf "\033\133?1049l" >> "/dev/stderr" # back from alternate buffer
system("stty isig icanon echo")

}'

If you execute the above code and press arrow key, you'll realize that this key has three output, which means the output of an arrow is actually three bytes. The output is like:

+0 records in
0+1 records out
1 byte copied, 0.673246 s, 0.0 kB/s

[1+0 records in
0+1 records out
1 byte copied, 8.5332e-05 s, 11.7 kB/s

B1+0 records in
0+1 records out
1 byte copied, 0.000104972 s, 9.5 kB/s

I am using the kB/s data to detect the behavior of continuous pressing a key. However, since pressing arrow key once would generate three bytes of data, it means that the last two bytes has very high kB/s value, which triggers the Move too fast error.

If you may, you can propose a way to avoid unnecessary file previewing during constant scrolling and I can try to implement it.

magpie514 commented 3 years ago

This is a pretty clever mechanism, and I'm not well-versed enough in using awk for keyboard handling to suggest something better (it's something I should experiment with). I just found it strange it worked with one key and not with another (I was pressing them slowly).

I tried measuring the value of sec when the message gets triggered. The results are all over the place, might be around 15.5 and can go up to 54.7, so raising the threshold to trigger might not be useful at all. I raised it to a large value, 56.5, and it only seemed to trigger after trying to parse large configs in my $HOME. Commenting the return in that same function seems to have no ill effects (but chafa is not installed in my system). One option could be to enable or disable chafa support with a variable, in that case it might not need the timing at all. Another one could be a different tool. I recall there was one I used once that worked by sending data to a FIFO and it stayed as a daemon of sorts. Ueberzug, I think? Another option could be un-setting preview mode on a "move too fast!" event, so re-enabling it is just one keypress. Another one could be to measure time using systime() and prevent re-execution within the same second by comparing the Unix timestamp, which should be a vanilla awk feature unless I'm wrong (I might, could be gawk/mawk and busybox is :shrug:, but I get the Unix time just with print systime().

Actually, taking a closer look, the commands are being executed on the spot. The chafa not found errors were actually shell output. I would be convenient to check for the existence of the programs with something like command -v chafa or command -v pdftoppm and prevent trying to begin with. That might be something for another issue, if you prefer.

huijunchen9260 commented 3 years ago

Should fix by a8144b3

huijunchen9260 commented 3 years ago

I do need help to implement ueberzug...it seems really hard for me. Tried but having no luck with it.

The dependency stuff is possible. But how do you think those "dependency not found" error message should be displayed?

magpie514 commented 3 years ago

Should fix by a8144b3

Perfect, works like a charm. I will close this issue to mark it as resolved.

I do need help to implement ueberzug...it seems really hard for me. Tried but having no luck with it.

The dependency stuff is possible. But how do you think those "dependency not found" error message should be displayed?

I'll give Ueberzug a try from within awk and see what happens. I've been meaning to use it from awk for a minor thing and this is a good excuse to try. I'll open another issue with my findings so implementation can be discussed from a working example, instead of trying to implement it directly as a PR, if that's agreeable with you. (I don't want to impose on specific implementation details, so I'll just focus on a working example)

As for warnings, the same way as the "move too fast!" warning should do the trick, perhaps like "Requirement %s not found", or "Cannot preview %s. Please install %s." (I'm not great at making warning messages that sound remotely human, but you get the idea). Maybe a yellow background with black text can be used for visual conveyance, but that's better left to your choice. I can try implementing them in a PR, since it's pretty much janitorial work. If you got no objections I'll aim for checking for the commands with command -v (which is, as far as I can tell, a POSIX standard, should be reliable enough) and add some checks and warnings where appropriate. I'll try to make them informative and pretty to look at, but we can discuss the details as we go.

Thanks for your prompt action. I'll start working on those.

huijunchen9260 commented 3 years ago

Sure. I will be extremely busy with my school work this week, I will try to discuss with you.

Probably you can use this for the dependency check.

https://github.com/soimort/translate-shell/blob/develop/include/Commons.awk#L587-L599

magpie514 commented 3 years ago

That's fascinating, I'll give it a shot. Good luck with everything!

huijunchen9260 commented 3 years ago

https://github.com/huijunchen9260/fm.awk/commit/c38eb81e636805327d68b1f5ebf624fae6854082

This might be an even better solution for "Move too fast!"

magpie514 commented 3 years ago

Ah, no subprocesses at all, that's a much better approach in my opinion.

huijunchen9260 commented 3 years ago

Somehow you can get current second using srand(); time = srand() lol. Awk is so amazing.

Reference