YN callbacks and better multi cursor

This commit is contained in:
Zachary Yedidia
2019-01-04 21:48:19 -05:00
parent 1ac4a8e7d3
commit 16e5f55323
5 changed files with 86 additions and 36 deletions

View File

@@ -138,14 +138,14 @@ func (h *BufHandler) CursorLeft() bool {
// CursorRight moves the cursor right
func (h *BufHandler) CursorRight() bool {
h.Cursor.Deselect(true)
h.Cursor.Deselect(false)
h.Cursor.Right()
return true
}
// WordRight moves the cursor one word to the right
func (h *BufHandler) WordRight() bool {
h.Cursor.Deselect(true)
h.Cursor.Deselect(false)
h.Cursor.WordRight()
return true
}
@@ -987,8 +987,17 @@ func (h *BufHandler) Escape() bool {
// Quit this will close the current tab or view that is open
func (h *BufHandler) Quit() bool {
screen.Screen.Fini()
os.Exit(0)
if h.Buf.Modified() {
InfoBar.YNPrompt("Save changes to "+h.Buf.GetName()+" before closing? (y,n,esc)", func(yes, canceled bool) {
if !canceled && !yes {
screen.Screen.Fini()
os.Exit(0)
}
})
} else {
screen.Screen.Fini()
os.Exit(0)
}
return false
}
@@ -1055,31 +1064,36 @@ func (h *BufHandler) SpawnMultiCursor() bool {
spawner := h.Buf.GetCursor(h.Buf.NumCursors() - 1)
if !spawner.HasSelection() {
spawner.SelectWord()
} else {
sel := spawner.GetSelection()
searchStart := spawner.CurSelection[1]
match, found, err := h.Buf.FindNext(string(sel), searchStart, true)
if err != nil {
InfoBar.Error(err)
}
if found {
c := buffer.NewCursor(h.Buf, buffer.Loc{})
c.SetSelectionStart(match[0])
c.SetSelectionEnd(match[1])
c.OrigSelection[0] = c.CurSelection[0]
c.OrigSelection[1] = c.CurSelection[1]
c.Loc = c.CurSelection[1]
h.Buf.AddCursor(c)
h.Buf.MergeCursors()
h.Win.Relocate()
} else {
InfoBar.Message("No matches found")
}
h.multiWord = true
return true
}
return false
sel := spawner.GetSelection()
searchStart := spawner.CurSelection[1]
search := string(sel)
if h.multiWord {
search = "\\b" + search + "\\b"
}
match, found, err := h.Buf.FindNext(search, searchStart, true)
if err != nil {
InfoBar.Error(err)
}
if found {
c := buffer.NewCursor(h.Buf, buffer.Loc{})
c.SetSelectionStart(match[0])
c.SetSelectionEnd(match[1])
c.OrigSelection[0] = c.CurSelection[0]
c.OrigSelection[1] = c.CurSelection[1]
c.Loc = c.CurSelection[1]
h.Buf.AddCursor(c)
h.Buf.MergeCursors()
} else {
InfoBar.Message("No matches found")
}
return true
}
// SpawnMultiCursorSelect adds a cursor at the beginning of each line of a selection
@@ -1158,6 +1172,8 @@ func (h *BufHandler) RemoveMultiCursor() bool {
if h.Buf.NumCursors() > 1 {
h.Buf.RemoveCursor(h.Buf.NumCursors() - 1)
h.Buf.UpdateCursors()
} else {
h.multiWord = false
}
return false
}
@@ -1165,5 +1181,6 @@ func (h *BufHandler) RemoveMultiCursor() bool {
// RemoveAllMultiCursors removes all cursors except the base cursor
func (h *BufHandler) RemoveAllMultiCursors() bool {
h.Buf.ClearCursors()
h.multiWord = false
return true
}

View File

@@ -90,6 +90,9 @@ type BufHandler struct {
// Last search stores the last successful search for FindNext and FindPrev
lastSearch string
// Should the current multiple cursor selection search based on word or
// based on selection (false for selection, true for word)
multiWord bool
splitID uint64
}

View File

@@ -34,10 +34,18 @@ func (h *InfoHandler) HandleEvent(event tcell.Event) {
done := h.DoKeyEvent(ke)
if !done && e.Key() == tcell.KeyRune {
h.DoRuneInsert(e.Rune())
done = true
if e.Rune() == 'y' && h.HasYN {
h.YNResp = true
h.DonePrompt(false)
} else if e.Rune() == 'n' && h.HasYN {
h.YNResp = false
h.DonePrompt(false)
} else if !h.HasYN {
h.DoRuneInsert(e.Rune())
done = true
}
}
if done && h.HasPrompt {
if done && h.HasPrompt && !h.HasYN {
resp := strings.TrimSpace(string(h.LineBytes(0)))
hist := h.History[h.PromptType]
hist[h.HistoryNum] = resp
@@ -144,7 +152,9 @@ func (h *InfoHandler) InsertTab() {
// TODO: autocomplete
}
func (h *InfoHandler) InsertNewline() {
h.DonePrompt(false)
if !h.HasYN {
h.DonePrompt(false)
}
}
func (h *InfoHandler) Quit() {
h.DonePrompt(true)

View File

@@ -167,7 +167,7 @@ func (c *Cursor) Deselect(start bool) {
if start {
c.Loc = c.CurSelection[0]
} else {
c.Loc = c.CurSelection[1]
c.Loc = c.CurSelection[1].Move(-1, c.buf)
}
c.ResetSelection()
c.StoreVisualX()

View File

@@ -15,10 +15,12 @@ type InfoBuf struct {
HasPrompt bool
HasMessage bool
HasError bool
HasYN bool
PromptType string
Msg string
Msg string
YNResp bool
// This map stores the history for all the different kinds of uses Prompt has
// It's a map of history type -> history array
@@ -30,6 +32,7 @@ type InfoBuf struct {
PromptCallback func(resp string, canceled bool)
EventCallback func(resp string)
YNCallback func(yes bool, canceled bool)
}
// NewBuffer returns a new infobuffer
@@ -92,16 +95,27 @@ func (i *InfoBuf) Prompt(prompt string, msg string, ptype string, eventcb func(s
i.PromptType = ptype
i.Msg = prompt
i.HasPrompt = true
i.HasMessage, i.HasError = false, false
i.HasMessage, i.HasError, i.HasYN = false, false, false
i.PromptCallback = donecb
i.EventCallback = eventcb
i.Buffer.Insert(i.Buffer.Start(), msg)
}
func (i *InfoBuf) YNPrompt(prompt string, donecb func(bool, bool)) {
if i.HasPrompt {
i.DonePrompt(true)
}
i.Msg = prompt
i.HasPrompt = true
i.HasYN = true
i.HasMessage, i.HasError = false, false
i.YNCallback = donecb
}
// DonePrompt finishes the current prompt and indicates whether or not it was canceled
func (i *InfoBuf) DonePrompt(canceled bool) {
i.HasPrompt = false
if i.PromptCallback != nil {
if i.PromptCallback != nil && !i.HasYN {
if canceled {
i.PromptCallback("", true)
h := i.History[i.PromptType]
@@ -113,8 +127,14 @@ func (i *InfoBuf) DonePrompt(canceled bool) {
h[len(h)-1] = resp
}
}
if i.YNCallback != nil && i.HasYN {
i.YNCallback(i.YNResp, canceled)
}
i.HasPrompt = false
i.HasYN = false
i.PromptCallback = nil
i.EventCallback = nil
i.YNCallback = nil
i.Replace(i.Start(), i.End(), "")
}