diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index 67893d82d8..a44c8a78a2 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -6,6 +6,7 @@ * `databricks auth describe` now reports where U2M (`databricks-cli`) tokens are stored: `plaintext` (`~/.databricks/token-cache.json`) or `secure` (OS keyring), and the source of the choice (env var, config setting, or default). * Marked the default profile in the interactive pickers shown by `databricks auth switch`, `databricks auth logout`, `databricks auth token`, and `databricks auth login`, and moved it to the top of the list. `databricks auth login` and `databricks auth logout` now offer the same selectors as `databricks auth token` and `databricks auth switch` respectively. +* The interactive auth profile pickers now start in search mode so typing immediately filters the list, and the action entries (`+ Create a new profile`, `→ Enter a host URL manually`) are visually distinct from real profiles and stay visible regardless of the search query. ### Bundles diff --git a/cmd/auth/profile_picker.go b/cmd/auth/profile_picker.go index 01279171ac..79fc440c56 100644 --- a/cmd/auth/profile_picker.go +++ b/cmd/auth/profile_picker.go @@ -19,8 +19,8 @@ const ( ) const ( - profilePickerCreateNewLabel = "Create a new profile" - profilePickerEnterHostLabel = "Enter a host URL manually" + profilePickerCreateNewLabel = "+ Create a new profile" + profilePickerEnterHostLabel = "→ Enter a host URL manually" ) // profilePickerOptions configures pickAuthProfile. @@ -114,16 +114,22 @@ func pickAuthProfile(ctx context.Context, profiles profile.Profiles, opts profil idx, err := cmdio.RunSelect(ctx, cmdio.SelectOptions{ Label: opts.Label, Items: items, - StartInSearchMode: len(profiles) > 5, + StartInSearchMode: true, Searcher: func(input string, index int) bool { + // Action entries (Create new / Enter host) stay visible regardless + // of the search query so the user can always reach them, including + // when the typed query doesn't match any profile. + if items[index].IsExtra { + return true + } input = strings.ToLower(input) return strings.Contains(strings.ToLower(items[index].Name), input) || strings.Contains(strings.ToLower(items[index].Host), input) || strings.Contains(strings.ToLower(items[index].AccountID), input) }, LabelTemplate: "{{ . | faint }}", - Active: `▸ {{.Name | bold}}{{if .IsDefault}} {{ "[default]" | green }}{{end}}{{if .AccountID}} (account: {{.AccountID|faint}}){{else if .Host}} ({{.Host|faint}}){{end}}`, - Inactive: ` {{.Name}}{{if .IsDefault}} [default]{{end}}{{if .AccountID}} (account: {{.AccountID|faint}}){{else if .Host}} ({{.Host|faint}}){{end}}`, + Active: `▸ {{if .IsExtra}}{{.Name | faint | bold}}{{else}}{{.Name | bold}}{{if .IsDefault}} {{ "[default]" | green }}{{end}}{{if .AccountID}} (account: {{.AccountID|faint}}){{else if .Host}} ({{.Host|faint}}){{end}}{{end}}`, + Inactive: ` {{if .IsExtra}}{{.Name | faint}}{{else}}{{.Name}}{{if .IsDefault}} [default]{{end}}{{if .AccountID}} (account: {{.AccountID|faint}}){{else if .Host}} ({{.Host|faint}}){{end}}{{end}}`, Selected: `{{ "` + noun + `" | faint }}: {{ .Name | bold }}`, }) if err != nil {