diff options
| author | Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com> | 2018-12-06 11:30:23 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-06 11:30:23 +0300 |
| commit | 24b407e4a9d4ee4e20e77ba186a81fa52b13397b (patch) | |
| tree | 30a5807b02670da42b57d2af322435d63200edfa | |
| parent | Update README.md (diff) | |
| parent | added version number flag (diff) | |
| download | gitbatch-24b407e4a9d4ee4e20e77ba186a81fa52b13397b.tar.gz | |
Merge pull request #25 from isacikgoz/develop
Develop
| -rw-r--r-- | main.go | 1 | ||||
| -rw-r--r-- | pkg/git/branch.go | 32 | ||||
| -rw-r--r-- | pkg/git/commit.go | 40 | ||||
| -rw-r--r-- | pkg/git/git-commands.go | 10 | ||||
| -rw-r--r-- | pkg/git/remote.go | 36 | ||||
| -rw-r--r-- | pkg/git/remotebranch.go | 57 | ||||
| -rw-r--r-- | pkg/gui/branchview.go | 33 | ||||
| -rw-r--r-- | pkg/gui/commitsview.go | 4 | ||||
| -rw-r--r-- | pkg/gui/diffview.go | 4 | ||||
| -rw-r--r-- | pkg/gui/errorview.go | 10 | ||||
| -rw-r--r-- | pkg/gui/gui-navigate.go | 54 | ||||
| -rw-r--r-- | pkg/gui/gui.go | 4 | ||||
| -rw-r--r-- | pkg/gui/keybindings.go | 322 | ||||
| -rw-r--r-- | pkg/gui/remotebranchview.go | 21 | ||||
| -rw-r--r-- | pkg/gui/remotesview.go | 25 |
15 files changed, 516 insertions, 137 deletions
@@ -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 |
