这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions crates/turborepo-ui/src/tui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ impl<W> App<W> {
Ok(())
}

pub fn scroll_terminal_output_by_page(&mut self, direction: Direction) -> Result<(), Error> {
let pane_rows = self.size.pane_rows();
let task = self.get_full_task_mut()?;
// Scroll by the height of the terminal pane
task.scroll_by(direction, usize::from(pane_rows))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

I hope you don't mind, I added a new method that generalized scrolling instead of scrolling by one in a for loop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice!


Ok(())
}

pub fn enter_search(&mut self) -> Result<(), Error> {
self.section_focus = LayoutSections::Search {
previous_selection: self.active_task()?.to_string(),
Expand Down Expand Up @@ -550,6 +559,18 @@ impl<W> App<W> {
term.resize(pane_rows, pane_cols);
})
}

pub fn jump_to_logs_top(&mut self) -> Result<(), Error> {
let task = self.get_full_task_mut()?;
task.parser.screen_mut().set_scrollback(usize::MAX);
Ok(())
}

pub fn jump_to_logs_bottom(&mut self) -> Result<(), Error> {
let task = self.get_full_task_mut()?;
task.parser.screen_mut().set_scrollback(0);
Ok(())
}
}

impl<W: Write> App<W> {
Expand Down Expand Up @@ -817,6 +838,22 @@ fn update(
app.is_task_selection_pinned = true;
app.scroll_terminal_output(Direction::Down)?;
}
Event::PageUp => {
app.is_task_selection_pinned = true;
app.scroll_terminal_output_by_page(Direction::Up)?;
}
Event::PageDown => {
app.is_task_selection_pinned = true;
app.scroll_terminal_output_by_page(Direction::Down)?;
}
Event::JumpToLogsTop => {
app.is_task_selection_pinned = true;
app.jump_to_logs_top()?;
}
Event::JumpToLogsBottom => {
app.is_task_selection_pinned = true;
app.jump_to_logs_bottom()?;
}
Event::EnterInteractive => {
app.is_task_selection_pinned = true;
app.interact()?;
Expand Down
5 changes: 5 additions & 0 deletions crates/turborepo-ui/src/tui/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ pub enum Event {
Down,
ScrollUp,
ScrollDown,
PageUp,
PageDown,
JumpToLogsTop,
JumpToLogsBottom,
SetStdin {
task: String,
stdin: Box<dyn std::io::Write + Send>,
Expand Down Expand Up @@ -64,6 +68,7 @@ pub enum Event {
SearchBackspace,
}

#[derive(Copy, Clone)]
pub enum Direction {
Up,
Down,
Expand Down
4 changes: 4 additions & 0 deletions crates/turborepo-ui/src/tui/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ fn translate_key_event(options: InputOptions, key_event: KeyEvent) -> Option<Eve
KeyCode::Char('h') => Some(Event::ToggleSidebar),
KeyCode::Char('u') => Some(Event::ScrollUp),
KeyCode::Char('d') => Some(Event::ScrollDown),
KeyCode::PageUp | KeyCode::Char('U') => Some(Event::PageUp),
KeyCode::PageDown | KeyCode::Char('D') => Some(Event::PageDown),
KeyCode::Char('t') => Some(Event::JumpToLogsTop),
KeyCode::Char('b') => Some(Event::JumpToLogsBottom),
KeyCode::Char('m') => Some(Event::ToggleHelpPopup),
KeyCode::Char('p') => Some(Event::TogglePinnedTask),
KeyCode::Up | KeyCode::Char('k') => Some(Event::Up),
Expand Down
13 changes: 9 additions & 4 deletions crates/turborepo-ui/src/tui/pane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const EXIT_INTERACTIVE_HINT: &str = "Ctrl-z - Stop interacting";
const ENTER_INTERACTIVE_HINT: &str = "i - Interact";
const HAS_SELECTION: &str = "c - Copy selection";
const SCROLL_LOGS: &str = "u/d - Scroll logs";
const PAGE_LOGS: &str = "U/D - Page logs";
const JUMP_IN_LOGS: &str = "t/b - Jump to top/buttom";
const TASK_LIST_HIDDEN: &str = "h - Show task list";

pub struct TerminalPane<'a, W> {
Expand Down Expand Up @@ -65,9 +67,9 @@ impl<'a, W> TerminalPane<'a, W> {
match self.section {
LayoutSections::Pane => build_message_vec(&[EXIT_INTERACTIVE_HINT]),
LayoutSections::TaskList if self.has_stdin() => {
build_message_vec(&[ENTER_INTERACTIVE_HINT, SCROLL_LOGS])
build_message_vec(&[ENTER_INTERACTIVE_HINT, SCROLL_LOGS, PAGE_LOGS, JUMP_IN_LOGS])
}
LayoutSections::TaskList => build_message_vec(&[SCROLL_LOGS]),
LayoutSections::TaskList => build_message_vec(&[SCROLL_LOGS, PAGE_LOGS, JUMP_IN_LOGS]),
LayoutSections::Search { results, .. } => {
Line::from(format!("/ {}", results.query())).left_aligned()
}
Expand Down Expand Up @@ -104,14 +106,17 @@ mod test {
let pane = TerminalPane::new(&term, "foo", &LayoutSections::TaskList, true);
assert_eq!(
String::from(pane.footer()),
" i - Interact u/d - Scroll logs"
" i - Interact u/d - Scroll logs U/D - Page logs t/b - Jump to top/buttom"
);
}

#[test]
fn test_footer_non_interactive() {
let term: TerminalOutput<Vec<u8>> = TerminalOutput::new(16, 16, None);
let pane = TerminalPane::new(&term, "foo", &LayoutSections::TaskList, true);
assert_eq!(String::from(pane.footer()), " u/d - Scroll logs");
assert_eq!(
String::from(pane.footer()),
" u/d - Scroll logs U/D - Page logs t/b - Jump to top/buttom"
);
}
}
33 changes: 19 additions & 14 deletions crates/turborepo-ui/src/tui/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ use ratatui::{
widgets::{Block, List, ListItem, Padding},
};

const BIND_LIST: [&str; 12] = [
"m - Toggle this help popup",
"↑ or j - Select previous task",
"↓ or k - Select next task",
"h - Toggle task list",
"p - Toggle pinned task selection",
"/ - Filter tasks to search term",
"ESC - Clear filter",
"i - Interact with task",
"Ctrl+z - Stop interacting with task",
"c - Copy logs selection (Only when logs are selected)",
"u - Scroll logs up",
"d - Scroll logs down",
];
const BIND_LIST: &[&str] = [
"m - Toggle this help popup",
"↑ or j - Select previous task",
"↓ or k - Select next task",
"h - Toggle task list",
"p - Toggle pinned task selection",
"/ - Filter tasks to search term",
"ESC - Clear filter",
"i - Interact with task",
"Ctrl+z - Stop interacting with task",
"c - Copy logs selection (Only when logs are selected)",
"u - Scroll logs up",
"d - Scroll logs down",
"Shift+u - Page logs up",
"Shift+d - Page logs down",
"t - Jump to top of logs",
"b - Jump to bottom of logs",
]
.as_slice();

pub fn popup_area(area: Rect) -> Rect {
let screen_width = area.width;
Expand Down
8 changes: 6 additions & 2 deletions crates/turborepo-ui/src/tui/term_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,14 @@ impl<W> TerminalOutput<W> {
}

pub fn scroll(&mut self, direction: Direction) -> Result<(), Error> {
self.scroll_by(direction, 1)
}

pub fn scroll_by(&mut self, direction: Direction, magnitude: usize) -> Result<(), Error> {
let scrollback = self.parser.screen().scrollback();
let new_scrollback = match direction {
Direction::Up => scrollback + 1,
Direction::Down => scrollback.saturating_sub(1),
Direction::Up => scrollback.saturating_add(magnitude),
Direction::Down => scrollback.saturating_sub(magnitude),
};
self.parser.screen_mut().set_scrollback(new_scrollback);
Ok(())
Expand Down
Loading