mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-21 12:16:54 +02:00
Obtain branches in a more robust way. Begin refactor work on gitcommands
This commit is contained in:
parent
3f89b5bf71
commit
d08241b2ea
42
branch.go
Normal file
42
branch.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Branch : A git branch
|
||||||
|
type Branch struct {
|
||||||
|
Name string
|
||||||
|
Recency string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Branch) getDisplayString() string {
|
||||||
|
return withPadding(b.Recency, 4) + coloredString(b.Name, b.getColor())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Branch) getColor() color.Attribute {
|
||||||
|
switch b.getType() {
|
||||||
|
case "feature":
|
||||||
|
return color.FgGreen
|
||||||
|
case "bugfix":
|
||||||
|
return color.FgYellow
|
||||||
|
case "hotfix":
|
||||||
|
return color.FgRed
|
||||||
|
default:
|
||||||
|
return color.FgWhite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// expected to return feature/bugfix/hotfix or blank string
|
||||||
|
func (b *Branch) getType() string {
|
||||||
|
return strings.Split(b.Name, "/")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func withPadding(str string, padding int) string {
|
||||||
|
if padding-len(str) < 0 {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
return str + strings.Repeat(" ", padding-len(str))
|
||||||
|
}
|
122
branch_list_builder.go
Normal file
122
branch_list_builder.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// context:
|
||||||
|
// we want to only show 'safe' branches (ones that haven't e.g. been deleted)
|
||||||
|
// which `git branch -a` gives us, but we also want the recency data that
|
||||||
|
// git reflog gives us.
|
||||||
|
// So we get the HEAD, then append get the reflog branches that intersect with
|
||||||
|
// our safe branches, then add the remaining safe branches, ensuring uniqueness
|
||||||
|
// along the way
|
||||||
|
|
||||||
|
type branchListBuilder struct{}
|
||||||
|
|
||||||
|
func newBranchListBuilder() *branchListBuilder {
|
||||||
|
return &branchListBuilder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *branchListBuilder) obtainCurrentBranch() Branch {
|
||||||
|
// Using git-go whenever possible
|
||||||
|
head, err := r.Head()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
name := head.Name().Short()
|
||||||
|
return Branch{Name: name, Recency: " *"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*branchListBuilder) obtainReflogBranches() []Branch {
|
||||||
|
branches := make([]Branch, 0)
|
||||||
|
rawString, err := runDirectCommand("git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD")
|
||||||
|
if err != nil {
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
branchLines := splitLines(rawString)
|
||||||
|
for _, line := range branchLines {
|
||||||
|
timeNumber, timeUnit, branchName := branchInfoFromLine(line)
|
||||||
|
timeUnit = abbreviatedTimeUnit(timeUnit)
|
||||||
|
branch := Branch{Name: branchName, Recency: timeNumber + timeUnit}
|
||||||
|
branches = append(branches, branch)
|
||||||
|
}
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *branchListBuilder) obtainSafeBranches() []Branch {
|
||||||
|
branches := make([]Branch, 0)
|
||||||
|
|
||||||
|
bIter, err := r.Branches()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = bIter.ForEach(func(b *plumbing.Reference) error {
|
||||||
|
name := b.Name().Short()
|
||||||
|
branches = append(branches, Branch{Name: name})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *branchListBuilder) appendNewBranches(finalBranches, newBranches, existingBranches []Branch, included bool) []Branch {
|
||||||
|
for _, newBranch := range newBranches {
|
||||||
|
if included == branchIncluded(newBranch.Name, existingBranches) {
|
||||||
|
finalBranches = append(finalBranches, newBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return finalBranches
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *branchListBuilder) build() []Branch {
|
||||||
|
branches := make([]Branch, 0)
|
||||||
|
head := b.obtainCurrentBranch()
|
||||||
|
validBranches := b.obtainSafeBranches()
|
||||||
|
reflogBranches := uniqueByName(append(b.obtainReflogBranches(), head))
|
||||||
|
|
||||||
|
branches = b.appendNewBranches(branches, reflogBranches, validBranches, true)
|
||||||
|
branches = b.appendNewBranches(branches, validBranches, branches, false)
|
||||||
|
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
|
func uniqueByName(branches []Branch) []Branch {
|
||||||
|
finalBranches := make([]Branch, 0)
|
||||||
|
for _, branch := range branches {
|
||||||
|
if branchIncluded(branch.Name, finalBranches) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
finalBranches = append(finalBranches, branch)
|
||||||
|
}
|
||||||
|
return finalBranches
|
||||||
|
}
|
||||||
|
|
||||||
|
// A line will have the form '10 days ago master' so we need to strip out the
|
||||||
|
// useful information from that into timeNumber, timeUnit, and branchName
|
||||||
|
func branchInfoFromLine(line string) (string, string, string) {
|
||||||
|
r := regexp.MustCompile("\\|.*\\s")
|
||||||
|
line = r.ReplaceAllString(line, " ")
|
||||||
|
words := strings.Split(line, " ")
|
||||||
|
return words[0], words[1], words[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
func abbreviatedTimeUnit(timeUnit string) string {
|
||||||
|
r := regexp.MustCompile("s$")
|
||||||
|
timeUnit = r.ReplaceAllString(timeUnit, "")
|
||||||
|
timeUnitMap := map[string]string{
|
||||||
|
"hour": "h",
|
||||||
|
"minute": "m",
|
||||||
|
"second": "s",
|
||||||
|
"week": "w",
|
||||||
|
"year": "y",
|
||||||
|
"day": "d",
|
||||||
|
"month": "m",
|
||||||
|
}
|
||||||
|
return timeUnitMap[timeUnit]
|
||||||
|
}
|
@ -91,7 +91,7 @@ func handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
|||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
branch := getSelectedBranch(v)
|
branch := getSelectedBranch(v)
|
||||||
diff, err := getBranchGraph(branch.Name, branch.BaseBranch)
|
diff, err := getBranchGraph(branch.Name)
|
||||||
if err != nil && strings.HasPrefix(diff, "fatal: ambiguous argument") {
|
if err != nil && strings.HasPrefix(diff, "fatal: ambiguous argument") {
|
||||||
diff = "There is no tracking for this branch"
|
diff = "There is no tracking for this branch"
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func refreshBranches(g *gocui.Gui) error {
|
|||||||
state.Branches = getGitBranches()
|
state.Branches = getGitBranches()
|
||||||
v.Clear()
|
v.Clear()
|
||||||
for _, branch := range state.Branches {
|
for _, branch := range state.Branches {
|
||||||
fmt.Fprintln(v, branch.DisplayString)
|
fmt.Fprintln(v, branch.getDisplayString())
|
||||||
}
|
}
|
||||||
resetOrigin(v)
|
resetOrigin(v)
|
||||||
return refreshStatus(g)
|
return refreshStatus(g)
|
||||||
|
17
colorer.go
Normal file
17
colorer.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func coloredString(str string, colorAttribute color.Attribute) string {
|
||||||
|
colour := color.New(colorAttribute)
|
||||||
|
return coloredStringDirect(str, colour)
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for aggregating a few color attributes rather than just sending a single one
|
||||||
|
func coloredStringDirect(str string, colour *color.Color) string {
|
||||||
|
return colour.SprintFunc()(fmt.Sprint(str))
|
||||||
|
}
|
158
gitcommands.go
158
gitcommands.go
@ -7,11 +7,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
gitconfig "github.com/tcnksm/go-gitconfig"
|
gitconfig "github.com/tcnksm/go-gitconfig"
|
||||||
git "gopkg.in/src-d/go-git.v4"
|
git "gopkg.in/src-d/go-git.v4"
|
||||||
@ -19,9 +17,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNoCheckedOutBranch : When we have no checked out branch
|
|
||||||
ErrNoCheckedOutBranch = errors.New("No currently checked out branch")
|
|
||||||
|
|
||||||
// ErrNoOpenCommand : When we don't know which command to use to open a file
|
// ErrNoOpenCommand : When we don't know which command to use to open a file
|
||||||
ErrNoOpenCommand = errors.New("Unsure what command to use to open this file")
|
ErrNoOpenCommand = errors.New("Unsure what command to use to open this file")
|
||||||
)
|
)
|
||||||
@ -38,14 +33,6 @@ type GitFile struct {
|
|||||||
DisplayString string
|
DisplayString string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Branch : A git branch
|
|
||||||
type Branch struct {
|
|
||||||
Name string
|
|
||||||
Type string
|
|
||||||
BaseBranch string
|
|
||||||
DisplayString string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Commit : A git commit
|
// Commit : A git commit
|
||||||
type Commit struct {
|
type Commit struct {
|
||||||
Sha string
|
Sha string
|
||||||
@ -140,29 +127,6 @@ func branchStringParts(branchString string) (string, string) {
|
|||||||
return splitBranchName[0], splitBranchName[1]
|
return splitBranchName[0], splitBranchName[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// branchPropertiesFromName : returns branch type, base, and color
|
|
||||||
func branchPropertiesFromName(name string) (string, string, color.Attribute) {
|
|
||||||
if strings.Contains(name, "feature/") {
|
|
||||||
return "feature", "develop", color.FgGreen
|
|
||||||
} else if strings.Contains(name, "bugfix/") {
|
|
||||||
return "bugfix", "develop", color.FgYellow
|
|
||||||
} else if strings.Contains(name, "hotfix/") {
|
|
||||||
return "hotfix", "master", color.FgRed
|
|
||||||
}
|
|
||||||
return "other", name, color.FgWhite
|
|
||||||
}
|
|
||||||
|
|
||||||
func coloredString(str string, colour *color.Color) string {
|
|
||||||
return colour.SprintFunc()(fmt.Sprint(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
func withPadding(str string, padding int) string {
|
|
||||||
if padding-len(str) < 0 {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
return str + strings.Repeat(" ", padding-len(str))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: DRY up this function and getGitBranches
|
// TODO: DRY up this function and getGitBranches
|
||||||
func getGitStashEntries() []StashEntry {
|
func getGitStashEntries() []StashEntry {
|
||||||
stashEntries := make([]StashEntry, 0)
|
stashEntries := make([]StashEntry, 0)
|
||||||
@ -214,10 +178,6 @@ func getGitStatusFiles() []GitFile {
|
|||||||
Deleted: unstagedChange == "D" || stagedChange == "D",
|
Deleted: unstagedChange == "D" || stagedChange == "D",
|
||||||
HasMergeConflicts: change == "UU",
|
HasMergeConflicts: change == "UU",
|
||||||
}
|
}
|
||||||
devLog("tracked", gitFile.Tracked)
|
|
||||||
devLog("hasUnstagedChanges", gitFile.HasUnstagedChanges)
|
|
||||||
devLog("HasStagedChanges", gitFile.HasStagedChanges)
|
|
||||||
devLog("DisplayString", gitFile.DisplayString)
|
|
||||||
gitFiles = append(gitFiles, gitFile)
|
gitFiles = append(gitFiles, gitFile)
|
||||||
}
|
}
|
||||||
devLog(gitFiles)
|
devLog(gitFiles)
|
||||||
@ -328,12 +288,8 @@ func runSubProcess(g *gocui.Gui, cmdName string, commandArgs ...string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBranchGraph(branch string, baseBranch string) (string, error) {
|
func getBranchGraph(branch string) (string, error) {
|
||||||
return runCommand("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium -100 " + branch)
|
return runCommand("git log --graph --color --abbrev-commit --decorate --date=relative --pretty=medium -100 " + branch)
|
||||||
|
|
||||||
// Leaving this guy commented out in case there's backlash from the design
|
|
||||||
// change and I want to make this configurable
|
|
||||||
// return runCommand("git log -p -30 --color --no-merges " + branch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyInGitRepo() {
|
func verifyInGitRepo() {
|
||||||
@ -480,11 +436,7 @@ func gitPull() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func gitPush() (string, error) {
|
func gitPush() (string, error) {
|
||||||
branchName := gitCurrentBranchName()
|
return runDirectCommand("git push -u origin " + state.Branches[0].Name)
|
||||||
if branchName == "" {
|
|
||||||
return "", ErrNoCheckedOutBranch
|
|
||||||
}
|
|
||||||
return runDirectCommand("git push -u origin " + branchName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitSquashPreviousTwoCommits(message string) (string, error) {
|
func gitSquashPreviousTwoCommits(message string) (string, error) {
|
||||||
@ -539,91 +491,12 @@ func gitCommitsToPush() []string {
|
|||||||
return splitLines(pushables)
|
return splitLines(pushables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCurrentBranchName() string {
|
|
||||||
branchName, err := runDirectCommand("git symbolic-ref --short HEAD")
|
|
||||||
// if there is an error, assume there are no branches yet
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return strings.TrimSpace(branchName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A line will have the form '10 days ago master' so we need to strip out the
|
|
||||||
// useful information from that into timeNumber, timeUnit, and branchName
|
|
||||||
func branchInfoFromLine(line string) (string, string, string) {
|
|
||||||
r := regexp.MustCompile("\\|.*\\s")
|
|
||||||
line = r.ReplaceAllString(line, " ")
|
|
||||||
words := strings.Split(line, " ")
|
|
||||||
return words[0], words[1], words[3]
|
|
||||||
}
|
|
||||||
|
|
||||||
func abbreviatedTimeUnit(timeUnit string) string {
|
|
||||||
r := regexp.MustCompile("s$")
|
|
||||||
timeUnit = r.ReplaceAllString(timeUnit, "")
|
|
||||||
timeUnitMap := map[string]string{
|
|
||||||
"hour": "h",
|
|
||||||
"minute": "m",
|
|
||||||
"second": "s",
|
|
||||||
"week": "w",
|
|
||||||
"year": "y",
|
|
||||||
"day": "d",
|
|
||||||
"month": "m",
|
|
||||||
}
|
|
||||||
return timeUnitMap[timeUnit]
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBranches() []Branch {
|
|
||||||
branches := make([]Branch, 0)
|
|
||||||
rawString, err := runDirectCommand("git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD")
|
|
||||||
if err != nil {
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
|
|
||||||
branchLines := splitLines(rawString)
|
|
||||||
for i, line := range branchLines {
|
|
||||||
timeNumber, timeUnit, branchName := branchInfoFromLine(line)
|
|
||||||
timeUnit = abbreviatedTimeUnit(timeUnit)
|
|
||||||
|
|
||||||
if branchAlreadyStored(branchName, branches) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
branch := constructBranch(timeNumber+timeUnit, branchName, i)
|
|
||||||
branches = append(branches, branch)
|
|
||||||
}
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
|
|
||||||
func constructBranch(prefix, name string, index int) Branch {
|
|
||||||
branchType, branchBase, colourAttr := branchPropertiesFromName(name)
|
|
||||||
if index == 0 {
|
|
||||||
prefix = " *"
|
|
||||||
}
|
|
||||||
colour := color.New(colourAttr)
|
|
||||||
displayString := withPadding(prefix, 4) + coloredString(name, colour)
|
|
||||||
return Branch{
|
|
||||||
Name: name,
|
|
||||||
Type: branchType,
|
|
||||||
BaseBranch: branchBase,
|
|
||||||
DisplayString: displayString,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getGitBranches() []Branch {
|
func getGitBranches() []Branch {
|
||||||
// check if there are any branches
|
builder := newBranchListBuilder()
|
||||||
branchCheck, _ := runCommand("git branch")
|
return builder.build()
|
||||||
if branchCheck == "" {
|
|
||||||
return []Branch{constructBranch("", gitCurrentBranchName(), 0)}
|
|
||||||
}
|
|
||||||
branches := getBranches()
|
|
||||||
if len(branches) == 0 {
|
|
||||||
branches = append(branches, constructBranch("", gitCurrentBranchName(), 0))
|
|
||||||
}
|
|
||||||
branches = getAndMergeFetchedBranches(branches)
|
|
||||||
return branches
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func branchAlreadyStored(branchName string, branches []Branch) bool {
|
func branchIncluded(branchName string, branches []Branch) bool {
|
||||||
for _, existingBranch := range branches {
|
for _, existingBranch := range branches {
|
||||||
if existingBranch.Name == branchName {
|
if existingBranch.Name == branchName {
|
||||||
return true
|
return true
|
||||||
@ -632,27 +505,6 @@ func branchAlreadyStored(branchName string, branches []Branch) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// here branches contains all the branches that we've checked out, along with
|
|
||||||
// the recency. In this function we append the branches that are in our heads
|
|
||||||
// directory i.e. things we've fetched but haven't necessarily checked out.
|
|
||||||
// Worth mentioning this has nothing to do with the 'git merge' operation
|
|
||||||
func getAndMergeFetchedBranches(branches []Branch) []Branch {
|
|
||||||
rawString, err := runDirectCommand("git branch --sort=-committerdate --no-color")
|
|
||||||
if err != nil {
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
branchLines := splitLines(rawString)
|
|
||||||
for _, line := range branchLines {
|
|
||||||
line = strings.Replace(line, "* ", "", -1)
|
|
||||||
line = strings.TrimSpace(line)
|
|
||||||
if branchAlreadyStored(line, branches) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
branches = append(branches, constructBranch("", line, len(branches)))
|
|
||||||
}
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
|
|
||||||
func gitResetHard() error {
|
func gitResetHard() error {
|
||||||
return w.Reset(&git.ResetOptions{Mode: git.HardReset})
|
return w.Reset(&git.ResetOptions{Mode: git.HardReset})
|
||||||
}
|
}
|
||||||
|
2
gui.go
2
gui.go
@ -261,6 +261,8 @@ func run() (err error) {
|
|||||||
}
|
}
|
||||||
defer g.Close()
|
defer g.Close()
|
||||||
|
|
||||||
|
g.FgColor = gocui.ColorMagenta
|
||||||
|
|
||||||
goEvery(g, time.Second*60, fetch)
|
goEvery(g, time.Second*60, fetch)
|
||||||
goEvery(g, time.Second*10, refreshFiles)
|
goEvery(g, time.Second*10, refreshFiles)
|
||||||
goEvery(g, time.Millisecond*10, updateLoader)
|
goEvery(g, time.Millisecond*10, updateLoader)
|
||||||
|
4
main.go
4
main.go
@ -28,6 +28,7 @@ var (
|
|||||||
versionFlag = flag.Bool("v", false, "Print the current version")
|
versionFlag = flag.Bool("v", false, "Print the current version")
|
||||||
|
|
||||||
w *git.Worktree
|
w *git.Worktree
|
||||||
|
r *git.Repository
|
||||||
)
|
)
|
||||||
|
|
||||||
func homeDirectory() string {
|
func homeDirectory() string {
|
||||||
@ -88,7 +89,8 @@ func fallbackVersion() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupWorktree() {
|
func setupWorktree() {
|
||||||
r, err := git.PlainOpen(".")
|
var err error
|
||||||
|
r, err = git.PlainOpen(".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func coloredConflictFile(content string, conflicts []conflict, conflictIndex int
|
|||||||
if i == conflict.end && len(remainingConflicts) > 0 {
|
if i == conflict.end && len(remainingConflicts) > 0 {
|
||||||
conflict, remainingConflicts = shiftConflict(remainingConflicts)
|
conflict, remainingConflicts = shiftConflict(remainingConflicts)
|
||||||
}
|
}
|
||||||
outputBuffer.WriteString(coloredString(line, colour) + "\n")
|
outputBuffer.WriteString(coloredStringDirect(line, colour) + "\n")
|
||||||
}
|
}
|
||||||
return outputBuffer.String(), nil
|
return outputBuffer.String(), nil
|
||||||
}
|
}
|
||||||
|
@ -24,16 +24,15 @@ func refreshStatus(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if state.HasMergeConflicts {
|
if state.HasMergeConflicts {
|
||||||
colour := color.New(color.FgYellow)
|
fmt.Fprint(v, coloredString(" (merging)", color.FgYellow))
|
||||||
fmt.Fprint(v, coloredString(" (merging)", colour))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(branches) == 0 {
|
if len(branches) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
branch := branches[0]
|
branch := branches[0]
|
||||||
// utilising the fact these all have padding to only grab the name
|
name := coloredString(branch.Name, branch.getColor())
|
||||||
// from the display string with the existing coloring applied
|
fmt.Fprint(v, " "+name)
|
||||||
fmt.Fprint(v, " "+branch.DisplayString[4:])
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
23
utils.go
Normal file
23
utils.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/gocui"
|
||||||
|
)
|
||||||
|
|
||||||
|
func splitLines(multilineString string) []string {
|
||||||
|
multilineString = strings.Replace(multilineString, "\r", "", -1)
|
||||||
|
if multilineString == "" || multilineString == "\n" {
|
||||||
|
return make([]string, 0)
|
||||||
|
}
|
||||||
|
lines := strings.Split(multilineString, "\n")
|
||||||
|
if lines[len(lines)-1] == "" {
|
||||||
|
return lines[:len(lines)-1]
|
||||||
|
}
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
|
func trimmedContent(v *gocui.View) string {
|
||||||
|
return strings.TrimSpace(v.Buffer())
|
||||||
|
}
|
@ -121,10 +121,6 @@ func getItemPosition(v *gocui.View) int {
|
|||||||
return oy + cy
|
return oy + cy
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimmedContent(v *gocui.View) string {
|
|
||||||
return strings.TrimSpace(v.Buffer())
|
|
||||||
}
|
|
||||||
|
|
||||||
func cursorUp(g *gocui.Gui, v *gocui.View) error {
|
func cursorUp(g *gocui.Gui, v *gocui.View) error {
|
||||||
// swallowing cursor movements in main
|
// swallowing cursor movements in main
|
||||||
// TODO: pull this out
|
// TODO: pull this out
|
||||||
@ -199,18 +195,6 @@ func renderString(g *gocui.Gui, viewName, s string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitLines(multilineString string) []string {
|
|
||||||
multilineString = strings.Replace(multilineString, "\r", "", -1)
|
|
||||||
if multilineString == "" || multilineString == "\n" {
|
|
||||||
return make([]string, 0)
|
|
||||||
}
|
|
||||||
lines := strings.Split(multilineString, "\n")
|
|
||||||
if lines[len(lines)-1] == "" {
|
|
||||||
return lines[:len(lines)-1]
|
|
||||||
}
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
func optionsMapToString(optionsMap map[string]string) string {
|
func optionsMapToString(optionsMap map[string]string) string {
|
||||||
optionsArray := make([]string, 0)
|
optionsArray := make([]string, 0)
|
||||||
for key, description := range optionsMap {
|
for key, description := range optionsMap {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user