Skip to content

Commit 2d45b68

Browse files
committed
feat(tui): add log selection and clipboard copy functionality
1 parent 3e62547 commit 2d45b68

5 files changed

Lines changed: 750 additions & 38 deletions

File tree

Cargo.lock

Lines changed: 143 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7+
arboard = { version = "3.6.1", default-features = false }
78
axum = { version = "0.8.8", features = ["json", "macros"] }
89
crossterm = "0.29.0"
910
ratatui = { version = "0.29.0", default-features = false, features = ["crossterm"] }

src/application/command_parser.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,14 @@ fn ensure_single_command(input: &str) -> Result<(), CommandParseError> {
127127
continue;
128128
}
129129

130-
if in_single_quote || in_double_quote {
131-
continue;
132-
}
133-
134130
if ch == ';' || ch == '|' || ch == '\n' || ch == '\r' {
135131
return Err(CommandParseError::MultipleCommandsNotAllowed);
136132
}
137133

134+
if in_single_quote || in_double_quote {
135+
continue;
136+
}
137+
138138
if ch == '&' && matches!(chars.peek(), Some('&')) {
139139
return Err(CommandParseError::MultipleCommandsNotAllowed);
140140
}
@@ -182,4 +182,11 @@ mod tests {
182182
assert_eq!(parsed.program, "python");
183183
assert_eq!(parsed.args, vec!["-c", "print('a && b')"]);
184184
}
185+
186+
#[test]
187+
fn rejects_newline_inside_quotes() {
188+
let error = parse_command_line("python -c \"line1\nline2\"")
189+
.expect_err("newline should be rejected even inside quotes");
190+
assert_eq!(error, CommandParseError::MultipleCommandsNotAllowed);
191+
}
185192
}

0 commit comments

Comments
 (0)