summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go1
-rw-r--r--pkg/git/branch.go32
-rw-r--r--pkg/git/commit.go40
-rw-r--r--pkg/git/git-commands.go10
-rw-r--r--pkg/git/remote.go36
-rw-r--r--pkg/git/remotebranch.go57
-rw-r--r--pkg/gui/branchview.go33
-rw-r--r--pkg/gui/commitsview.go4
-rw-r--r--pkg/gui/diffview.go4
-rw-r--r--pkg/gui/errorview.go10
-rw-r--r--pkg/gui/gui-navigate.go54
-rw-r--r--pkg/gui/gui.go4
-rw-r--r--pkg/gui/keybindings.go322
-rw-r--r--pkg/gui/remotebranchview.go21
-rw-r--r--pkg/gui/remotesview.go25
15 files changed, 516 insertions, 137 deletions
diff --git a/main.go b/main.go
index 3e011e9..011f952 100644
--- a/main.go
+++ b/main.go
@@ -17,6 +17,7 @@ var (
)
func main() {
+ kingpin.Version("gitbatch version 0.0.1 (alpha)")
// parse the command line flag and options
kingpin.Parse()
diff --git a/pkg/git/branch.go b/pkg/git/branch.go
index 7c67992..204ddb2 100644
--- a/pkg/git/branch.go
+++ b/pkg/git/branch.go
@@ -59,6 +59,24 @@ func (entity *RepoEntity) loadLocalBranches() error {
// NextBranch checkouts the next branch
func (entity *RepoEntity) NextBranch() *Branch {
+ currentBranchIndex := entity.findCurrentBranchIndex()
+ if currentBranchIndex == len(entity.Branches)-1 {
+ return entity.Branches[0]
+ }
+ return entity.Branches[currentBranchIndex+1]
+}
+
+// PreviousBranch checkouts the previous branch
+func (entity *RepoEntity) PreviousBranch() *Branch {
+ currentBranchIndex := entity.findCurrentBranchIndex()
+ if currentBranchIndex == 0 {
+ return entity.Branches[len(entity.Branches)-1]
+ }
+ return entity.Branches[currentBranchIndex-1]
+}
+
+// returns the active branch index
+func (entity *RepoEntity) findCurrentBranchIndex() int {
currentBranch := entity.Branch
currentBranchIndex := 0
for i, lbs := range entity.Branches {
@@ -66,10 +84,7 @@ func (entity *RepoEntity) NextBranch() *Branch {
currentBranchIndex = i
}
}
- if currentBranchIndex == len(entity.Branches)-1 {
- return entity.Branches[0]
- }
- return entity.Branches[currentBranchIndex+1]
+ return currentBranchIndex
}
// Checkout to given branch. If any errors occur, the method returns it instead
@@ -152,3 +167,12 @@ func (entity *RepoEntity) pullDiffsToUpstream() ([]*Commit, error) {
}
return remoteCommits, nil
}
+
+func (entity *RepoEntity) pushDiffsToUpstream() ([]string, error) {
+ sliced := make([]string, 0)
+ hashes := UpstreamPushDiffs(entity.AbsPath)
+ if hashes != "?" {
+ sliced = strings.Split(hashes, "\n")
+ }
+ return sliced, nil
+}
diff --git a/pkg/git/commit.go b/pkg/git/commit.go
index a15b3a4..13b0f54 100644
--- a/pkg/git/commit.go
+++ b/pkg/git/commit.go
@@ -27,18 +27,15 @@ const (
// LocalCommit is the commit that recorded locally
LocalCommit CommitType = "local"
// RemoteCommit is the commit that not merged to local branch
+ EvenCommit CommitType = "even"
+ // RemoteCommit is the commit that not merged to local branch
RemoteCommit CommitType = "remote"
)
// NextCommit iterates over next commit of a branch
// TODO: the commits entites can tied to branch instead ot the repository
func (entity *RepoEntity) NextCommit() error {
- currentCommitIndex := 0
- for i, cs := range entity.Commits {
- if cs.Hash == entity.Commit.Hash {
- currentCommitIndex = i
- }
- }
+ currentCommitIndex := entity.findCurrentCommitIndex()
if currentCommitIndex == len(entity.Commits)-1 {
entity.Commit = entity.Commits[0]
return nil
@@ -49,12 +46,7 @@ func (entity *RepoEntity) NextCommit() error {
// PreviousCommit iterates to opposite direction
func (entity *RepoEntity) PreviousCommit() error {
- currentCommitIndex := 0
- for i, cs := range entity.Commits {
- if cs.Hash == entity.Commit.Hash {
- currentCommitIndex = i
- }
- }
+ currentCommitIndex := entity.findCurrentCommitIndex()
if currentCommitIndex == 0 {
entity.Commit = entity.Commits[len(entity.Commits)-1]
return nil
@@ -63,6 +55,17 @@ func (entity *RepoEntity) PreviousCommit() error {
return nil
}
+// returns the active commit index
+func (entity *RepoEntity) findCurrentCommitIndex() int {
+ currentCommitIndex := 0
+ for i, cs := range entity.Commits {
+ if cs.Hash == entity.Commit.Hash {
+ currentCommitIndex = i
+ }
+ }
+ return currentCommitIndex
+}
+
// loads the local commits by simply using git log way. ALso, gets the upstream
// diff commits
func (entity *RepoEntity) loadCommits() error {
@@ -91,15 +94,26 @@ func (entity *RepoEntity) loadCommits() error {
for _, rmc := range rmcs {
entity.Commits = append(entity.Commits, rmc)
}
+ lcs, err := entity.pushDiffsToUpstream()
+ if err != nil {
+ log.Trace("git rev-list failed " + err.Error())
+ return err
+ }
// ... just iterates over the commits
err = cIter.ForEach(func(c *object.Commit) error {
re := regexp.MustCompile(`\r?\n`)
+ cmType := EvenCommit
+ for _, lc := range lcs {
+ if lc == re.ReplaceAllString(c.Hash.String(), " ") {
+ cmType = LocalCommit
+ }
+ }
commit := &Commit{
Hash: re.ReplaceAllString(c.Hash.String(), " "),
Author: c.Author.Email,
Message: re.ReplaceAllString(c.Message, " "),
Time: c.Author.When.String(),
- CommitType: LocalCommit,
+ CommitType: cmType,
}
entity.Commits = append(entity.Commits, commit)
diff --git a/pkg/git/git-commands.go b/pkg/git/git-commands.go
index 9518322..fdcec12 100644
--- a/pkg/git/git-commands.go
+++ b/pkg/git/git-commands.go
@@ -93,6 +93,16 @@ func (entity *RepoEntity) FetchWithGit(remote string) error {
return nil
}
+// DryFetchAndPruneWithGit is wrapper of the git fetch <remote> --prune --dry-run command
+func (entity *RepoEntity) DryFetchAndPruneWithGit(remote string) string {
+ args := []string{"fetch", remote, "--prune", "--dry-run"}
+ d, err := helpers.RunCommandWithOutput(entity.AbsPath, "git", args)
+ if err != nil {
+ return "?"
+ }
+ return d
+}
+
// PullWithGit is wrapper of the git pull <remote>/<branch> command
func (entity *RepoEntity) PullWithGit(remote, branch string) error {
args := []string{"pull", remote, branch}
diff --git a/pkg/git/remote.go b/pkg/git/remote.go
index 7ea896f..d1aeeab 100644
--- a/pkg/git/remote.go
+++ b/pkg/git/remote.go
@@ -16,13 +16,7 @@ type Remote struct {
// NextRemote iterates over next branch of a remote
func (entity *RepoEntity) NextRemote() error {
- currentRemoteIndex := 0
- for i, remote := range entity.Remotes {
- if remote.Name == entity.Remote.Name {
- currentRemoteIndex = i
- }
- }
- // WARNING: DIDN'T CHECK THE LIFE CYCLE
+ currentRemoteIndex := entity.findCurrentRemoteIndex()
if currentRemoteIndex == len(entity.Remotes)-1 {
entity.Remote = entity.Remotes[0]
} else {
@@ -35,6 +29,32 @@ func (entity *RepoEntity) NextRemote() error {
return nil
}
+// PreviousRemote iterates over previous branch of a remote
+func (entity *RepoEntity) PreviousRemote() error {
+ currentRemoteIndex := entity.findCurrentRemoteIndex()
+ if currentRemoteIndex == 0 {
+ entity.Remote = entity.Remotes[len(entity.Remotes)-1]
+ } else {
+ entity.Remote = entity.Remotes[currentRemoteIndex-1]
+ }
+ // TODO: same code on 3 different occasion, maybe something wrong?
+ if err := entity.Remote.switchRemoteBranch(entity.Remote.Name + "/" + entity.Branch.Name); err != nil {
+ // probably couldn't find, but its ok.
+ }
+ return nil
+}
+
+// returns the active remote index
+func (entity *RepoEntity) findCurrentRemoteIndex() int {
+ currentRemoteIndex := 0
+ for i, remote := range entity.Remotes {
+ if remote.Name == entity.Remote.Name {
+ currentRemoteIndex = i
+ }
+ }
+ return currentRemoteIndex
+}
+
// search for remotes in go-git way. It is the short way to get remotes but it
// does not give any insght about remote branches
func (entity *RepoEntity) loadRemotes() error {
@@ -48,7 +68,7 @@ func (entity *RepoEntity) loadRemotes() error {
Name: rm.Config().Name,
URL: rm.Config().URLs,
}
- remote.loadRemoteBranches(&r)
+ remote.loadRemoteBranches(entity)
if len(remote.Branches) > 0 {
remote.Branch = remote.Branches[0]
}
diff --git a/pkg/git/remotebranch.go b/pkg/git/remotebranch.go
index 6ece4a2..c58a6d4 100644
--- a/pkg/git/remotebranch.go
+++ b/pkg/git/remotebranch.go
@@ -2,10 +2,11 @@ package git
import (
"errors"
+ "regexp"
"strings"
+ "github.com/isacikgoz/gitbatch/pkg/helpers"
log "github.com/sirupsen/logrus"
- "gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/storer"
)
@@ -15,17 +16,12 @@ import (
type RemoteBranch struct {
Name string
Reference *plumbing.Reference
+ Deleted bool
}
// NextRemoteBranch iterates to the next remote branch
func (remote *Remote) NextRemoteBranch() error {
- currentRemoteIndex := 0
- for i, rb := range remote.Branches {
- if rb.Reference.Hash() == remote.Branch.Reference.Hash() {
- currentRemoteIndex = i
- }
- }
- // WARNING: DIDN'T CHECK THE LIFE CYCLE
+ currentRemoteIndex := remote.findCurrentRemoteBranchIndex()
if currentRemoteIndex == len(remote.Branches)-1 {
remote.Branch = remote.Branches[0]
} else {
@@ -34,21 +30,45 @@ func (remote *Remote) NextRemoteBranch() error {
return nil
}
+// PreviousRemoteBranch iterates to the previous remote branch
+func (remote *Remote) PreviousRemoteBranch() error {
+ currentRemoteIndex := remote.findCurrentRemoteBranchIndex()
+ if currentRemoteIndex == 0 {
+ remote.Branch = remote.Branches[len(remote.Branches)-1]
+ } else {
+ remote.Branch = remote.Branches[currentRemoteIndex-1]
+ }
+ return nil
+}
+
+// returns the active remote branch index
+func (remote *Remote) findCurrentRemoteBranchIndex() int {
+ currentRemoteIndex := 0
+ for i, rb := range remote.Branches {
+ if rb.Reference.Hash() == remote.Branch.Reference.Hash() {
+ currentRemoteIndex = i
+ }
+ }
+ return currentRemoteIndex
+}
+
// search for the remote branches of the remote. It takes the go-git's repo
// pointer in order to get storer struct
-func (remote *Remote) loadRemoteBranches(r *git.Repository) error {
+func (remote *Remote) loadRemoteBranches(entity *RepoEntity) error {
remote.Branches = make([]*RemoteBranch, 0)
- bs, err := remoteBranchesIter(r.Storer)
+ bs, err := remoteBranchesIter(entity.Repository.Storer)
if err != nil {
log.Warn("Cannot initiate iterator " + err.Error())
return err
}
defer bs.Close()
err = bs.ForEach(func(b *plumbing.Reference) error {
+ deleted := false
if strings.Split(b.Name().Short(), "/")[0] == remote.Name {
remote.Branches = append(remote.Branches, &RemoteBranch{
Name: b.Name().Short(),
Reference: b,
+ Deleted: deleted,
})
}
return nil
@@ -86,3 +106,20 @@ func (remote *Remote) switchRemoteBranch(remoteBranchName string) error {
}
return errors.New("Remote branch not found.")
}
+
+func deletedRemoteBranches(entity *RepoEntity, remote string) ([]string, error) {
+ deletedRemoteBranches := make([]string, 0)
+ output := entity.DryFetchAndPruneWithGit(remote)
+ output = helpers.TrimTrailingNewline(output)
+ re := regexp.MustCompile(` - \[deleted\].+-> `)
+ if output != "?" {
+ sliced := strings.Split(output, "\n")
+ for _, s := range sliced {
+ if re.MatchString(s) {
+ ss := re.ReplaceAllString(s, "")
+ deletedRemoteBranches = append(deletedRemoteBranches, ss)
+ }
+ }
+ }
+ return deletedRemoteBranches, nil
+}
diff --git a/pkg/gui/branchview.go b/pkg/gui/branchview.go
index a64c3c3..b6a2b43 100644
--- a/pkg/gui/branchview.go
+++ b/pkg/gui/branchview.go
@@ -10,7 +10,7 @@ import (
// updates the branchview for given entity
func (gui *Gui) updateBranch(g *gocui.Gui, entity *git.RepoEntity) error {
var err error
- out, err := g.View("branch")
+ out, err := g.View(branchViewFeature.Name)
if err != nil {
return err
}
@@ -38,11 +38,38 @@ func (gui *Gui) nextBranch(g *gocui.Gui, v *gocui.View) error {
entity := gui.getSelectedRepository()
if err = entity.Checkout(entity.NextBranch()); err != nil {
if err = gui.openErrorView(g, err.Error(),
- "You should manually resolve this issue"); err != nil {
+ "You should manually resolve this issue",
+ branchViewFeature.Name); err != nil {
return err
}
return nil
}
+ if err = gui.checkoutFollowUp(g, entity); err != nil {
+ return err
+ }
+ return nil
+}
+
+// iteration handler for the branchview
+func (gui *Gui) previousBranch(g *gocui.Gui, v *gocui.View) error {
+ var err error
+ entity := gui.getSelectedRepository()
+ if err = entity.Checkout(entity.PreviousBranch()); err != nil {
+ if err = gui.openErrorView(g, err.Error(),
+ "You should manually resolve this issue",
+ branchViewFeature.Name); err != nil {
+ return err
+ }
+ return nil
+ }
+ if err = gui.checkoutFollowUp(g, entity); err != nil {
+ return err
+ }
+ return nil
+}
+
+// after checkout a branch some refreshments needed
+func (gui *Gui) checkoutFollowUp(g *gocui.Gui, entity *git.RepoEntity) (err error) {
if err = gui.updateBranch(g, entity); err != nil {
return err
}
@@ -56,4 +83,4 @@ func (gui *Gui) nextBranch(g *gocui.Gui, v *gocui.View) error {
return err
}
return nil
-}
+} \ No newline at end of file
diff --git a/pkg/gui/commitsview.go b/pkg/gui/commitsview.go
index 91cb795..6d1325c 100644
--- a/pkg/gui/commitsview.go
+++ b/pkg/gui/commitsview.go
@@ -20,8 +20,10 @@ func (gui *Gui) updateCommits(g *gocui.Gui, entity *git.RepoEntity) error {
totalcommits := len(entity.Commits)
for i, c := range entity.Commits {
var body string
- if c.CommitType == git.LocalCommit {
+ if c.CommitType == git.EvenCommit {
body = cyan.Sprint(c.Hash[:hashLength]) + " " + c.Message
+ } else if c.CommitType == git.LocalCommit {
+ body = blue.Sprint(c.Hash[:hashLength]) + " " + c.Message
} else {
body = yellow.Sprint(c.Hash[:hashLength]) + " " + c.Message
}
diff --git a/pkg/gui/diffview.go b/pkg/gui/diffview.go
index 6f512ce..b775f95 100644
--- a/pkg/gui/diffview.go
+++ b/pkg/gui/diffview.go
@@ -47,10 +47,10 @@ func (gui *Gui) closeCommitDiffView(g *gocui.Gui, v *gocui.View) error {
if err := g.DeleteView(v.Name()); err != nil {
return nil
}
- if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil {
+ if _, err := g.SetCurrentView(commitViewFeature.Name); err != nil {
return err
}
- gui.updateKeyBindingsView(g, mainViewFeature.Name)
+ gui.updateKeyBindingsView(g, commitViewFeature.Name)
return nil
}
diff --git a/pkg/gui/errorview.go b/pkg/gui/errorview.go
index 362a656..b4be162 100644
--- a/pkg/gui/errorview.go
+++ b/pkg/gui/errorview.go
@@ -6,10 +6,12 @@ import (
"github.com/jroimartin/gocui"
)
+var errorReturnView string
+
// open an error view to inform user with a message and a useful note
-func (gui *Gui) openErrorView(g *gocui.Gui, message string, note string) error {
+func (gui *Gui) openErrorView(g *gocui.Gui, message, note, returnViewName string) error {
maxX, maxY := g.Size()
-
+ errorReturnView = returnViewName
v, err := g.SetView(errorViewFeature.Name, maxX/2-30, maxY/2-3, maxX/2+30, maxY/2+3)
if err != nil {
if err != gocui.ErrUnknownView {
@@ -34,9 +36,9 @@ func (gui *Gui) closeErrorView(g *gocui.Gui, v *gocui.View) error {
if err := g.DeleteView(v.Name()); err != nil {
return nil
}
- if _, err := g.SetCurrentView(mainViewFeature.Name); err != nil {
+ if _, err := g.SetCurrentView(errorReturnView); err != nil {
return err
}
- gui.updateKeyBindingsView(g, mainViewFeature.Name)
+ gui.updateKeyBindingsView(g, errorReturnView)
return nil
}
diff --git a/pkg/gui/gui-navigate.go b/pkg/gui/gui-navigate.go
new file mode 100644
index 0000000..56d96de
--- /dev/null
+++ b/pkg/gui/gui-navigate.go
@@ -0,0 +1,54 @@
+package gui
+
+import (
+ log "github.com/sirupsen/logrus"
+ "github.com/jroimartin/gocui"
+)
+
+// focus to next view
+func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
+ var focusedViewName string
+ if v == nil || v.Name() == mainViews[len(mainViews)-1].Name {
+ focusedViewName = mainViews[0].Name
+ } else {
+ for i := range mainViews {
+ if v.Name() == mainViews[i].Name {
+ focusedViewName = mainViews[i+1].Name
+ break
+ }
+ if i == len(mainViews)-1 {
+ return nil
+ }
+ }
+ }
+ if _, err := g.SetCurrentView(focusedViewName); err != nil {
+ log.Warn("Loading view cannot be focused.")
+ return nil
+ }
+ gui.updateKeyBindingsView(g, focusedViewName)
+ return nil
+}
+
+// focus to previous view
+func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
+ var focusedViewName string
+ if v == nil || v.Name() == mainViews[0].Name {
+ focusedViewName = mainViews[len(mainViews)-1].Name
+ } else {
+ for i := range mainViews {
+ if v.Name() == mainViews[i].Name {
+ focusedViewName = mainViews[i-1].Name
+ break
+ }
+ if i == len(mainViews)-1 {
+ return nil
+ }
+ }
+ }
+ if _, err := g.SetCurrentView(focusedViewName); err != nil {
+ log.Warn("Loading view cannot be focused.")
+ return nil
+ }
+ gui.updateKeyBindingsView(g, focusedViewName)
+ return nil
+}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index c6950fb..b781ba5 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -68,6 +68,8 @@ var (
fetchMode = mode{ModeID: FetchMode, DisplayString: "Fetch", CommandString: "fetch"}
pullMode = mode{ModeID: PullMode, DisplayString: "Pull", CommandString: "pull"}
mergeMode = mode{ModeID: MergeMode, DisplayString: "Merge", CommandString: "merge"}
+
+ mainViews = []viewFeature{mainViewFeature, remoteViewFeature, remoteBranchViewFeature, branchViewFeature, commitViewFeature}
)
// NewGui creates a Gui opject and fill it's state related entites
@@ -117,6 +119,8 @@ func (gui *Gui) Run() error {
defer g.Close()
gui.g = g
+ g.Highlight = true
+ g.SelFgColor = gocui.ColorGreen
g.SetManagerFunc(gui.layout)
if err := gui.generateKeybindings(); err != nil {
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index a388b51..b2622bc 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -20,32 +20,65 @@ type KeyBinding struct {
// generate the gui's controls a.k.a. keybindings
func (gui *Gui) generateKeybindings() error {
- gui.KeyBindings = []*KeyBinding{
+ // Mainviews common keybindings
+ for _, view := range mainViews {
+ mainKeybindings := []*KeyBinding{
+ {
+ View: view.Name,
+ Key: 'q',
+ Modifier: gocui.ModNone,
+ Handler: gui.quit,
+ Display: "q",
+ Description: "Quit",
+ Vital: true,
+ }, {
+ View: view.Name,
+ Key: gocui.KeyTab,
+ Modifier: gocui.ModNone,
+ Handler: gui.switchMode,
+ Display: "tab",
+ Description: "Switch mode",
+ Vital: true,
+ }, {
+ View: view.Name,
+ Key: gocui.KeyArrowLeft,
+ Modifier: gocui.ModNone,
+ Handler: gui.previousView,
+ Display: "←",
+ Description: "Previous Panel",
+ Vital: false,
+ }, {
+ View: view.Name,
+ Key: gocui.KeyArrowRight,
+ Modifier: gocui.ModNone,
+ Handler: gui.nextView,
+ Display: "→",
+ Description: "Next Panel",
+ Vital: false,
+ }, {
+ View: view.Name,
+ Key: 'l',
+ Modifier: gocui.ModNone,
+ Handler: gui.nextView,
+ Display: "l",
+ Description: "Previous Panel",
+ Vital: false,
+ }, {
+ View: view.Name,
+ Key: 'h',
+ Modifier: gocui.ModNone,
+ Handler: gui.previousView,
+ Display: "h",
+ Description: "Next Panel",
+ Vital: false,
+ },
+ }
+ for _, binding := range mainKeybindings {
+ gui.KeyBindings = append(gui.KeyBindings, binding)
+ }
+ }
+ individualKeybindings := []*KeyBinding{
{
- View: "",
- Key: gocui.KeyCtrlC,
- Modifier: gocui.ModNone,
- Handler: gui.quit,
- Display: "ctrl + c",
- Description: "Force application to quit",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 'q',
- Modifier: gocui.ModNone,
- Handler: gui.quit,
- Display: "q",
- Description: "Quit",
- Vital: true,
- }, {
- View: mainViewFeature.Name,
- Key: gocui.KeyTab,
- Modifier: gocui.ModNone,
- Handler: gui.switchMode,
- Display: "tab",
- Description: "Switch mode",
- Vital: true,
- }, {
View: mainViewFeature.Name,
Key: gocui.KeyArrowUp,
Modifier: gocui.ModNone,
@@ -79,59 +112,11 @@ func (gui *Gui) generateKeybindings() error {
Vital: false,
}, {
View: mainViewFeature.Name,
- Key: 'b',
- Modifier: gocui.ModNone,
- Handler: gui.nextBranch,
- Display: "b",
- Description: "Iterate over branches",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 'r',
- Modifier: gocui.ModNone,
- Handler: gui.nextRemote,
- Display: "r",
- Description: "Iterate over remotes",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 'e',
- Modifier: gocui.ModNone,
- Handler: gui.nextRemoteBranch,
- Display: "e",
- Description: "Iterate over remote branches",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 's',
- Modifier: gocui.ModNone,
- Handler: gui.nextCommit,
- Display: "s",
- Description: "Iterate over commits",
- Vital: false,
- },{
- View: mainViewFeature.Name,
- Key: 's',
- Modifier: gocui.ModAlt,
- Handler: gui.prevCommit,
- Display: "alt + s",
- Description: "Iterate over commits",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 'd',
- Modifier: gocui.ModNone,
- Handler: gui.openCommitDiffView,
- Display: "d",
- Description: "Show commit diff",
- Vital: false,
- }, {
- View: mainViewFeature.Name,
- Key: 'c',
+ Key: gocui.KeySpace,
Modifier: gocui.ModNone,
- Handler: gui.openCheatSheetView,
- Display: "c",
- Description: "Controls",
+ Handler: gui.markRepository,
+ Display: "space",
+ Description: "Add to queue",
Vital: true,
}, {
View: mainViewFeature.Name,
@@ -143,14 +128,6 @@ func (gui *Gui) generateKeybindings() error {
Vital: true,
}, {
View: mainViewFeature.Name,
- Key: gocui.KeySpace,
- Modifier: gocui.ModNone,
- Handler: gui.markRepository,
- Display: "space",
- Description: "Add to queue",
- Vital: true,
- }, {
- View: mainViewFeature.Name,
Key: gocui.KeyCtrlSpace,
Modifier: gocui.ModNone,
Handler: gui.markAllRepositories,
@@ -167,6 +144,14 @@ func (gui *Gui) generateKeybindings() error {
Vital: false,
}, {
View: mainViewFeature.Name,
+ Key: 'c',
+ Modifier: gocui.ModNone,
+ Handler: gui.openCheatSheetView,
+ Display: "c",
+ Description: "Controls",
+ Vital: true,
+ }, {
+ View: mainViewFeature.Name,
Key: 'n',
Modifier: gocui.ModNone,
Handler: gui.sortByName,
@@ -182,6 +167,160 @@ func (gui *Gui) generateKeybindings() error {
Description: "Sort repositories by Modification date",
Vital: false,
}, {
+ View: "",
+ Key: gocui.KeyCtrlC,
+ Modifier: gocui.ModNone,
+ Handler: gui.quit,
+ Display: "ctrl + c",
+ Description: "Force application to quit",
+ Vital: false,
+ },
+ // Branch View Controls
+ {
+ View: branchViewFeature.Name,
+ Key: gocui.KeyArrowDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.nextBranch,
+ Display: "↓",
+ Description: "Iterate over branches",
+ Vital: false,
+ }, {
+ View: branchViewFeature.Name,
+ Key: gocui.KeyArrowUp,
+ Modifier: gocui.ModNone,
+ Handler: gui.previousBranch,
+ Display: "↑",
+ Description: "Iterate over branches",
+ Vital: false,
+ }, {
+ View: branchViewFeature.Name,
+ Key: 'j',
+ Modifier: gocui.ModNone,
+ Handler: gui.nextBranch,
+ Display: "j",
+ Description: "Down",
+ Vital: false,
+ }, {
+ View: branchViewFeature.Name,
+ Key: 'k',
+ Modifier: gocui.ModNone,
+ Handler: gui.previousBranch,
+ Display: "k",
+ Description: "Up",
+ Vital: false,
+ },
+ // Remote View Controls
+ {
+ View: remoteViewFeature.Name,
+ Key: gocui.KeyArrowDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.nextRemote,
+ Display: "↓",
+ Description: "Iterate over remotes",
+ Vital: false,
+ }, {
+ View: remoteViewFeature.Name,
+ Key: gocui.KeyArrowUp,
+ Modifier: gocui.ModNone,
+ Handler: gui.previousRemote,
+ Display: "↑",
+ Description: "Iterate over remotes",
+ Vital: false,
+ }, {
+ View: remoteViewFeature.Name,
+ Key: 'j',
+ Modifier: gocui.ModNone,
+ Handler: gui.nextRemote,
+ Display: "j",
+ Description: "Down",
+ Vital: false,
+ }, {
+ View: remoteViewFeature.Name,
+ Key: 'k',
+ Modifier: gocui.ModNone,
+ Handler: gui.previousRemote,
+ Display: "k",
+ Description: "Up",
+ Vital: false,
+ },
+ // Remote Branch View Controls
+ {
+ View: remoteBranchViewFeature.Name,
+ Key: gocui.KeyArrowDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.nextRemoteBranch,
+ Display: "↓",
+ Description: "Iterate over remote branches",
+ Vital: false,
+ }, {
+ View: remoteBranchViewFeature.Name,
+ Key: gocui.KeyArrowUp,
+ Modifier: gocui.ModNone,
+ Handler: gui.previousRemoteBranch,
+ Display: "↑",
+ Description: "Iterate over remote branches",
+ Vital: false,
+ }, {
+ View: remoteBranchViewFeature.Name,
+ Key: 'j',
+ Modifier: gocui.ModNone,
+ Handler: gui.nextRemoteBranch,
+ Display: "j",
+ Description: "Down",
+ Vital: false,
+ }, {
+ View: remoteBranchViewFeature.Name,
+ Key: 'k',
+ Modifier: gocui.ModNone,
+ Handler: gui.previousRemoteBranch,
+ Display: "k",
+ Description: "Up",
+ Vital: false,
+ },
+ // Commit View Controls
+ {
+ View: commitViewFeature.Name,
+ Key: gocui.KeyArrowDown,
+ Modifier: gocui.ModNone,
+ Handler: gui.nextCommit,
+ Display: "↓",
+ Description: "Iterate over commits",
+ Vital: false,
+ },{
+ View: commitViewFeature.Name,
+ Key: gocui.KeyArrowUp,
+ Modifier: gocui.ModNone,
+ Handler: gui.prevCommit,
+ Display: "↑",
+ Description: "Iterate over commits",
+ Vital: false,
+ }, {
+ View: commitViewFeature.Name,
+ Key: 'j',
+ Modifier: gocui.ModNone,
+ Handler: gui.nextCommit,
+ Display: "j",
+ Description: "Down",
+ Vital: false,
+ }, {
+ View: commitViewFeature.Name,
+ Key: 'k',
+ Modifier: gocui.ModNone,
+ Handler: gui.prevCommit,
+ Display: "k",
+ Description: "Up",
+ Vital: false,
+ },{
+ View: commitViewFeature.Name,
+ Key: 'd',
+ Modifier: gocui.ModNone,
+ Handler: gui.openCommitDiffView,
+ Display: "d",
+ Description: "Show commit diff",
+ Vital: true,
+ },
+ // Diff View Controls
+ {
View: commitDiffViewFeature.Name,
Key: 'c',
Modifier: gocui.ModNone,
@@ -221,7 +360,9 @@ func (gui *Gui) generateKeybindings() error {
Display: "j",
Description: "Page down",
Vital: false,
- }, {
+ },
+ // Application Controls
+ {
View: cheatSheetViewFeature.Name,
Key: 'c',
Modifier: gocui.ModNone,
@@ -261,7 +402,9 @@ func (gui *Gui) generateKeybindings() error {
Display: "j",
Description: "Down",
Vital: false,
- }, {
+ },
+ // Error View
+ {
View: errorViewFeature.Name,
Key: 'c',
Modifier: gocui.ModNone,
@@ -269,7 +412,10 @@ func (gui *Gui) generateKeybindings() error {
Display: "c",
Description: "close/cancel",
Vital: true,
- },
+ },
+ }
+ for _, binding := range individualKeybindings {
+ gui.KeyBindings = append(gui.KeyBindings, binding)
}
return nil
}
diff --git a/pkg/gui/remotebranchview.go b/pkg/gui/remotebranchview.go
index f720830..eb65d55 100644
--- a/pkg/gui/remotebranchview.go
+++ b/pkg/gui/remotebranchview.go
@@ -19,12 +19,16 @@ func (gui *Gui) updateRemoteBranches(g *gocui.Gui, entity *git.RepoEntity) error
trb := len(entity.Remote.Branches)
if trb > 0 {
for i, r := range entity.Remote.Branches {
+ rName := r.Name
+ if r.Deleted {
+ rName = rName + ws + dirty
+ }
if r.Name == entity.Remote.Branch.Name {
currentindex = i
- fmt.Fprintln(out, selectionIndicator+r.Name)
+ fmt.Fprintln(out, selectionIndicator+rName)
continue
}
- fmt.Fprintln(out, tab+r.Name)
+ fmt.Fprintln(out, tab+rName)
}
if err = gui.smartAnchorRelativeToLine(out, currentindex, trb); err != nil {
return err
@@ -45,3 +49,16 @@ func (gui *Gui) nextRemoteBranch(g *gocui.Gui, v *gocui.View) error {
}
return nil
}
+
+// iteration handler for the remotebranchview
+func (gui *Gui) previousRemoteBranch(g *gocui.Gui, v *gocui.View) error {
+ var err error
+ entity := gui.getSelectedRepository()
+ if err = entity.Remote.PreviousRemoteBranch(); err != nil {
+ return err
+ }
+ if err = gui.updateRemoteBranches(g, entity); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/pkg/gui/remotesview.go b/pkg/gui/remotesview.go
index a7cbc43..6f31265 100644
--- a/pkg/gui/remotesview.go
+++ b/pkg/gui/remotesview.go
@@ -44,11 +44,32 @@ func (gui *Gui) nextRemote(g *gocui.Gui, v *gocui.View) error {
if err = entity.NextRemote(); err != nil {
return err
}
- if err = gui.updateRemotes(g, entity); err != nil {
+ if err = gui.remoteChangeFollowUp(g, entity); err != nil {
return err
}
- if err = gui.updateRemoteBranches(g, entity); err != nil {
+ return err
+}
+
+// iteration handler for the remotesview
+func (gui *Gui) previousRemote(g *gocui.Gui, v *gocui.View) error {
+ var err error
+ entity := gui.getSelectedRepository()
+ if err = entity.PreviousRemote(); err != nil {
+ return err
+ }
+ if err = gui.remoteChangeFollowUp(g, entity); err != nil {
return err
}
return err
}
+
+// after checkout a remote some refreshments needed
+func (gui *Gui) remoteChangeFollowUp(g *gocui.Gui, entity *git.RepoEntity) (err error) {
+ if err = gui.updateRemotes(g, entity); err != nil {
+ return err
+ }
+ if err = gui.updateRemoteBranches(g, entity); err != nil {
+ return err
+ }
+ return nil
+} \ No newline at end of file