mirror of
				https://github.com/jesseduffield/lazygit.git
				synced 2025-10-30 23:57:43 +02:00 
			
		
		
		
	add more suggestions
This commit is contained in:
		| @@ -311,6 +311,9 @@ type AppState struct { | ||||
| 	LastUpdateCheck     int64 | ||||
| 	RecentRepos         []string | ||||
| 	StartupPopupVersion int | ||||
|  | ||||
| 	// these are for custom commands typed in directly, not for custom commands in the lazygit config | ||||
| 	CustomCommandsHistory []string | ||||
| } | ||||
|  | ||||
| func getDefaultAppState() *AppState { | ||||
|   | ||||
| @@ -218,7 +218,7 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions) | ||||
| func (gui *Gui) handleCheckoutByName() error { | ||||
| 	return gui.prompt(promptOpts{ | ||||
| 		title:               gui.Tr.BranchName + ":", | ||||
| 		findSuggestionsFunc: gui.getBranchNameSuggestionsFunc(), | ||||
| 		findSuggestionsFunc: gui.getRefsSuggestionsFunc(), | ||||
| 		handleConfirm: func(response string) error { | ||||
| 			return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ | ||||
| 				span: "Checkout branch", | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| package gui | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/jesseduffield/gocui" | ||||
| @@ -33,7 +34,6 @@ type askOpts struct { | ||||
| 	handleConfirm       func() error | ||||
| 	handleClose         func() error | ||||
| 	handlersManageFocus bool | ||||
| 	findSuggestionsFunc func(string) []*types.Suggestion | ||||
| } | ||||
|  | ||||
| type promptOpts struct { | ||||
| @@ -50,7 +50,6 @@ func (gui *Gui) ask(opts askOpts) error { | ||||
| 		handleConfirm:       opts.handleConfirm, | ||||
| 		handleClose:         opts.handleClose, | ||||
| 		handlersManageFocus: opts.handlersManageFocus, | ||||
| 		findSuggestionsFunc: opts.findSuggestionsFunc, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @@ -103,13 +102,6 @@ func (gui *Gui) wrappedPromptConfirmationFunction(handlersManageFocus bool, func | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (gui *Gui) clearConfirmationViewKeyBindings() { | ||||
| 	keybindingConfig := gui.Config.GetUserConfig().Keybinding | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Confirm), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.ConfirmAlt1), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Return), gocui.ModNone) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error { | ||||
| 	// we've already closed it so we can just return | ||||
| 	if !gui.Views.Confirmation.Visible { | ||||
| @@ -165,7 +157,13 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i | ||||
| 		height/2 + panelHeight/2 | ||||
| } | ||||
|  | ||||
| func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, findSuggestionsFunc func(string) []*types.Suggestion, editable bool) error { | ||||
| func (gui *Gui) prepareConfirmationPanel( | ||||
| 	title, | ||||
| 	prompt string, | ||||
| 	hasLoader bool, | ||||
| 	findSuggestionsFunc func(string) []*types.Suggestion, | ||||
| 	editable bool, | ||||
| ) error { | ||||
| 	x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt) | ||||
| 	// calling SetView on an existing view returns the same view, so I'm not bothering | ||||
| 	// to reassign to gui.Views.Confirmation | ||||
| @@ -185,14 +183,15 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, f | ||||
| 	gui.findSuggestions = findSuggestionsFunc | ||||
| 	if findSuggestionsFunc != nil { | ||||
| 		suggestionsViewHeight := 11 | ||||
| 		suggestionsView, err := gui.g.SetView("suggestions", x0, y1, x1, y1+suggestionsViewHeight, 0) | ||||
| 		suggestionsView, err := gui.g.SetView("suggestions", x0, y1+1, x1, y1+suggestionsViewHeight, 0) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		suggestionsView.Wrap = false | ||||
| 		suggestionsView.FgColor = theme.GocuiDefaultTextColor | ||||
| 		gui.setSuggestions([]*types.Suggestion{}) | ||||
| 		gui.setSuggestions(findSuggestionsFunc("")) | ||||
| 		suggestionsView.Visible = true | ||||
| 		suggestionsView.Title = fmt.Sprintf(gui.Tr.SuggestionsTitle, gui.Config.GetUserConfig().Keybinding.Universal.TogglePanel) | ||||
| 	} | ||||
|  | ||||
| 	gui.g.Update(func(g *gocui.Gui) error { | ||||
| @@ -248,7 +247,7 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error { | ||||
| 	gui.renderString(gui.Views.Options, actions) | ||||
| 	var onConfirm func() error | ||||
| 	if opts.handleConfirmPrompt != nil { | ||||
| 		onConfirm = gui.wrappedPromptConfirmationFunction(opts.handlersManageFocus, opts.handleConfirmPrompt, func() string { return gui.Views.Confirmation.Buffer() }) | ||||
| 		onConfirm = gui.wrappedPromptConfirmationFunction(opts.handlersManageFocus, opts.handleConfirmPrompt, func() string { return gui.Views.Confirmation.TextArea.GetContent() }) | ||||
| 	} else { | ||||
| 		onConfirm = gui.wrappedConfirmationFunction(opts.handlersManageFocus, opts.handleConfirm) | ||||
| 	} | ||||
| @@ -260,7 +259,11 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error { | ||||
| 	} | ||||
|  | ||||
| 	keybindingConfig := gui.Config.GetUserConfig().Keybinding | ||||
| 	onSuggestionConfirm := gui.wrappedPromptConfirmationFunction(opts.handlersManageFocus, opts.handleConfirmPrompt, func() string { return gui.getSelectedSuggestionValue() }) | ||||
| 	onSuggestionConfirm := gui.wrappedPromptConfirmationFunction( | ||||
| 		opts.handlersManageFocus, | ||||
| 		opts.handleConfirmPrompt, | ||||
| 		gui.getSelectedSuggestionValue, | ||||
| 	) | ||||
|  | ||||
| 	confirmationKeybindings := []confirmationKeybinding{ | ||||
| 		{ | ||||
| @@ -319,6 +322,16 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (gui *Gui) clearConfirmationViewKeyBindings() { | ||||
| 	keybindingConfig := gui.Config.GetUserConfig().Keybinding | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Confirm), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.ConfirmAlt1), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("confirmation", gui.getKey(keybindingConfig.Universal.Return), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("suggestions", gui.getKey(keybindingConfig.Universal.Confirm), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("suggestions", gui.getKey(keybindingConfig.Universal.ConfirmAlt1), gocui.ModNone) | ||||
| 	_ = gui.g.DeleteKeybinding("suggestions", gui.getKey(keybindingConfig.Universal.Return), gocui.ModNone) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) wrappedHandler(f func() error) func(g *gocui.Gui, v *gocui.View) error { | ||||
| 	return func(g *gocui.Gui, v *gocui.View) error { | ||||
| 		return f() | ||||
|   | ||||
| @@ -125,7 +125,8 @@ func (gui *Gui) handleCreateDiffingMenuPanel() error { | ||||
| 			displayString: gui.Tr.LcEnterRefToDiff, | ||||
| 			onPress: func() error { | ||||
| 				return gui.prompt(promptOpts{ | ||||
| 					title: gui.Tr.LcEnteRefName, | ||||
| 					title:               gui.Tr.LcEnteRefName, | ||||
| 					findSuggestionsFunc: gui.getRefsSuggestionsFunc(), | ||||
| 					handleConfirm: func(response string) error { | ||||
| 						gui.State.Modes.Diffing.Ref = strings.TrimSpace(response) | ||||
| 						return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) | ||||
|   | ||||
| @@ -659,8 +659,9 @@ func (gui *Gui) handlePullFiles() error { | ||||
| 		} | ||||
|  | ||||
| 		return gui.prompt(promptOpts{ | ||||
| 			title:          gui.Tr.EnterUpstream, | ||||
| 			initialContent: "origin/" + currentBranch.Name, | ||||
| 			title:               gui.Tr.EnterUpstream, | ||||
| 			initialContent:      "origin/" + currentBranch.Name, | ||||
| 			findSuggestionsFunc: gui.getRemoteBranchesSuggestionsFunc("/"), | ||||
| 			handleConfirm: func(upstream string) error { | ||||
| 				if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil { | ||||
| 					errorMessage := err.Error() | ||||
| @@ -798,8 +799,9 @@ func (gui *Gui) pushFiles() error { | ||||
| 			return gui.push(pushOpts{setUpstream: true}) | ||||
| 		} else { | ||||
| 			return gui.prompt(promptOpts{ | ||||
| 				title:          gui.Tr.EnterUpstream, | ||||
| 				initialContent: "origin " + currentBranch.Name, | ||||
| 				title:               gui.Tr.EnterUpstream, | ||||
| 				initialContent:      "origin " + currentBranch.Name, | ||||
| 				findSuggestionsFunc: gui.getRemoteBranchesSuggestionsFunc(" "), | ||||
| 				handleConfirm: func(upstream string) error { | ||||
| 					var upstreamBranch, upstreamRemote string | ||||
| 					split := strings.Split(upstream, " ") | ||||
| @@ -884,8 +886,21 @@ func (gui *Gui) anyFilesWithMergeConflicts() bool { | ||||
|  | ||||
| func (gui *Gui) handleCustomCommand() error { | ||||
| 	return gui.prompt(promptOpts{ | ||||
| 		title: gui.Tr.CustomCommand, | ||||
| 		title:               gui.Tr.CustomCommand, | ||||
| 		findSuggestionsFunc: gui.getCustomCommandsHistorySuggestionsFunc(), | ||||
| 		handleConfirm: func(command string) error { | ||||
| 			gui.Config.GetAppState().CustomCommandsHistory = utils.Limit( | ||||
| 				utils.Uniq( | ||||
| 					append(gui.Config.GetAppState().CustomCommandsHistory, command), | ||||
| 				), | ||||
| 				1000, | ||||
| 			) | ||||
|  | ||||
| 			err := gui.Config.SaveAppState() | ||||
| 			if err != nil { | ||||
| 				gui.Log.Error(err) | ||||
| 			} | ||||
|  | ||||
| 			gui.OnRunCommand(oscommands.NewCmdLogEntry(command, gui.Tr.Spans.CustomCommand, true)) | ||||
| 			return gui.runSubprocessWithSuspenseAndRefresh( | ||||
| 				gui.OSCommand.PrepareShellSubProcess(command), | ||||
|   | ||||
| @@ -36,7 +36,7 @@ func (gui *Gui) handleCreateFilteringMenuPanel() error { | ||||
| 		onPress: func() error { | ||||
| 			return gui.prompt(promptOpts{ | ||||
| 				findSuggestionsFunc: gui.getFilePathSuggestionsFunc(), | ||||
| 				title:               gui.Tr.LcEnterFileName, | ||||
| 				title:               gui.Tr.EnterFileName, | ||||
| 				handleConfirm: func(response string) error { | ||||
| 					return gui.setFiltering(strings.TrimSpace(response)) | ||||
| 				}, | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package gui | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/jesseduffield/lazygit/pkg/gui/presentation" | ||||
| @@ -42,11 +43,7 @@ func matchesToSuggestions(matches []string) []*types.Suggestion { | ||||
| func (gui *Gui) getRemoteSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	remoteNames := gui.getRemoteNames() | ||||
|  | ||||
| 	return func(input string) []*types.Suggestion { | ||||
| 		return matchesToSuggestions( | ||||
| 			utils.FuzzySearch(input, remoteNames), | ||||
| 		) | ||||
| 	} | ||||
| 	return fuzzySearchFunc(remoteNames) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getBranchNames() []string { | ||||
| @@ -61,7 +58,12 @@ func (gui *Gui) getBranchNameSuggestionsFunc() func(string) []*types.Suggestion | ||||
| 	branchNames := gui.getBranchNames() | ||||
|  | ||||
| 	return func(input string) []*types.Suggestion { | ||||
| 		matchingBranchNames := utils.FuzzySearch(sanitizedBranchName(input), branchNames) | ||||
| 		var matchingBranchNames []string | ||||
| 		if input == "" { | ||||
| 			matchingBranchNames = branchNames | ||||
| 		} else { | ||||
| 			matchingBranchNames = utils.FuzzySearch(input, branchNames) | ||||
| 		} | ||||
|  | ||||
| 		suggestions := make([]*types.Suggestion, len(matchingBranchNames)) | ||||
| 		for i, branchName := range matchingBranchNames { | ||||
| @@ -79,6 +81,8 @@ func (gui *Gui) getBranchNameSuggestionsFunc() func(string) []*types.Suggestion | ||||
| // gui.State.FilesTrie. On the main thread we'll be doing a fuzzy search via | ||||
| // gui.State.FilesTrie. So if we've looked for a file previously, we'll start with | ||||
| // the old trie and eventually it'll be swapped out for the new one. | ||||
| // Notably, unlike other suggestion functions we're not showing all the options | ||||
| // if nothing has been typed because there'll be too much to display efficiently | ||||
| func (gui *Gui) getFilePathSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	_ = gui.WithWaitingStatus(gui.Tr.LcLoadingFileSuggestions, func() error { | ||||
| 		trie := patricia.NewTrie() | ||||
| @@ -131,3 +135,56 @@ func (gui *Gui) getFilePathSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 		return suggestions | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getRemoteBranchNames(separator string) []string { | ||||
| 	result := []string{} | ||||
| 	for _, remote := range gui.State.Remotes { | ||||
| 		for _, branch := range remote.Branches { | ||||
| 			result = append(result, fmt.Sprintf("%s%s%s", remote.Name, separator, branch.Name)) | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getRemoteBranchesSuggestionsFunc(separator string) func(string) []*types.Suggestion { | ||||
| 	return fuzzySearchFunc(gui.getRemoteBranchNames(separator)) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getTagNames() []string { | ||||
| 	result := make([]string, len(gui.State.Tags)) | ||||
| 	for i, tag := range gui.State.Tags { | ||||
| 		result[i] = tag.Name | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getRefsSuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	remoteBranchNames := gui.getRemoteBranchNames("/") | ||||
| 	localBranchNames := gui.getBranchNames() | ||||
| 	tagNames := gui.getTagNames() | ||||
| 	additionalRefNames := []string{"HEAD", "FETCH_HEAD", "MERGE_HEAD", "ORIG_HEAD"} | ||||
|  | ||||
| 	refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), additionalRefNames...) | ||||
|  | ||||
| 	return fuzzySearchFunc(refNames) | ||||
| } | ||||
|  | ||||
| func (gui *Gui) getCustomCommandsHistorySuggestionsFunc() func(string) []*types.Suggestion { | ||||
| 	// reversing so that we display the latest command first | ||||
| 	history := utils.Reverse(gui.Config.GetAppState().CustomCommandsHistory) | ||||
|  | ||||
| 	return fuzzySearchFunc(history) | ||||
| } | ||||
|  | ||||
| func fuzzySearchFunc(options []string) func(string) []*types.Suggestion { | ||||
| 	return func(input string) []*types.Suggestion { | ||||
| 		var matches []string | ||||
| 		if input == "" { | ||||
| 			matches = options | ||||
| 		} else { | ||||
| 			matches = utils.FuzzySearch(input, options) | ||||
| 		} | ||||
|  | ||||
| 		return matchesToSuggestions(matches) | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -111,6 +111,7 @@ func (gui *Gui) createAllViews() error { | ||||
| 	gui.Views.Credentials.Editable = true | ||||
|  | ||||
| 	gui.Views.Suggestions.Visible = false | ||||
| 	gui.Views.Suggestions.ContainsList = true | ||||
|  | ||||
| 	gui.Views.Menu.Visible = false | ||||
|  | ||||
|   | ||||
| @@ -358,7 +358,7 @@ func chineseTranslationSet() TranslationSet { | ||||
| 		LcFilterBy:                          "过滤", | ||||
| 		LcExitFilterMode:                    "停止按路径过滤", | ||||
| 		LcFilterPathOption:                  "输入要过滤的路径", | ||||
| 		LcEnterFileName:                     "输入路径:", | ||||
| 		EnterFileName:                       "输入路径:", | ||||
| 		FilteringMenuTitle:                  "正在过滤", | ||||
| 		MustExitFilterModeTitle:             "命令不可用", | ||||
| 		MustExitFilterModePrompt:            "命令在过滤模式下不可用。退出过滤模式?", | ||||
| @@ -419,7 +419,7 @@ func chineseTranslationSet() TranslationSet { | ||||
| 		SubCommitsTitle:                     "子提交", | ||||
| 		SubmodulesTitle:                     "子模块", | ||||
| 		NavigationTitle:                     "列表面板导航", | ||||
| 		SuggestionsTitle:                    "意见建议", | ||||
| 		SuggestionsCheatsheetTitle:          "意见建议", | ||||
| 		PushingTagStatus:                    "推送标签", | ||||
| 		PullRequestURLCopiedToClipboard:     "抓取请求网址已复制到剪贴板", | ||||
| 		CommitMessageCopiedToClipboard:      "提交消息复制到剪贴板", | ||||
|   | ||||
| @@ -327,7 +327,7 @@ func dutchTranslationSet() TranslationSet { | ||||
| 		LcFilterBy:                          "filter bij", | ||||
| 		LcExitFilterMode:                    "stop met filteren bij pad", | ||||
| 		LcFilterPathOption:                  "vulin pad om op te filteren", | ||||
| 		LcEnterFileName:                     "vulin path:", | ||||
| 		EnterFileName:                       "Vulin path:", | ||||
| 		FilteringMenuTitle:                  "Filteren", | ||||
| 		MustExitFilterModeTitle:             "Command niet beschikbaar", | ||||
| 		MustExitFilterModePrompt:            "Command niet beschikbaar in filter modus. Sluit filter modus?", | ||||
|   | ||||
| @@ -342,7 +342,7 @@ type TranslationSet struct { | ||||
| 	LcFilterBy                          string | ||||
| 	LcExitFilterMode                    string | ||||
| 	LcFilterPathOption                  string | ||||
| 	LcEnterFileName                     string | ||||
| 	EnterFileName                       string | ||||
| 	FilteringMenuTitle                  string | ||||
| 	MustExitFilterModeTitle             string | ||||
| 	MustExitFilterModePrompt            string | ||||
| @@ -404,6 +404,8 @@ type TranslationSet struct { | ||||
| 	SubCommitsTitle                     string | ||||
| 	SubmodulesTitle                     string | ||||
| 	NavigationTitle                     string | ||||
| 	SuggestionsCheatsheetTitle          string | ||||
| 	// Unlike the cheatsheet title above, the real suggestions title has a little message saying press tab to focus | ||||
| 	SuggestionsTitle                    string | ||||
| 	ExtrasTitle                         string | ||||
| 	PushingTagStatus                    string | ||||
| @@ -867,7 +869,7 @@ func englishTranslationSet() TranslationSet { | ||||
| 		LcFilterBy:                          "filter by", | ||||
| 		LcExitFilterMode:                    "stop filtering by path", | ||||
| 		LcFilterPathOption:                  "enter path to filter by", | ||||
| 		LcEnterFileName:                     "enter path:", | ||||
| 		EnterFileName:                       "Enter path:", | ||||
| 		FilteringMenuTitle:                  "Filtering", | ||||
| 		MustExitFilterModeTitle:             "Command not available", | ||||
| 		MustExitFilterModePrompt:            "Command not available in filtered mode. Exit filtered mode?", | ||||
| @@ -930,7 +932,8 @@ func englishTranslationSet() TranslationSet { | ||||
| 		SubCommitsTitle:                     "Sub-commits", | ||||
| 		SubmodulesTitle:                     "Submodules", | ||||
| 		NavigationTitle:                     "List Panel Navigation", | ||||
| 		SuggestionsTitle:                    "Suggestions", | ||||
| 		SuggestionsCheatsheetTitle:          "Suggestions", | ||||
| 		SuggestionsTitle:                    "Suggestions (press %s to focus)", | ||||
| 		ExtrasTitle:                         "Extras", | ||||
| 		PushingTagStatus:                    "pushing tag", | ||||
| 		PullRequestURLCopiedToClipboard:     "Pull request URL copied to clipboard", | ||||
|   | ||||
| @@ -116,3 +116,31 @@ func StringArraysOverlap(strArrA []string, strArrB []string) bool { | ||||
|  | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func Uniq(values []string) []string { | ||||
| 	added := make(map[string]bool) | ||||
| 	result := make([]string, 0, len(values)) | ||||
| 	for _, value := range values { | ||||
| 		if added[value] { | ||||
| 			continue | ||||
| 		} | ||||
| 		added[value] = true | ||||
| 		result = append(result, value) | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func Limit(values []string, limit int) []string { | ||||
| 	if len(values) > limit { | ||||
| 		return values[:limit] | ||||
| 	} | ||||
| 	return values | ||||
| } | ||||
|  | ||||
| func Reverse(values []string) []string { | ||||
| 	result := make([]string, len(values)) | ||||
| 	for i, val := range values { | ||||
| 		result[len(values)-i-1] = val | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|   | ||||
| @@ -165,3 +165,86 @@ func TestEscapeSpecialChars(t *testing.T) { | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestUniq(t *testing.T) { | ||||
| 	for _, test := range []struct { | ||||
| 		values []string | ||||
| 		want   []string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			want:   []string{"a", "b", "c"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "a", "b", "c"}, | ||||
| 			want:   []string{"a", "b", "c"}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		if got := Uniq(test.values); !assert.EqualValues(t, got, test.want) { | ||||
| 			t.Errorf("Uniq(%v) = %v; want %v", test.values, got, test.want) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestLimit(t *testing.T) { | ||||
| 	for _, test := range []struct { | ||||
| 		values []string | ||||
| 		limit  int | ||||
| 		want   []string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			limit:  3, | ||||
| 			want:   []string{"a", "b", "c"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			limit:  4, | ||||
| 			want:   []string{"a", "b", "c"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			limit:  2, | ||||
| 			want:   []string{"a", "b"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			limit:  1, | ||||
| 			want:   []string{"a"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			limit:  0, | ||||
| 			want:   []string{}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{}, | ||||
| 			limit:  0, | ||||
| 			want:   []string{}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		if got := Limit(test.values, test.limit); !assert.EqualValues(t, got, test.want) { | ||||
| 			t.Errorf("Limit(%v, %d) = %v; want %v", test.values, test.limit, got, test.want) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestReverse(t *testing.T) { | ||||
| 	for _, test := range []struct { | ||||
| 		values []string | ||||
| 		want   []string | ||||
| 	}{ | ||||
| 		{ | ||||
| 			values: []string{"a", "b", "c"}, | ||||
| 			want:   []string{"c", "b", "a"}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			values: []string{}, | ||||
| 			want:   []string{}, | ||||
| 		}, | ||||
| 	} { | ||||
| 		if got := Reverse(test.values); !assert.EqualValues(t, got, test.want) { | ||||
| 			t.Errorf("Reverse(%v) = %v; want %v", test.values, got, test.want) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -81,7 +81,7 @@ func localisedTitle(mApp *app.App, str string) string { | ||||
| 		"search":         tr.SearchTitle, | ||||
| 		"secondary":      tr.SecondaryTitle, | ||||
| 		"stash":          tr.StashTitle, | ||||
| 		"suggestions":    tr.SuggestionsTitle, | ||||
| 		"suggestions":    tr.SuggestionsCheatsheetTitle, | ||||
| 		"extras":         tr.ExtrasTitle, | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user