mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-17 14:27:12 +09:00
This adds the `savecursor` option which will remember where the cursor was when the file was closed and put it back when the file is opened again. The option is off by default so that people aren't confused as to why the cursor isn't at the start of a file when they open it. This commit also adds a more general ability to serialize a buffer so various components can be saved (which could also be useful for persistent undo). Fixes #107
130 lines
2.5 KiB
Go
130 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"regexp"
|
|
|
|
"github.com/zyedidia/tcell"
|
|
)
|
|
|
|
var (
|
|
// What was the last search
|
|
lastSearch string
|
|
|
|
// Where should we start the search down from (or up from)
|
|
searchStart int
|
|
|
|
// Is there currently a search in progress
|
|
searching bool
|
|
)
|
|
|
|
// BeginSearch starts a search
|
|
func BeginSearch() {
|
|
searching = true
|
|
messenger.hasPrompt = true
|
|
messenger.Message("Find: ")
|
|
}
|
|
|
|
// EndSearch stops the current search
|
|
func EndSearch() {
|
|
searching = false
|
|
messenger.hasPrompt = false
|
|
messenger.Clear()
|
|
messenger.Reset()
|
|
if lastSearch != "" {
|
|
messenger.Message("^P Previous ^N Next")
|
|
}
|
|
}
|
|
|
|
// HandleSearchEvent takes an event and a view and will do a real time match from the messenger's output
|
|
// to the current buffer. It searches down the buffer.
|
|
func HandleSearchEvent(event tcell.Event, v *View) {
|
|
switch e := event.(type) {
|
|
case *tcell.EventKey:
|
|
switch e.Key() {
|
|
case tcell.KeyCtrlQ, tcell.KeyCtrlC, tcell.KeyEscape, tcell.KeyEnter:
|
|
// Done
|
|
EndSearch()
|
|
return
|
|
}
|
|
}
|
|
|
|
messenger.HandleEvent(event)
|
|
|
|
if messenger.cursorx < 0 {
|
|
// Done
|
|
EndSearch()
|
|
return
|
|
}
|
|
|
|
if messenger.response == "" {
|
|
v.Cursor.ResetSelection()
|
|
// We don't end the search though
|
|
return
|
|
}
|
|
|
|
Search(messenger.response, v, true)
|
|
|
|
return
|
|
}
|
|
|
|
// Search searches in the view for the given regex. The down bool
|
|
// specifies whether it should search down from the searchStart position
|
|
// or up from there
|
|
func Search(searchStr string, v *View, down bool) {
|
|
if searchStr == "" {
|
|
return
|
|
}
|
|
var str string
|
|
var charPos int
|
|
text := v.Buf.String()
|
|
if down {
|
|
str = text[searchStart:]
|
|
charPos = searchStart
|
|
} else {
|
|
str = text[:searchStart]
|
|
}
|
|
r, err := regexp.Compile(searchStr)
|
|
if settings["ignorecase"].(bool) {
|
|
r, err = regexp.Compile("(?i)" + searchStr)
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
matches := r.FindAllStringIndex(str, -1)
|
|
var match []int
|
|
if matches == nil {
|
|
// Search the entire buffer now
|
|
matches = r.FindAllStringIndex(text, -1)
|
|
charPos = 0
|
|
if matches == nil {
|
|
v.Cursor.ResetSelection()
|
|
return
|
|
}
|
|
|
|
if !down {
|
|
match = matches[len(matches)-1]
|
|
} else {
|
|
match = matches[0]
|
|
}
|
|
str = text
|
|
}
|
|
|
|
if !down {
|
|
match = matches[len(matches)-1]
|
|
} else {
|
|
match = matches[0]
|
|
}
|
|
|
|
if match[0] == match[1] {
|
|
return
|
|
}
|
|
|
|
v.Cursor.CurSelection[0] = charPos + runePos(match[0], str)
|
|
v.Cursor.CurSelection[1] = charPos + runePos(match[1], str)
|
|
v.Cursor.X, v.Cursor.Y = FromCharPos(charPos+match[1]-1, v.Buf)
|
|
if v.Relocate() {
|
|
v.matches = Match(v)
|
|
}
|
|
lastSearch = searchStr
|
|
}
|