linutil/tui/src/running_command.rs

359 lines
14 KiB
Rust
Raw Normal View History

use crate::{float::FloatContent, hint::Shortcut, shortcuts, theme::Theme};
use linutil_core::Command;
2024-06-06 23:56:45 +01:00
use oneshot::{channel, Receiver};
use portable_pty::{
ChildKiller, CommandBuilder, ExitStatus, MasterPty, NativePtySystem, PtySize, PtySystem,
};
use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind},
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
prelude::*,
symbols::border,
widgets::Block,
2024-06-06 23:56:45 +01:00
};
use std::{
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
fs::File,
io::{Result, Write},
sync::{Arc, Mutex},
thread::JoinHandle,
};
use time::{macros::format_description, OffsetDateTime};
use tui_term::widget::PseudoTerminal;
use vt100_ctt::{Parser, Screen};
2024-06-06 23:56:45 +01:00
pub struct RunningCommand {
/// A buffer to save all the command output (accumulates, until the command exits)
buffer: Arc<Mutex<Vec<u8>>>,
/// A handle for the thread running the command
2024-07-19 14:56:09 +01:00
command_thread: Option<JoinHandle<ExitStatus>>,
/// A handle to kill the running process; it's an option because it can only be used once
child_killer: Option<Receiver<Box<dyn ChildKiller + Send + Sync>>>,
/// A join handle for the thread that reads command output and sends it to the main thread
_reader_thread: JoinHandle<()>,
/// Virtual terminal (pty) handle, used for resizing the pty
pty_master: Box<dyn MasterPty + Send>,
/// Used for sending keys to the emulated terminal
writer: Box<dyn Write + Send>,
/// Only set after the process has ended
status: Option<ExitStatus>,
log_path: Option<String>,
scroll_offset: usize,
2024-06-06 23:56:45 +01:00
}
impl FloatContent for RunningCommand {
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
fn draw(&mut self, frame: &mut Frame, area: Rect, theme: &Theme) {
// Define the block for the terminal display
let block = if !self.is_finished() {
// Display a block indicating the command is running
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
Block::bordered()
.border_set(border::ROUNDED)
.title_top(Line::from("Running the command....").centered())
.title_style(Style::default().reversed())
.title_bottom(Line::from("Press Ctrl-C to KILL the command"))
} else {
// Display a block with the command's exit status
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
let title_line = if self.get_exit_status().success() {
Line::styled(
"SUCCESS! Press <ENTER> to close this window",
Style::default().fg(theme.success_color()).reversed(),
)
} else {
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
Line::styled(
"FAILED! Press <ENTER> to close this window",
Style::default().fg(theme.fail_color()).reversed(),
)
};
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
let log_path = if let Some(log_path) = &self.log_path {
Line::from(format!(" Log saved: {} ", log_path))
} else {
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
Line::from(" Press 'l' to save command log ")
};
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
Block::bordered()
.border_set(border::ROUNDED)
.title_top(title_line.centered())
.title_bottom(log_path.centered())
};
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
// Calculate the inner size of the terminal area, considering borders
let inner_size = block.inner(area).as_size();
// Process the buffer and create the pseudo-terminal widget
let screen = self.screen(inner_size);
let pseudo_term = PseudoTerminal::new(&screen).block(block);
// Render the widget on the frame
frame.render_widget(pseudo_term, area);
}
fn handle_mouse_event(&mut self, event: &MouseEvent) -> bool {
match event.kind {
MouseEventKind::ScrollUp => {
self.scroll_offset = self.scroll_offset.saturating_add(1);
}
MouseEventKind::ScrollDown => {
self.scroll_offset = self.scroll_offset.saturating_sub(1);
}
_ => {}
}
true
}
/// Handle key events of the running command "window". Returns true when the "window" should be
/// closed
fn handle_key_event(&mut self, key: &KeyEvent) -> bool {
match key.code {
// Handle Ctrl-C to kill the command
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
self.kill_child();
}
// Close the window when Enter is pressed and the command is finished
KeyCode::Enter if self.is_finished() => {
return true;
}
KeyCode::PageUp => {
self.scroll_offset = self.scroll_offset.saturating_add(10);
}
KeyCode::PageDown => {
self.scroll_offset = self.scroll_offset.saturating_sub(10);
}
KeyCode::Char('l') if self.is_finished() => {
if let Ok(log_path) = self.save_log() {
self.log_path = Some(log_path);
}
}
// Pass other key events to the terminal
_ => self.handle_passthrough_key_event(key),
}
false
}
fn is_finished(&self) -> bool {
// Check if the command thread has finished
if let Some(command_thread) = &self.command_thread {
command_thread.is_finished()
} else {
true
}
}
2024-09-06 22:36:12 +01:00
fn get_shortcut_list(&self) -> (&str, Box<[Shortcut]>) {
2024-09-06 22:36:12 +01:00
if self.is_finished() {
(
"Finished command",
shortcuts!(
("Close window", ["Enter", "q"]),
("Scroll up", ["Page up"]),
("Scroll down", ["Page down"]),
("Save log", ["l"]),
),
)
2024-09-06 22:36:12 +01:00
} else {
(
"Running command",
shortcuts!(
("Kill the command", ["CTRL-c"]),
("Scroll up", ["Page up"]),
("Scroll down", ["Page down"]),
),
)
2024-09-06 22:36:12 +01:00
}
}
}
2024-06-06 23:56:45 +01:00
impl RunningCommand {
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
pub fn new(commands: &[&Command]) -> Self {
2024-06-06 23:56:45 +01:00
let pty_system = NativePtySystem::default();
// Build the command based on the provided Command enum variant
let mut cmd: CommandBuilder = CommandBuilder::new("sh");
cmd.arg("-c");
// All the merged commands are passed as a single argument to reduce the overhead of rebuilding the command arguments for each and every command
let mut script = String::new();
for command in commands {
match command {
Command::Raw(prompt) => script.push_str(&format!("{}\n", prompt)),
Command::LocalFile {
executable,
args,
file,
} => {
if let Some(parent_directory) = file.parent() {
script.push_str(&format!("cd {}\n", parent_directory.display()));
}
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
script.push_str(executable);
for arg in args {
script.push(' ');
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
script.push_str(arg);
}
2024-09-22 19:24:06 +01:00
script.push('\n'); // Ensures that each command is properly separated for execution preventing directory errors
}
Command::None => panic!("Command::None was treated as a command"),
}
}
2024-06-06 23:56:45 +01:00
cmd.arg(script);
// Open a pseudo-terminal with initial size
2024-06-06 23:56:45 +01:00
let pair = pty_system
.openpty(PtySize {
rows: 24, // Initial number of rows (will be updated dynamically)
cols: 80, // Initial number of columns (will be updated dynamically)
2024-06-06 23:56:45 +01:00
pixel_width: 0,
pixel_height: 0,
})
.unwrap();
let (tx, rx) = channel();
// Thread waiting for the child to complete
let command_handle = std::thread::spawn(move || {
let mut child = pair.slave.spawn_command(cmd).unwrap();
let killer = child.clone_killer();
tx.send(killer).unwrap();
child.wait().unwrap()
});
let mut reader = pair.master.try_clone_reader().unwrap(); // This is a reader, this is where we
// A buffer, shared between the thread that reads the command output, and the main tread.
// The main thread only reads the contents
2024-06-06 23:56:45 +01:00
let command_buffer: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new()));
let reader_handle = {
// Arc is just a reference, so we can create an owned copy without any problem
let command_buffer = command_buffer.clone();
// The closure below moves all variables used into it, so we can no longer use them,
// that's why command_buffer.clone(), because we need to use command_buffer later
2024-06-06 23:56:45 +01:00
std::thread::spawn(move || {
let mut buf = [0u8; 8192];
loop {
let size = reader.read(&mut buf).unwrap(); // Can block here
if size == 0 {
break; // EOF
}
let mut mutex = command_buffer.lock(); // Only lock the mutex after the read is
// done, to minimise the time it is opened
let command_buffer = mutex.as_mut().unwrap();
command_buffer.extend_from_slice(&buf[0..size]);
// The mutex is closed here automatically
}
})
};
let writer = pair.master.take_writer().unwrap();
2024-06-06 23:56:45 +01:00
Self {
buffer: command_buffer,
command_thread: Some(command_handle),
child_killer: Some(rx),
_reader_thread: reader_handle,
pty_master: pair.master,
writer,
2024-06-06 23:56:45 +01:00
status: None,
log_path: None,
scroll_offset: 0,
2024-06-06 23:56:45 +01:00
}
}
2024-06-06 23:56:45 +01:00
fn screen(&mut self, size: Size) -> Screen {
// Resize the emulated pty
self.pty_master
.resize(PtySize {
rows: size.height,
cols: size.width,
pixel_width: 0,
pixel_height: 0,
})
.unwrap();
// Process the buffer with a parser with the current screen size
// We don't actually need to create a new parser every time, but it is so much easier this
2024-06-06 23:56:45 +01:00
// way, and doesn't cost that much
let mut parser = Parser::new(size.height, size.width, 1000);
2024-06-06 23:56:45 +01:00
let mutex = self.buffer.lock();
let buffer = mutex.as_ref().unwrap();
parser.process(buffer);
// Adjust the screen content based on the scroll offset
parser.screen_mut().set_scrollback(self.scroll_offset);
2024-06-06 23:56:45 +01:00
parser.screen().clone()
}
2024-06-06 23:56:45 +01:00
/// This function will block if the command is not finished
fn get_exit_status(&mut self) -> ExitStatus {
if self.command_thread.is_some() {
let handle = self.command_thread.take().unwrap();
let exit_status = handle.join().unwrap();
self.status = Some(exit_status.clone());
exit_status
} else {
self.status.as_ref().unwrap().clone()
}
}
/// Send SIGHUB signal, *not* SIGKILL or SIGTERM, to the child process
2024-06-06 23:56:45 +01:00
pub fn kill_child(&mut self) {
if !self.is_finished() {
let mut killer = self.child_killer.take().unwrap().recv().unwrap();
killer.kill().unwrap();
}
}
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
fn save_log(&self) -> Result<String> {
let mut log_path = std::env::temp_dir();
let date_format = format_description!("[year]-[month]-[day]-[hour]-[minute]-[second]");
log_path.push(format!(
"linutil_log_{}.log",
OffsetDateTime::now_local()
.unwrap_or(OffsetDateTime::now_utc())
.format(&date_format)
.unwrap()
));
refact: rust fixes and optimizations (#933) * fix: getting locked out when running script * Use success and fail colors and reorder imports Use theme color instead of using ratatui::Color for running_command success and fail + search preview text color + min tui warning color, add colors for confirmation prompt, fix inverted success and fail colors * Remove redundant code in themes Removed redundant match statement with a function * Fix scroll beyond list, color bleeding and refact in confirmation.rs Remove unnecessary usage of pub in ConfirmPropmt struct fields, simplify numbering, prevent scrolling beyond list, fix color bleeding * Implement case insensitive, fix word disappearing bug Use regex for case insesitive finding, implement String instead of char<Vec>, fix word disappearing by recalculating the render x for preview text * Revert "Remove redundant code in themes" This reverts commit 3b7e859af80bfa1f453928a74c47efd897e26934. * Reference instead of passing the vector * Revert regex and String implementation Use Vec<char> for search_input to prevent panics when using multi-byte characters, use lowercase conversion instead of regex, Added comments for clarity * Replace ansi and text wrapping code with ratatui Replaced ansi related code for tree sitter highlight with direct ratatui::text. Cache the processed text in appstate to remove processing of text for every frame render.Create paragraph instead of list so that scroll and wrapping can be done without external crates. Add caps keys for handle_key_event. * Fix conflicts * Reference instead of borrowing commands, refact mut variables Reference instead of borrowing commands from state, Refactor draw function variables to immutable, calculate innersize from block instead of manual definition * Update tui/src/filter.rs Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com> * Rendering optimizations and function refactors Handle `find_command` inside state itself -> `get_command_by_name`. Move tips to a seperate file for modularity. Pass the whole args to state instead of seperate args. Use const for float and confirmation prompt float sizes. Add the `longest_tab_length` to appstate struct so that it will not be calculated for each frame render use static str instead String for tips. Use function for spawning confirmprompt. Merge command list and task items list rendering a single widget instead of two. Remove redundant keys in handle_key. Optimize scrolling logic. Rename `toggle_task_list_guide` -> `enable_task_list_guide` * Cleanup Use prelude for ratatui imports. Use const for theme functions, add missing hints * Update deps, remove unused temp-dir * Add accidentally deleted preview.tape Add labels + Wait 2sec after program ends * Add fields to config files Skip Confirmation, Bypass Size * Remove accidentally commited config file --------- Co-authored-by: Liam <33645555+lj3954@users.noreply.github.com>
2024-11-17 18:24:54 +00:00
let mut file = File::create(&log_path)?;
let buffer = self.buffer.lock().unwrap();
file.write_all(&buffer)?;
Ok(log_path.to_string_lossy().into_owned())
}
/// Convert the KeyEvent to pty key codes, and send them to the virtual terminal
fn handle_passthrough_key_event(&mut self, key: &KeyEvent) {
let input_bytes = match key.code {
KeyCode::Char(ch) => {
let raw_utf8 = || ch.to_string().into_bytes();
match ch.to_ascii_uppercase() {
_ if key.modifiers != KeyModifiers::CONTROL => raw_utf8(),
// https://github.com/fyne-io/terminal/blob/master/input.go
// https://gist.github.com/ConnerWill/d4b6c776b509add763e17f9f113fd25b
'2' | '@' | ' ' => vec![0],
'3' | '[' => vec![27],
'4' | '\\' => vec![28],
'5' | ']' => vec![29],
'6' | '^' => vec![30],
'7' | '-' | '_' => vec![31],
c if ('A'..='_').contains(&c) => {
let ascii_val = c as u8;
let ascii_to_send = ascii_val - 64;
vec![ascii_to_send]
}
_ => raw_utf8(),
}
}
KeyCode::Enter => vec![b'\n'],
KeyCode::Backspace => vec![0x7f],
KeyCode::Left => vec![27, 91, 68],
KeyCode::Right => vec![27, 91, 67],
KeyCode::Up => vec![27, 91, 65],
KeyCode::Down => vec![27, 91, 66],
KeyCode::Tab => vec![9],
KeyCode::Home => vec![27, 91, 72],
KeyCode::End => vec![27, 91, 70],
KeyCode::BackTab => vec![27, 91, 90],
KeyCode::Delete => vec![27, 91, 51, 126],
KeyCode::Insert => vec![27, 91, 50, 126],
KeyCode::Esc => vec![27],
_ => return,
};
// Send the keycodes to the virtual terminal
let _ = self.writer.write_all(&input_bytes);
}
2024-07-19 14:56:09 +01:00
}