forked from mirror/readline
add HistorySearchFold
This commit is contained in:
parent
283f5429f7
commit
5073debd7e
|
@ -68,6 +68,8 @@ func main() {
|
||||||
AutoComplete: completer,
|
AutoComplete: completer,
|
||||||
InterruptPrompt: "^C",
|
InterruptPrompt: "^C",
|
||||||
EOFPrompt: "exit",
|
EOFPrompt: "exit",
|
||||||
|
|
||||||
|
HistorySearchFold: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (o *opHistory) FindBck(isNewSearch bool, rs []rune, start int) (int, *list.
|
||||||
item = item[:start]
|
item = item[:start]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx := runes.IndexAllBck(item, rs)
|
idx := runes.IndexAllBckEx(item, rs, o.cfg.HistoryFoldSearch)
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ func (o *opHistory) FindFwd(isNewSearch bool, rs []rune, start int) (int, *list.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx := runes.IndexAll(item, rs)
|
idx := runes.IndexAllEx(item, rs, o.cfg.HistoryFoldSearch)
|
||||||
if idx < 0 {
|
if idx < 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ type Config struct {
|
||||||
// specify the max length of historys, it's 500 by default, set it to -1 to disable history
|
// specify the max length of historys, it's 500 by default, set it to -1 to disable history
|
||||||
HistoryLimit int
|
HistoryLimit int
|
||||||
DisableAutoSaveHistory bool
|
DisableAutoSaveHistory bool
|
||||||
|
// enable case-insensitive history searching
|
||||||
|
HistorySearchFold bool
|
||||||
|
|
||||||
// AutoCompleter will called once user press TAB
|
// AutoCompleter will called once user press TAB
|
||||||
AutoComplete AutoCompleter
|
AutoComplete AutoCompleter
|
||||||
|
|
62
runes.go
62
runes.go
|
@ -3,6 +3,7 @@ package readline
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
var runes = Runes{}
|
var runes = Runes{}
|
||||||
|
@ -10,6 +11,42 @@ var TabWidth = 4
|
||||||
|
|
||||||
type Runes struct{}
|
type Runes struct{}
|
||||||
|
|
||||||
|
func (Runes) EqualRune(a, b rune, fold bool) bool {
|
||||||
|
if a == b {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if !fold {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if a > b {
|
||||||
|
a, b = b, a
|
||||||
|
}
|
||||||
|
if b < utf8.RuneSelf && 'A' <= a && a <= 'Z' {
|
||||||
|
if b == a+'a'-'A' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Runes) EqualRuneFold(a, b rune) bool {
|
||||||
|
return r.EqualRune(a, b, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Runes) EqualFold(a, b []rune) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < len(a); i++ {
|
||||||
|
if r.EqualRuneFold(a[i], b[i]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (Runes) Equal(a, b []rune) bool {
|
func (Runes) Equal(a, b []rune) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
|
@ -22,12 +59,11 @@ func (Runes) Equal(a, b []rune) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search in runes from end to front
|
func (rs Runes) IndexAllBckEx(r, sub []rune, fold bool) int {
|
||||||
func (Runes) IndexAllBck(r, sub []rune) int {
|
|
||||||
for i := len(r) - len(sub); i >= 0; i-- {
|
for i := len(r) - len(sub); i >= 0; i-- {
|
||||||
found := true
|
found := true
|
||||||
for j := 0; j < len(sub); j++ {
|
for j := 0; j < len(sub); j++ {
|
||||||
if r[i+j] != sub[j] {
|
if !rs.EqualRune(r[i+j], sub[j], fold) {
|
||||||
found = false
|
found = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -39,15 +75,24 @@ func (Runes) IndexAllBck(r, sub []rune) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search in runes from end to front
|
||||||
|
func (rs Runes) IndexAllBck(r, sub []rune) int {
|
||||||
|
return rs.IndexAllBckEx(r, sub, false)
|
||||||
|
}
|
||||||
|
|
||||||
// Search in runes from front to end
|
// Search in runes from front to end
|
||||||
func (Runes) IndexAll(r, sub []rune) int {
|
func (rs Runes) IndexAll(r, sub []rune) int {
|
||||||
|
return rs.IndexAllEx(r, sub, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs Runes) IndexAllEx(r, sub []rune, fold bool) int {
|
||||||
for i := 0; i < len(r); i++ {
|
for i := 0; i < len(r); i++ {
|
||||||
found := true
|
found := true
|
||||||
if len(r[i:]) < len(sub) {
|
if len(r[i:]) < len(sub) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
for j := 0; j < len(sub); j++ {
|
for j := 0; j < len(sub); j++ {
|
||||||
if r[i+j] != sub[j] {
|
if !rs.EqualRune(r[i+j], sub[j], fold) {
|
||||||
found = false
|
found = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -128,6 +173,13 @@ func (Runes) Copy(r []rune) []rune {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Runes) HasPrefixFold(r, prefix []rune) bool {
|
||||||
|
if len(r) < len(prefix) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return runes.EqualFold(r[:len(prefix)], prefix)
|
||||||
|
}
|
||||||
|
|
||||||
func (Runes) HasPrefix(r, prefix []rune) bool {
|
func (Runes) HasPrefix(r, prefix []rune) bool {
|
||||||
if len(r) < len(prefix) {
|
if len(r) < len(prefix) {
|
||||||
return false
|
return false
|
||||||
|
|
Loading…
Reference in New Issue