Skip to content

Commit d9d4bde

Browse files
committed
Fix scroll limitation #41
1 parent fc0e201 commit d9d4bde

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
0.1.1
5+
-----
6+
7+
- Fix scroll limitation in source view #41
8+
49
0.1.0
510
-----
611

src/app.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ impl App {
371371
AppEvent::HistoryNext => {
372372
for _ in 0..self.take_motion() {
373373
self.history.next();
374+
self.recenter();
374375
if self.history.is_current() && (self.listening_status == ListenStatus::Connected) {
375376
self.sender
376377
.send(AppEvent::ChangeSessionViewMode(SessionViewMode::Current))
@@ -381,6 +382,7 @@ impl App {
381382
AppEvent::HistoryPrevious => {
382383
for _ in 0..self.take_motion() {
383384
self.history.previous();
385+
self.recenter();
384386
}
385387
}
386388
AppEvent::Listen => {
@@ -469,6 +471,7 @@ impl App {
469471
self.take_motion() as i16,
470472
);
471473
self.populate_stack_context().await?;
474+
self.recenter();
472475
}
473476
AppEvent::ToggleFullscreen => {
474477
self.session_view.full_screen = !self.session_view.full_screen;
@@ -637,8 +640,9 @@ impl App {
637640
context,
638641
});
639642
}
640-
self.history.push(entry);
641643
self.session_view.reset();
644+
self.history.push(entry);
645+
self.recenter();
642646
Ok(())
643647
}
644648

@@ -671,6 +675,14 @@ impl App {
671675
self.analyzed_files = HashMap::new();
672676
self.workspace.reset();
673677
}
678+
679+
fn recenter(&mut self) -> () {
680+
let entry = self.history.current();
681+
match entry {
682+
Some(entry) => self.session_view.scroll_to_line(entry.source(self.session_view.stack_depth()).line_no),
683+
None => (),
684+
}
685+
}
674686
}
675687

676688
fn apply_scroll(scroll: (u16, u16), amount: (i16, i16), motion: i16) -> (u16, u16) {

src/view/session.rs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::cell::Cell;
2+
13
use super::context::ContextComponent;
24
use super::source::SourceComponent;
35
use super::stack::StackComponent;
@@ -184,6 +186,7 @@ fn build_pane_widget(frame: &mut Frame, app: &App, pane: &Pane, area: Rect, inde
184186
};
185187
}
186188

189+
#[derive(Default)]
187190
pub struct SearchState {
188191
pub show: bool,
189192
pub search: String,
@@ -196,9 +199,11 @@ impl SearchState {
196199
}
197200
}
198201

202+
#[derive(Default)]
199203
pub struct SessionViewState {
200204
pub full_screen: bool,
201205
pub source_scroll: (u16, u16),
206+
pub source_area: Cell<Rect>,
202207
pub context_scroll: (u16, u16),
203208
pub context_filter: SearchState,
204209
pub stack_scroll: (u16, u16),
@@ -207,17 +212,12 @@ pub struct SessionViewState {
207212
pub current_pane: usize,
208213
}
209214

210-
impl Default for SessionViewState {
211-
fn default() -> Self {
212-
Self::new()
213-
}
214-
}
215-
216215
impl SessionViewState {
217216
pub fn new() -> Self {
218217
Self {
219218
full_screen: false,
220219
source_scroll: (0, 0),
220+
source_area: Cell::new(Rect::new(0, 0, 0, 0)),
221221
context_scroll: (0, 0),
222222
context_filter: SearchState {
223223
show: false,
@@ -271,10 +271,56 @@ impl SessionViewState {
271271
pub(crate) fn stack_depth(&self) -> u16 {
272272
self.stack_scroll.0
273273
}
274+
275+
pub(crate) fn scroll_to_line(&mut self, line_no: u32) -> () {
276+
let area = self.source_area.get();
277+
let mid_point = (area.height as u32).div_ceil(2);
278+
let offset = if line_no > mid_point {
279+
line_no - mid_point
280+
} else {
281+
0
282+
};
283+
self.source_scroll.0 = offset as u16;
284+
}
274285
}
275286

276-
#[derive(Debug, Clone)]
287+
#[derive(Debug, Clone, Default)]
277288
pub enum SessionViewMode {
289+
#[default]
278290
Current,
279291
History,
280292
}
293+
294+
#[cfg(test)]
295+
mod test {
296+
use super::*;
297+
298+
#[test]
299+
pub fn scroll_to_line() -> () {
300+
let mut view = SessionViewState::default();
301+
view.source_area = Cell::new(Rect{
302+
x: 0,
303+
y: 0,
304+
width: 0,
305+
height: 10,
306+
});
307+
view.scroll_to_line(0);
308+
309+
assert_eq!(0, view.source_scroll.0);
310+
311+
view.scroll_to_line(5);
312+
assert_eq!(0, view.source_scroll.0);
313+
314+
view.scroll_to_line(6);
315+
assert_eq!(1, view.source_scroll.0);
316+
317+
view.scroll_to_line(10);
318+
assert_eq!(5, view.source_scroll.0);
319+
320+
view.scroll_to_line(20);
321+
assert_eq!(15, view.source_scroll.0);
322+
323+
view.scroll_to_line(100);
324+
assert_eq!(95, view.source_scroll.0);
325+
}
326+
}

src/view/source.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ impl View for SourceComponent {
3434
.constraints(constraints)
3535
.split(area);
3636

37+
// make the app aware of the source area so we can
38+
// center the source code on the releant line when
39+
// setpping into code
40+
app.session_view.source_area.set(rows[0]);
41+
3742
let mut annotations = vec![];
3843
let mut lines: Vec<Line> = Vec::new();
3944

@@ -86,23 +91,16 @@ impl View for SourceComponent {
8691
}
8792
}
8893

89-
let scroll: u16 = if stack.source.line_no as u16 > area.height {
90-
let center = (stack.source.line_no as u16)
91-
.saturating_sub(area.height.div_ceil(2)) as i16;
92-
center
93-
.saturating_add(app.session_view.source_scroll.0 as i16)
94-
.max(0) as u16
95-
} else {
96-
app.session_view.source_scroll.0
97-
};
98-
99-
frame.render_widget(Paragraph::new(lines.clone()).scroll((scroll, app.session_view.source_scroll.1)), rows[0]);
94+
frame.render_widget(
95+
Paragraph::new(lines.clone()).scroll(app.session_view.source_scroll),
96+
rows[0],
97+
);
10098

10199
for (line_no, line_length, line) in annotations {
102100
let x_offset = rows[0].x + (line_length as u16).saturating_sub(app.session_view.source_scroll.1);
103101
let area = Rect {
104102
x: x_offset,
105-
y: (line_no as u32).saturating_sub(scroll as u32) as u16 + 1,
103+
y: (line_no as u32).saturating_sub(app.session_view.source_scroll.0 as u32) as u16 + 1,
106104
width: rows[0].width.saturating_sub(x_offset),
107105
height: 1,
108106
};

0 commit comments

Comments
 (0)