Skip to content

Commit 59f1b3e

Browse files
committed
Reset horizontal scroll when cursor on empty line
Reset horizontal scroll to 0 when the cursor moves onto an empty/blank line. Adds EditorApp fields (reset_scroll_x_pending, previous_cursor_byte_pos) and initializes them. In ui_editor, pending resets are applied before the ScrollArea so they take effect immediately, cursor movement to an empty line schedules the reset, and the final stored scroll state also respects the reset. Temporarily reduces the UI animation time during editor rendering and restores it afterward.
1 parent 529ed84 commit 59f1b3e

3 files changed

Lines changed: 43 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ pub struct EditorApp {
126126
pub(crate) start_maximized: bool,
127127
/// Current maximized state, updated every frame from the OS viewport
128128
pub(crate) is_maximized: bool,
129+
130+
/// Flag to reset horizontal scroll to 0 on next frame (when cursor on empty line)
131+
pub(crate) reset_scroll_x_pending: bool,
132+
133+
/// Previous cursor byte position (to detect navigation)
134+
pub(crate) previous_cursor_byte_pos: Option<usize>,
129135
}
130136

131137
impl EditorApp {
@@ -210,6 +216,8 @@ impl EditorApp {
210216
last_copy_time: None,
211217

212218
style_dirty: true, // Apply style on startup
219+
reset_scroll_x_pending: false,
220+
previous_cursor_byte_pos: None,
213221
}
214222
}
215223
}

src/ui_editor.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ impl EditorApp {
9292
}
9393
}
9494

95+
// Apply pending horizontal scroll reset BEFORE ScrollArea
96+
if self.reset_scroll_x_pending {
97+
scroll_state.offset.x = 0.0;
98+
scroll_state.store(ui.ctx(), scroll_id);
99+
self.reset_scroll_x_pending = false;
100+
}
101+
102+
// The user requested the cursor/scroll animation to be 75% faster
103+
let original_animation_time = ui.style().animation_time;
104+
ui.style_mut().animation_time = original_animation_time * 0.25;
105+
95106
let scroll_output = egui::ScrollArea::both()
96107
.id_salt("main_editor")
97108
.auto_shrink(false)
@@ -443,6 +454,20 @@ impl EditorApp {
443454

444455
self.highlighted_line = Some(line_num);
445456

457+
// Detect if cursor is on an empty or blank line → schedule scroll reset
458+
let line_start = text[..cursor_byte_pos].rfind('\n').map(|i| i + 1).unwrap_or(0);
459+
let line_end = text[cursor_byte_pos..].find('\n').map(|i| cursor_byte_pos + i).unwrap_or(text.len());
460+
let current_line = &text[line_start..line_end];
461+
462+
// Only reset if the cursor ACTUALLY moved to an empty line
463+
// (don't lock the view to 0 if they try to scroll horizontally while on an empty line)
464+
if self.previous_cursor_byte_pos != Some(cursor_byte_pos) {
465+
if current_line.trim().is_empty() {
466+
self.reset_scroll_x_pending = true;
467+
}
468+
}
469+
self.previous_cursor_byte_pos = Some(cursor_byte_pos);
470+
446471
let char_start =
447472
cursor_range.primary.index.min(cursor_range.secondary.index);
448473
let char_end =
@@ -456,8 +481,15 @@ impl EditorApp {
456481
});
457482
});
458483

459-
// Save final scroll state
460-
scroll_output.state.store(ui.ctx(), scroll_id);
484+
// Apply horizontal scroll reset for current frame too
485+
let mut final_state = scroll_output.state;
486+
if self.reset_scroll_x_pending {
487+
final_state.offset.x = 0.0;
488+
}
489+
final_state.store(ui.ctx(), scroll_id);
490+
491+
// Restore animation time
492+
ui.style_mut().animation_time = original_animation_time;
461493
}
462494

463495
fn handle_tab_key(ui: &egui::Ui, id: egui::Id, unindent: bool, text: &mut String, settings: &crate::settings::Settings, is_modified: &mut bool) {

0 commit comments

Comments
 (0)