Case-fold patterns.
This commit is contained in:
parent
df14a314e4
commit
96942f9acc
5 changed files with 162 additions and 80 deletions
102
file.go
102
file.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SelectFile displays the file selection dialog.
|
// SelectFile displays the file selection dialog.
|
||||||
|
@ -69,6 +70,8 @@ func Filename(filename string) Option {
|
||||||
|
|
||||||
// FileFilter is an Option that sets a filename filter.
|
// FileFilter is an Option that sets a filename filter.
|
||||||
//
|
//
|
||||||
|
// On Windows and macOS filtering is always case-insensitive.
|
||||||
|
//
|
||||||
// macOS hides filename filters from the user,
|
// macOS hides filename filters from the user,
|
||||||
// and only supports filtering by extension
|
// and only supports filtering by extension
|
||||||
// (or "uniform type identifiers").
|
// (or "uniform type identifiers").
|
||||||
|
@ -78,6 +81,7 @@ func Filename(filename string) Option {
|
||||||
type FileFilter struct {
|
type FileFilter struct {
|
||||||
Name string // display string that describes the filter (optional)
|
Name string // display string that describes the filter (optional)
|
||||||
Patterns []string // filter patterns for the display string
|
Patterns []string // filter patterns for the display string
|
||||||
|
CaseFold bool // if set patterns are matched case-insensitively
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FileFilter) apply(o *options) {
|
func (f FileFilter) apply(o *options) {
|
||||||
|
@ -91,7 +95,7 @@ func (f FileFilters) apply(o *options) {
|
||||||
o.fileFilters = append(o.fileFilters, f...)
|
o.fileFilters = append(o.fileFilters, f...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows' patterns need a name.
|
// Windows patterns need a name.
|
||||||
func (f FileFilters) name() {
|
func (f FileFilters) name() {
|
||||||
for i, filter := range f {
|
for i, filter := range f {
|
||||||
if filter.Name == "" {
|
if filter.Name == "" {
|
||||||
|
@ -100,47 +104,42 @@ func (f FileFilters) name() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows' patterns are case insensitive, don't support character classes or escaping.
|
// Windows patterns are case-insensitive, don't support character classes or escaping.
|
||||||
//
|
//
|
||||||
// First we remove character classes, then escaping. Patterns with literal wildcards are invalid.
|
// First we remove character classes, then escaping. Patterns with literal wildcards are invalid.
|
||||||
// The semicolon is a separator, so we replace it with the single character wildcard.
|
// The semicolon is a separator, so we replace it with the single character wildcard.
|
||||||
// Empty and invalid filters/patterns are ignored.
|
|
||||||
func (f FileFilters) simplify() {
|
func (f FileFilters) simplify() {
|
||||||
var i = 0
|
for i := range f {
|
||||||
for _, filter := range f {
|
|
||||||
var j = 0
|
var j = 0
|
||||||
for _, pattern := range filter.Patterns {
|
for _, pattern := range f[i].Patterns {
|
||||||
var escape, invalid bool
|
var escape, invalid bool
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
for _, r := range removeClasses(pattern) {
|
for _, b := range []byte(removeClasses(pattern)) {
|
||||||
if !escape && r == '\\' {
|
if !escape && b == '\\' {
|
||||||
escape = true
|
escape = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if escape && (r == '*' || r == '?') {
|
if escape && (b == '*' || b == '?') {
|
||||||
invalid = true
|
invalid = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if r == ';' {
|
if b == ';' {
|
||||||
r = '?'
|
b = '?'
|
||||||
}
|
}
|
||||||
buf.WriteRune(r)
|
buf.WriteByte(b)
|
||||||
escape = false
|
escape = false
|
||||||
}
|
}
|
||||||
if buf.Len() > 0 && !invalid {
|
if buf.Len() > 0 && !invalid {
|
||||||
filter.Patterns[j] = buf.String()
|
f[i].Patterns[j] = buf.String()
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if j > 0 {
|
if j != 0 {
|
||||||
filter.Patterns = filter.Patterns[:j]
|
f[i].Patterns = f[i].Patterns[:j]
|
||||||
f[i] = filter
|
} else {
|
||||||
i++
|
f[i].Patterns = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ; i < len(f); i++ {
|
|
||||||
f[i] = FileFilter{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// macOS types may be specified as extension strings without the leading period,
|
// macOS types may be specified as extension strings without the leading period,
|
||||||
|
@ -163,17 +162,17 @@ func (f FileFilters) types() []string {
|
||||||
|
|
||||||
var escape bool
|
var escape bool
|
||||||
var buf strings.Builder
|
var buf strings.Builder
|
||||||
for _, r := range removeClasses(ext) {
|
for _, b := range []byte(removeClasses(ext)) {
|
||||||
switch {
|
switch {
|
||||||
case escape:
|
case escape:
|
||||||
escape = false
|
escape = false
|
||||||
case r == '\\':
|
case b == '\\':
|
||||||
escape = true
|
escape = true
|
||||||
continue
|
continue
|
||||||
case r == '*' || r == '?':
|
case b == '*' || b == '?':
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
buf.WriteRune(r)
|
buf.WriteByte(b)
|
||||||
}
|
}
|
||||||
if buf.Len() > 0 {
|
if buf.Len() > 0 {
|
||||||
res = append(res, buf.String())
|
res = append(res, buf.String())
|
||||||
|
@ -187,8 +186,57 @@ func (f FileFilters) types() []string {
|
||||||
return append([]string{""}, res...)
|
return append([]string{""}, res...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unix patterns are case-sensitive. Fold them if requested.
|
||||||
|
func (f FileFilters) casefold() {
|
||||||
|
for i := range f {
|
||||||
|
if !f[i].CaseFold {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for j, pattern := range f[i].Patterns {
|
||||||
|
var class = -1
|
||||||
|
var escape bool
|
||||||
|
var buf strings.Builder
|
||||||
|
for i, r := range pattern {
|
||||||
|
switch {
|
||||||
|
case escape:
|
||||||
|
escape = false
|
||||||
|
case r == '\\':
|
||||||
|
escape = true
|
||||||
|
case class < 0:
|
||||||
|
if r == '[' {
|
||||||
|
class = i
|
||||||
|
}
|
||||||
|
case class < i-1:
|
||||||
|
if r == ']' {
|
||||||
|
class = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nr := unicode.SimpleFold(r)
|
||||||
|
if r == nr {
|
||||||
|
buf.WriteRune(r)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if class < 0 {
|
||||||
|
buf.WriteByte('[')
|
||||||
|
}
|
||||||
|
buf.WriteRune(r)
|
||||||
|
for r != nr {
|
||||||
|
buf.WriteRune(nr)
|
||||||
|
nr = unicode.SimpleFold(nr)
|
||||||
|
}
|
||||||
|
if class < 0 {
|
||||||
|
buf.WriteByte(']')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f[i].Patterns[j] = buf.String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove character classes from pattern, assuming case insensitivity.
|
// Remove character classes from pattern, assuming case insensitivity.
|
||||||
// Classes of one character (case insensitive) are replaced by the character.
|
// Classes of one character (case-insensitive) are replaced by the character.
|
||||||
// Others are replaced by the single character wildcard.
|
// Others are replaced by the single character wildcard.
|
||||||
func removeClasses(pattern string) string {
|
func removeClasses(pattern string) string {
|
||||||
var res strings.Builder
|
var res strings.Builder
|
||||||
|
@ -229,7 +277,7 @@ func removeClasses(pattern string) string {
|
||||||
// Find a character class in the pattern.
|
// Find a character class in the pattern.
|
||||||
func findClass(pattern string) (start, end int) {
|
func findClass(pattern string) (start, end int) {
|
||||||
start = -1
|
start = -1
|
||||||
escape := false
|
var escape bool
|
||||||
for i, b := range []byte(pattern) {
|
for i, b := range []byte(pattern) {
|
||||||
switch {
|
switch {
|
||||||
case escape:
|
case escape:
|
||||||
|
@ -240,7 +288,7 @@ func findClass(pattern string) (start, end int) {
|
||||||
if b == '[' {
|
if b == '[' {
|
||||||
start = i
|
start = i
|
||||||
}
|
}
|
||||||
case 0 <= start && start < i-1:
|
case start < i-1:
|
||||||
if b == ']' {
|
if b == ']' {
|
||||||
return start, i + 1
|
return start, i + 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@ func TestFileFilters_name(t *testing.T) {
|
||||||
data FileFilters
|
data FileFilters
|
||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{FileFilters{{"", []string{`*.png`}}}, "*.png"},
|
{FileFilters{{"", []string{`*.png`}, true}}, "*.png"},
|
||||||
{FileFilters{{"", []string{`*.png`, `*.jpg`}}}, "*.png *.jpg"},
|
{FileFilters{{"", []string{`*.png`, `*.jpg`}, true}}, "*.png *.jpg"},
|
||||||
{FileFilters{{"Image files", []string{`*.png`, `*.jpg`}}}, "Image files"},
|
{FileFilters{{"Image files", []string{`*.png`, `*.jpg`}, true}}, "Image files"},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
tt.data.name()
|
tt.data.name()
|
||||||
|
@ -24,57 +24,88 @@ func TestFileFilters_name(t *testing.T) {
|
||||||
|
|
||||||
func TestFileFilters_simplify(t *testing.T) {
|
func TestFileFilters_simplify(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
data FileFilters
|
data []string
|
||||||
want []string
|
want []string
|
||||||
}{
|
}{
|
||||||
{FileFilters{{"", []string{``}}}, nil},
|
{[]string{``}, nil},
|
||||||
{FileFilters{{"", []string{`*.png`}}}, []string{"*.png"}},
|
{[]string{`*.\?`}, nil},
|
||||||
{FileFilters{{"", []string{`*.pn?`}}}, []string{"*.pn?"}},
|
{[]string{`*.png`}, []string{"*.png"}},
|
||||||
{FileFilters{{"", []string{`*.pn;`}}}, []string{"*.pn?"}},
|
{[]string{`*.pn?`}, []string{"*.pn?"}},
|
||||||
{FileFilters{{"", []string{`*.pn\?`}}}, nil},
|
{[]string{`*.pn;`}, []string{"*.pn?"}},
|
||||||
{FileFilters{{"", []string{`*.[PpNnGg]`}}}, []string{"*.?"}},
|
{[]string{`*.[PpNnGg]`}, []string{"*.?"}},
|
||||||
{FileFilters{{"", []string{`*.[Pp][Nn][Gg]`}}}, []string{"*.PNG"}},
|
{[]string{`*.[Pp][Nn][Gg]`}, []string{"*.PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[Pp][\Nn][G\g]`}}}, []string{"*.PNG"}},
|
{[]string{`*.[Pp][\Nn][G\g]`}, []string{"*.PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[PNG`}}}, []string{"*.[PNG"}},
|
{[]string{`*.[PNG`}, []string{"*.[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.]PNG`}}}, []string{"*.]PNG"}},
|
{[]string{`*.]PNG`}, []string{"*.]PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[[]PNG`}}}, []string{"*.[PNG"}},
|
{[]string{`*.[[]PNG`}, []string{"*.[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[]]PNG`}}}, []string{"*.]PNG"}},
|
{[]string{`*.[]]PNG`}, []string{"*.]PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[\[]PNG`}}}, []string{"*.[PNG"}},
|
{[]string{`*.[\[]PNG`}, []string{"*.[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[\]]PNG`}}}, []string{"*.]PNG"}},
|
{[]string{`*.[\]]PNG`}, []string{"*.]PNG"}},
|
||||||
{FileFilters{{"", []string{`public.png`}}}, []string{"public.png"}},
|
{[]string{`public.png`}, []string{"public.png"}},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
tt.data.simplify()
|
filters := FileFilters{FileFilter{Patterns: tt.data}}
|
||||||
if got := tt.data[0].Patterns; !reflect.DeepEqual(got, tt.want) {
|
filters.simplify()
|
||||||
|
if got := filters[0].Patterns; !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("FileFilters.simplify[%d] = %q; want %q", i, got, tt.want)
|
t.Errorf("FileFilters.simplify[%d] = %q; want %q", i, got, tt.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFileFilters_casefold(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
data []string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{[]string{`*.png`}, []string{`*.[pP][nN][gG]`}},
|
||||||
|
{[]string{`*.pn?`}, []string{`*.[pP][nN]?`}},
|
||||||
|
{[]string{`*.pn;`}, []string{`*.[pP][nN];`}},
|
||||||
|
{[]string{`*.pn\?`}, []string{`*.[pP][nN]\?`}},
|
||||||
|
{[]string{`*.[PpNnGg]`}, []string{`*.[PppPNnnNGggG]`}},
|
||||||
|
{[]string{`*.[Pp][Nn][Gg]`}, []string{`*.[PppP][NnnN][GggG]`}},
|
||||||
|
{[]string{`*.[Pp][\Nn][G\g]`}, []string{`*.[PppP][\NnnN][Gg\gG]`}},
|
||||||
|
{[]string{`*.[PNG`}, []string{`*.[PpNnGg`}},
|
||||||
|
{[]string{`*.]PNG`}, []string{`*.][Pp][Nn][Gg]`}},
|
||||||
|
{[]string{`*.[[]PNG`}, []string{`*.[[][Pp][Nn][Gg]`}},
|
||||||
|
{[]string{`*.[]]PNG`}, []string{`*.[]][Pp][Nn][Gg]`}},
|
||||||
|
{[]string{`*.[\[]PNG`}, []string{`*.[\[][Pp][Nn][Gg]`}},
|
||||||
|
{[]string{`*.[\]]PNG`}, []string{`*.[\]][Pp][Nn][Gg]`}},
|
||||||
|
}
|
||||||
|
for i, tt := range tests {
|
||||||
|
filters := FileFilters{FileFilter{Patterns: tt.data}}
|
||||||
|
filters[0].CaseFold = true
|
||||||
|
filters.casefold()
|
||||||
|
if got := filters[0].Patterns; !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("FileFilters.casefold[%d] = %q; want %q", i, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestFileFilters_types(t *testing.T) {
|
func TestFileFilters_types(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
data FileFilters
|
data []string
|
||||||
want []string
|
want []string
|
||||||
}{
|
}{
|
||||||
{FileFilters{{"", []string{``}}}, nil},
|
{[]string{``}, nil},
|
||||||
{FileFilters{{"", []string{`*.png`}}}, []string{"", "png"}},
|
{[]string{`*.png`}, []string{"", "png"}},
|
||||||
{FileFilters{{"", []string{`*.pn?`}}}, nil},
|
{[]string{`*.pn?`}, nil},
|
||||||
{FileFilters{{"", []string{`*.pn;`}}}, []string{"", "pn;"}},
|
{[]string{`*.pn;`}, []string{"", "pn;"}},
|
||||||
{FileFilters{{"", []string{`*.pn\?`}}}, []string{"", "pn?"}},
|
{[]string{`*.pn\?`}, []string{"", "pn?"}},
|
||||||
{FileFilters{{"", []string{`*.[PpNnGg]`}}}, nil},
|
{[]string{`*.[PpNnGg]`}, nil},
|
||||||
{FileFilters{{"", []string{`*.[Pp][Nn][Gg]`}}}, []string{"", "PNG"}},
|
{[]string{`*.[Pp][Nn][Gg]`}, []string{"", "PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[Pp][\Nn][G\g]`}}}, []string{"", "PNG"}},
|
{[]string{`*.[Pp][\Nn][G\g]`}, []string{"", "PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[PNG`}}}, []string{"", "[PNG"}},
|
{[]string{`*.[PNG`}, []string{"", "[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.]PNG`}}}, []string{"", "]PNG"}},
|
{[]string{`*.]PNG`}, []string{"", "]PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[[]PNG`}}}, []string{"", "[PNG"}},
|
{[]string{`*.[[]PNG`}, []string{"", "[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[]]PNG`}}}, []string{"", "]PNG"}},
|
{[]string{`*.[]]PNG`}, []string{"", "]PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[\[]PNG`}}}, []string{"", "[PNG"}},
|
{[]string{`*.[\[]PNG`}, []string{"", "[PNG"}},
|
||||||
{FileFilters{{"", []string{`*.[\]]PNG`}}}, []string{"", "]PNG"}},
|
{[]string{`*.[\]]PNG`}, []string{"", "]PNG"}},
|
||||||
{FileFilters{{"", []string{`public.png`}}}, []string{"", "public.png"}},
|
{[]string{`public.png`}, []string{"", "public.png"}},
|
||||||
{FileFilters{{"", []string{`-public-.png`}}}, []string{"", "png"}},
|
{[]string{`-public-.png`}, []string{"", "png"}},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
if got := tt.data.types(); !reflect.DeepEqual(got, tt.want) {
|
filters := FileFilters{FileFilter{Patterns: tt.data}}
|
||||||
|
if got := filters.types(); !reflect.DeepEqual(got, tt.want) {
|
||||||
t.Errorf("FileFilters.types[%d] = %v; want %v", i, got, tt.want)
|
t.Errorf("FileFilters.types[%d] = %v; want %v", i, got, tt.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
file_test.go
20
file_test.go
|
@ -20,9 +20,9 @@ func ExampleSelectFile() {
|
||||||
zenity.SelectFile(
|
zenity.SelectFile(
|
||||||
zenity.Filename(defaultPath),
|
zenity.Filename(defaultPath),
|
||||||
zenity.FileFilters{
|
zenity.FileFilters{
|
||||||
{"Go files", []string{"*.go"}},
|
{"Go files", []string{"*.go"}, true},
|
||||||
{"Web files", []string{"*.html", "*.js", "*.css"}},
|
{"Web files", []string{"*.html", "*.js", "*.css"}, true},
|
||||||
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}},
|
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}, true},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ func ExampleSelectFileMultiple() {
|
||||||
zenity.SelectFileMultiple(
|
zenity.SelectFileMultiple(
|
||||||
zenity.Filename(defaultPath),
|
zenity.Filename(defaultPath),
|
||||||
zenity.FileFilters{
|
zenity.FileFilters{
|
||||||
{"Go files", []string{"*.go"}},
|
{"Go files", []string{"*.go"}, true},
|
||||||
{"Web files", []string{"*.html", "*.js", "*.css"}},
|
{"Web files", []string{"*.html", "*.js", "*.css"}, true},
|
||||||
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}},
|
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}, true},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,9 +41,9 @@ func ExampleSelectFileSave() {
|
||||||
zenity.ConfirmOverwrite(),
|
zenity.ConfirmOverwrite(),
|
||||||
zenity.Filename(defaultName),
|
zenity.Filename(defaultName),
|
||||||
zenity.FileFilters{
|
zenity.FileFilters{
|
||||||
{"Go files", []string{"*.go"}},
|
{"Go files", []string{"*.go"}, true},
|
||||||
{"Web files", []string{"*.html", "*.js", "*.css"}},
|
{"Web files", []string{"*.html", "*.js", "*.css"}, true},
|
||||||
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}},
|
{"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}, true},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ func TestSelectFileSave_script(t *testing.T) {
|
||||||
str, err := zenity.SelectFileSave(
|
str, err := zenity.SelectFileSave(
|
||||||
zenity.ConfirmOverwrite(),
|
zenity.ConfirmOverwrite(),
|
||||||
zenity.Filename("Χρτο.go"),
|
zenity.Filename("Χρτο.go"),
|
||||||
zenity.FileFilter{"Go files", []string{"*.go"}},
|
zenity.FileFilter{"Go files", []string{"*.go"}, true},
|
||||||
)
|
)
|
||||||
if skip, err := skip(err); skip {
|
if skip, err := skip(err); skip {
|
||||||
t.Skip("skipping:", err)
|
t.Skip("skipping:", err)
|
||||||
|
|
|
@ -340,6 +340,9 @@ func initFilters(filters FileFilters) []uint16 {
|
||||||
filters.name()
|
filters.name()
|
||||||
var res []uint16
|
var res []uint16
|
||||||
for _, f := range filters {
|
for _, f := range filters {
|
||||||
|
if f.Name == "" || len(f.Patterns) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
res = append(res, utf16.Encode([]rune(f.Name))...)
|
res = append(res, utf16.Encode([]rune(f.Name))...)
|
||||||
res = append(res, 0)
|
res = append(res, 0)
|
||||||
for _, p := range f.Patterns {
|
for _, p := range f.Patterns {
|
||||||
|
|
|
@ -56,11 +56,11 @@ func Test_applyOptions(t *testing.T) {
|
||||||
{name: "ConfirmCreate", args: ConfirmCreate(), want: options{confirmCreate: true}},
|
{name: "ConfirmCreate", args: ConfirmCreate(), want: options{confirmCreate: true}},
|
||||||
{name: "ShowHidden", args: ShowHidden(), want: options{showHidden: true}},
|
{name: "ShowHidden", args: ShowHidden(), want: options{showHidden: true}},
|
||||||
{name: "Filename", args: Filename("file.go"), want: options{filename: "file.go"}},
|
{name: "Filename", args: Filename("file.go"), want: options{filename: "file.go"}},
|
||||||
{name: "FileFilter", args: FileFilter{"Go files", []string{"*.go"}}, want: options{
|
{name: "FileFilter", args: FileFilter{"Go files", []string{"*.go"}, true}, want: options{
|
||||||
fileFilters: FileFilters{{"Go files", []string{"*.go"}}},
|
fileFilters: FileFilters{{"Go files", []string{"*.go"}, true}},
|
||||||
}},
|
}},
|
||||||
{name: "FileFilters", args: FileFilters{{"Go files", []string{"*.go"}}}, want: options{
|
{name: "FileFilters", args: FileFilters{{"Go files", []string{"*.go"}, true}}, want: options{
|
||||||
fileFilters: FileFilters{{"Go files", []string{"*.go"}}},
|
fileFilters: FileFilters{{"Go files", []string{"*.go"}, true}},
|
||||||
}},
|
}},
|
||||||
|
|
||||||
// Color selection options
|
// Color selection options
|
||||||
|
|
Loading…
Reference in a new issue