summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2018-08-13 21:16:21 +1000
committerJesse Duffield <jessedduffield@gmail.com>2018-08-13 21:16:21 +1000
commit9e725ae24e8fcecefec35a65b50476d371653ffb (patch)
tree840df3748f981967a3b9f7c276602832dab360d3 /pkg
parent97cff656121270e9c790432e28622d92ab7b0f1a (diff)
got this bad boy compiling again
Diffstat (limited to 'pkg')
-rw-r--r--pkg/app/app.go22
-rw-r--r--pkg/commands/git_structs.go6
-rw-r--r--pkg/commands/os.go28
-rw-r--r--pkg/gui/branches_panel.go4
-rw-r--r--pkg/gui/commits_panel.go6
-rw-r--r--pkg/gui/files_panel.go68
-rw-r--r--pkg/gui/gui.go84
-rw-r--r--pkg/gui/keybindings.go18
-rw-r--r--pkg/gui/merge_panel.go165
-rw-r--r--pkg/gui/stash_panel.go49
-rw-r--r--pkg/gui/status_panel.go17
-rw-r--r--pkg/gui/view_helpers.go37
-rw-r--r--pkg/utils/utils.go4
13 files changed, 267 insertions, 241 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index b6318b745..011375737 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -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
}
diff --git a/pkg/commands/git_structs.go b/pkg/commands/git_structs.go
index 2f7255be1..6b10b18bb 100644
--- a/pkg/commands/git_structs.go
+++ b/pkg/commands/git_structs.go
@@ -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
}
diff --git a/pkg/commands/os.go b/pkg/commands/os.go
index 2313b5550..3be1e1288 100644
--- a/pkg/commands/os.go
+++ b/pkg/commands/os.go
@@ -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
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 53b8465cb..2820b7b9e 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -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
}
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 45134e44a..faff6ad32 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -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
}
diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go
index 9ffcafa44..8c60fcbf4 100644
--- a/pkg/gui/files_panel.go
+++ b/pkg/gui/files_panel.go
@@ -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)
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 402b4ff32..aa524ce0d 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -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
}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 194746d28..6a8a645f5 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -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},
}...)
}
diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go
index 7e0a3a873..81e37f593 100644
--- a/pkg/gui/merge_panel.go
+++ b/pkg/gui/merge_panel.go
@@ -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)
-}
-
-func currentViewName(g *gocui.Gui) string {
- currentView := g.CurrentView()
- return currentView.Name()
+ return gui.refreshMergePanel(g)
}
-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.Co