Files
codex/prs/bolinfest/study/PR-2683-study.md
2025-09-02 15:17:45 -07:00

167 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
**Burst Paste Edge Cases: Review Guide (PR #2683)**
**DOs**
- Bold the keyword, then colon + concise description below each, with a short code example.
- Idempotent setters: perform side effects only when state changes.
```rust
fn set_disable_paste_burst(&mut self, disabled: bool) {
let was_disabled = self.disable_paste_burst;
self.disable_paste_burst = disabled;
if disabled && !was_disabled {
self.paste_burst.clear_window_after_non_char();
}
}
```
- Constructor wiring: pass config flags into `new()` and centralize side effects via a setter.
```rust
impl ChatComposer {
pub fn new(..., disable_paste_burst: bool) -> Self {
let mut this = Self { /* fields */, paste_burst: PasteBurst::default(), disable_paste_burst: false };
this.set_disable_paste_burst(disable_paste_burst);
this
}
}
```
- Doc comments: use `///`, describe behavior and return values succinctly.
```rust
/// Flush buffered content if the inter-key timeout elapsed.
/// Returns Some(buffered_or_saved_text) when a flush occurs, otherwise None.
pub fn flush_if_due(&mut self, now: Instant) -> Option<String> { /* ... */ }
```
- Clear, accurate names: use descriptive enum variants (e.g., `RetainFirstChar`).
```rust
pub(crate) enum CharDecision {
BeginBuffer { retro_chars: u16 },
BufferAppend,
RetainFirstChar,
BeginBufferFromPending,
}
```
- Unicode-safe heuristics: count characters, not bytes; document rationale.
```rust
/// Begin buffering if recent text likely came from a paste (whitespace or long).
let looks_pastey = grabbed.chars().any(|c| c.is_whitespace()) || grabbed.chars().count() >= 16;
```
- Tight, total returns: ensure boolean helpers return on all paths; prefer single expression.
```rust
pub(crate) fn handle_paste_burst_tick(&mut self, fr: FrameRequester) -> bool {
if self.bottom_pane.flush_paste_burst_if_due() {
self.request_redraw();
true
} else if self.bottom_pane.is_in_paste_burst() {
fr.schedule_frame_in(ChatComposer::recommended_paste_flush_delay());
true
} else {
false
}
}
```
- Friendly imports: import types once; avoid fully qualified paths where possible.
```rust
use std::time::Duration;
pub(crate) fn request_redraw_in(&self, dur: Duration) {
self.frame_requester.schedule_frame_in(dur);
}
```
- Smart redraw scheduling: request immediate redraw on flush; schedule a delayed tick while capturing.
```rust
if needs_redraw { self.request_redraw(); }
if self.composer.is_in_paste_burst() {
self.request_redraw_in(ChatComposer::recommended_paste_flush_delay());
}
```
- Simple tests: keep helpers minimal; human-like typing with a small delay; use simple literals.
```rust
fn type_chars_humanlike(c: &mut ChatComposer, chars: &[char]) {
for &ch in chars {
let _ = c.handle_key_event(KeyEvent::new(KeyCode::Char(ch), KeyModifiers::NONE));
std::thread::sleep(ChatComposer::recommended_paste_flush_delay());
let _ = c.flush_paste_burst_if_due();
}
}
let count = 32;
```
- Exact fixtures: keep field names and timestamp formats precise.
```json
// Right
{"ts":"2025-08-09T15:58:15.433Z","dir":"to_tui","kind":"app_event","variant":"RequestRedraw"}
// Wrong
{"ts":"2025-08-09T15:58:15.4F33Z","fdir":"to_tui","kind":"app_event","variant":"RequestRedraw"}
```
**DONTs**
- Repeat side effects: dont re-clear state when the flag was already set.
```rust
// Dont: always clear even if already disabled.
self.disable_paste_burst = disabled;
if disabled { self.paste_burst.clear_window_after_non_char(); }
```
- Use `//` where `///` is required: dont skimp on doc comments or omit return-value notes.
```rust
// Dont
// Timer: flush buffered burst if timeout elapsed.
```
- Hide config outside constructors: dont require callers to set flags post-init without a clear reason.
```rust
// Dont
let mut c = ChatComposer::new(...);
c.set_disable_paste_burst(true); // Wire it through new() instead.
```
- Fully qualify types repeatedly: dont write long paths when an import suffices.
```rust
// Dont
pub fn request_redraw_in(&self, dur: std::time::Duration) { /* ... */ }
```
- Count bytes for heuristics: dont use `.len()` on `String` slices for thresholds.
```rust
// Dont
let looks_pastey = grabbed.contains(' ') || grabbed.len() >= 16;
```
- Leave partial returns: dont forget a return value in one branch.
```rust
// Dont
if flushed { self.request_redraw(); /* missing return */ }
```
- Overuse `#[cfg(test)]` inside `mod tests`: dont gate internals unnecessarily within a test module.
```rust
// Dont
#[cfg(test)]
fn helper_in_mod_tests_only() { /* ... */ }
```
- Introduce fixture typos: dont change keys (`dir``fdir`) or corrupt timestamps.
```json
// Dont
{"ts":"...15.4F33Z","fdir":"to_tui", ...}
```
- Redundant renders: dont render and also schedule a follow-up in the same frame when a flush just happened.
```rust
// Dont
self.draw_now();
fr.schedule_frame_in(Duration::from_millis(1));
```
- Aggressive retro-grab: dont yank preceding text unless the heuristic clearly indicates paste.
```rust
// Dont
begin_with_retro_grabbed(before.to_string(), now); // without checking whitespace/length
```