Skip to content

Commit

Permalink
Breaking into different files
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed May 26, 2018
1 parent fe99e70 commit bb12309
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 354 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
development.log
commands.log
67 changes: 67 additions & 0 deletions commit_panel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// lots of this has been directly ported from one of the example files, will brush up later

// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
"fmt"

"github.com/jroimartin/gocui"
)

func handleCommitPress(g *gocui.Gui, currentView *gocui.View) error {
devLog(stagedFiles(state.GitFiles))
if len(stagedFiles(state.GitFiles)) == 0 {
return nil
}
maxX, maxY := g.Size()
// var v *gocui.View
if v, err := g.SetView("commit", maxX/2-30, maxY/2-1, maxX/2+30, maxY/2+1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.Title = "Commit Message"
v.Editable = true
if _, err := g.SetCurrentView("commit"); err != nil {
return err
}
switchFocus(g, currentView, v)
}
return nil
}

func handleCommitSubmit(g *gocui.Gui, v *gocui.View) error {
if len(v.BufferLines()) == 0 {
return closeCommitPrompt(g, v)
}
message := fmt.Sprint(v.BufferLines()[0])
// for whatever reason, a successful commit returns an error, so we're not
// going to check for an error here
if err := gitCommit(message); err != nil {
devLog(err)
panic(err)
}
refreshFiles(g)
refreshLogs(g)
return closeCommitPrompt(g, v)
}

func closeCommitPrompt(g *gocui.Gui, v *gocui.View) error {
filesView, _ := g.View("files")
switchFocus(g, v, filesView)
devLog("test prompt close")
if err := g.DeleteView("commit"); err != nil {
return err
}
if _, err := g.SetCurrentView(state.PreviousView); err != nil {
return err
}
return nil
}

func handleCommitPromptFocus(g *gocui.Gui, v *gocui.View) error {
return renderString(g, "options", "esc: close, enter: commit")
}
62 changes: 62 additions & 0 deletions confirmation_panel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// lots of this has been directly ported from one of the example files, will brush up later

// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (

// "io"
// "io/ioutil"

"math"
// "strings"

"github.com/jroimartin/gocui"
)

func wrappedConfirmationFunction(function func(*gocui.Gui, *gocui.View) error) func(*gocui.Gui, *gocui.View) error {
return func(g *gocui.Gui, v *gocui.View) error {
if function != nil {
if err := function(g, v); err != nil {
panic(err)
}
}
if err := returnFocus(g, v); err != nil {
panic(err)
}
g.DeleteKeybindings("confirmation")
return g.DeleteView("confirmation")
}
}

func getConfirmationPanelDimensions(g *gocui.Gui, prompt string) (int, int, int, int) {
width, height := g.Size()
panelWidth := 60
panelHeight := int(math.Ceil(float64(len(prompt)) / float64(panelWidth)))
return width/2 - panelWidth/2,
height/2 - panelHeight/2 - panelHeight%2 - 1,
width/2 + panelWidth/2,
height/2 + panelHeight/2
}

func createConfirmationPanel(g *gocui.Gui, sourceView *gocui.View, title, prompt string, handleYes, handleNo func(*gocui.Gui, *gocui.View) error) error {
x0, y0, x1, y1 := getConfirmationPanelDimensions(g, prompt)
if v, err := g.SetView("confirmation", x0, y0, x1, y1); err != nil {
if err != gocui.ErrUnknownView {
return err
}
v.Title = title
renderString(g, "confirmation", prompt+" (y/n)")
switchFocus(g, sourceView, v)
if err := g.SetKeybinding("confirmation", 'n', gocui.ModNone, wrappedConfirmationFunction(handleNo)); err != nil {
return err
}
if err := g.SetKeybinding("confirmation", 'y', gocui.ModNone, wrappedConfirmationFunction(handleYes)); err != nil {
return err
}
}
return nil
}
136 changes: 136 additions & 0 deletions files_panel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// lots of this has been directly ported from one of the example files, will brush up later

// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (

// "io"
// "io/ioutil"

// "strings"

"strings"

"github.com/fatih/color"
"github.com/jroimartin/gocui"
)

func stagedFiles(files []GitFile) []GitFile {
result := make([]GitFile, 0)
for _, file := range files {
if file.HasStagedChanges {
result = append(result, file)
}
}
return result
}

func handleFilePress(g *gocui.Gui, v *gocui.View) error {
file := getSelectedFile(v)

if file.HasUnstagedChanges {
stageFile(file.Name)
} else {
unStageFile(file.Name)
}

if err := refreshFiles(g); err != nil {
return err
}
if err := handleFileSelect(g, v); err != nil {
return err
}

return nil
}

func getSelectedFile(v *gocui.View) GitFile {
lineNumber := getItemPosition(v)
if len(state.GitFiles) == 0 {
return GitFile{
Name: "noFile",
DisplayString: "none",
HasStagedChanges: false,
HasUnstagedChanges: false,
Tracked: false,
Deleted: false,
}
}
return state.GitFiles[lineNumber]
}

func handleFileRemove(g *gocui.Gui, v *gocui.View) error {
file := getSelectedFile(v)
var deleteVerb string
if file.Tracked {
deleteVerb = "checkout"
} else {
deleteVerb = "delete"
}
return createConfirmationPanel(g, v, strings.Title(deleteVerb)+" file", "Are you sure you want to "+deleteVerb+" "+file.Name+" (you will lose your changes)?", func(g *gocui.Gui, v *gocui.View) error {
if err := removeFile(file); err != nil {
panic(err)
}
return refreshFiles(g)
}, nil)
}

func handleFileSelect(g *gocui.Gui, v *gocui.View) error {
item := getSelectedFile(v)
var optionsString string
baseString := "space: toggle staged, c: commit changes, option+o: open"
if item.Tracked {
optionsString = baseString + ", option+d: checkout"
} else {
optionsString = baseString + ", option+d: delete"
}
renderString(g, "options", optionsString)
diff := getDiff(item)
return renderString(g, "main", diff)
}

func handleFileOpen(g *gocui.Gui, v *gocui.View) error {
file := getSelectedFile(v)
_, err := openFile(file.Name)
return err
}

func handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
file := getSelectedFile(v)
_, err := sublimeOpenFile(file.Name)
return err
}

func refreshFiles(g *gocui.Gui) error {
filesView, err := g.View("files")
if err != nil {
return err
}

// get files to stage
gitFiles := getGitStatusFiles()
state.GitFiles = mergeGitStatusFiles(state.GitFiles, gitFiles)

filesView.Clear()
red := color.New(color.FgRed)
green := color.New(color.FgGreen)
for _, gitFile := range state.GitFiles {
if !gitFile.Tracked {
red.Fprintln(filesView, gitFile.DisplayString)
continue
}
green.Fprint(filesView, gitFile.DisplayString[0:1])
red.Fprint(filesView, gitFile.DisplayString[1:3])
if gitFile.HasUnstagedChanges {
red.Fprintln(filesView, gitFile.Name)
} else {
green.Fprintln(filesView, gitFile.Name)
}
}
correctCursor(filesView)
return nil
}
57 changes: 52 additions & 5 deletions gitcommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

// "log"
"fmt"
"os"
"os/exec"
"strings"
)
Expand All @@ -30,6 +31,23 @@ type Branch struct {
BaseBranch string
}

func devLog(objects ...interface{}) {
localLog("/Users/jesseduffieldduffield/go/src/github.com/jesseduffield/gitgot/development.log", objects...)
}

func commandLog(objects ...interface{}) {
localLog("/Users/jesseduffieldduffield/go/src/github.com/jesseduffield/gitgot/commands.log", objects...)
localLog("/Users/jesseduffieldduffield/go/src/github.com/jesseduffield/gitgot/development.log", objects...)
}

func localLog(path string, objects ...interface{}) {
f, _ := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0644)
defer f.Close()
for _, object := range objects {
f.WriteString(fmt.Sprint(object) + "\n")
}
}

// Map (from https://gobyexample.com/collection-functions)
func Map(vs []string, f func(string) string) []string {
vsm := make([]string, len(vs))
Expand All @@ -39,6 +57,15 @@ func Map(vs []string, f func(string) string) []string {
return vsm
}

func includes(list []string, a string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}

func mergeGitStatusFiles(oldGitFiles, newGitFiles []GitFile) []GitFile {
if len(oldGitFiles) == 0 {
return newGitFiles
Expand All @@ -57,9 +84,10 @@ func mergeGitStatusFiles(oldGitFiles, newGitFiles []GitFile) []GitFile {
}

func runDirectCommand(command string) (string, error) {
commandLog(command)
cmdOut, err := exec.Command("bash", "-c", command).Output()
devLog(string(cmdOut))
devLog(fmt.Sprint(err))
devLog(err)
return string(cmdOut), err
}

Expand All @@ -74,7 +102,7 @@ func getGitBranches() []Branch {
branches := make([]Branch, 0)
rawString, _ := runDirectCommand(getBranchesCommand)
branchLines := splitLines(rawString)
for _, line := range branchLines {
for i, line := range branchLines {
name := branchNameFromString(line)
var branchType string
var baseBranch string
Expand All @@ -91,16 +119,19 @@ func getGitBranches() []Branch {
branchType = "other"
baseBranch = name
}
if i == 0 {
line = line[:2] + "\t*" + line[2:]
}
branches = append(branches, Branch{name, line, branchType, baseBranch})
}
devLog(fmt.Sprint(branches))
devLog(branches)
return branches
}

func getGitStatusFiles() []GitFile {
statusOutput, _ := getGitStatus()
statusStrings := splitLines(statusOutput)
devLog(fmt.Sprint(statusStrings))
devLog(statusStrings)
// a file can have both staged and unstaged changes
// I'll probably end up ignoring the unstaged flag for now but might revisit
// tracked, staged, unstaged
Expand Down Expand Up @@ -135,17 +166,33 @@ func gitCheckout(branch string, force bool) error {
}

func runCommand(cmd string) (string, error) {
commandLog(cmd)
splitCmd := strings.Split(cmd, " ")
cmdOut, err := exec.Command(splitCmd[0], splitCmd[1:]...).Output()
devLog(cmd)
devLog(string(cmdOut[:]))
return string(cmdOut), err
}

func openFile(filename string) (string, error) {
return runCommand("open " + filename)
}

func sublimeOpenFile(filename string) (string, error) {
return runCommand("subl " + filename)
}

func getBranchDiff(branch string, baseBranch string) (string, error) {
return runCommand("git diff --color " + baseBranch + "..." + branch)
}

func getLog() string {
result, err := runDirectCommand("git log --color --oneline")
if err != nil {
panic(err)
}
return result
}

func getDiff(file GitFile) string {
cachedArg := ""
if file.HasStagedChanges {
Expand Down
Loading

0 comments on commit bb12309

Please sign in to comment.