Skip to content
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

[Request] Don't Block at End of Stream #572

Open
Sepero opened this issue Sep 17, 2024 · 9 comments
Open

[Request] Don't Block at End of Stream #572

Sepero opened this issue Sep 17, 2024 · 9 comments

Comments

@Sepero
Copy link

Sepero commented Sep 17, 2024

Recently I've been testing the pagers ov and moar.

When piping data to these pagers, then scrolling to the end of the stream, the program doesn't lockup and block. An indicator that the end of the stream has been reached, and normal functionality of the program to scroll, search, charge view, etc continues.

I'd like to make a feature request that less would also not freeze waiting for more data. Waiting endlessly for more data that may or may not ever come.

@polluks
Copy link
Contributor

polluks commented Sep 18, 2024

What about --quit-at-eof?

@Sepero
Copy link
Author

Sepero commented Sep 22, 2024

What about --quit-at-eof?

If I understand correctly, that flag has no affect on an unfinished/blocking stream.

For example, run dmesg -w | less -S then press the END key. It won't go to the end of output. Instead, the screen will simply freeze forever, waiting for end of stream will never come.

A pager like ov will jump to the latest available line from stream, then allow user input again. It doesn't freeze and prevent user input.

@polluks
Copy link
Contributor

polluks commented Sep 22, 2024

At least there's no freeze in macOS.

@gwsw
Copy link
Owner

gwsw commented Sep 22, 2024

You can use ESC-G to jump to the end of the buffered data and retain control of the UI. However there are cases where if you attempt to read past the end of buffered data (on an open pipe), less will block waiting for data from the pipe. The pipe must remain open for this situation to arise; for example

 i=1; while :; do echo $i; sleep 1; let i=$i+1; done ) | less 

If you let the screen fill up and then page forward, eventually you will reach a point where less is waiting for data from the pipe. You can break out of the wait and regain control by entering ^X.

@Sepero
Copy link
Author

Sepero commented Sep 23, 2024

If I understand ^X correctly, it causes less to unfreeze and allow input, but at the cost of stopping reading the stream.

On the other hand, ov never blocks or freezes, and ^X is not necessary. Pressing END will simply display the last of currently streamed content, and begin receiving user input again. As more input is piped to the pager, pressing END again will again display the last of currently streamed content.

If such feature were to be implemented in less, perhaps a "no-blocking" argument could be given to provide this behavior.

@gwsw
Copy link
Owner

gwsw commented Sep 23, 2024

There were some changes in this area in the post659 branch. I think it behaves more like you want.

If you are on a 40 line terminal and press f, less tries to read the next 39 lines, even if that requires blocking, since you requested 39 lines. ^X will abort that process and return control. If you then again press f, less tries to read the next 39 lines again. Any lines that have already arrived from the pipe will display immediately; if there are less than 39 lines available it will block waiting for data. ESC-G acts similar to how you describe ov's END command; it displays the end of buffered content.

If you want to try this branch, let me know if you find any behavior that doesn't act like you expect.

@Sepero
Copy link
Author

Sepero commented Sep 24, 2024

That's great, so it seems most the functionally to behave without freezing on streams is already there. Perhaps it could be added.

If implemented, a --no-blocking option would ideally behave in ways like this, using standard keys:

  1. Pressing END goes to last streamed line (like ESC G)
  2. Pressing Down would never freeze. Stop at the last streamed line.
  3. Doing a /search beyond the end of currently streamed input may freeze less, and be unfrozen with ^X, but the stream never stops being read (no need to press f).

@piotr-dobrogost
Copy link

piotr-dobrogost commented Sep 25, 2024

There were some changes in this area in the post659 branch. I think it behaves more like you want.

I think changes mentioned here are in 9933cf1 commit which was the result of discussion in issue #553.

3. Doing a /search beyond the end of currently streamed input may freeze less, and be unfrozen with ^X, but the stream never stops being read (no need to press f).

For me this would be surprising and not coherent with behavior described in points 1 and 2 which seem to suggest that no action should implicitly try to read more data.

If you are on a 40 line terminal and press f, less tries to read the next 39 lines, even if that requires blocking, since you requested 39 lines.

I'm not sure most people would agree that by pressing f they requested 39 lines. I think the intention is to request at most the next 39 lines as one (most of the time) does not know how much data is left.

I think the most natural behavior and what most people want is how it works in lnav where new data is being read continuously, without blocking UI, and ready to be accessed in whatever way; going to the end, searching etc.. In addition user can pause reading new data anytime by pressing =. I encourage to try ( i=1; while :; do echo $i; sleep 0.2; let i=$i+1; done ) | lnav and see.
Would it be possible to have such behavior in less?

Generally the fact that less' UI freezes when reading more data is the root cause of many complaints from users which find (rightly so) such behavior unexpected and undesirable. The big problem seems to be that instead of fixing this root cause less went the other way and started to introduce new commands (like CTRL-X or ESC-G) which still does not solve the problem and which makes using less more complicated than it should be.

@Sepero
Copy link
Author

Sepero commented Sep 28, 2024

  1. Doing a /search beyond the end of currently streamed input may freeze less, and be unfrozen with ^X, but the stream never stops being read (no need to press f).

For me this would be surprising and not coherent with behavior described in points 1 and 2 which seem to suggest that no action should implicitly try to read more data.

Fair point. If it blocks on search, then that would mean the searched text was not found YET, but will continue to search as new input arrives. Though, ov doesn't behave this way. Regarding this behavior- I could go either way. Search and stop, OR search and block (with message "^X to stop search"), I would prefer the second behavior but both are acceptable to me.

If you are on a 40 line terminal and press f, less tries to read the next 39 lines, even if that requires blocking, since you requested 39 lines.

I'm not sure most people would agree that by pressing f they requested 39 lines. I think the intention is to request at most the next 39 lines as one (most of the time) does not know how much data is left.

Yes

Generally the fact that less' UI freezes when reading more data is the root cause of many complaints from users which find (rightly so) such behavior unexpected and undesirable. The big problem seems to be that instead of fixing this root cause less went the other way and started to introduce new commands (like CTRL-X or ESC-G) which still does not solve the problem and which makes using less more complicated than it should be.

Unfortunately, I have to agree.
The ideas of improving less behavior were good, but the implementation perhaps could have been better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants