// Package filter implements the Elvish filter DSL. // // The filter DSL is a subset of Elvish's expression syntax, and is useful for // filtering a list of items. It is currently used in the listing modes of the // interactive editor.
package filter import ( ) // Compile parses and compiles a filter. func ( string) (Filter, error) { , := parseFilter() , := compileFilter() return , diag.Errors(, ) } func ( string) (*parse.Filter, error) { := &parse.Filter{} := parse.ParseAs(parse.Source{Name: "filter", Code: }, , parse.Config{}) return , } func ( *parse.Filter) (Filter, error) { if len(.Opts) > 0 { return nil, notSupportedError{"option"} } , := compileCompounds(.Args) if != nil { return nil, } return andFilter{}, nil } func ( []*parse.Compound) ([]Filter, error) { := make([]Filter, len()) for , := range { , := compileCompound() if != nil { return nil, } [] = } return , nil } func ( *parse.Compound) (Filter, error) { if , := cmpd.Primary(); { switch .Type { case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted: := .Value := == strings.ToLower() return substringFilter{, }, nil case parse.List: return compileList(.Elements) } } return nil, notSupportedError{cmpd.Shape()} } var errEmptySubfilter = errors.New("empty subfilter") func ( []*parse.Compound) (Filter, error) { if len() == 0 { return nil, errEmptySubfilter } , := cmpd.StringLiteral([0]) if ! { return nil, notSupportedError{"non-literal subfilter head"} } switch { case "re": if len() == 1 { return nil, notSupportedError{"re subfilter with no argument"} } if len() > 2 { return nil, notSupportedError{"re subfilter with two or more arguments"} } := [1] , := cmpd.StringLiteral() if ! { return nil, notSupportedError{"re subfilter with " + cmpd.Shape()} } , := regexp.Compile() if != nil { return nil, } return regexpFilter{}, nil case "and": , := compileCompounds([1:]) if != nil { return nil, } return andFilter{}, nil case "or": , := compileCompounds([1:]) if != nil { return nil, } return orFilter{}, nil default: return nil, notSupportedError{"head " + parse.SourceText([0])} } } type notSupportedError struct{ what string } func ( notSupportedError) () string { return .what + " not supported" }