diff --git a/Gopkg.lock b/Gopkg.lock index e0ffcac52..7921b97fc 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -197,11 +197,11 @@ [[projects]] branch = "master" - digest = "1:99fb77d961652c3e4d313aa40faa0a982992ddf38e357400a5f2dcaa95394737" + digest = "1:98610085008f8593244c81f802d885acf4302093dd3e37737fc6543ae86ce471" name = "github.com/jesseduffield/gocui" packages = ["."] pruneopts = "NUT" - revision = "66ccf02cc748e3b4726fe1370d60ac2c5619974d" + revision = "625842035f050c8af384f639da328c6a0a0e4ca3" [[projects]] branch = "master" diff --git a/pkg/gui/commit_message_panel.go b/pkg/gui/commit_message_panel.go index 62892f09b..b087f5904 100644 --- a/pkg/gui/commit_message_panel.go +++ b/pkg/gui/commit_message_panel.go @@ -71,33 +71,6 @@ func (gui *Gui) handleCommitFocused(g *gocui.Gui, v *gocui.View) error { return gui.renderString(g, "options", message) } -func (gui *Gui) simpleEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) { - switch { - case key == gocui.KeyBackspace || key == gocui.KeyBackspace2: - v.EditDelete(true) - case key == gocui.KeyDelete: - v.EditDelete(false) - case key == gocui.KeyArrowDown: - v.MoveCursor(0, 1, false) - case key == gocui.KeyArrowUp: - v.MoveCursor(0, -1, false) - case key == gocui.KeyArrowLeft: - v.MoveCursor(-1, 0, false) - case key == gocui.KeyArrowRight: - v.MoveCursor(1, 0, false) - case key == gocui.KeyTab: - v.EditNewLine() - case key == gocui.KeySpace: - v.EditWrite(' ') - case key == gocui.KeyInsert: - v.Overwrite = !v.Overwrite - default: - v.EditWrite(ch) - } - - gui.RenderCommitLength() -} - func (gui *Gui) getBufferLength(view *gocui.View) string { return " " + strconv.Itoa(strings.Count(view.Buffer(), "")-1) + " " } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index e3aea23cb..04ed13554 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -459,7 +459,6 @@ func (gui *Gui) layout(g *gocui.Gui) error { commitMessageView.Title = gui.Tr.SLocalize("CommitMessage") commitMessageView.FgColor = gocui.ColorWhite commitMessageView.Editable = true - commitMessageView.Editor = gocui.EditorFunc(gui.simpleEditor) } } @@ -476,7 +475,6 @@ func (gui *Gui) layout(g *gocui.Gui) error { credentialsView.Title = gui.Tr.SLocalize("CredentialsUsername") credentialsView.FgColor = gocui.ColorWhite credentialsView.Editable = true - credentialsView.Editor = gocui.EditorFunc(gui.simpleEditor) } } diff --git a/vendor/github.com/jesseduffield/gocui/edit.go b/vendor/github.com/jesseduffield/gocui/edit.go index b99f74f93..f8eb08a57 100644 --- a/vendor/github.com/jesseduffield/gocui/edit.go +++ b/vendor/github.com/jesseduffield/gocui/edit.go @@ -33,18 +33,10 @@ var DefaultEditor Editor = EditorFunc(simpleEditor) // simpleEditor is used as the default gocui editor. func simpleEditor(v *View, key Key, ch rune, mod Modifier) { switch { - case ch != 0 && mod == 0: - v.EditWrite(ch) - case key == KeySpace: - v.EditWrite(' ') case key == KeyBackspace || key == KeyBackspace2: v.EditDelete(true) case key == KeyDelete: v.EditDelete(false) - case key == KeyInsert: - v.Overwrite = !v.Overwrite - case key == KeyEnter: - v.EditNewLine() case key == KeyArrowDown: v.MoveCursor(0, 1, false) case key == KeyArrowUp: @@ -53,6 +45,20 @@ func simpleEditor(v *View, key Key, ch rune, mod Modifier) { v.MoveCursor(-1, 0, false) case key == KeyArrowRight: v.MoveCursor(1, 0, false) + case key == KeyTab: + v.EditNewLine() + case key == KeySpace: + v.EditWrite(' ') + case key == KeyInsert: + v.Overwrite = !v.Overwrite + case key == KeyCtrlU: + v.EditDeleteToStartOfLine() + case key == KeyCtrlA: + v.EditGotoToStartOfLine() + case key == KeyCtrlE: + v.EditGotoToEndOfLine() + default: + v.EditWrite(ch) } } @@ -63,6 +69,48 @@ func (v *View) EditWrite(ch rune) { v.moveCursor(w, 0, true) } +// EditDeleteToStartOfLine is the equivalent of pressing ctrl+U in your terminal, it deletes to the end of the line. Or if you are already at the start of the line, it deletes the newline character +func (v *View) EditDeleteToStartOfLine() { + x, _ := v.Cursor() + if x == 0 { + v.EditDelete(true) + } else { + // delete characters until we are the start of the line + for x > 0 { + v.EditDelete(true) + x, _ = v.Cursor() + } + } +} + +// EditGotoToStartOfLine takes you to the start of the current line +func (v *View) EditGotoToStartOfLine() { + x, _ := v.Cursor() + for x > 0 { + v.MoveCursor(-1, 0, false) + x, _ = v.Cursor() + } +} + +// EditGotoToEndOfLine takes you to the end of the line +func (v *View) EditGotoToEndOfLine() { + _, y := v.Cursor() + _ = v.SetCursor(0, y+1) + x, newY := v.Cursor() + if newY == y { + // we must be on the last line, so lets move to the very end + prevX := -1 + for prevX != x { + prevX = x + v.MoveCursor(1, 0, false) + x, _ = v.Cursor() + } + } else { + // most left so now we're at the end of the original line + v.MoveCursor(-1, 0, false) + } +} + // EditDelete deletes a rune at the cursor position. back determines the // direction. func (v *View) EditDelete(back bool) { diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index cd22d3d00..37e46cc0f 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -733,7 +733,7 @@ func (g *Gui) execKeybindings(v *View, ev *termbox.Event) (matched bool, err err if kb.matchView(v) { return g.execKeybinding(v, kb) } - if kb.viewName == "" && ((v != nil && !v.Editable) || kb.ch == 0) { + if kb.viewName == "" && ((v != nil && !v.Editable) || (kb.ch == 0 && kb.key != KeyCtrlU && kb.key != KeyCtrlA && kb.key != KeyCtrlE)) { globalKb = kb } } diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index 7cf632c84..9d6553cbc 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -8,6 +8,7 @@ import ( "bytes" "io" "strings" + "sync" "time" "github.com/go-errors/errors" @@ -91,6 +92,8 @@ type View struct { // If HasLoader is true, the message will be appended with a spinning loader animation HasLoader bool + + writeMutex sync.Mutex } type viewLine struct { @@ -224,6 +227,8 @@ func (v *View) Origin() (x, y int) { // be called to clear the view's buffer. func (v *View) Write(p []byte) (n int, err error) { v.tainted = true + v.writeMutex.Lock() + defer v.writeMutex.Unlock() for _, ch := range bytes.Runes(p) { switch ch { @@ -250,6 +255,7 @@ func (v *View) Write(p []byte) (n int, err error) { } } } + return len(p), nil } @@ -603,3 +609,8 @@ func Loader() cell { chr: chr, } } + +// IsTainted tells us if the view is tainted +func (v *View) IsTainted() bool { + return v.tainted +}