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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ Keyboard controls:
| `Shift-Up` / `Shift-Down` | Select a range; release Shift to write the comment |
| `v` | Start or cancel range selection |
| `Enter` | Comment on a source range, edit a focused comment, or save the editor |
| `Shift-Enter` / `Alt-Enter` | Insert a newline in a comment |
| `Ctrl-O` | Insert a newline in a comment |
| `Esc` | Cancel selection or editing |
| `e` / `d` | Edit or delete a focused comment or one on the cursor line |
Expand Down
14 changes: 13 additions & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::BTreeMap;

use ratatui_textarea::{CursorMove, TextArea};
use ratatui_textarea::{CursorMove, TextArea, WrapMode};

use crate::{
domain::{Comment, ReviewDocument},
Expand Down Expand Up @@ -53,6 +53,7 @@ impl CommentEditor {
};
textarea.set_placeholder_text("Write a comment…");
textarea.set_cursor_line_style(ratatui::style::Style::default());
textarea.set_wrap_mode(WrapMode::WordOrGlyph);
textarea.move_cursor(CursorMove::Bottom);
textarea.move_cursor(CursorMove::End);
Self {
Expand Down Expand Up @@ -487,6 +488,17 @@ mod tests {
assert_eq!(app.status.as_deref(), Some("Comment cannot be empty"));
}

#[test]
fn comment_editor_wraps_words_and_long_tokens() {
let mut app = app();
app.open_selected_editor();

assert_eq!(
app.editor.as_ref().unwrap().textarea.wrap_mode(),
WrapMode::WordOrGlyph
);
}

#[test]
fn whitespace_only_comment_stays_open() {
let mut app = app();
Expand Down
32 changes: 32 additions & 0 deletions src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,38 @@ mod tests {
assert!(terminal.backend().to_string().contains("▶─ code"));
}

#[test]
fn annotation_editor_word_wraps_to_its_inner_width() {
let source = SourceBuffer::from_bytes("sample", b"one\n").unwrap();
let review = ReviewDocument::empty(source.source_ref());
let mut app = App::new(source, review);
app.open_selected_editor();
app.editor
.as_mut()
.unwrap()
.textarea
.insert_str("alpha beta gamma delta epsilon");
let backend = TestBackend::new(20, 9);
let mut terminal = Terminal::new(backend).unwrap();

terminal
.draw(|frame| drop(render_app(frame, &mut app)))
.unwrap();

let buffer = terminal.backend().buffer();
let editor_rows = (2..7)
.map(|row| {
(1..19)
.map(|column| buffer[(column, row)].symbol())
.collect::<String>()
})
.collect::<Vec<_>>();
assert!(editor_rows
.iter()
.any(|row| row.contains("alpha beta gamma")));
assert!(editor_rows.iter().any(|row| row.contains("delta epsilon")));
}

#[test]
fn following_cursor_scrolls_long_documents() {
let text = (1..=30)
Expand Down
15 changes: 15 additions & 0 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,21 @@ mod tests {
assert_eq!(app.review.comments[0].body, "x");
}

#[test]
fn shift_enter_inserts_an_annotation_newline_without_submitting() {
let mut app = app();
app.open_selected_editor();
handle_key(
KeyEvent::new(KeyCode::Char('a'), KeyModifiers::NONE),
&mut app,
);

handle_key(KeyEvent::new(KeyCode::Enter, KeyModifiers::SHIFT), &mut app);

assert_eq!(app.editor.as_ref().unwrap().body(), "a\n");
assert!(app.review.comments.is_empty());
}

#[test]
fn shift_arrows_open_the_selected_range_when_shift_is_released() {
let mut app = app();
Expand Down
25 changes: 20 additions & 5 deletions src/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,7 @@ impl TerminalGuard {
PASTE_ENABLED.store(true, Ordering::SeqCst);
execute!(
tty,
PushKeyboardEnhancementFlags(
KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
| KeyboardEnhancementFlags::REPORT_EVENT_TYPES
| KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES
)
PushKeyboardEnhancementFlags(keyboard_enhancement_flags())
)?;
KEYBOARD_ENHANCED.store(true, Ordering::SeqCst);
if mouse_enabled {
Expand All @@ -63,6 +59,13 @@ impl TerminalGuard {
}
}

fn keyboard_enhancement_flags() -> KeyboardEnhancementFlags {
KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
| KeyboardEnhancementFlags::REPORT_EVENT_TYPES
| KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES
| KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
}

impl Drop for TerminalGuard {
fn drop(&mut self) {
restore_terminal();
Expand Down Expand Up @@ -109,3 +112,15 @@ fn restore_terminal() {
let _ = disable_raw_mode();
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn enhanced_input_requests_shifted_characters() {
assert!(
keyboard_enhancement_flags().contains(KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS)
);
}
}