mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-06 15:10:27 +09:00
YN callbacks and better multi cursor
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(), "")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user