cliedit: Add support for &ignore-case and &smart-case to builtin matchers.

This commit is contained in:
Qi Xiao 2019-11-28 22:59:49 +00:00
parent d4c61f46ab
commit ec2fb88bc0
2 changed files with 42 additions and 6 deletions

View File

@ -316,7 +316,7 @@ func commonPrefix(s1, s2 string) string {
// The type for a native Go matcher. This is not equivalent to the Elvish
// counterpart, which streams input and output. This is because we can actually
// afford calling a Go function for each item, so omitting the streaming
// behavior makes the implementation easier.
// behavior makes the implementation simpler.
//
// Native Go matchers are wrapped into Elvish matchers, but never the other way
// around.
@ -325,14 +325,30 @@ func commonPrefix(s1, s2 string) string {
// wrapped into match-substr and match-prefix respectively.
type matcher func(text, seed string) bool
type wrappedMatcher func(fm *eval.Frame, seed string, inputs eval.Inputs)
type matcherOpts struct {
IgnoreCase bool
SmartCase bool
}
func (*matcherOpts) SetDefaultOptions() {}
type wrappedMatcher func(fm *eval.Frame, opts matcherOpts, seed string, inputs eval.Inputs)
func wrapMatcher(m matcher) wrappedMatcher {
return func(fm *eval.Frame, seed string, input eval.Inputs) {
return func(fm *eval.Frame, opts matcherOpts, seed string, inputs eval.Inputs) {
out := fm.OutputChan()
input(func(v interface{}) {
out <- m(vals.ToString(v), seed)
})
if opts.IgnoreCase || (opts.SmartCase && seed == strings.ToLower(seed)) {
if opts.IgnoreCase {
seed = strings.ToLower(seed)
}
inputs(func(v interface{}) {
out <- m(strings.ToLower(vals.ToString(v)), seed)
})
} else {
inputs(func(v interface{}) {
out <- m(vals.ToString(v), seed)
})
}
}
}

View File

@ -217,3 +217,23 @@ func TestBuiltinMatchers(t *testing.T) {
"subseq": vals.MakeList(true, true, true, true, false, true, true, false),
})
}
func TestBuiltinMatchers_Options(t *testing.T) {
f := setup()
defer f.Cleanup()
// The two options work identically on all the builtin matchers, so we only
// test for match-prefix for simplicity.
evals(f.Evaler,
`@a = (edit:match-prefix &ignore-case ab [abc aBc AbC])`,
`@b = (edit:match-prefix &ignore-case aB [abc aBc AbC])`,
`@c = (edit:match-prefix &smart-case ab [abc aBc Abc])`,
`@d = (edit:match-prefix &smart-case aB [abc aBc AbC])`,
)
testGlobals(t, f.Evaler, map[string]interface{}{
"a": vals.MakeList(true, true, true),
"b": vals.MakeList(true, true, true),
"c": vals.MakeList(true, true, true),
"d": vals.MakeList(false, true, false),
})
}