diff --git a/README.md b/README.md index 14a366d..593c4bd 100644 --- a/README.md +++ b/README.md @@ -144,8 +144,10 @@ If you want the exact delta configuration I'm using - [it can be found here](htt | Key | Description | | :---------------- | :------------------------------- | -| j | Next file | -| k | Previous file | +| j | Next node | +| k | Previous node | +| n | Next file | +| p / N | Previous file | | Ctrl-d | Scroll the diff down | | Ctrl-u | Scroll the diff up | | e | Toggle the file tree | diff --git a/pkg/ui/keys.go b/pkg/ui/keys.go index caa9c88..0eb127d 100644 --- a/pkg/ui/keys.go +++ b/pkg/ui/keys.go @@ -8,6 +8,8 @@ type KeyMap struct { ToggleNode key.Binding Up key.Binding Down key.Binding + NextFile key.Binding + PrevFile key.Binding CtrlD key.Binding CtrlU key.Binding ToggleFileTree key.Binding @@ -42,6 +44,14 @@ var keys = &KeyMap{ key.WithKeys("down", "j"), key.WithHelp("↓/j", "next file"), ), + NextFile: key.NewBinding( + key.WithKeys("n"), + key.WithHelp("n", "next file"), + ), + PrevFile: key.NewBinding( + key.WithKeys("p", "N"), + key.WithHelp("p/N", "prev file"), + ), CtrlD: key.NewBinding( key.WithKeys("ctrl+d"), key.WithHelp("ctrl+d", "diff down"), @@ -93,6 +103,8 @@ func KeyGroups() [][]key.Binding { keys.SwitchPanel, keys.Up, keys.Down, + keys.NextFile, + keys.PrevFile, keys.CtrlD, keys.CtrlU, }, { diff --git a/pkg/ui/panes/diffviewer/diffviewer.go b/pkg/ui/panes/diffviewer/diffviewer.go index 94c02a1..b0cb03b 100644 --- a/pkg/ui/panes/diffviewer/diffviewer.go +++ b/pkg/ui/panes/diffviewer/diffviewer.go @@ -69,9 +69,9 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.String() { - case "down", "j": + case "down", "j", "n": break - case "up", "k": + case "up", "k", "N", "p": break default: vp, vpCmd := m.vp.Update(msg) diff --git a/pkg/ui/panes/filetree/filetree.go b/pkg/ui/panes/filetree/filetree.go index 202a1a3..002a783 100644 --- a/pkg/ui/panes/filetree/filetree.go +++ b/pkg/ui/panes/filetree/filetree.go @@ -131,6 +131,52 @@ func (m *Model) Up() { m.t.Up() } +// NextFile moves the cursor to the next file node, skipping directories. +func (m *Model) NextFile() bool { + curr := m.t.NodeAtCurrentOffset() + if curr == nil { + return false + } + nodes := m.t.AllNodes() + found := false + for _, node := range nodes { + if !found { + if node.YOffset() == curr.YOffset() { + found = true + } + continue + } + if _, ok := node.GivenValue().(*filenode.FileNode); ok { + m.t.SetYOffset(node.YOffset()) + return true + } + } + return false +} + +// PrevFile moves the cursor to the previous file node, skipping directories. +func (m *Model) PrevFile() bool { + curr := m.t.NodeAtCurrentOffset() + if curr == nil { + return false + } + nodes := m.t.AllNodes() + lastFileOffset := -1 + for _, node := range nodes { + if node.YOffset() >= curr.YOffset() { + break + } + if _, ok := node.GivenValue().(*filenode.FileNode); ok { + lastFileOffset = node.YOffset() + } + } + if lastFileOffset >= 0 { + m.t.SetYOffset(lastFileOffset) + return true + } + return false +} + func (m *Model) SetCursorByPath(path string) { if len(m.files) == 0 { return diff --git a/pkg/ui/tui.go b/pkg/ui/tui.go index f791f7f..0cf97a3 100644 --- a/pkg/ui/tui.go +++ b/pkg/ui/tui.go @@ -180,6 +180,12 @@ func (m mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { m.activePanel = FileTreePanel } } + case key.Matches(msg, keys.PrevFile): + m, cmd = m.moveToFile(-1) + cmds = append(cmds, cmd) + case key.Matches(msg, keys.NextFile): + m, cmd = m.moveToFile(1) + cmds = append(cmds, cmd) case key.Matches(msg, keys.Up): if m.activePanel == FileTreePanel { m, cmd = m.moveCursor(-1) @@ -743,6 +749,27 @@ func abs(x int) int { return x } +func (m mainModel) moveToFile(movement int) (mainModel, tea.Cmd) { + var cmd tea.Cmd + var moved bool + switch movement { + case -1: + moved = m.fileTree.PrevFile() + case 1: + moved = m.fileTree.NextFile() + } + + if !moved { + return m, nil + } + + node := m.fileTree.GetCurrNode() + m, cmd = m.setNodeDiff(node) + m.diffViewer.GoToTop() + + return m, cmd +} + func (m mainModel) moveCursor(movement int) (mainModel, tea.Cmd) { var cmd tea.Cmd switch movement {