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

feat(backend): Add convenience methods for setting up terminals #1180

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

joshka
Copy link
Member

@joshka joshka commented Jun 16, 2024

Adds:

  • CrosstermBackend::stdout and CrosstermBackend::stderr for creating
    backends with std::io::stdout and std::io::stderr respectively.
  • CrosstermBackend::stdout_with_defaults and
    CrosstermBackend::stderr_with_defaults for creating
    backends with that use the alternate screen and raw mode.
  • CrosstermBackend::with_raw_mode for enabling raw mode.
  • CrosstermBackend::with_alternate_screen for switching to the
    alternate screen.
  • CrosstermBackend::with_mouse_capture for enabling mouse support.
  • CrosstermBackend::reset for resetting the terminal to its default
    state.
  • Drop implementation for restoring raw mode, mouse capture, and
    alternate screen on drop.

Most applications should generally use stdout_with_defaults to create
a backend with raw mode and the alternate screen, and now longer need
to worry about restoring the terminal to its default state when the
application exits. The reset method can be used to restore the terminal to
its default state if needed (e.g. in a panic handler).

use ratatui::{backend::CrosstermBackend};

let backend = CrosstermBackend::stdout_with_defaults()?;
// or
let backend = CrosstermBackend::stderr_with_defaults()?;
// or with custom settings
let backend = CrosstermBackend::stdout()
    .with_raw_mode()?
    .with_alternate_screen()?
    .with_mouse_capture()?
use std::io::stderr();

// in a panic / error handler:
CrosstermBackend::reset(stderr())

@joshka joshka changed the title feat(backend): add convenience methods feat(backend): Add convenience methods for setting up terminals Jun 16, 2024
Copy link

codecov bot commented Jun 16, 2024

Codecov Report

Attention: Patch coverage is 0% with 83 lines in your changes missing coverage. Please review.

Project coverage is 93.9%. Comparing base (3f2f2cd) to head (97bf4a3).
Report is 10 commits behind head on main.

Files Patch % Lines
src/backend/crossterm.rs 0.0% 83 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##            main   #1180     +/-   ##
=======================================
- Coverage   94.4%   93.9%   -0.5%     
=======================================
  Files         62      62             
  Lines      14941   15127    +186     
=======================================
+ Hits       14110   14217    +107     
- Misses       831     910     +79     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@joshka joshka force-pushed the jm/crossterm-init branch 2 times, most recently from aacf548 to 1d176d9 Compare June 16, 2024 01:28
@joshka
Copy link
Member Author

joshka commented Jun 16, 2024

Note - this is intentionally only implemented for crossterm right now, and it's not carried through to the examples as yet to allow for review of the concept without the bulk.

Note also the comments / previous effort on #280

Copy link
Member

@EdJoPaTo EdJoPaTo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like seeing the with_* methods and the internal state to allow for a simpler reset. This will simplify a lot of code.

With other stuff I have my problems, noted on them directly for easier, threaded discussions.

src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
joshka added a commit that referenced this pull request Jun 18, 2024
In <#1180> and
<#1181>, we introduced some
simpler ways to create a backend and terminal, and to setup color_eyre
to handle errors. This PR updates the examples to use these new methods,
and removes a bunch of unnecessary boilerplate code.
@joshka joshka requested a review from EdJoPaTo June 18, 2024 06:07
@joshka joshka added Status: Controversial There is some discussion about whether this is the right direction. Clarify and seek consensus. Status: Review Needed PR needs a review / Issue needs buy-in from other maintainers / users labels Jun 19, 2024
@joshka joshka dismissed EdJoPaTo’s stale review June 20, 2024 00:49

Changes addressed

@joshka joshka requested a review from orhun June 20, 2024 00:50
Copy link
Member

@EdJoPaTo EdJoPaTo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the simplicity that will come with this and a built-in panic handler. I still want to provoke some thoughts about the current state here. (Also, I want to test this branch to get a feel for its real world usage, which I haven't done yet.)

src/backend/crossterm.rs Outdated Show resolved Hide resolved
examples/minimal.rs Outdated Show resolved Hide resolved
examples/colors_rgb.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
examples/colors_rgb.rs Show resolved Hide resolved
Adds:
- `CrosstermBackend::stdout` and `CrosstermBackend::stderr` for creating
  backends with `std::io::stdout` and `std::io::stderr` respectively.
- `CrosstermBackend::into_terminal` for converting a backend into a
  terminal.
- `CrosstermBackend::into_terminal_with_options` for converting a
  backend into a terminal with options.
- `CrosstermBackend::into_terminal_with_defaults` for converting a
  backend into a terminal with default settings (raw mode and alternate
  screen).
- `CrosstermBackend::with_raw_mode` for enabling raw mode.
- `CrosstermBackend::with_alternate_screen` for switching to the
  alternate screen.
- `CrosstermBackend::with_mouse_support` for enabling mouse support.
- `CrosstermBackend::reset` for resetting the terminal to its default
  state.
- `Drop` implementation for restoring raw mode, mouse capture, and
  alternate screen on drop.

Most applications can now just use the `into_terminal_with_defaults`
method to set up the terminal with raw mode and the alternate screen,
and now longer need to worry about restoring the terminal to its default
state when the application exits. The reset method can be used to
restore the terminal to its default state if needed (e.g. in a panic
handler).

```rust
use ratatui::backend::CrosstermBackend;

let terminal = CrosstermBackend::stdout()
     .into_terminal_with_defaults()?;
```
@EdJoPaTo
Copy link
Member

I am curious why crossterm itself doesn't have something like this. I think everyone using crossterm would benefit from something like this. Should this be proposed for crossterm?

@joshka
Copy link
Member Author

joshka commented Jun 28, 2024

I am curious why crossterm itself doesn't have something like this. I think everyone using crossterm would benefit from something like this. Should this be proposed for crossterm?

Define "this".

Regardless it doesn't change whether we'd want this PR to land in the meantime as the development cycle on that side of the fence is pretty slow.

@EdJoPaTo do you have any hard blockers for this PR getting merged? This PR underpins a massive simplification of all the example code in Ratatui as well as customer apps, tutorials, recipes, etc. I'm blocked on completing all of that by this not being merged.

Copy link
Member

@EdJoPaTo EdJoPaTo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still like the simplification that will come with this a lot. Some curiosity / minor nitpicks remain, some docs should improve, then I think this can be merged.


@joshka dismissed my review, I think this should be enabled automatically for this repo: dismiss reviews on new commits. Either it's quite fast to review them again or it might have changed something that should be reviewed again. (Maybe also a review of multiple and not just one person might be ideal especially for bigger things.)

examples/minimal.rs Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
examples/colors_rgb.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
@joshka
Copy link
Member Author

joshka commented Jun 28, 2024

@joshka dismissed my review, I think this should be enabled automatically for this repo: dismiss reviews on new commits. Either it's quite fast to review them again or it might have changed something that should be reviewed again. (Maybe also a review of multiple and not just one person might be ideal especially for bigger things.)

That approach causes a long turn around time for things which don't matter. I prefer to work based on trust that we'll do the right thing once given the go ahead to merge.

Co-authored-by: EdJoPaTo <rfc-conform-git-commit-email@funny-long-domain-label-everyone-hates-as-it-is-too-long.edjopato.de>
Copy link
Member Author

@joshka joshka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've noted that a most of these points are nitpicks and my tolerance for handling this amount of not relevant feedback on this PR is rapidly approaching zero. There's nothing that would block this from being merged or that would cause a user not to understand how these methods work. As such resolving them.

examples/colors_rgb.rs Show resolved Hide resolved
examples/minimal.rs Show resolved Hide resolved
src/backend/crossterm.rs Outdated Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
src/backend/crossterm.rs Show resolved Hide resolved
joshka

This comment was marked as duplicate.

@joshka joshka requested a review from EdJoPaTo June 28, 2024 15:30
@joshka
Copy link
Member Author

joshka commented Jun 28, 2024

@EdJoPaTo see my email about nits etc.

@kdheepak
Copy link
Collaborator

Most of the PR looks good to me (but I haven't read all the comments on this thread), will do so over the weekend.

Comment on lines +160 to +164
pub fn stdout() -> io::Result<Self> {
Self::new(io::stdout())
.with_raw_mode()?
.with_alternate_screen()
}
Copy link
Collaborator

@kdheepak kdheepak Jun 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says:

  • CrosstermBackend::stdout and CrosstermBackend::stderr for creating backends with std::io::stdout and std::io::stderr respectively.
  • CrosstermBackend::stdout_with_defaults and CrosstermBackend::stderr_with_defaults for creating backends with that use the alternate screen and raw mode.

which doesn't match this implementation.

I prefer it to work the way the PR description mentions. It makes it much more clearer imo.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, CrosstermBackend::stdout_tui and CrosstermBackend::stderr_tui.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea behind doing some reasonable defaults (raw/alternate screen) on these is that this is necessary for 90% of all apps. Anything else can do CrosstermBackend::new(stdout()).with_xxx()...

Copy link
Collaborator

@kdheepak kdheepak Jun 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be a little confusing imo to find in a Ratatui app's user code two things that are very similar but do different things

  • CrosstermBackend::new(stdout()) for inline
  • CrosstermBackend::stdout() for a TUI

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the reasonable defaults in place here, I'm just not convinced that the name conveys those defaults clearly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Controversial There is some discussion about whether this is the right direction. Clarify and seek consensus. Status: Review Needed PR needs a review / Issue needs buy-in from other maintainers / users
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants