mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-13 00:07:59 +02:00
Merge branch 'master' into feature/use-dep
This commit is contained in:
commit
15f982daae
13
README.md
13
README.md
@ -1,7 +1,8 @@
|
|||||||
# lazygit
|
# lazygit [](https://goreportcard.com/report/github.com/jesseduffield/lazygit)
|
||||||
|
|
||||||
A simple terminal UI for git commands, written in Go with the [gocui](https://github.com/jroimartin/gocui "gocui") library.
|
A simple terminal UI for git commands, written in Go with the [gocui](https://github.com/jroimartin/gocui "gocui") library.
|
||||||
|
|
||||||
are YOU tired of typing every git command directly into the terminal, but you're too stubborn to use Sourcetree because you'll never forgive Atlassian for making Jira? This is the app for you!
|
Are YOU tired of typing every git command directly into the terminal, but you're too stubborn to use Sourcetree because you'll never forgive Atlassian for making Jira? This is the app for you!
|
||||||
|
|
||||||
[Tutorial](https://www.youtube.com/watch?v=VDXvbHZYeKY)
|
[Tutorial](https://www.youtube.com/watch?v=VDXvbHZYeKY)
|
||||||
|
|
||||||
@ -10,11 +11,11 @@ are YOU tired of typing every git command directly into the terminal, but you're
|
|||||||
## Installation
|
## Installation
|
||||||
In a terminal call this command:
|
In a terminal call this command:
|
||||||
`go get github.com/jesseduffield/lazygit`
|
`go get github.com/jesseduffield/lazygit`
|
||||||
(if you don't have Go installed, you can follow the installation guide [Here](https://golang.org/doc/install)
|
(if you don't have Go installed, you can follow the installation guide [here](https://golang.org/doc/install).
|
||||||
|
|
||||||
then just call `lazygit` in your terminal inside a git repository
|
Then just call `lazygit` in your terminal inside a git repository.
|
||||||
|
|
||||||
If you want, you can also add an alias for this with `echo "alias lg='lazygit'" >> ~/.zshrc` (or whichever rc file you're using)
|
If you want, you can also add an alias for this with `echo "alias lg='lazygit'" >> ~/.zshrc` (or whichever rc file you're using).
|
||||||
|
|
||||||
## Cool features
|
## Cool features
|
||||||
- Adding files easily
|
- Adding files easily
|
||||||
@ -31,4 +32,4 @@ If you want, you can also add an alias for this with `echo "alias lg='lazygit'"
|
|||||||

|

|
||||||
|
|
||||||
## Work in progress
|
## Work in progress
|
||||||
This is still a work in progress so there's still bugs to iron out and as this is my first project in Go the code could no doubt use an increase in quality, but I'll be improving on it whenever I find the time. If you have any feedback feel free to raise an issue/submit a PR.
|
This is still a work in progress so there's still bugs to iron out and as this is my first project in Go the code could no doubt use an increase in quality, but I'll be improving on it whenever I find the time. If you have any feedback feel free to [raise an issue](https://github.com/jesseduffield/lazygit/issues)/[submit a PR](https://github.com/jesseduffield/lazygit/pulls).
|
||||||
|
218
commits_panel.go
218
commits_panel.go
@ -1,138 +1,138 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrNoCommits : When no commits are found for the branch
|
// ErrNoCommits : When no commits are found for the branch
|
||||||
ErrNoCommits = errors.New("No commits for this branch")
|
ErrNoCommits = errors.New("No commits for this branch")
|
||||||
)
|
)
|
||||||
|
|
||||||
func refreshCommits(g *gocui.Gui) error {
|
func refreshCommits(g *gocui.Gui) error {
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
state.Commits = getCommits()
|
state.Commits = getCommits()
|
||||||
v, err := g.View("commits")
|
v, err := g.View("commits")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
v.Clear()
|
v.Clear()
|
||||||
red := color.New(color.FgRed)
|
red := color.New(color.FgRed)
|
||||||
yellow := color.New(color.FgYellow)
|
yellow := color.New(color.FgYellow)
|
||||||
white := color.New(color.FgWhite)
|
white := color.New(color.FgWhite)
|
||||||
shaColor := white
|
shaColor := white
|
||||||
for _, commit := range state.Commits {
|
for _, commit := range state.Commits {
|
||||||
if commit.Pushed {
|
if commit.Pushed {
|
||||||
shaColor = red
|
shaColor = red
|
||||||
} else {
|
} else {
|
||||||
shaColor = yellow
|
shaColor = yellow
|
||||||
}
|
}
|
||||||
shaColor.Fprint(v, commit.Sha+" ")
|
shaColor.Fprint(v, commit.Sha+" ")
|
||||||
white.Fprintln(v, commit.Name)
|
white.Fprintln(v, commit.Name)
|
||||||
}
|
}
|
||||||
refreshStatus(g)
|
refreshStatus(g)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error {
|
func handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error {
|
||||||
return createConfirmationPanel(g, commitView, "Reset To Commit", "Are you sure you want to reset to this commit?", func(g *gocui.Gui, v *gocui.View) error {
|
return createConfirmationPanel(g, commitView, "Reset To Commit", "Are you sure you want to reset to this commit?", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
commit, err := getSelectedCommit(g)
|
commit, err := getSelectedCommit(g)
|
||||||
devLog(commit)
|
devLog(commit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if output, err := gitResetToCommit(commit.Sha); err != nil {
|
if output, err := gitResetToCommit(commit.Sha); err != nil {
|
||||||
return createErrorPanel(g, output)
|
return createErrorPanel(g, output)
|
||||||
}
|
}
|
||||||
if err := refreshCommits(g); err != nil {
|
if err := refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := refreshFiles(g); err != nil {
|
if err := refreshFiles(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
resetOrigin(commitView)
|
resetOrigin(commitView)
|
||||||
return handleCommitSelect(g, nil)
|
return handleCommitSelect(g, nil)
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderCommitsOptions(g *gocui.Gui) error {
|
func renderCommitsOptions(g *gocui.Gui) error {
|
||||||
return renderOptionsMap(g, map[string]string{
|
return renderOptionsMap(g, map[string]string{
|
||||||
"s": "squash down",
|
"s": "squash down",
|
||||||
"r": "rename",
|
"r": "rename",
|
||||||
"g": "reset to this commit",
|
"g": "reset to this commit",
|
||||||
"← → ↑ ↓": "navigate",
|
"← → ↑ ↓": "navigate",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
func handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
|
||||||
if err := renderCommitsOptions(g); err != nil {
|
if err := renderCommitsOptions(g); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
commit, err := getSelectedCommit(g)
|
commit, err := getSelectedCommit(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != ErrNoCommits {
|
if err != ErrNoCommits {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return renderString(g, "main", "No commits for this branch")
|
return renderString(g, "main", "No commits for this branch")
|
||||||
}
|
}
|
||||||
commitText := gitShow(commit.Sha)
|
commitText := gitShow(commit.Sha)
|
||||||
return renderString(g, "main", commitText)
|
return renderString(g, "main", commitText)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
func handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
if getItemPosition(v) != 0 {
|
if getItemPosition(v) != 0 {
|
||||||
return createErrorPanel(g, "Can only squash topmost commit")
|
return createErrorPanel(g, "Can only squash topmost commit")
|
||||||
}
|
}
|
||||||
if len(state.Commits) == 1 {
|
if len(state.Commits) == 1 {
|
||||||
return createErrorPanel(g, "You have no commits to squash with")
|
return createErrorPanel(g, "You have no commits to squash with")
|
||||||
}
|
}
|
||||||
commit, err := getSelectedCommit(g)
|
commit, err := getSelectedCommit(g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if output, err := gitSquashPreviousTwoCommits(commit.Name); err != nil {
|
if output, err := gitSquashPreviousTwoCommits(commit.Name); err != nil {
|
||||||
return createErrorPanel(g, output)
|
return createErrorPanel(g, output)
|
||||||
}
|
}
|
||||||
if err := refreshCommits(g); err != nil {
|
if err := refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
refreshStatus(g)
|
refreshStatus(g)
|
||||||
return handleCommitSelect(g, v)
|
return handleCommitSelect(g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
|
func handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
|
||||||
if getItemPosition(v) != 0 {
|
if getItemPosition(v) != 0 {
|
||||||
return createErrorPanel(g, "Can only rename topmost commit")
|
return createErrorPanel(g, "Can only rename topmost commit")
|
||||||
}
|
}
|
||||||
createPromptPanel(g, v, "Rename Commit", func(g *gocui.Gui, v *gocui.View) error {
|
createPromptPanel(g, v, "Rename Commit", func(g *gocui.Gui, v *gocui.View) error {
|
||||||
if output, err := gitRenameCommit(v.Buffer()); err != nil {
|
if output, err := gitRenameCommit(v.Buffer()); err != nil {
|
||||||
return createErrorPanel(g, output)
|
return createErrorPanel(g, output)
|
||||||
}
|
}
|
||||||
if err := refreshCommits(g); err != nil {
|
if err := refreshCommits(g); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return handleCommitSelect(g, v)
|
return handleCommitSelect(g, v)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSelectedCommit(g *gocui.Gui) (Commit, error) {
|
func getSelectedCommit(g *gocui.Gui) (Commit, error) {
|
||||||
v, err := g.View("commits")
|
v, err := g.View("commits")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if len(state.Commits) == 0 {
|
if len(state.Commits) == 0 {
|
||||||
return Commit{}, ErrNoCommits
|
return Commit{}, ErrNoCommits
|
||||||
}
|
}
|
||||||
lineNumber := getItemPosition(v)
|
lineNumber := getItemPosition(v)
|
||||||
if lineNumber > len(state.Commits)-1 {
|
if lineNumber > len(state.Commits)-1 {
|
||||||
colorLog(color.FgRed, "potential error in getSelected Commit (mismatched ui and state)", state.Commits, lineNumber)
|
colorLog(color.FgRed, "potential error in getSelected Commit (mismatched ui and state)", state.Commits, lineNumber)
|
||||||
return state.Commits[len(state.Commits)-1], nil
|
return state.Commits[len(state.Commits)-1], nil
|
||||||
}
|
}
|
||||||
return state.Commits[lineNumber], nil
|
return state.Commits[lineNumber], nil
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,11 @@ func createPromptPanel(g *gocui.Gui, currentView *gocui.View, title string, hand
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmationView.Editable = true
|
|
||||||
g.Cursor = true
|
g.Cursor = true
|
||||||
|
|
||||||
|
confirmationView.Editable = true
|
||||||
confirmationView.Title = title
|
confirmationView.Title = title
|
||||||
|
confirmationView.FgColor = gocui.ColorWhite
|
||||||
switchFocus(g, currentView, confirmationView)
|
switchFocus(g, currentView, confirmationView)
|
||||||
return setKeyBindings(g, handleYes, nil)
|
return setKeyBindings(g, handleYes, nil)
|
||||||
}
|
}
|
||||||
@ -87,6 +88,7 @@ func createConfirmationPanel(g *gocui.Gui, currentView *gocui.View, title, promp
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
confirmationView.Title = title
|
confirmationView.Title = title
|
||||||
|
confirmationView.FgColor = gocui.ColorWhite
|
||||||
renderString(g, "confirmation", prompt)
|
renderString(g, "confirmation", prompt)
|
||||||
switchFocus(g, currentView, confirmationView)
|
switchFocus(g, currentView, confirmationView)
|
||||||
return setKeyBindings(g, handleYes, handleNo)
|
return setKeyBindings(g, handleYes, handleNo)
|
||||||
@ -101,10 +103,8 @@ func setKeyBindings(g *gocui.Gui, handleYes, handleNo func(*gocui.Gui, *gocui.Vi
|
|||||||
if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, wrappedConfirmationFunction(handleYes)); err != nil {
|
if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, wrappedConfirmationFunction(handleYes)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := g.SetKeybinding("confirmation", gocui.KeyEsc, gocui.ModNone, wrappedConfirmationFunction(handleNo)); err != nil {
|
|
||||||
return err
|
return g.SetKeybinding("confirmation", gocui.KeyEsc, gocui.ModNone, wrappedConfirmationFunction(handleNo))
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, prompt string) error {
|
func createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, prompt string) error {
|
||||||
|
@ -59,11 +59,8 @@ func handleFilePress(g *gocui.Gui, v *gocui.View) error {
|
|||||||
if err := refreshFiles(g); err != nil {
|
if err := refreshFiles(g); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := handleFileSelect(g, v); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return handleFileSelect(g, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSelectedFile(g *gocui.Gui) (GitFile, error) {
|
func getSelectedFile(g *gocui.Gui) (GitFile, error) {
|
||||||
@ -163,8 +160,8 @@ func handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
|
|||||||
if message == "" {
|
if message == "" {
|
||||||
return createErrorPanel(g, "You cannot commit without a commit message")
|
return createErrorPanel(g, "You cannot commit without a commit message")
|
||||||
}
|
}
|
||||||
if err := gitCommit(message); err != nil {
|
if output, err := gitCommit(message); err != nil {
|
||||||
panic(err)
|
return createErrorPanel(g, output)
|
||||||
}
|
}
|
||||||
refreshFiles(g)
|
refreshFiles(g)
|
||||||
return refreshCommits(g)
|
return refreshCommits(g)
|
||||||
@ -180,8 +177,10 @@ func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (string, err
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err = open(file.Name)
|
if output, err := open(file.Name); err != nil {
|
||||||
return err
|
return createErrorPanel(g, output)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
func handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
@ -119,8 +119,7 @@ func runDirectCommand(command string) (string, error) {
|
|||||||
Command("bash", "-c", command).
|
Command("bash", "-c", command).
|
||||||
CombinedOutput()
|
CombinedOutput()
|
||||||
devLog("run direct command time for command: ", command, time.Now().Sub(timeStart))
|
devLog("run direct command time for command: ", command, time.Now().Sub(timeStart))
|
||||||
|
return sanitisedCommandOutput(cmdOut, err)
|
||||||
return string(cmdOut), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func branchStringParts(branchString string) (string, string) {
|
func branchStringParts(branchString string) (string, string) {
|
||||||
@ -299,13 +298,21 @@ func gitCheckout(branch string, force bool) (string, error) {
|
|||||||
return runCommand("git checkout " + forceArg + branch)
|
return runCommand("git checkout " + forceArg + branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||||
|
outputString := string(output)
|
||||||
|
if outputString == "" && err != nil {
|
||||||
|
return err.Error(), err
|
||||||
|
}
|
||||||
|
return outputString, err
|
||||||
|
}
|
||||||
|
|
||||||
func runCommand(command string) (string, error) {
|
func runCommand(command string) (string, error) {
|
||||||
commandStartTime := time.Now()
|
commandStartTime := time.Now()
|
||||||
commandLog(command)
|
commandLog(command)
|
||||||
splitCmd := strings.Split(command, " ")
|
splitCmd := strings.Split(command, " ")
|
||||||
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
|
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).CombinedOutput()
|
||||||
devLog("run command time: ", time.Now().Sub(commandStartTime))
|
devLog("run command time: ", time.Now().Sub(commandStartTime))
|
||||||
return string(cmdOut), err
|
return sanitisedCommandOutput(cmdOut, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func openFile(filename string) (string, error) {
|
func openFile(filename string) (string, error) {
|
||||||
@ -441,9 +448,8 @@ func removeFile(file GitFile) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitCommit(message string) error {
|
func gitCommit(message string) (string, error) {
|
||||||
_, err := runDirectCommand("git commit -m \"" + message + "\"")
|
return runDirectCommand("git commit -m \"" + message + "\"")
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func gitPull() (string, error) {
|
func gitPull() (string, error) {
|
||||||
|
28
gui.go
28
gui.go
@ -10,6 +10,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
// "strings"
|
// "strings"
|
||||||
|
|
||||||
"github.com/golang-collections/collections/stack"
|
"github.com/golang-collections/collections/stack"
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
)
|
)
|
||||||
@ -124,6 +125,9 @@ func keybindings(g *gocui.Gui) error {
|
|||||||
if err := g.SetKeybinding("files", 's', gocui.ModNone, handleSublimeFileOpen); err != nil {
|
if err := g.SetKeybinding("files", 's', gocui.ModNone, handleSublimeFileOpen); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := g.SetKeybinding("files", 'v', gocui.ModNone, handleVsCodeFileOpen); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := g.SetKeybinding("files", 'i', gocui.ModNone, handleIgnoreFile); err != nil {
|
if err := g.SetKeybinding("files", 'i', gocui.ModNone, handleIgnoreFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -193,15 +197,14 @@ func keybindings(g *gocui.Gui) error {
|
|||||||
if err := g.SetKeybinding("stash", 'k', gocui.ModNone, handleStashPop); err != nil {
|
if err := g.SetKeybinding("stash", 'k', gocui.ModNone, handleStashPop); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := g.SetKeybinding("stash", 'd', gocui.ModNone, handleStashDrop); err != nil {
|
|
||||||
return err
|
return g.SetKeybinding("stash", 'd', gocui.ModNone, handleStashDrop)
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func layout(g *gocui.Gui) error {
|
func layout(g *gocui.Gui) error {
|
||||||
g.Highlight = true
|
g.Highlight = true
|
||||||
g.SelFgColor = gocui.AttrBold
|
g.SelFgColor = gocui.ColorWhite | gocui.AttrBold
|
||||||
|
g.FgColor = gocui.ColorBlack
|
||||||
width, height := g.Size()
|
width, height := g.Size()
|
||||||
leftSideWidth := width / 3
|
leftSideWidth := width / 3
|
||||||
statusFilesBoundary := 2
|
statusFilesBoundary := 2
|
||||||
@ -225,10 +228,10 @@ func layout(g *gocui.Gui) error {
|
|||||||
v.Wrap = true
|
v.Wrap = true
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
} else {
|
|
||||||
g.DeleteView("limit")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g.DeleteView("limit")
|
||||||
|
|
||||||
optionsTop := height - 2
|
optionsTop := height - 2
|
||||||
// hiding options if there's not enough space
|
// hiding options if there's not enough space
|
||||||
if height < 30 {
|
if height < 30 {
|
||||||
@ -242,6 +245,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
v.Title = "Diff"
|
v.Title = "Diff"
|
||||||
v.Wrap = true
|
v.Wrap = true
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("status", 0, 0, leftSideWidth, statusFilesBoundary, gocui.BOTTOM|gocui.RIGHT); err != nil {
|
if v, err := g.SetView("status", 0, 0, leftSideWidth, statusFilesBoundary, gocui.BOTTOM|gocui.RIGHT); err != nil {
|
||||||
@ -249,6 +253,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Title = "Status"
|
v.Title = "Status"
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
filesView, err := g.SetView("files", 0, statusFilesBoundary+panelSpacing, leftSideWidth, filesBranchesBoundary, gocui.TOP|gocui.BOTTOM)
|
filesView, err := g.SetView("files", 0, statusFilesBoundary+panelSpacing, leftSideWidth, filesBranchesBoundary, gocui.TOP|gocui.BOTTOM)
|
||||||
@ -258,6 +263,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
}
|
}
|
||||||
filesView.Highlight = true
|
filesView.Highlight = true
|
||||||
filesView.Title = "Files"
|
filesView.Title = "Files"
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("branches", 0, filesBranchesBoundary+panelSpacing, leftSideWidth, commitsBranchesBoundary, gocui.TOP|gocui.BOTTOM); err != nil {
|
if v, err := g.SetView("branches", 0, filesBranchesBoundary+panelSpacing, leftSideWidth, commitsBranchesBoundary, gocui.TOP|gocui.BOTTOM); err != nil {
|
||||||
@ -265,7 +271,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Title = "Branches"
|
v.Title = "Branches"
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("commits", 0, commitsBranchesBoundary+panelSpacing, leftSideWidth, commitsStashBoundary, gocui.TOP|gocui.BOTTOM); err != nil {
|
if v, err := g.SetView("commits", 0, commitsBranchesBoundary+panelSpacing, leftSideWidth, commitsStashBoundary, gocui.TOP|gocui.BOTTOM); err != nil {
|
||||||
@ -273,7 +279,7 @@ func layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Title = "Commits"
|
v.Title = "Commits"
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("stash", 0, commitsStashBoundary+panelSpacing, leftSideWidth, optionsTop, gocui.TOP|gocui.RIGHT); err != nil {
|
if v, err := g.SetView("stash", 0, commitsStashBoundary+panelSpacing, leftSideWidth, optionsTop, gocui.TOP|gocui.RIGHT); err != nil {
|
||||||
@ -281,13 +287,15 @@ func layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Title = "Stash"
|
v.Title = "Stash"
|
||||||
|
v.FgColor = gocui.ColorWhite
|
||||||
}
|
}
|
||||||
|
|
||||||
if v, err := g.SetView("options", -1, optionsTop, width, optionsTop+2, 0); err != nil {
|
if v, err := g.SetView("options", -1, optionsTop, width, optionsTop+2, 0); err != nil {
|
||||||
if err != gocui.ErrUnknownView {
|
if err != gocui.ErrUnknownView {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.BgColor = gocui.ColorBlue
|
v.BgColor = gocui.ColorDefault
|
||||||
|
v.FgColor = gocui.ColorBlue
|
||||||
v.Frame = false
|
v.Frame = false
|
||||||
v.Title = "Options"
|
v.Title = "Options"
|
||||||
|
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func refreshStatus(g *gocui.Gui) error {
|
func refreshStatus(g *gocui.Gui) error {
|
||||||
v, err := g.View("status")
|
v, err := g.View("status")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// for some reason if this isn't wrapped in an update the clear seems to
|
// for some reason if this isn't wrapped in an update the clear seems to
|
||||||
// be applied after the other things or something like that; the panel's
|
// be applied after the other things or something like that; the panel's
|
||||||
// contents end up cleared
|
// contents end up cleared
|
||||||
g.Update(func(*gocui.Gui) error {
|
g.Update(func(*gocui.Gui) error {
|
||||||
v.Clear()
|
v.Clear()
|
||||||
pushables, pullables := gitUpstreamDifferenceCount()
|
pushables, pullables := gitUpstreamDifferenceCount()
|
||||||
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
|
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
|
||||||
branches := state.Branches
|
branches := state.Branches
|
||||||
if err := updateHasMergeConflictStatus(); err != nil {
|
if err := updateHasMergeConflictStatus(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if state.HasMergeConflicts {
|
if state.HasMergeConflicts {
|
||||||
colour := color.New(color.FgYellow)
|
colour := color.New(color.FgYellow)
|
||||||
fmt.Fprint(v, coloredString(" (merging)", colour))
|
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
|
// utilising the fact these all have padding to only grab the name
|
||||||
// from the display string with the existing coloring applied
|
// from the display string with the existing coloring applied
|
||||||
fmt.Fprint(v, " "+branch.DisplayString[4:])
|
fmt.Fprint(v, " "+branch.DisplayString[4:])
|
||||||
colorLog(color.FgCyan, time.Now().Sub(startTime))
|
colorLog(color.FgCyan, time.Now().Sub(startTime))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user