Initial attempt at search

This commit is contained in:
Zachary Yedidia
2016-04-10 17:27:02 -04:00
parent 1331265681
commit 139bc3cda2
4 changed files with 93 additions and 21 deletions

View File

@@ -76,13 +76,13 @@ func (c *Cursor) Loc() int {
// ResetSelection resets the user's selection
func (c *Cursor) ResetSelection() {
c.curSelection[0] = 0
c.curSelection[1] = 0
c.curSelection[0] = -1
c.curSelection[1] = -1
}
// HasSelection returns whether or not the user has selected anything
func (c *Cursor) HasSelection() bool {
return c.curSelection[1] != c.curSelection[0]
return c.curSelection[1] != -1 || c.curSelection[0] != -1
}
// DeleteSelection deletes the currently selected text

View File

@@ -43,6 +43,8 @@ type Messenger struct {
// style to use when drawing the message
style tcell.Style
realtimePrompt bool
// We have to keep track of the cursor for prompting
cursorx int
}

View File

@@ -138,25 +138,69 @@ func main() {
// Wait for the user's action
event := screen.PollEvent()
// Check if we should quit
switch e := event.(type) {
case *tcell.EventKey:
switch e.Key() {
case tcell.KeyCtrlQ:
// Make sure not to quit if there are unsaved changes
if view.CanClose("Quit anyway? ") {
screen.Fini()
os.Exit(0)
if messenger.realtimePrompt {
switch e := event.(type) {
case *tcell.EventKey:
if e.Key() == tcell.KeyEscape {
// Cancel
messenger.hasPrompt = false
messenger.realtimePrompt = false
messenger.Clear()
messenger.Reset()
continue
} else if e.Key() == tcell.KeyCtrlC {
// Cancel
messenger.hasPrompt = false
messenger.realtimePrompt = false
messenger.Clear()
messenger.Reset()
continue
} else if e.Key() == tcell.KeyCtrlQ {
// Cancel
messenger.hasPrompt = false
messenger.realtimePrompt = false
messenger.Clear()
messenger.Reset()
continue
} else if e.Key() == tcell.KeyEnter {
// User is done entering their response
messenger.hasPrompt = false
messenger.realtimePrompt = false
messenger.Clear()
messenger.Reset()
continue
}
case tcell.KeyCtrlE:
input, canceled := messenger.Prompt("> ")
if !canceled {
HandleCommand(input, view)
}
if messenger.cursorx < 0 {
// Cancel
messenger.realtimePrompt = false
messenger.hasPrompt = false
messenger.Clear()
messenger.Reset()
continue
}
messenger.HandleEvent(event)
} else {
// Check if we should quit
switch e := event.(type) {
case *tcell.EventKey:
switch e.Key() {
case tcell.KeyCtrlQ:
// Make sure not to quit if there are unsaved changes
if view.CanClose("Quit anyway? ") {
screen.Fini()
os.Exit(0)
}
case tcell.KeyCtrlE:
input, canceled := messenger.Prompt("> ")
if !canceled {
HandleCommand(input, view)
}
case tcell.KeyCtrlH:
DisplayHelp()
// Make sure to resize the view if the user resized the terminal while looking at the help text
view.Resize(screen.Size())
}
case tcell.KeyCtrlH:
DisplayHelp()
// Make sure to resize the view if the user resized the terminal while looking at the help text
view.Resize(screen.Size())
}
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/atotto/clipboard"
"github.com/gdamore/tcell"
"io/ioutil"
"regexp"
"strconv"
"strings"
"time"
@@ -338,6 +339,26 @@ func (v *View) HandleEvent(event tcell.Event) {
// This bool determines whether the view is relocated at the end of the function
// By default it's true because most events should cause a relocate
relocate := true
if messenger.realtimePrompt {
str := strings.Join(v.buf.lines[v.cursor.y:], "\n")
charPos := ToCharPos(0, v.cursor.y, v.buf)
r, err := regexp.Compile(messenger.response)
if err != nil {
return
}
match := r.FindStringIndex(str)
if match == nil {
v.cursor.ResetSelection()
return
}
v.cursor.curSelection[0] = charPos + match[0]
v.cursor.curSelection[1] = charPos + match[1] - 1
v.cursor.x, v.cursor.y = FromCharPos(charPos+match[1]-1, v.buf)
v.Relocate()
return
}
// By default we don't update and syntax highlighting
v.UpdateLines(-2, 0)
switch e := event.(type) {
@@ -402,6 +423,10 @@ func (v *View) HandleEvent(event tcell.Event) {
v.UpdateLines(v.cursor.y, v.cursor.y)
case tcell.KeyCtrlS:
v.Save()
case tcell.KeyCtrlF:
messenger.realtimePrompt = true
messenger.hasPrompt = true
messenger.Message("Find: ")
case tcell.KeyCtrlZ:
v.eh.Undo()
// Rehighlight the entire buffer
@@ -504,7 +529,7 @@ func (v *View) HandleEvent(event tcell.Event) {
} else if v.doubleClick {
v.cursor.AddWordToSelection()
} else {
v.cursor.curSelection[1] = v.cursor.Loc()
v.cursor.curSelection[1] = v.cursor.Loc() - 1
}
}
v.mouseReleased = false
@@ -569,6 +594,7 @@ func (v *View) DisplayView() {
// }
// The character number of the character in the top left of the screen
charNum := ToCharPos(0, v.topline, v.buf)
// Convert the length of buffer to a string, and get the length of the string