mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
Refactor query and caretPos
This commit is contained in:
parent
3b2b1fe07a
commit
11dfa1b426
137
action.go
137
action.go
|
|
@ -151,16 +151,12 @@ func doAcceptChar(i *Input, ev termbox.Event) {
|
|||
}
|
||||
|
||||
if ev.Ch > 0 {
|
||||
if len(i.query) == i.caretPos {
|
||||
i.query = append(i.query, ev.Ch)
|
||||
if i.QueryLen() == i.CaretPos().Int() {
|
||||
i.AppendQuery(ev.Ch)
|
||||
} else {
|
||||
buf := make([]rune, len(i.query)+1)
|
||||
copy(buf, i.query[:i.caretPos])
|
||||
buf[i.caretPos] = ev.Ch
|
||||
copy(buf[i.caretPos+1:], i.query[i.caretPos:])
|
||||
i.query = buf
|
||||
i.InsertQueryAt(ev.Ch, i.CaretPos().Int())
|
||||
}
|
||||
i.caretPos++
|
||||
i.MoveCaretPos(1)
|
||||
i.ExecQuery()
|
||||
}
|
||||
}
|
||||
|
|
@ -284,22 +280,23 @@ func doToggleSelectionAndSelectNext(i *Input, ev termbox.Event) {
|
|||
}
|
||||
|
||||
func doDeleteBackwardWord(i *Input, _ termbox.Event) {
|
||||
if i.caretPos == 0 {
|
||||
if i.CaretPos() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for pos := i.caretPos - 1; pos >= 0; pos-- {
|
||||
for pos := i.CaretPos().Int() - 1; pos >= 0; pos-- {
|
||||
q := i.Query()
|
||||
if pos == 0 {
|
||||
i.query = i.query[i.caretPos:]
|
||||
i.SetQuery(q[i.CaretPos().Int():])
|
||||
break
|
||||
}
|
||||
|
||||
if unicode.IsSpace(i.query[pos]) {
|
||||
buf := make([]rune, len(i.query)-(i.caretPos-pos))
|
||||
copy(buf, i.query[:pos])
|
||||
copy(buf[pos:], i.query[i.caretPos:])
|
||||
i.query = buf
|
||||
i.caretPos = pos
|
||||
if unicode.IsSpace(q[pos]) {
|
||||
buf := make([]rune, q.QueryLen()-(i.CaretPos().Int()-pos))
|
||||
copy(buf, q[:pos])
|
||||
copy(buf[pos:], q[i.CaretPos().Int():])
|
||||
i.SetQuery(buf)
|
||||
i.SetCaretPos(pos)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -313,16 +310,16 @@ func doDeleteBackwardWord(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doForwardWord(i *Input, _ termbox.Event) {
|
||||
if i.caretPos >= len(i.query) {
|
||||
if i.CaretPos().Int() >= i.QueryLen() {
|
||||
return
|
||||
}
|
||||
|
||||
foundSpace := false
|
||||
for pos := i.caretPos; pos < len(i.query); pos++ {
|
||||
r := i.query[pos]
|
||||
for pos := i.CaretPos().Int(); pos < i.QueryLen(); pos++ {
|
||||
r := i.Query()[pos]
|
||||
if foundSpace {
|
||||
if !unicode.IsSpace(r) {
|
||||
i.caretPos = pos
|
||||
i.SetCaretPos(pos)
|
||||
i.DrawMatches(nil)
|
||||
return
|
||||
}
|
||||
|
|
@ -334,28 +331,28 @@ func doForwardWord(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
// not found. just move to the end of the buffer
|
||||
i.caretPos = len(i.query)
|
||||
i.SetCaretPos(i.QueryLen())
|
||||
i.DrawMatches(nil)
|
||||
|
||||
}
|
||||
|
||||
func doBackwardWord(i *Input, _ termbox.Event) {
|
||||
if i.caretPos == 0 {
|
||||
if i.CaretPos().Int() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if i.caretPos >= len(i.query) {
|
||||
i.caretPos--
|
||||
if i.CaretPos().Int() >= i.QueryLen() {
|
||||
i.MoveCaretPos(-1)
|
||||
}
|
||||
|
||||
// if we start from a whitespace-ish position, we should
|
||||
// rewind to the end of the previous word, and then do the
|
||||
// search all over again
|
||||
SEARCH_PREV_WORD:
|
||||
if unicode.IsSpace(i.query[i.caretPos]) {
|
||||
for pos := i.caretPos; pos > 0; pos-- {
|
||||
if !unicode.IsSpace(i.query[pos]) {
|
||||
i.caretPos = pos
|
||||
if unicode.IsSpace(i.Query()[i.CaretPos().Int()]) {
|
||||
for pos := i.CaretPos().Int(); pos > 0; pos-- {
|
||||
if !unicode.IsSpace(i.Query()[pos]) {
|
||||
i.SetCaretPos(pos)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -363,57 +360,57 @@ SEARCH_PREV_WORD:
|
|||
|
||||
// if we start from the first character of a word, we
|
||||
// should attempt to move back and search for the previous word
|
||||
if i.caretPos > 0 && unicode.IsSpace(i.query[i.caretPos-1]) {
|
||||
i.caretPos--
|
||||
if i.CaretPos() > 0 && unicode.IsSpace(i.Query()[i.CaretPos()-1]) {
|
||||
i.MoveCaretPos(-1)
|
||||
goto SEARCH_PREV_WORD
|
||||
}
|
||||
|
||||
// Now look for a space
|
||||
for pos := i.caretPos; pos > 0; pos-- {
|
||||
if unicode.IsSpace(i.query[pos]) {
|
||||
i.caretPos = pos + 1
|
||||
for pos := i.CaretPos(); pos > 0; pos-- {
|
||||
if unicode.IsSpace(i.Query()[pos]) {
|
||||
i.SetCaretPos(int(pos + 1))
|
||||
i.DrawMatches(nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// not found. just move to the beginning of the buffer
|
||||
i.caretPos = 0
|
||||
i.SetCaretPos(0)
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doForwardChar(i *Input, _ termbox.Event) {
|
||||
if i.caretPos >= len(i.query) {
|
||||
if i.CaretPos().Int() >= i.QueryLen() {
|
||||
return
|
||||
}
|
||||
i.caretPos++
|
||||
i.MoveCaretPos(1)
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doBackwardChar(i *Input, _ termbox.Event) {
|
||||
if i.caretPos <= 0 {
|
||||
if i.CaretPos() <= 0 {
|
||||
return
|
||||
}
|
||||
i.caretPos--
|
||||
i.MoveCaretPos(-1)
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doDeleteForwardWord(i *Input, _ termbox.Event) {
|
||||
if len(i.query) <= i.caretPos {
|
||||
if i.QueryLen() <= i.CaretPos().Int() {
|
||||
return
|
||||
}
|
||||
|
||||
for pos := i.caretPos; pos < len(i.query); pos++ {
|
||||
if pos == len(i.query)-1 {
|
||||
i.query = i.query[:i.caretPos]
|
||||
for pos := i.CaretPos().Int(); pos < i.QueryLen(); pos++ {
|
||||
if pos == i.QueryLen()-1 {
|
||||
i.SetQuery(i.Query()[:i.CaretPos()])
|
||||
break
|
||||
}
|
||||
|
||||
if unicode.IsSpace(i.query[pos]) {
|
||||
buf := make([]rune, len(i.query)-(pos-i.caretPos))
|
||||
copy(buf, i.query[:i.caretPos])
|
||||
copy(buf[i.caretPos:], i.query[pos:])
|
||||
i.query = buf
|
||||
if unicode.IsSpace(i.Query()[pos]) {
|
||||
buf := make([]rune, i.QueryLen()-(pos-i.CaretPos().Int()))
|
||||
copy(buf, i.Query()[:i.CaretPos()])
|
||||
copy(buf[i.CaretPos():], i.Query()[pos:])
|
||||
i.SetQuery(buf)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -427,17 +424,17 @@ func doDeleteForwardWord(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doBeginningOfLine(i *Input, _ termbox.Event) {
|
||||
i.caretPos = 0
|
||||
i.SetCaretPos(0)
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doEndOfLine(i *Input, _ termbox.Event) {
|
||||
i.caretPos = len(i.query)
|
||||
i.SetCaretPos(i.QueryLen())
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doEndOfFile(i *Input, ev termbox.Event) {
|
||||
if len(i.query) > 0 {
|
||||
if i.QueryLen() > 0 {
|
||||
doDeleteForwardChar(i, ev)
|
||||
} else {
|
||||
doCancel(i, ev)
|
||||
|
|
@ -445,8 +442,8 @@ func doEndOfFile(i *Input, ev termbox.Event) {
|
|||
}
|
||||
|
||||
func doKillBeginningOfLine(i *Input, _ termbox.Event) {
|
||||
i.query = i.query[i.caretPos:]
|
||||
i.caretPos = 0
|
||||
i.SetQuery(i.Query()[i.CaretPos():])
|
||||
i.SetCaretPos(0)
|
||||
if i.ExecQuery() {
|
||||
return
|
||||
}
|
||||
|
|
@ -455,11 +452,11 @@ func doKillBeginningOfLine(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doKillEndOfLine(i *Input, _ termbox.Event) {
|
||||
if len(i.query) <= i.caretPos {
|
||||
if i.QueryLen() <= i.CaretPos().Int() {
|
||||
return
|
||||
}
|
||||
|
||||
i.query = i.query[0:i.caretPos]
|
||||
i.SetQuery(i.Query()[0:i.CaretPos()])
|
||||
if i.ExecQuery() {
|
||||
return
|
||||
}
|
||||
|
|
@ -468,20 +465,20 @@ func doKillEndOfLine(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doDeleteAll(i *Input, _ termbox.Event) {
|
||||
i.query = make([]rune, 0)
|
||||
i.SetQuery(make([]rune, 0))
|
||||
i.current = nil
|
||||
i.DrawMatches(nil)
|
||||
}
|
||||
|
||||
func doDeleteForwardChar(i *Input, _ termbox.Event) {
|
||||
if len(i.query) <= i.caretPos {
|
||||
if i.QueryLen() <= i.CaretPos().Int() {
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]rune, len(i.query)-1)
|
||||
copy(buf, i.query[:i.caretPos])
|
||||
copy(buf[i.caretPos:], i.query[i.caretPos+1:])
|
||||
i.query = buf
|
||||
buf := make([]rune, i.QueryLen()-1)
|
||||
copy(buf, i.Query()[:i.CaretPos()])
|
||||
copy(buf[i.CaretPos():], i.Query()[i.CaretPos()+1:])
|
||||
i.SetQuery(buf)
|
||||
|
||||
if i.ExecQuery() {
|
||||
return
|
||||
|
|
@ -492,23 +489,23 @@ func doDeleteForwardChar(i *Input, _ termbox.Event) {
|
|||
}
|
||||
|
||||
func doDeleteBackwardChar(i *Input, ev termbox.Event) {
|
||||
if len(i.query) <= 0 {
|
||||
if i.QueryLen() <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
switch i.caretPos {
|
||||
switch i.CaretPos().Int() {
|
||||
case 0:
|
||||
// No op
|
||||
return
|
||||
case len(i.query):
|
||||
i.query = i.query[:len(i.query)-1]
|
||||
case i.QueryLen():
|
||||
i.SetQuery(i.Query()[:i.QueryLen()-1])
|
||||
default:
|
||||
buf := make([]rune, len(i.query)-1)
|
||||
copy(buf, i.query[:i.caretPos])
|
||||
copy(buf[i.caretPos-1:], i.query[i.caretPos:])
|
||||
i.query = buf
|
||||
buf := make([]rune, i.QueryLen()-1)
|
||||
copy(buf, i.Query()[:i.CaretPos()])
|
||||
copy(buf[i.CaretPos()-1:], i.Query()[i.CaretPos():])
|
||||
i.SetQuery(buf)
|
||||
}
|
||||
i.caretPos--
|
||||
i.MoveCaretPos(-1)
|
||||
|
||||
if i.ExecQuery() {
|
||||
return
|
||||
|
|
|
|||
61
ctx.go
61
ctx.go
|
|
@ -37,15 +37,60 @@ type PageInfo struct {
|
|||
perPage int
|
||||
}
|
||||
|
||||
type CaretPosition int
|
||||
|
||||
func (p CaretPosition) Int() int {
|
||||
return int(p)
|
||||
}
|
||||
|
||||
func (p CaretPosition) CaretPos() CaretPosition {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *CaretPosition) SetCaretPos(where int) {
|
||||
*p = CaretPosition(where)
|
||||
}
|
||||
|
||||
func (p *CaretPosition) MoveCaretPos(offset int) {
|
||||
*p = CaretPosition(p.Int() + offset)
|
||||
}
|
||||
|
||||
type FilterQuery []rune
|
||||
|
||||
func (q FilterQuery) Query() FilterQuery {
|
||||
return q
|
||||
}
|
||||
|
||||
func (q FilterQuery) String() string {
|
||||
return string(q)
|
||||
}
|
||||
|
||||
func (q FilterQuery) QueryLen() int {
|
||||
return len(q)
|
||||
}
|
||||
|
||||
func (q *FilterQuery) AppendQuery(r rune) {
|
||||
*q = FilterQuery(append([]rune(*q), r))
|
||||
}
|
||||
|
||||
func (q *FilterQuery) InsertQueryAt(ch rune, where int) {
|
||||
sq := []rune(*q)
|
||||
buf := make([]rune, q.QueryLen()+1)
|
||||
copy(buf, sq[:where])
|
||||
buf[where] = ch
|
||||
copy(buf[where+1:], sq[where:])
|
||||
*q = FilterQuery(buf)
|
||||
}
|
||||
|
||||
// Ctx contains all the important data. while you can easily access
|
||||
// data in this struct from anwyehre, only do so via channels
|
||||
type Ctx struct {
|
||||
*Hub
|
||||
CaretPosition
|
||||
FilterQuery
|
||||
enableSep bool
|
||||
result []Match
|
||||
mutex sync.Mutex
|
||||
query []rune
|
||||
caretPos int
|
||||
currentLine int
|
||||
currentPage *PageInfo
|
||||
maxPage int
|
||||
|
|
@ -66,10 +111,10 @@ type Ctx struct {
|
|||
func NewCtx(o CtxOptions) *Ctx {
|
||||
c := &Ctx{
|
||||
Hub: NewHub(),
|
||||
CaretPosition: 0,
|
||||
FilterQuery: FilterQuery{},
|
||||
result: []Match{},
|
||||
mutex: sync.Mutex{},
|
||||
query: []rune{},
|
||||
caretPos: 0,
|
||||
currentPage: &PageInfo{0, 1, 0},
|
||||
maxPage: 0,
|
||||
selection: Selection([]int{}),
|
||||
|
|
@ -174,8 +219,8 @@ func (c *Ctx) WaitDone() {
|
|||
}
|
||||
|
||||
func (c *Ctx) ExecQuery() bool {
|
||||
if len(c.query) > 0 {
|
||||
c.SendQuery(string(c.query))
|
||||
if c.QueryLen() > 0 {
|
||||
c.SendQuery(c.Query().String())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -222,8 +267,8 @@ func (c *Ctx) NewInput() *Input {
|
|||
}
|
||||
|
||||
func (c *Ctx) SetQuery(q []rune) {
|
||||
c.query = q
|
||||
c.caretPos = len(q)
|
||||
c.FilterQuery = FilterQuery(q)
|
||||
c.SetCaretPos(c.QueryLen())
|
||||
}
|
||||
|
||||
func (c *Ctx) Matcher() Matcher {
|
||||
|
|
|
|||
18
layout.go
18
layout.go
|
|
@ -144,19 +144,19 @@ func (u UserPrompt) Draw() {
|
|||
// print "QUERY>"
|
||||
printScreen(0, location, u.config.Style.BasicFG(), u.config.Style.BasicBG(), u.prefix, false)
|
||||
|
||||
if u.caretPos <= 0 {
|
||||
u.caretPos = 0 // sanity
|
||||
if u.CaretPos() <= 0 { // XXX Do we really need this?
|
||||
u.SetCaretPos(0) // sanity
|
||||
}
|
||||
|
||||
if u.caretPos > len(u.query) {
|
||||
u.caretPos = len(u.query)
|
||||
if u.CaretPos().Int() > u.QueryLen() { // XXX Do we really need this?
|
||||
u.SetCaretPos(u.QueryLen())
|
||||
}
|
||||
|
||||
if u.caretPos == len(u.query) {
|
||||
if u.CaretPos().Int() == u.QueryLen() {
|
||||
// the entire string + the caret after the string
|
||||
fg := u.config.Style.QueryFG()
|
||||
bg := u.config.Style.QueryBG()
|
||||
qs := string(u.query)
|
||||
qs := u.Query().String()
|
||||
ql := runewidth.StringWidth(qs)
|
||||
printScreen(u.prefixLen+1, location, fg, bg, qs, false)
|
||||
printScreen(u.prefixLen+1+ql, location, fg|termbox.AttrReverse, bg|termbox.AttrReverse, " ", false)
|
||||
|
|
@ -166,8 +166,8 @@ func (u UserPrompt) Draw() {
|
|||
prev := 0
|
||||
fg := u.config.Style.QueryFG()
|
||||
bg := u.config.Style.QueryBG()
|
||||
for i, r := range u.query {
|
||||
if i == u.caretPos {
|
||||
for i, r := range []rune(u.Query()) {
|
||||
if i == u.CaretPos().Int() {
|
||||
fg |= termbox.AttrReverse
|
||||
bg |= termbox.AttrReverse
|
||||
}
|
||||
|
|
@ -383,7 +383,7 @@ CALCULATE_PAGE:
|
|||
}
|
||||
|
||||
if l.maxPage < currentPage.index {
|
||||
if len(targets) == 0 && len(l.query) == 0 {
|
||||
if len(targets) == 0 && l.QueryLen() == 0 {
|
||||
// wait for targets
|
||||
return fmt.Errorf("no targets or query. nothing to do")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue