diff --git a/README.md b/README.md index cf0b0cb..b843eaa 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ For now, these are the only implemented dialogs: * message (error, info, question, warning) * file selection -Behavior on Windows, macOS and other UNIXes might differ sliglty. +Behavior on Windows, macOS and other UNIXes might differ slightly. Some of that is intended (reflecting platform differences), other bits are unfortunate limitations, -others still open to be fixed. +others still are open to be fixed. ## Why? -There are a bunch of other dialog packages for Go. +There are a bunch of other dialog packages for Go.\ Why reinvent this particular wheel? #### Requirements: diff --git a/cmd/zenity/main.go b/cmd/zenity/main.go index b99bb3d..85e75b9 100644 --- a/cmd/zenity/main.go +++ b/cmd/zenity/main.go @@ -90,7 +90,7 @@ func setupFlags() { // Message options flag.StringVar(&text, "text", "", "Set the dialog text") - flag.StringVar(&iconName, "icon-name", "", "Set the dialog icon (error, information, question, warning)") + flag.StringVar(&iconName, "icon-name", "", "Set the dialog icon (error, info, question, warning)") flag.StringVar(&okLabel, "ok-label", "", "Set the label of the OK button") flag.StringVar(&cancelLabel, "cancel-label", "", "Set the label of the Cancel button") flag.StringVar(&extraButton, "extra-button", "", "Add an extra button") diff --git a/file_test.go b/file_test.go index 4fda4ab..97fc577 100644 --- a/file_test.go +++ b/file_test.go @@ -1,67 +1,54 @@ -package zenity +package zenity_test -import "testing" +import "github.com/ncruces/zenity" const defaultPath = "" +const defaultName = "" -func TestSelectFile(t *testing.T) { - res, err := SelectFile(Filename(defaultPath), FileFilters{ - {"Go files", []string{"*.go"}}, - {"Web files", []string{"*.html", "*.js", "*.css"}}, - {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, - }.New()) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleSelectFile() { + zenity.SelectFile( + zenity.Filename(defaultPath), + zenity.FileFilters{ + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, + }.New()) + // Output: } -func TestSelectFileMutiple(t *testing.T) { - res, err := SelectFileMutiple(Filename(defaultPath), FileFilters{ - {"Go files", []string{"*.go"}}, - {"Web files", []string{"*.html", "*.js", "*.css"}}, - {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, - }.New()) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleSelectFileMutiple() { + zenity.SelectFileMutiple( + zenity.Filename(defaultPath), + zenity.FileFilters{ + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, + }.New()) + // Output: } -func TestSelectFileSave(t *testing.T) { - res, err := SelectFileSave(Filename(defaultPath), ConfirmOverwrite, FileFilters{ - {"Go files", []string{"*.go"}}, - {"Web files", []string{"*.html", "*.js", "*.css"}}, - {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, - }.New()) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleSelectFileSave() { + zenity.SelectFileSave( + zenity.ConfirmOverwrite, + zenity.Filename(defaultName), + zenity.FileFilters{ + {"Go files", []string{"*.go"}}, + {"Web files", []string{"*.html", "*.js", "*.css"}}, + {"Image files", []string{"*.png", "*.gif", "*.ico", "*.jpg", "*.webp"}}, + }.New()) + // Output: } -func TestSelectDirectory(t *testing.T) { - res, err := SelectFile(Directory, Filename(defaultPath)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleSelectFile_directory() { + zenity.SelectFile( + zenity.Filename(defaultPath), + zenity.Directory) + // Output: } -func TestSelectDirectoryMultiple(t *testing.T) { - res, err := SelectFileMutiple(Directory, Filename(defaultPath)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleSelectFileMutiple_directory() { + zenity.SelectFileMutiple( + zenity.Filename(defaultPath), + zenity.Directory) + // Output: } diff --git a/file_unix.go b/file_unix.go index 17ea30d..9aaa240 100644 --- a/file_unix.go +++ b/file_unix.go @@ -10,6 +10,11 @@ import ( "github.com/ncruces/zenity/internal/zen" ) +// Display file selection dialog. +// +// Returns an empty string on cancel. +// +// Valid options: Title, Directory, Filename, FileFilters. func SelectFile(options ...Option) (string, error) { opts := optsParse(options) @@ -38,6 +43,11 @@ func SelectFile(options ...Option) (string, error) { return string(out), nil } +// Display multiple file selection dialog. +// +// Returns a nil slice on cancel. +// +// Valid options: Title, Directory, Filename, FileFilters. func SelectFileMutiple(options ...Option) ([]string, error) { opts := optsParse(options) @@ -66,6 +76,11 @@ func SelectFileMutiple(options ...Option) ([]string, error) { return strings.Split(string(out), cmd.Separator), nil } +// Display save file selection dialog. +// +// Returns an empty string on cancel. +// +// Valid options: Title, Filename, ConfirmOverwrite, FileFilters. func SelectFileSave(options ...Option) (string, error) { opts := optsParse(options) diff --git a/msg_test.go b/msg_test.go index 67fd5b2..0498c67 100644 --- a/msg_test.go +++ b/msg_test.go @@ -1,43 +1,31 @@ -package zenity +package zenity_test -import "testing" +import "github.com/ncruces/zenity" -func TestError(t *testing.T) { - res, err := Error("An error has occured.", Title("Error"), Icon(ErrorIcon)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleError() { + zenity.Error("An error has occured.", + zenity.Title("Error"), + zenity.Icon(zenity.ErrorIcon)) + // Output: } -func TestInfo(t *testing.T) { - res, err := Info("All updates are complete.", Title("Information"), Icon(InfoIcon)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleInfo() { + zenity.Info("All updates are complete.", + zenity.Title("Information"), + zenity.Icon(zenity.InfoIcon)) + // Output: } -func TestWarning(t *testing.T) { - res, err := Warning("Are you sure you want to proceed?", Title("Warning"), Icon(WarningIcon)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleWarning() { + zenity.Warning("Are you sure you want to proceed?", + zenity.Title("Warning"), + zenity.Icon(zenity.WarningIcon)) + // Output: } -func TestQuestion(t *testing.T) { - res, err := Question("Are you sure you want to proceed?", Title("Question"), Icon(QuestionIcon)) - - if err != nil { - t.Error(err) - } else { - t.Logf("%#v", res) - } +func ExampleQuestion() { + zenity.Question("Are you sure you want to proceed?", + zenity.Title("Question"), + zenity.Icon(zenity.QuestionIcon)) + // Output: } diff --git a/msg_unix.go b/msg_unix.go index 29d1d6e..718ab8f 100644 --- a/msg_unix.go +++ b/msg_unix.go @@ -8,18 +8,39 @@ import ( "github.com/ncruces/zenity/internal/zen" ) +// Display error dialog. +// +// Returns true on OK, false on dismiss, or ErrExtraButton. +// +// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize. func Error(text string, options ...Option) (bool, error) { return message("--error", text, options) } +// Display info dialog. +// +// Returns true on OK, false on dismiss, or ErrExtraButton. +// +// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize. func Info(text string, options ...Option) (bool, error) { return message("--info", text, options) } +// Display question dialog. +// +// Returns true on OK, false on Cancel, or ErrExtraButton. +// +// Valid options: Title, Icon, OKLabel, CancelLabel, ExtraButton, NoWrap, +// Ellipsize, DefaultCancel. func Question(text string, options ...Option) (bool, error) { return message("--question", text, options) } +// Display warning dialog. +// +// Returns true on OK, false on dismiss, or ErrExtraButton. +// +// Valid options: Title, Icon, OKLabel, ExtraButton, NoWrap, Ellipsize. func Warning(text string, options ...Option) (bool, error) { return message("--warning", text, options) } diff --git a/zenity.go b/zenity.go index 08b5f6f..40e52d7 100644 --- a/zenity.go +++ b/zenity.go @@ -32,6 +32,7 @@ type options struct { defcancel bool } +// Options are arguments you pass to dialog functions to customize their behavior. type Option func(*options) func optsParse(options []Option) (res options) { @@ -43,6 +44,7 @@ func optsParse(options []Option) (res options) { // General options +// Option to set the dialog title. func Title(title string) Option { return func(o *options) { o.title = title @@ -51,27 +53,41 @@ func Title(title string) Option { // File selection options +// Option to set the filename. +// +// You can specify a file name, a directory path, or both. +// Specifying a file name, makes it the default selected file. +// Specifying a directory path, make it the default dialog location. func Filename(filename string) Option { return func(o *options) { o.filename = filename } } +// Option to activate directory-only selection. func Directory(o *options) { o.directory = true } +// Option to confirm file selection if filename already exists. func ConfirmOverwrite(o *options) { o.overwrite = true } +// FileFilter encapsulates a filename filter. type FileFilter struct { - Name string - Patterns []string + Name string // display string that describes the filter (optional) + Patterns []string // filter patterns for the display string } +// FileFilters is a list of filename filters. +// +// macOS hides filename filters from the user, +// and only supports filtering by extension (or "type"). +// We make an effort to convert any "*.EXT" like patterns. type FileFilters []FileFilter +// Creates Option to set the filename filter list. func (f FileFilters) New() Option { return func(o *options) { o.filters = f @@ -80,6 +96,7 @@ func (f FileFilters) New() Option { // Message options +// MessageIcon is the enumeration for message dialog icons. type MessageIcon int const ( @@ -89,38 +106,45 @@ const ( WarningIcon ) +// Option to set the dialog icon. func Icon(icon MessageIcon) Option { return func(o *options) { o.icon = icon } } +// Option to set the label of the OK button. func OKLabel(ok string) Option { return func(o *options) { o.ok = ok } } +// Option to set the label of the Cancel button. func CancelLabel(cancel string) Option { return func(o *options) { o.cancel = cancel } } +// Option to add an extra button. func ExtraButton(extra string) Option { return func(o *options) { o.extra = extra } } +// Option to disable enable text wrapping. func NoWrap(o *options) { o.nowrap = true } +// Option to enable ellipsizing in the dialog text. func Ellipsize(o *options) { o.ellipsize = true } +// Option to give Cancel button focus by default. func DefaultCancel(o *options) { o.defcancel = true }