this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

last selection kinks

alice 1262a28c 17fc2bac

+54 -4
+23 -4
tic80_rust/src/editor/code.rs
··· 284 284 // Right-justified 3-digit label, drawn flush to gutter (no extra left/right padding) 285 285 let _ = fb.print_text(&label, area.x, gutter_y, 14, true, 1, true); 286 286 287 - // Text slice 288 - let mut line = self.rope.line(line_idx).to_string(); 289 - if line.ends_with('\n') { 290 - line.pop(); 287 + // Text slice (track newline separately to handle selection over EOL/empty lines) 288 + let mut src_line = self.rope.line(line_idx).to_string(); 289 + let had_nl = src_line.ends_with('\n'); 290 + if had_nl { 291 + src_line.pop(); 291 292 } 293 + let line = src_line; 292 294 let start = self.scroll_col.min(line.chars().count()); 293 295 let mut iter = line.chars().skip(start); 294 296 let vis: String = iter.by_ref().take(cols_vis).collect(); ··· 313 315 let s = ch.to_string(); 314 316 // TIC default text color (no syntax) is white (12), 6px tall 315 317 let _ = fb.print_text(&s, cell_x, cell_y, 12, true, 1, true); 318 + } 319 + } 320 + // Extra selection cell for newline (EOL) when selected 321 + if had_nl { 322 + if let Some((sel_start, sel_end)) = sel { 323 + let display_len = line.chars().count(); 324 + let nl_idx = line_char_start + display_len; // index of '\n' in rope for this line 325 + if sel_start <= nl_idx && sel_end > nl_idx { 326 + let nl_col = i32::try_from(display_len).unwrap_or(0); 327 + let col_vis = nl_col - self.scroll_col as i32; 328 + if col_vis >= 0 && col_vis < cols_vis as i32 { 329 + let cell_x = area.x + gutter_w + gap + col_vis * 6; 330 + let cell_y = gutter_y; 331 + fb.rect(cell_x, cell_y, 7, 7, 0); 332 + fb.rect(cell_x - 1, cell_y - 1, 7, 7, 14); 333 + } 334 + } 316 335 } 317 336 } 318 337 }
+31
tic80_rust/tests/editor_newline_selection_tests.rs
··· 1 + use std::cell::RefCell; 2 + use std::rc::Rc; 3 + 4 + use tic80_rust::editor::code::{Area, CodeBuffer}; 5 + use tic80_rust::gfx::framebuffer::Framebuffer; 6 + 7 + #[test] 8 + fn selection_covers_newline_cell_on_empty_line() { 9 + // Line 1 is empty between a and b 10 + let text = "a\n\nb\n"; 11 + let mut cb = CodeBuffer::from_text(text); 12 + // Select from end of first line through the empty line 13 + cb.caret_line = 0; 14 + cb.caret_col = 1; // after 'a' 15 + cb.start_selection(); 16 + cb.caret_line = 2; 17 + cb.caret_col = 0; // before 'b' 18 + 19 + let fb_rc = Rc::new(RefCell::new(Framebuffer::new())); 20 + let mut fb = fb_rc.borrow_mut(); 21 + let area = Area { x: 0, y: 7, w: 240, h: 40 }; 22 + cb.draw(&mut fb, area); 23 + 24 + // Expect a selection cell drawn on the empty line at column 0 (gutter=18 + gap=1) 25 + let gutter = 18i32; 26 + let gap = 1i32; 27 + let x = gutter + gap; 28 + let y = area.y + 7; // second row (empty line) 29 + let c = fb.pix(x, y, None).unwrap_or(0); 30 + assert_ne!(c, 0, "expected selection cell on empty line for newline"); 31 + }