feat: add an inline view mode (#648)

* add inline viewport

* Add inline_height setting. Zero disables inline mode (the default)
This commit is contained in:
Patrick Decat 2023-03-25 18:27:20 +01:00 committed by GitHub
parent 03f7e5543e
commit 13ce5f746c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 11 deletions

3
Cargo.lock generated
View File

@ -1764,8 +1764,7 @@ dependencies = [
[[package]] [[package]]
name = "ratatui" name = "ratatui"
version = "0.20.1" version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/conradludgate/tui-rs-revival?branch=inline#6ed61959ecfc560e4e6a00a1410bb5fcbf0eda91"
checksum = "dcc0d032bccba900ee32151ec0265667535c230169f5a011154cdcd984e16829"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cassowary", "cassowary",

View File

@ -81,3 +81,6 @@ version = "0.3"
default-features = false default-features = false
features = ["ansi", "fmt", "registry", "env-filter"] features = ["ansi", "fmt", "registry", "env-filter"]
optional = true optional = true
[patch.crates-io]
ratatui = { git = "https://github.com/conradludgate/tui-rs-revival", branch = "inline" }

View File

@ -151,6 +151,7 @@ pub struct Settings {
pub filter_mode: FilterMode, pub filter_mode: FilterMode,
pub filter_mode_shell_up_key_binding: Option<FilterMode>, pub filter_mode_shell_up_key_binding: Option<FilterMode>,
pub shell_up_key_binding: bool, pub shell_up_key_binding: bool,
pub inline_height: u16,
pub show_preview: bool, pub show_preview: bool,
pub exit_mode: ExitMode, pub exit_mode: ExitMode,
pub word_jump_mode: WordJumpMode, pub word_jump_mode: WordJumpMode,
@ -336,6 +337,7 @@ impl Settings {
.set_default("search_mode", "fuzzy")? .set_default("search_mode", "fuzzy")?
.set_default("filter_mode", "global")? .set_default("filter_mode", "global")?
.set_default("shell_up_key_binding", false)? .set_default("shell_up_key_binding", false)?
.set_default("inline_height", 0)?
.set_default("show_preview", false)? .set_default("show_preview", false)?
.set_default("exit_mode", "return-original")? .set_default("exit_mode", "return-original")?
.set_default("session_token", "")? .set_default("session_token", "")?

View File

@ -33,7 +33,7 @@ use ratatui::{
style::{Color, Modifier, Style}, style::{Color, Modifier, Style},
text::{Span, Spans, Text}, text::{Span, Spans, Text},
widgets::{Block, BorderType, Borders, Paragraph}, widgets::{Block, BorderType, Borders, Paragraph},
Frame, Terminal, Frame, Terminal, TerminalOptions, Viewport,
}; };
const RETURN_ORIGINAL: usize = usize::MAX; const RETURN_ORIGINAL: usize = usize::MAX;
@ -466,29 +466,37 @@ impl State {
struct Stdout { struct Stdout {
stdout: std::io::Stdout, stdout: std::io::Stdout,
inline_mode: bool,
} }
impl Stdout { impl Stdout {
pub fn new() -> std::io::Result<Self> { pub fn new(inline_mode: bool) -> std::io::Result<Self> {
terminal::enable_raw_mode()?; terminal::enable_raw_mode()?;
let mut stdout = stdout(); let mut stdout = stdout();
if !inline_mode {
execute!(stdout, terminal::EnterAlternateScreen)?;
}
execute!( execute!(
stdout, stdout,
terminal::EnterAlternateScreen,
event::EnableMouseCapture, event::EnableMouseCapture,
event::EnableBracketedPaste event::EnableBracketedPaste,
)?; )?;
Ok(Self { stdout }) Ok(Self {
stdout,
inline_mode,
})
} }
} }
impl Drop for Stdout { impl Drop for Stdout {
fn drop(&mut self) { fn drop(&mut self) {
if !self.inline_mode {
execute!(self.stdout, terminal::LeaveAlternateScreen).unwrap();
}
execute!( execute!(
self.stdout, self.stdout,
terminal::LeaveAlternateScreen,
event::DisableMouseCapture, event::DisableMouseCapture,
event::DisableBracketedPaste event::DisableBracketedPaste,
) )
.unwrap(); .unwrap();
terminal::disable_raw_mode().unwrap(); terminal::disable_raw_mode().unwrap();
@ -531,9 +539,18 @@ pub async fn history(
settings: &Settings, settings: &Settings,
db: &mut impl Database, db: &mut impl Database,
) -> Result<String> { ) -> Result<String> {
let stdout = Stdout::new()?; let stdout = Stdout::new(settings.inline_height > 0)?;
let backend = CrosstermBackend::new(stdout); let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?; let mut terminal = Terminal::with_options(
backend,
TerminalOptions {
viewport: if settings.inline_height > 0 {
Viewport::Inline(settings.inline_height)
} else {
Viewport::Fullscreen
},
},
)?;
let mut input = Cursor::from(query.join(" ")); let mut input = Cursor::from(query.join(" "));
// Put the cursor at the end of the query by default // Put the cursor at the end of the query by default
@ -608,6 +625,11 @@ pub async fn history(
results = app.query_results(db).await?; results = app.query_results(db).await?;
} }
}; };
if settings.inline_height > 0 {
terminal.clear()?;
}
if index < results.len() { if index < results.len() {
// index is in bounds so we return that entry // index is in bounds so we return that entry
Ok(results.swap_remove(index).command.clone()) Ok(results.swap_remove(index).command.clone())