mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-01-04 03:48:07 +02:00
got this bad boy compiling again
This commit is contained in:
parent
97cff65612
commit
9e725ae24e
@ -2,9 +2,9 @@ package app
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||
@ -18,7 +18,21 @@ type App struct {
|
||||
Log *logrus.Logger
|
||||
OSCommand *commands.OSCommand
|
||||
GitCommand *commands.GitCommand
|
||||
Gui *gocui.Gui
|
||||
Gui *gui.Gui
|
||||
}
|
||||
|
||||
func newLogger(config config.AppConfigurer) *logrus.Logger {
|
||||
log := logrus.New()
|
||||
if !config.GetDebug() {
|
||||
log.Out = nil
|
||||
return log
|
||||
}
|
||||
file, err := os.OpenFile("development.log", os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
panic("unable to log to file") // TODO: don't panic (also, remove this call to the `panic` function)
|
||||
}
|
||||
log.Out = file
|
||||
return log
|
||||
}
|
||||
|
||||
// NewApp retruns a new applications
|
||||
@ -28,7 +42,7 @@ func NewApp(config config.AppConfigurer) (*App, error) {
|
||||
Config: config,
|
||||
}
|
||||
var err error
|
||||
app.Log = logrus.New()
|
||||
app.Log = newLogger(config)
|
||||
app.OSCommand, err = commands.NewOSCommand(app.Log)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -37,7 +51,7 @@ func NewApp(config config.AppConfigurer) (*App, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
app.Gui, err = gui.NewGui(app.Log, app.GitCommand, config.GetVersion())
|
||||
app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, config.GetVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ type StashEntry struct {
|
||||
// Conflict : A git conflict with a start middle and end corresponding to line
|
||||
// numbers in the file where the conflict bars appear
|
||||
type Conflict struct {
|
||||
start int
|
||||
middle int
|
||||
end int
|
||||
Start int
|
||||
Middle int
|
||||
End int
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/jesseduffield/gocui"
|
||||
gitconfig "github.com/tcnksm/go-gitconfig"
|
||||
)
|
||||
|
||||
@ -105,28 +104,34 @@ func (c *OSCommand) GetOpenCommand() (string, string, error) {
|
||||
|
||||
// VsCodeOpenFile opens the file in code, with the -r flag to open in the
|
||||
// current window
|
||||
func (c *OSCommand) VsCodeOpenFile(g *gocui.Gui, filename string) (string, error) {
|
||||
return c.RunCommand("code -r " + filename)
|
||||
// each of these open files needs to have the same function signature because
|
||||
// they're being passed as arguments into another function,
|
||||
// but only editFile actually returns a *exec.Cmd
|
||||
func (c *OSCommand) VsCodeOpenFile(filename string) (*exec.Cmd, error) {
|
||||
_, err := c.RunCommand("code -r " + filename)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// SublimeOpenFile opens the filein sublime
|
||||
// may be deprecated in the future
|
||||
func (c *OSCommand) SublimeOpenFile(g *gocui.Gui, filename string) (string, error) {
|
||||
return c.RunCommand("subl " + filename)
|
||||
func (c *OSCommand) SublimeOpenFile(filename string) (*exec.Cmd, error) {
|
||||
_, err := c.RunCommand("subl " + filename)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// OpenFile opens a file with the given
|
||||
func (c *OSCommand) OpenFile(g *gocui.Gui, filename string) (string, error) {
|
||||
func (c *OSCommand) OpenFile(filename string) (*exec.Cmd, error) {
|
||||
cmdName, cmdTrail, err := c.GetOpenCommand()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return c.RunCommand(cmdName + " " + filename + cmdTrail)
|
||||
_, err = c.RunCommand(cmdName + " " + filename + cmdTrail)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// EditFile opens a file in a subprocess using whatever editor is available,
|
||||
// falling back to core.editor, VISUAL, EDITOR, then vi
|
||||
func (c *OSCommand) editFile(g *gocui.Gui, filename string) (string, error) {
|
||||
func (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {
|
||||
editor, _ := gitconfig.Global("core.editor")
|
||||
if editor == "" {
|
||||
editor = os.Getenv("VISUAL")
|
||||
@ -140,10 +145,9 @@ func (c *OSCommand) editFile(g *gocui.Gui, filename string) (string, error) {
|
||||
}
|
||||
}
|
||||
if editor == "" {
|
||||
return "", ErrNoEditorDefined
|
||||
return nil, ErrNoEditorDefined
|
||||
}
|
||||
c.PrepareSubProcess(editor, filename)
|
||||
return "", nil
|
||||
return c.PrepareSubProcess(editor, filename)
|
||||
}
|
||||
|
||||
// PrepareSubProcess iniPrepareSubProcessrocess then tells the Gui to switch to it
|
||||
|
@ -117,7 +117,7 @@ func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// refreshStatus is called at the end of this because that's when we can
|
||||
// gui.refreshStatus is called at the end of this because that's when we can
|
||||
// be sure there is a state.Branches array to pick the current branch from
|
||||
func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
||||
g.Update(func(g *gocui.Gui) error {
|
||||
@ -135,7 +135,7 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
|
||||
fmt.Fprintln(v, branch.GetDisplayString())
|
||||
}
|
||||
gui.resetOrigin(v)
|
||||
return refreshStatus(g)
|
||||
return gui.refreshStatus(g)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error {
|
||||
shaColor.Fprint(v, commit.Sha+" ")
|
||||
white.Fprintln(v, commit.Name)
|
||||
}
|
||||
refreshStatus(g)
|
||||
gui.refreshStatus(g)
|
||||
if g.CurrentView().Name() == "commits" {
|
||||
gui.handleCommitSelect(g, v)
|
||||
}
|
||||
@ -105,7 +105,7 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := gui.refreshCommits(g); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
refreshStatus(g)
|
||||
gui.refreshStatus(g)
|
||||
return gui.handleCommitSelect(g, v)
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := gui.refreshCommits(g); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return refreshStatus(g)
|
||||
return gui.refreshStatus(g)
|
||||
}, nil)
|
||||
return nil
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
// "strings"
|
||||
|
||||
"errors"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
@ -171,7 +172,7 @@ func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View) error {
|
||||
gui.renderfilesOptions(g, &file)
|
||||
var content string
|
||||
if file.HasMergeConflicts {
|
||||
return refreshMergePanel(g)
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
content = gui.GitCommand.Diff(file)
|
||||
@ -191,9 +192,9 @@ func (gui *Gui) handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleCommitEditorPress - handle when the user wants to commit changes via
|
||||
// handleCommitEditorPress - handle when the user wants to commit changes via
|
||||
// their editor rather than via the popup panel
|
||||
func (gui *Gui) HandleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error {
|
||||
func (gui *Gui) handleCommitEditorPress(g *gocui.Gui, filesView *gocui.View) error {
|
||||
if len(gui.stagedFiles(gui.State.Files)) == 0 && !gui.State.HasMergeConflicts {
|
||||
return gui.createErrorPanel(g, "There are no staged files to commit")
|
||||
}
|
||||
@ -214,7 +215,7 @@ func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, open func(*gocui.Gui, string) (string, error)) error {
|
||||
func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (*exec.Cmd, error)) error {
|
||||
file, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
if err != errNoFiles {
|
||||
@ -222,26 +223,31 @@ func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, open func(*gocui.Gu
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if _, err := open(g, file.Name); err != nil {
|
||||
sub, err := open(file.Name)
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(g, err.Error())
|
||||
}
|
||||
if sub != nil {
|
||||
gui.SubProcess = sub
|
||||
return ErrSubProcess
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.genericFileOpen(g, v, gui.editFile)
|
||||
return gui.genericFileOpen(g, v, gui.OSCommand.EditFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.genericFileOpen(g, v, gui.openFile)
|
||||
return gui.genericFileOpen(g, v, gui.OSCommand.OpenFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.genericFileOpen(g, v, gui.sublimeOpenFile)
|
||||
return gui.genericFileOpen(g, v, gui.OSCommand.SublimeOpenFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.genericFileOpen(g, v, gui.vsCodeOpenFile)
|
||||
return gui.genericFileOpen(g, v, gui.OSCommand.VsCodeOpenFile)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
@ -250,13 +256,13 @@ func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
|
||||
func (gui *Gui) refreshStateFiles() {
|
||||
// get files to stage
|
||||
files := getGitStatusFiles()
|
||||
gui.State.Files = mergeGitStatusFiles(gui.State.Files, files)
|
||||
updateHasMergeConflictStatus()
|
||||
files := gui.GitCommand.GetStatusFiles()
|
||||
gui.State.Files = gui.GitCommand.MergeStatusFiles(gui.State.Files, files)
|
||||
gui.updateHasMergeConflictStatus()
|
||||
}
|
||||
|
||||
func (gui *Gui) updateHasMergeConflictStatus() error {
|
||||
merging, err := isInMergeState()
|
||||
merging, err := gui.GitCommand.IsInMergeState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -290,7 +296,7 @@ func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) {
|
||||
}
|
||||
return "", gui.renderString(g, "main", "No file to display")
|
||||
}
|
||||
cat, err := catFile(item.Name)
|
||||
cat, err := gui.GitCommand.CatFile(item.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -302,12 +308,12 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
refreshStateFiles()
|
||||
gui.refreshStateFiles()
|
||||
filesView.Clear()
|
||||
for _, file := range gui.State.Files {
|
||||
renderFile(file, filesView)
|
||||
gui.renderFile(file, filesView)
|
||||
}
|
||||
correctCursor(filesView)
|
||||
gui.correctCursor(filesView)
|
||||
if filesView == g.CurrentView() {
|
||||
gui.handleFileSelect(g, filesView)
|
||||
}
|
||||
@ -315,14 +321,14 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) pullFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
createMessagePanel(g, v, "", "Pulling...")
|
||||
gui.createMessagePanel(g, v, "", "Pulling...")
|
||||
go func() {
|
||||
if output, err := gitPull(); err != nil {
|
||||
if output, err := gui.GitCommand.Pull(); err != nil {
|
||||
gui.createErrorPanel(g, output)
|
||||
} else {
|
||||
gui.closeConfirmationPrompt(g)
|
||||
refreshCommits(g)
|
||||
refreshStatus(g)
|
||||
gui.refreshCommits(g)
|
||||
gui.refreshStatus(g)
|
||||
}
|
||||
gui.refreshFiles(g)
|
||||
}()
|
||||
@ -330,15 +336,15 @@ func (gui *Gui) pullFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
|
||||
createMessagePanel(g, v, "", "Pushing...")
|
||||
gui.createMessagePanel(g, v, "", "Pushing...")
|
||||
go func() {
|
||||
branchName = gui.State.Branches[0].Name
|
||||
if output, err := commands.Push(branchName); err != nil {
|
||||
branchName := gui.State.Branches[0].Name
|
||||
if output, err := gui.GitCommand.Push(branchName); err != nil {
|
||||
gui.createErrorPanel(g, output)
|
||||
} else {
|
||||
gui.closeConfirmationPrompt(g)
|
||||
refreshCommits(g)
|
||||
refreshStatus(g)
|
||||
gui.refreshCommits(g)
|
||||
gui.refreshStatus(g)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
@ -360,22 +366,22 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.createErrorPanel(g, "This file has no merge conflicts")
|
||||
}
|
||||
gui.switchFocus(g, v, mergeView)
|
||||
return refreshMergePanel(g)
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleAbortMerge(g *gocui.Gui, v *gocui.View) error {
|
||||
output, err := gitAbortMerge()
|
||||
output, err := gui.GitCommand.AbortMerge()
|
||||
if err != nil {
|
||||
return gui.createErrorPanel(g, output)
|
||||
}
|
||||
createMessagePanel(g, v, "", "Merge aborted")
|
||||
refreshStatus(g)
|
||||
gui.createMessagePanel(g, v, "", "Merge aborted")
|
||||
gui.refreshStatus(g)
|
||||
return gui.refreshFiles(g)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleResetHard(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.createConfirmationPanel(g, v, "Clear file panel", "Are you sure you want `reset --hard HEAD`? You may lose changes", func(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := commands.ResetHard(); err != nil {
|
||||
if err := gui.GitCommand.ResetHard(); err != nil {
|
||||
gui.createErrorPanel(g, err.Error())
|
||||
}
|
||||
return gui.refreshFiles(g)
|
||||
|
@ -37,12 +37,27 @@ type Gui struct {
|
||||
OSCommand *commands.OSCommand
|
||||
Version string
|
||||
SubProcess *exec.Cmd
|
||||
State StateType
|
||||
State guiState
|
||||
}
|
||||
|
||||
type guiState struct {
|
||||
Files []commands.File
|
||||
Branches []commands.Branch
|
||||
Commits []commands.Commit
|
||||
StashEntries []commands.StashEntry
|
||||
PreviousView string
|
||||
HasMergeConflicts bool
|
||||
ConflictIndex int
|
||||
ConflictTop bool
|
||||
Conflicts []commands.Conflict
|
||||
EditHistory *stack.Stack
|
||||
Platform platform
|
||||
Version string
|
||||
}
|
||||
|
||||
// NewGui builds a new gui handler
|
||||
func NewGui(log *logrus.Logger, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, version string) (*Gui, error) {
|
||||
initialState := StateType{
|
||||
initialState := guiState{
|
||||
Files: make([]commands.File, 0),
|
||||
PreviousView: "files",
|
||||
Commits: make([]commands.Commit, 0),
|
||||
@ -64,21 +79,6 @@ func NewGui(log *logrus.Logger, gitCommand *commands.GitCommand, oSCommand *comm
|
||||
}, nil
|
||||
}
|
||||
|
||||
type StateType struct {
|
||||
Files []commands.File
|
||||
Branches []commands.Branch
|
||||
Commits []commands.Commit
|
||||
StashEntries []commands.StashEntry
|
||||
PreviousView string
|
||||
HasMergeConflicts bool
|
||||
ConflictIndex int
|
||||
ConflictTop bool
|
||||
Conflicts []commands.Conflict
|
||||
EditHistory *stack.Stack
|
||||
Platform platform
|
||||
Version string
|
||||
}
|
||||
|
||||
type platform struct {
|
||||
os string
|
||||
shell string
|
||||
@ -105,7 +105,7 @@ func getPlatform() platform {
|
||||
}
|
||||
}
|
||||
|
||||
func scrollUpMain(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) scrollUpMain(g *gocui.Gui, v *gocui.View) error {
|
||||
mainView, _ := g.View("main")
|
||||
ox, oy := mainView.Origin()
|
||||
if oy >= 1 {
|
||||
@ -114,7 +114,7 @@ func scrollUpMain(g *gocui.Gui, v *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func scrollDownMain(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) scrollDownMain(g *gocui.Gui, v *gocui.View) error {
|
||||
mainView, _ := g.View("main")
|
||||
ox, oy := mainView.Origin()
|
||||
if oy < len(mainView.BufferLines()) {
|
||||
@ -123,8 +123,8 @@ func scrollDownMain(g *gocui.Gui, v *gocui.View) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleRefresh(g *gocui.Gui, v *gocui.View) error {
|
||||
return refreshSidePanels(g)
|
||||
func (gui *Gui) handleRefresh(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.refreshSidePanels(g)
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
@ -257,35 +257,35 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
// these are only called once
|
||||
gui.handleFileSelect(g, filesView)
|
||||
gui.refreshFiles(g)
|
||||
refreshBranches(g)
|
||||
refreshCommits(g)
|
||||
refreshStashEntries(g)
|
||||
nextView(g, nil)
|
||||
gui.refreshBranches(g)
|
||||
gui.refreshCommits(g)
|
||||
gui.refreshStashEntries(g)
|
||||
gui.nextView(g, nil)
|
||||
}
|
||||
|
||||
resizePopupPanels(g)
|
||||
gui.resizePopupPanels(g)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetch(g *gocui.Gui) error {
|
||||
gitFetch()
|
||||
refreshStatus(g)
|
||||
func (gui *Gui) fetch(g *gocui.Gui) error {
|
||||
gui.GitCommand.Fetch()
|
||||
gui.refreshStatus(g)
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateLoader(g *gocui.Gui) error {
|
||||
func (gui *Gui) updateLoader(g *gocui.Gui) error {
|
||||
if confirmationView, _ := g.View("confirmation"); confirmationView != nil {
|
||||
content := gui.trimmedContent(confirmationView)
|
||||
if strings.Contains(content, "...") {
|
||||
staticContent := strings.Split(content, "...")[0] + "..."
|
||||
gui.renderString(g, "confirmation", staticContent+" "+loader())
|
||||
gui.renderString(g, "confirmation", staticContent+" "+gui.loader())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) error) {
|
||||
func (gui *Gui) goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) error) {
|
||||
go func() {
|
||||
for range time.Tick(interval) {
|
||||
function(g)
|
||||
@ -293,36 +293,36 @@ func goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) err
|
||||
}()
|
||||
}
|
||||
|
||||
func resizePopupPanels(g *gocui.Gui) error {
|
||||
func (gui *Gui) resizePopupPanels(g *gocui.Gui) error {
|
||||
v := g.CurrentView()
|
||||
if v.Name() == "commitMessage" || v.Name() == "confirmation" {
|
||||
return resizePopupPanel(g, v)
|
||||
return gui.resizePopupPanel(g, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run setup the gui with keybindings and start the mainloop
|
||||
func (gui *Gui) Run() (*exec.Cmd, error) {
|
||||
func (gui *Gui) Run() error {
|
||||
g, err := gocui.NewGui(gocui.OutputNormal, OverlappingEdges)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
g.FgColor = gocui.ColorDefault
|
||||
|
||||
goEvery(g, time.Second*60, fetch)
|
||||
goEvery(g, time.Second*10, gui.refreshFiles)
|
||||
goEvery(g, time.Millisecond*10, updateLoader)
|
||||
gui.goEvery(g, time.Second*60, gui.fetch)
|
||||
gui.goEvery(g, time.Second*10, gui.refreshFiles)
|
||||
gui.goEvery(g, time.Millisecond*10, gui.updateLoader)
|
||||
|
||||
g.SetManagerFunc(gui.layout)
|
||||
|
||||
if err = gui.keybindings(g); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
err = g.MainLoop()
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// RunWithSubprocesses loops, instantiating a new gocui.Gui with each iteration
|
||||
@ -342,6 +342,6 @@ func (gui *Gui) RunWithSubprocesses() {
|
||||
}
|
||||
}
|
||||
|
||||
func quit(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}
|
||||
|
@ -70,15 +70,15 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
|
||||
// input in the confirmation panel
|
||||
for _, viewName := range []string{"files", "branches", "commits", "stash"} {
|
||||
bindings = append(bindings, []Binding{
|
||||
{ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: nextView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: previousView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: nextView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: cursorUp},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: cursorDown},
|
||||
{ViewName: viewName, Key: 'h', Modifier: gocui.ModNone, Handler: previousView},
|
||||
{ViewName: viewName, Key: 'l', Modifier: gocui.ModNone, Handler: nextView},
|
||||
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: cursorUp},
|
||||
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: cursorDown},
|
||||
{ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.nextView},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.cursorUp},
|
||||
{ViewName: viewName, Key: gocui.KeyArrowDown, Modifier: gocui.ModNone, Handler: gui.cursorDown},
|
||||
{ViewName: viewName, Key: 'h', Modifier: gocui.ModNone, Handler: gui.previousView},
|
||||
{ViewName: viewName, Key: 'l', Modifier: gocui.ModNone, Handler: gui.nextView},
|
||||
{ViewName: viewName, Key: 'k', Modifier: gocui.ModNone, Handler: gui.cursorUp},
|
||||
{ViewName: viewName, Key: 'j', Modifier: gocui.ModNone, Handler: gui.cursorDown},
|
||||
}...)
|
||||
}
|
||||
|
||||
|
@ -16,89 +16,89 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
func findConflicts(content string) ([]commands.Conflict, error) {
|
||||
func (gui *Gui) findConflicts(content string) ([]commands.Conflict, error) {
|
||||
conflicts := make([]commands.Conflict, 0)
|
||||
var newConflict conflict
|
||||
var newConflict commands.Conflict
|
||||
for i, line := range utils.SplitLines(content) {
|
||||
if line == "<<<<<<< HEAD" || line == "<<<<<<< MERGE_HEAD" || line == "<<<<<<< Updated upstream" {
|
||||
newConflict = conflict{start: i}
|
||||
newConflict = commands.Conflict{Start: i}
|
||||
} else if line == "=======" {
|
||||
newConflict.middle = i
|
||||
newConflict.Middle = i
|
||||
} else if strings.HasPrefix(line, ">>>>>>> ") {
|
||||
newConflict.end = i
|
||||
newConflict.End = i
|
||||
conflicts = append(conflicts, newConflict)
|
||||
}
|
||||
}
|
||||
return conflicts, nil
|
||||
}
|
||||
|
||||
func shiftConflict(conflicts []commands.Conflict) (commands.Conflict, []commands.Conflict) {
|
||||
func (gui *Gui) shiftConflict(conflicts []commands.Conflict) (commands.Conflict, []commands.Conflict) {
|
||||
return conflicts[0], conflicts[1:]
|
||||
}
|
||||
|
||||
func shouldHighlightLine(index int, conflict commands.Conflict, top bool) bool {
|
||||
return (index >= conflict.start && index <= conflict.middle && top) || (index >= conflict.middle && index <= conflict.end && !top)
|
||||
func (gui *Gui) shouldHighlightLine(index int, conflict commands.Conflict, top bool) bool {
|
||||
return (index >= conflict.Start && index <= conflict.Middle && top) || (index >= conflict.Middle && index <= conflict.End && !top)
|
||||
}
|
||||
|
||||
func coloredConflictFile(content string, conflicts []commands.Conflict, conflictIndex int, conflictTop, hasFocus bool) (string, error) {
|
||||
func (gui *Gui) coloredConflictFile(content string, conflicts []commands.Conflict, conflictIndex int, conflictTop, hasFocus bool) (string, error) {
|
||||
if len(conflicts) == 0 {
|
||||
return content, nil
|
||||
}
|
||||
conflict, remainingConflicts := shiftConflict(conflicts)
|
||||
conflict, remainingConflicts := gui.shiftConflict(conflicts)
|
||||
var outputBuffer bytes.Buffer
|
||||
for i, line := range splitLines(content) {
|
||||
for i, line := range utils.SplitLines(content) {
|
||||
colourAttr := color.FgWhite
|
||||
if i == conflict.start || i == conflict.middle || i == conflict.end {
|
||||
if i == conflict.Start || i == conflict.Middle || i == conflict.End {
|
||||
colourAttr = color.FgRed
|
||||
}
|
||||
colour := color.New(colourAttr)
|
||||
if hasFocus && conflictIndex < len(conflicts) && conflicts[conflictIndex] == conflict && shouldHighlightLine(i, conflict, conflictTop) {
|
||||
if hasFocus && conflictIndex < len(conflicts) && conflicts[conflictIndex] == conflict && gui.shouldHighlightLine(i, conflict, conflictTop) {
|
||||
colour.Add(color.Bold)
|
||||
}
|
||||
if i == conflict.end && len(remainingConflicts) > 0 {
|
||||
conflict, remainingConflicts = shiftConflict(remainingConflicts)
|
||||
if i == conflict.End && len(remainingConflicts) > 0 {
|
||||
conflict, remainingConflicts = gui.shiftConflict(remainingConflicts)
|
||||
}
|
||||
outputBuffer.WriteString(coloredStringDirect(line, colour) + "\n")
|
||||
outputBuffer.WriteString(utils.ColoredStringDirect(line, colour) + "\n")
|
||||
}
|
||||
return outputBuffer.String(), nil
|
||||
}
|
||||
|
||||
func handleSelectTop(g *gocui.Gui, v *gocui.View) error {
|
||||
state.ConflictTop = true
|
||||
return refreshMergePanel(g)
|
||||
func (gui *Gui) handleSelectTop(g *gocui.Gui, v *gocui.View) error {
|
||||
gui.State.ConflictTop = true
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func handleSelectBottom(g *gocui.Gui, v *gocui.View) error {
|
||||
state.ConflictTop = false
|
||||
return refreshMergePanel(g)
|
||||
func (gui *Gui) handleSelectBottom(g *gocui.Gui, v *gocui.View) error {
|
||||
gui.State.ConflictTop = false
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func handleSelectNextConflict(g *gocui.Gui, v *gocui.View) error {
|
||||
if state.ConflictIndex >= len(state.Conflicts)-1 {
|
||||
func (gui *Gui) handleSelectNextConflict(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.State.ConflictIndex >= len(gui.State.Conflicts)-1 {
|
||||
return nil
|
||||
}
|
||||
state.ConflictIndex++
|
||||
return refreshMergePanel(g)
|
||||
gui.State.ConflictIndex++
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func handleSelectPrevConflict(g *gocui.Gui, v *gocui.View) error {
|
||||
if state.ConflictIndex <= 0 {
|
||||
func (gui *Gui) handleSelectPrevConflict(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.State.ConflictIndex <= 0 {
|
||||
return nil
|
||||
}
|
||||
state.ConflictIndex--
|
||||
return refreshMergePanel(g)
|
||||
gui.State.ConflictIndex--
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func isIndexToDelete(i int, conflict commands.Conflict, pick string) bool {
|
||||
return i == conflict.middle ||
|
||||
i == conflict.start ||
|
||||
i == conflict.end ||
|
||||
func (gui *Gui) isIndexToDelete(i int, conflict commands.Conflict, pick string) bool {
|
||||
return i == conflict.Middle ||
|
||||
i == conflict.Start ||
|
||||
i == conflict.End ||
|
||||
pick != "both" &&
|
||||
(pick == "bottom" && i > conflict.start && i < conflict.middle) ||
|
||||
(pick == "top" && i > conflict.middle && i < conflict.end)
|
||||
(pick == "bottom" && i > conflict.Start && i < conflict.Middle) ||
|
||||
(pick == "top" && i > conflict.Middle && i < conflict.End)
|
||||
}
|
||||
|
||||
func resolveConflict(g *gocui.Gui, conflict commands.Conflict, pick string) error {
|
||||
func (gui *Gui) resolveConflict(g *gocui.Gui, conflict commands.Conflict, pick string) error {
|
||||
gitFile, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -116,126 +116,121 @@ func resolveConflict(g *gocui.Gui, conflict commands.Conflict, pick string) erro
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
if !isIndexToDelete(i, conflict, pick) {
|
||||
if !gui.isIndexToDelete(i, conflict, pick) {
|
||||
output += line
|
||||
}
|
||||
}
|
||||
devLog(output)
|
||||
gui.Log.Info(output)
|
||||
return ioutil.WriteFile(gitFile.Name, []byte(output), 0644)
|
||||
}
|
||||
|
||||
func pushFileSnapshot(g *gocui.Gui) error {
|
||||
func (gui *Gui) pushFileSnapshot(g *gocui.Gui) error {
|
||||
gitFile, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
content, err := catFile(gitFile.Name)
|
||||
content, err := gui.GitCommand.CatFile(gitFile.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state.EditHistory.Push(content)
|
||||
gui.State.EditHistory.Push(content)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePopFileSnapshot(g *gocui.Gui, v *gocui.View) error {
|
||||
if state.EditHistory.Len() == 0 {
|
||||
func (gui *Gui) handlePopFileSnapshot(g *gocui.Gui, v *gocui.View) error {
|
||||
if gui.State.EditHistory.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
prevContent := state.EditHistory.Pop().(string)
|
||||
prevContent := gui.State.EditHistory.Pop().(string)
|
||||
gitFile, err := gui.getSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ioutil.WriteFile(gitFile.Name, []byte(prevContent), 0644)
|
||||
return refreshMergePanel(g)
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func handlePickHunk(g *gocui.Gui, v *gocui.View) error {
|
||||
conflict := state.Conflicts[state.ConflictIndex]
|
||||
pushFileSnapshot(g)
|
||||
func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error {
|
||||
conflict := gui.State.Conflicts[gui.State.ConflictIndex]
|
||||
gui.pushFileSnapshot(g)
|
||||
pick := "bottom"
|
||||
if state.ConflictTop {
|
||||
if gui.State.ConflictTop {
|
||||
pick = "top"
|
||||
}
|
||||
err := resolveConflict(g, conflict, pick)
|
||||
err := gui.resolveConflict(g, conflict, pick)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
refreshMergePanel(g)
|
||||
gui.refreshMergePanel(g)
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePickBothHunks(g *gocui.Gui, v *gocui.View) error {
|
||||
conflict := state.Conflicts[state.ConflictIndex]
|
||||
pushFileSnapshot(g)
|
||||
err := resolveConflict(g, conflict, "both")
|
||||
func (gui *Gui) handlePickBothHunks(g *gocui.Gui, v *gocui.View) error {
|
||||
conflict := gui.State.Conflicts[gui.State.ConflictIndex]
|
||||
gui.pushFileSnapshot(g)
|
||||
err := gui.resolveConflict(g, conflict, "both")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return refreshMergePanel(g)
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func currentViewName(g *gocui.Gui) string {
|
||||
currentView := g.CurrentView()
|
||||
return currentView.Name()
|
||||
}
|
||||
|
||||
func refreshMergePanel(g *gocui.Gui) error {
|
||||
cat, err := catSelectedFile(g)
|
||||
func (gui *Gui) refreshMergePanel(g *gocui.Gui) error {
|
||||
cat, err := gui.catSelectedFile(g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state.Conflicts, err = findConflicts(cat)
|
||||
gui.State.Conflicts, err = gui.findConflicts(cat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(state.Conflicts) == 0 {
|
||||
return handleCompleteMerge(g)
|
||||
} else if state.ConflictIndex > len(state.Conflicts)-1 {
|
||||
state.ConflictIndex = len(state.Conflicts) - 1
|
||||
if len(gui.State.Conflicts) == 0 {
|
||||
return gui.handleCompleteMerge(g)
|
||||
} else if gui.State.ConflictIndex > len(gui.State.Conflicts)-1 {
|
||||
gui.State.ConflictIndex = len(gui.State.Conflicts) - 1
|
||||
}
|
||||
hasFocus := currentViewName(g) == "main"
|
||||
hasFocus := gui.currentViewName(g) == "main"
|
||||
if hasFocus {
|
||||
renderMergeOptions(g)
|
||||
gui.renderMergeOptions(g)
|
||||
}
|
||||
content, err := coloredConflictFile(cat, state.Conflicts, state.ConflictIndex, state.ConflictTop, hasFocus)
|
||||
content, err := gui.coloredConflictFile(cat, gui.State.Conflicts, gui.State.ConflictIndex, gui.State.ConflictTop, hasFocus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := scrollToConflict(g); err != nil {
|
||||
if err := gui.scrollToConflict(g); err != nil {
|
||||
return err
|
||||
}
|
||||
return gui.renderString(g, "main", content)
|
||||
}
|
||||
|
||||
func scrollToConflict(g *gocui.Gui) error {
|
||||
func (gui *Gui) scrollToConflict(g *gocui.Gui) error {
|
||||
mainView, err := g.View("main")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(state.Conflicts) == 0 {
|
||||
if len(gui.State.Conflicts) == 0 {
|
||||
return nil
|
||||
}
|
||||
conflict := state.Conflicts[state.ConflictIndex]
|
||||
conflict := gui.State.Conflicts[gui.State.ConflictIndex]
|
||||
ox, _ := mainView.Origin()
|
||||
_, height := mainView.Size()
|
||||
conflictMiddle := (conflict.end + conflict.start) / 2
|
||||
conflictMiddle := (conflict.End + conflict.Start) / 2
|
||||
newOriginY := int(math.Max(0, float64(conflictMiddle-(height/2))))
|
||||
return mainView.SetOrigin(ox, newOriginY)
|
||||
}
|
||||
|
||||
func switchToMerging(g *gocui.Gui) error {
|
||||
state.ConflictIndex = 0
|
||||
state.ConflictTop = true
|
||||
func (gui *Gui) switchToMerging(g *gocui.Gui) error {
|
||||
gui.State.ConflictIndex = 0
|
||||
gui.State.ConflictTop = true
|
||||
_, err := g.SetCurrentView("main")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return refreshMergePanel(g)
|
||||
return gui.refreshMergePanel(g)
|
||||
}
|
||||
|
||||
func renderMergeOptions(g *gocui.Gui) error {
|
||||
func (gui *Gui) renderMergeOptions(g *gocui.Gui) error {
|
||||
return gui.renderOptionsMap(g, map[string]string{
|
||||
"↑ ↓": "select hunk",
|
||||
"← →": "navigate conflicts",
|
||||
@ -245,7 +240,7 @@ func renderMergeOptions(g *gocui.Gui) error {
|
||||
})
|
||||
}
|
||||
|
||||
func handleEscapeMerge(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) handleEscapeMerge(g *gocui.Gui, v *gocui.View) error {
|
||||
filesView, err := g.View("files")
|
||||
if err != nil {
|
||||
return err
|
||||
@ -254,12 +249,12 @@ func handleEscapeMerge(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.switchFocus(g, v, filesView)
|
||||
}
|
||||
|
||||
func handleCompleteMerge(g *gocui.Gui) error {
|
||||
func (gui *Gui) handleCompleteMerge(g *gocui.Gui) error {
|
||||
filesView, err := g.View("files")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stageSelectedFile(g)
|
||||
gui.stageSelectedFile(g)
|
||||
gui.refreshFiles(g)
|
||||
return gui.switchFocus(g, nil, filesView)
|
||||
}
|
||||
|
@ -4,17 +4,18 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
)
|
||||
|
||||
func refreshStashEntries(g *gocui.Gui) error {
|
||||
func (gui *Gui) refreshStashEntries(g *gocui.Gui) error {
|
||||
g.Update(func(g *gocui.Gui) error {
|
||||
v, err := g.View("stash")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
state.StashEntries = getGitStashEntries()
|
||||
gui.State.StashEntries = gui.GitCommand.GetStashEntries()
|
||||
v.Clear()
|
||||
for _, stashEntry := range state.StashEntries {
|
||||
for _, stashEntry := range gui.State.StashEntries {
|
||||
fmt.Fprintln(v, stashEntry.DisplayString)
|
||||
}
|
||||
return gui.resetOrigin(v)
|
||||
@ -22,15 +23,15 @@ func refreshStashEntries(g *gocui.Gui) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSelectedStashEntry(v *gocui.View) *StashEntry {
|
||||
if len(state.StashEntries) == 0 {
|
||||
func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry {
|
||||
if len(gui.State.StashEntries) == 0 {
|
||||
return nil
|
||||
}
|
||||
lineNumber := gui.getItemPosition(v)
|
||||
return &state.StashEntries[lineNumber]
|
||||
return &gui.State.StashEntries[lineNumber]
|
||||
}
|
||||
|
||||
func renderStashOptions(g *gocui.Gui) error {
|
||||
func (gui *Gui) renderStashOptions(g *gocui.Gui) error {
|
||||
return gui.renderOptionsMap(g, map[string]string{
|
||||
"space": "apply",
|
||||
"g": "pop",
|
||||
@ -39,54 +40,54 @@ func renderStashOptions(g *gocui.Gui) error {
|
||||
})
|
||||
}
|
||||
|
||||
func handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := renderStashOptions(g); err != nil {
|
||||
func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
|
||||
if err := gui.renderStashOptions(g); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
stashEntry := getSelectedStashEntry(v)
|
||||
stashEntry := gui.getSelectedStashEntry(v)
|
||||
if stashEntry == nil {
|
||||
gui.renderString(g, "main", "No stash entries")
|
||||
return
|
||||
}
|
||||
diff, _ := getStashEntryDiff(stashEntry.Index)
|
||||
diff, _ := gui.GitCommand.GetStashEntryDiff(stashEntry.Index)
|
||||
gui.renderString(g, "main", diff)
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleStashApply(g *gocui.Gui, v *gocui.View) error {
|
||||
return stashDo(g, v, "apply")
|
||||
func (gui *Gui) handleStashApply(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.stashDo(g, v, "apply")
|
||||
}
|
||||
|
||||
func handleStashPop(g *gocui.Gui, v *gocui.View) error {
|
||||
return stashDo(g, v, "pop")
|
||||
func (gui *Gui) handleStashPop(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.stashDo(g, v, "pop")
|
||||
}
|
||||
|
||||
func handleStashDrop(g *gocui.Gui, v *gocui.View) error {
|
||||
func (gui *Gui) handleStashDrop(g *gocui.Gui, v *gocui.View) error {
|
||||
return gui.createConfirmationPanel(g, v, "Stash drop", "Are you sure you want to drop this stash entry?", func(g *gocui.Gui, v *gocui.View) error {
|
||||
return stashDo(g, v, "drop")
|
||||
return gui.stashDo(g, v, "drop")
|
||||
}, nil)
|
||||
}
|
||||
|
||||
func stashDo(g *gocui.Gui, v *gocui.View, method string) error {
|
||||
stashEntry := getSelectedStashEntry(v)
|
||||
func (gui *Gui) stashDo(g *gocui.Gui, v *gocui.View, method string) error {
|
||||
stashEntry := gui.getSelectedStashEntry(v)
|
||||
if stashEntry == nil {
|
||||
return gui.createErrorPanel(g, "No stash to "+method)
|
||||
}
|
||||
if output, err := gitStashDo(stashEntry.Index, method); err != nil {
|
||||
if output, err := gui.GitCommand.StashDo(stashEntry.Index, method); err != nil {
|
||||
gui.createErrorPanel(g, output)
|
||||
}
|
||||
refreshStashEntries(g)
|
||||
gui.refreshStashEntries(g)
|
||||
return gui.refreshFiles(g)
|
||||
}
|
||||
|
||||
func handleStashSave(g *gocui.Gui, filesView *gocui.View) error {
|
||||
func (gui *Gui) handleStashSave(g *gocui.Gui, filesView *gocui.View) error {
|
||||
gui.createPromptPanel(g, filesView, "Stash changes", func(g *gocui.Gui, v *gocui.View) error {
|
||||
if output, err := gitStashSave(gui.trimmedContent(v)); err != nil {
|
||||
if output, err := gui.GitCommand.StashSave(gui.trimmedContent(v)); err != nil {
|
||||
gui.createErrorPanel(g, output)
|
||||
}
|
||||
refreshStashEntries(g)
|
||||
gui.refreshStashEntries(g)
|
||||
return gui.refreshFiles(g)
|
||||
})
|
||||
return nil
|
||||
|
@ -5,9 +5,10 @@ import (
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
func refreshStatus(g *gocui.Gui) error {
|
||||
func (gui *Gui) refreshStatus(g *gocui.Gui) error {
|
||||
v, err := g.View("status")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -17,22 +18,22 @@ func refreshStatus(g *gocui.Gui) error {
|
||||
// contents end up cleared
|
||||
g.Update(func(*gocui.Gui) error {
|
||||
v.Clear()
|
||||
pushables, pullables := git.UpstreamDifferenceCount()
|
||||
pushables, pullables := gui.GitCommand.UpstreamDifferenceCount()
|
||||
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
|
||||
branches := state.Branches
|
||||
if err := updateHasMergeConflictStatus(); err != nil {
|
||||
branches := gui.State.Branches
|
||||
if err := gui.updateHasMergeConflictStatus(); err != nil {
|
||||
return err
|
||||
}
|
||||
if state.HasMergeConflicts {
|
||||
fmt.Fprint(v, coloredString(" (merging)", color.FgYellow))
|
||||
if gui.State.HasMergeConflicts {
|
||||
fmt.Fprint(v, utils.ColoredString(" (merging)", color.FgYellow))
|
||||
}
|
||||
|
||||
if len(branches) == 0 {
|
||||
return nil
|
||||
}
|
||||
branch := branches[0]
|
||||
name := coloredString(branch.Name, branch.getColor())
|
||||
repo := getCurrentProject()
|
||||
name := utils.ColoredString(branch.Name, branch.GetColor())
|
||||
repo := utils.GetCurrentRepoName()
|
||||
fmt.Fprint(v, " "+repo+" → "+name)
|
||||
return nil
|
||||
})
|
||||
|
@ -13,7 +13,7 @@ var cyclableViews = []string{"files", "branches", "commits", "stash"}
|
||||
|
||||
func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
|
||||
gui.refreshBranches(g)
|
||||
gui.gui.refreshFiles(g)
|
||||
gui.refreshFiles(g)
|
||||
gui.refreshCommits(g)
|
||||
return nil
|
||||
}
|
||||
@ -38,7 +38,7 @@ func (gui *Gui) nextView(g *gocui.Gui, v *gocui.View) error {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return gui.gui.switchFocus(g, v, focusedView)
|
||||
return gui.switchFocus(g, v, focusedView)
|
||||
}
|
||||
|
||||
func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
@ -52,7 +52,7 @@ func (gui *Gui) previousView(g *gocui.Gui, v *gocui.View) error {
|
||||
break
|
||||
}
|
||||
if i == len(cyclableViews)-1 {
|
||||
devLog(v.Name() + " is not in the list of views")
|
||||
gui.Log.Info(v.Name() + " is not in the list of views")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -72,27 +72,27 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
|
||||
case "files":
|
||||
return gui.handleFileSelect(g, v)
|
||||
case "branches":
|
||||
return handleBranchSelect(g, v)
|
||||
return gui.handleBranchSelect(g, v)
|
||||
case "confirmation":
|
||||
return nil
|
||||
case "commitMessage":
|
||||
return handleCommitFocused(g, v)
|
||||
return gui.handleCommitFocused(g, v)
|
||||
case "main":
|
||||
// TODO: pull this out into a 'view focused' function
|
||||
refreshMergePanel(g)
|
||||
gui.refreshMergePanel(g)
|
||||
v.Highlight = false
|
||||
return nil
|
||||
case "commits":
|
||||
return handleCommitSelect(g, v)
|
||||
return gui.handleCommitSelect(g, v)
|
||||
case "stash":
|
||||
return handleStashEntrySelect(g, v)
|
||||
return gui.handleStashEntrySelect(g, v)
|
||||
default:
|
||||
panic("No view matching newLineFocused switch statement")
|
||||
}
|
||||
}
|
||||
|
||||
func (gui *Gui) returnFocus(g *gocui.Gui, v *gocui.View) error {
|
||||
previousView, err := g.View(state.PreviousView)
|
||||
previousView, err := g.View(gui.State.PreviousView)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -105,16 +105,16 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error {
|
||||
// we should never stack confirmation panels
|
||||
if oldView != nil && oldView.Name() != "confirmation" {
|
||||
oldView.Highlight = false
|
||||
devLog("setting previous view to:", oldView.Name())
|
||||
state.PreviousView = oldView.Name()
|
||||
gui.Log.Info("setting previous view to:", oldView.Name())
|
||||
gui.State.PreviousView = oldView.Name()
|
||||
}
|
||||
newView.Highlight = true
|
||||
devLog("new focused view is " + newView.Name())
|
||||
gui.Log.Info("new focused view is " + newView.Name())
|
||||
if _, err := g.SetCurrentView(newView.Name()); err != nil {
|
||||
return err
|
||||
}
|
||||
g.Cursor = newView.Editable
|
||||
return newLineFocused(g, newView)
|
||||
return gui.newLineFocused(g, newView)
|
||||
}
|
||||
|
||||
func (gui *Gui) getItemPosition(v *gocui.View) int {
|
||||
@ -138,7 +138,7 @@ func (gui *Gui) cursorUp(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
}
|
||||
|
||||
newLineFocused(g, v)
|
||||
gui.newLineFocused(g, v)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ func (gui *Gui) cursorDown(g *gocui.Gui, v *gocui.View) error {
|
||||
}
|
||||
}
|
||||
|
||||
newLineFocused(g, v)
|
||||
gui.newLineFocused(g, v)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
||||
}
|
||||
|
||||
func (gui *Gui) renderOptionsMap(g *gocui.Gui, optionsMap map[string]string) error {
|
||||
return gui.renderString(g, "options", optionsMapToString(optionsMap))
|
||||
return gui.renderString(g, "options", gui.optionsMapToString(optionsMap))
|
||||
}
|
||||
|
||||
func (gui *Gui) loader() string {
|
||||
@ -237,3 +237,8 @@ func (gui *Gui) getCommitMessageView(g *gocui.Gui) *gocui.View {
|
||||
func (gui *Gui) trimmedContent(v *gocui.View) string {
|
||||
return strings.TrimSpace(v.Buffer())
|
||||
}
|
||||
|
||||
func (gui *Gui) currentViewName(g *gocui.Gui) string {
|
||||
currentView := g.CurrentView()
|
||||
return currentView.Name()
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ func ColoredStringDirect(str string, colour *color.Color) string {
|
||||
return colour.SprintFunc()(fmt.Sprint(str))
|
||||
}
|
||||
|
||||
// GetCurrentProject gets the repo's base name
|
||||
func GetCurrentProject() string {
|
||||
// GetCurrentRepoName gets the repo's base name
|
||||
func GetCurrentRepoName() string {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalln(err.Error())
|
||||
|
Loading…
Reference in New Issue
Block a user