Skip to content

Commit 4e97e4a

Browse files
ColonelBucket8altsem
authored andcommitted
feat: add keybinding to scroll top and bottom
1 parent 5aba426 commit 4e97e4a

9 files changed

Lines changed: 77 additions & 18 deletions

File tree

src/default_config.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ blame.code_line = { mods = "DIM" }
105105

106106
[bindings]
107107
root.quit = ["q", "esc"]
108-
root.refresh = ["g"]
108+
root.refresh = ["g+r"]
109109
root.toggle_section = ["tab"]
110110
root.move_up = ["k", "up"]
111111
root.move_down = ["j", "down"]
@@ -116,6 +116,8 @@ root.move_next_section = ["alt+j", "alt+down"]
116116
root.move_parent_section = ["alt+h", "alt+left"]
117117
root.half_page_up = ["ctrl+u"]
118118
root.half_page_down = ["ctrl+d"]
119+
root.move_top = ["g+g"]
120+
root.move_bottom = ["G"]
119121
root.show_refs = ["Y"]
120122
root.show = ["enter"]
121123
root.discard = ["K"]

src/ops/editor.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,31 @@ impl OpTrait for HalfPageDown {
300300
"Half page down".into()
301301
}
302302
}
303+
304+
pub(crate) struct MoveTop;
305+
impl OpTrait for MoveTop {
306+
fn get_action(&self, _target: &ItemData) -> Option<Action> {
307+
Some(Rc::new(|app, _term| {
308+
app.screen_mut().move_cursor_to_top();
309+
Ok(())
310+
}))
311+
}
312+
313+
fn display(&self, _state: &State) -> String {
314+
"Top".into()
315+
}
316+
}
317+
318+
pub(crate) struct MoveBottom;
319+
impl OpTrait for MoveBottom {
320+
fn get_action(&self, _target: &ItemData) -> Option<Action> {
321+
Some(Rc::new(|app, _term| {
322+
app.screen_mut().move_cursor_to_bottom();
323+
Ok(())
324+
}))
325+
}
326+
327+
fn display(&self, _state: &State) -> String {
328+
"Bottom".into()
329+
}
330+
}

src/ops/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ pub(crate) enum Op {
121121
MovePrevSection,
122122
MoveNextSection,
123123
MoveParentSection,
124+
MoveTop,
125+
MoveBottom,
124126
HalfPageUp,
125127
HalfPageDown,
126128

@@ -153,6 +155,8 @@ impl Op {
153155
Op::MoveParentSection => Box::new(editor::MoveParentSection),
154156
Op::HalfPageUp => Box::new(editor::HalfPageUp),
155157
Op::HalfPageDown => Box::new(editor::HalfPageDown),
158+
Op::MoveTop => Box::new(editor::MoveTop),
159+
Op::MoveBottom => Box::new(editor::MoveBottom),
156160
Op::Checkout => Box::new(branch::Checkout),
157161
Op::CheckoutNewBranch => Box::new(branch::CheckoutNewBranch),
158162
Op::Spinoff => Box::new(branch::Spinoff),

src/screen/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,30 @@ impl Screen {
326326
}
327327
}
328328

329+
pub(crate) fn move_cursor_to_top(&mut self) {
330+
if self.line_index.is_empty() {
331+
return;
332+
}
333+
if let Some(first) = self.find_first_selectable() {
334+
self.cursor = first;
335+
self.scroll = 0;
336+
}
337+
}
338+
339+
pub(crate) fn move_cursor_to_bottom(&mut self) {
340+
if self.line_index.is_empty() {
341+
return;
342+
}
343+
if let Some(last) = self.find_last_selectable() {
344+
self.cursor = last;
345+
self.scroll_fit_end();
346+
}
347+
}
348+
349+
fn find_last_selectable(&self) -> Option<usize> {
350+
(0..self.line_index.len()).rfind(|&line_i| !self.at_line(line_i).unselectable)
351+
}
352+
329353
pub(crate) fn is_collapsed(&self, item: &Item) -> bool {
330354
self.collapsed.contains(&item.id)
331355
}

src/tests/commit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn commit_instant_fixup() {
1919
commit(&ctx.dir, "instant_fixup.txt", "mistake\n");
2020
fs::write(ctx.dir.join("instant_fixup.txt"), "fixed\n").unwrap();
2121
run(&ctx.dir, &["git", "add", "."]);
22-
ctx.update(&mut state, keys("gjjjjjcF"));
22+
ctx.update(&mut state, keys("grjjjjjcF"));
2323

2424
insta::assert_snapshot!(ctx.redact_buffer());
2525
}
@@ -38,7 +38,7 @@ fn commit_instant_fixup_stashes_changes_and_keeps_empty() {
3838
fs::write(ctx.dir.join("instant_fixup.txt"), "fixed\n").unwrap();
3939
run(&ctx.dir, &["git", "add", "."]);
4040
fs::write(ctx.dir.join("instant_fixup.txt"), "unstaged\n").unwrap();
41-
ctx.update(&mut state, keys("gjjjjjjjjjcF"));
41+
ctx.update(&mut state, keys("grjjjjjjjjjcF"));
4242

4343
insta::assert_snapshot!(ctx.redact_buffer());
4444
}

src/tests/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ fn hide_untracked() {
312312
// Git expects "no|normal|all" here; "off" can error on some versions and break `git status`.
313313
config.set_str("status.showUntrackedFiles", "no").unwrap();
314314

315-
ctx.update(&mut app, keys("g"));
315+
ctx.update(&mut app, keys("gr"));
316316
insta::assert_snapshot!(ctx.redact_buffer());
317317
}
318318

@@ -366,7 +366,7 @@ fn updated_externally() {
366366

367367
fs::write(ctx.dir.join("a"), "test\n").unwrap();
368368

369-
ctx.update(&mut app, keys("g"));
369+
ctx.update(&mut app, keys("gr"));
370370
insta::assert_snapshot!(ctx.redact_buffer());
371371
}
372372

@@ -443,7 +443,7 @@ fn crlf_diff() {
443443

444444
commit(&ctx.dir, "crlf.txt", "unchanged\r\nunchanged\r\n");
445445
fs::write(ctx.dir.join("crlf.txt"), "unchanged\r\nchanged\r\n").unwrap();
446-
ctx.update(&mut app, keys("g"));
446+
ctx.update(&mut app, keys("gr"));
447447

448448
insta::assert_snapshot!(ctx.redact_buffer());
449449
}
@@ -455,7 +455,7 @@ fn tab_diff() {
455455

456456
commit(&ctx.dir, "tab.txt", "this has no tab prefixed\n");
457457
fs::write(ctx.dir.join("tab.txt"), "\tthis has a tab prefixed\n").unwrap();
458-
ctx.update(&mut app, keys("g"));
458+
ctx.update(&mut app, keys("gr"));
459459

460460
insta::assert_snapshot!(ctx.redact_buffer());
461461
}
@@ -471,7 +471,7 @@ fn non_utf8_diff() {
471471
b"File with invalid UTF-8: \xff\xfe\n",
472472
)
473473
.unwrap();
474-
ctx.update(&mut app, keys("g"));
474+
ctx.update(&mut app, keys("gr"));
475475

476476
insta::assert_snapshot!(ctx.redact_buffer());
477477
}
@@ -486,7 +486,7 @@ fn ext_diff() {
486486
run(&ctx.dir, &["git", "add", "-N", "unstaged.txt"]);
487487
run(&ctx.dir, &["git", "add", "staged.txt"]);
488488
run(&ctx.dir, &["git", "config", "diff.external", "/dev/null"]);
489-
ctx.update(&mut app, keys("g"));
489+
ctx.update(&mut app, keys("gr"));
490490

491491
insta::assert_snapshot!(ctx.redact_buffer());
492492
}

src/tests/snapshots/gitu__tests__help_menu.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
source: src/tests/mod.rs
3+
assertion_line: 50
34
expression: ctx.redact_buffer()
45
---
56
On branch main |
@@ -16,10 +17,10 @@ expression: ctx.redact_buffer()
1617
alt+k/alt+up Prev section m Merge |
1718
alt+j/alt+down Next section M Remote |
1819
alt+h/alt+left Parent section F Pull |
19-
ctrl+u Half page up P Push |
20-
ctrl+d Half page down r Rebase |
21-
g Refresh X Reset |
22-
q/esc Quit/Close V Revert |
23-
A Cherry-pick |
24-
z Stash |
25-
styles_hash: f023ed50da817507
20+
g+g Top P Push |
21+
G Bottom r Rebase |
22+
ctrl+u Half page up X Reset |
23+
ctrl+d Half page down V Revert |
24+
g+r Refresh A Cherry-pick |
25+
q/esc Quit/Close z Stash |
26+
styles_hash: d3bd90efdd7b7678

src/ui/layout/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ mod tests {
665665
layout.text("<alt+h>/<alt+left> Parent section");
666666
layout.text("<ctrl+u> Half page up");
667667
layout.text("<ctrl+d> Half page down");
668-
layout.text("g Refresh");
668+
layout.text("g+r Refresh");
669669
layout.text("q/<esc> Quit/Close");
670670
});
671671
layout.vertical(None, OPTS, |layout| {

src/ui/layout/snapshots/gitu__ui__layout__tests__gitu_mockup.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ j/<down> Down h/? Help K Discard
2525
<alt+h>/<alt+left> Parent section r Rebase
2626
<ctrl+u> Half page up X Reset
2727
<ctrl+d> Half page down V Revert
28-
g Refresh z Stash
28+
g+r Refresh z Stash
2929
q/<esc> Quit/Close

0 commit comments

Comments
 (0)