mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-17 00:18:05 +02:00
add more suggestions
This commit is contained in:
@ -311,6 +311,9 @@ type AppState struct {
|
|||||||
LastUpdateCheck int64
|
LastUpdateCheck int64
|
||||||
RecentRepos []string
|
RecentRepos []string
|
||||||
StartupPopupVersion int
|
StartupPopupVersion int
|
||||||
|
|
||||||
|
// these are for custom commands typed in directly, not for custom commands in the lazygit config
|
||||||
|
CustomCommandsHistory []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultAppState() *AppState {
|
func getDefaultAppState() *AppState {
|
||||||
|
@ -218,7 +218,7 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
|
|||||||
func (gui *Gui) handleCheckoutByName() error {
|
func (gui *Gui) handleCheckoutByName() error {
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
title: gui.Tr.BranchName + ":",
|
title: gui.Tr.BranchName + ":",
|
||||||
findSuggestionsFunc: gui.getBranchNameSuggestionsFunc(),
|
findSuggestionsFunc: gui.getRefsSuggestionsFunc(),
|
||||||
handleConfirm: func(response string) error {
|
handleConfirm: func(response string) error {
|
||||||
return gui.handleCheckoutRef(response, handleCheckoutRefOptions{
|
return gui.handleCheckoutRef(response, handleCheckoutRefOptions{
|
||||||
span: "Checkout branch",
|
span: "Checkout branch",
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
@ -33,7 +34,6 @@ type askOpts struct {
|
|||||||
handleConfirm func() error
|
handleConfirm func() error
|
||||||
handleClose func() error
|
handleClose func() error
|
||||||
handlersManageFocus bool
|
handlersManageFocus bool
|
||||||
findSuggestionsFunc func(string) []*types.Suggestion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type promptOpts struct {
|
type promptOpts struct {
|
||||||
@ -50,7 +50,6 @@ func (gui *Gui) ask(opts askOpts) error {
|
|||||||
handleConfirm: opts.handleConfirm,
|
handleConfirm: opts.handleConfirm,
|
||||||
handleClose: opts.handleClose,
|
handleClose: opts.handleClose,
|
||||||
handlersManageFocus: opts.handlersManageFocus,
|
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 {
|
func (gui *Gui) closeConfirmationPrompt(handlersManageFocus bool) error {
|
||||||
// we've already closed it so we can just return
|
// we've already closed it so we can just return
|
||||||
if !gui.Views.Confirmation.Visible {
|
if !gui.Views.Confirmation.Visible {
|
||||||
@ -165,7 +157,13 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i
|
|||||||
height/2 + panelHeight/2
|
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)
|
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
|
||||||
// calling SetView on an existing view returns the same view, so I'm not bothering
|
// calling SetView on an existing view returns the same view, so I'm not bothering
|
||||||
// to reassign to gui.Views.Confirmation
|
// to reassign to gui.Views.Confirmation
|
||||||
@ -185,14 +183,15 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, f
|
|||||||
gui.findSuggestions = findSuggestionsFunc
|
gui.findSuggestions = findSuggestionsFunc
|
||||||
if findSuggestionsFunc != nil {
|
if findSuggestionsFunc != nil {
|
||||||
suggestionsViewHeight := 11
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
suggestionsView.Wrap = false
|
suggestionsView.Wrap = false
|
||||||
suggestionsView.FgColor = theme.GocuiDefaultTextColor
|
suggestionsView.FgColor = theme.GocuiDefaultTextColor
|
||||||
gui.setSuggestions([]*types.Suggestion{})
|
gui.setSuggestions(findSuggestionsFunc(""))
|
||||||
suggestionsView.Visible = true
|
suggestionsView.Visible = true
|
||||||
|
suggestionsView.Title = fmt.Sprintf(gui.Tr.SuggestionsTitle, gui.Config.GetUserConfig().Keybinding.Universal.TogglePanel)
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.g.Update(func(g *gocui.Gui) error {
|
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)
|
gui.renderString(gui.Views.Options, actions)
|
||||||
var onConfirm func() error
|
var onConfirm func() error
|
||||||
if opts.handleConfirmPrompt != nil {
|
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 {
|
} else {
|
||||||
onConfirm = gui.wrappedConfirmationFunction(opts.handlersManageFocus, opts.handleConfirm)
|
onConfirm = gui.wrappedConfirmationFunction(opts.handlersManageFocus, opts.handleConfirm)
|
||||||
}
|
}
|
||||||
@ -260,7 +259,11 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keybindingConfig := gui.Config.GetUserConfig().Keybinding
|
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{
|
confirmationKeybindings := []confirmationKeybinding{
|
||||||
{
|
{
|
||||||
@ -319,6 +322,16 @@ func (gui *Gui) setKeyBindings(opts createPopupPanelOpts) error {
|
|||||||
return nil
|
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 {
|
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 func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return f()
|
return f()
|
||||||
|
@ -125,7 +125,8 @@ func (gui *Gui) handleCreateDiffingMenuPanel() error {
|
|||||||
displayString: gui.Tr.LcEnterRefToDiff,
|
displayString: gui.Tr.LcEnterRefToDiff,
|
||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
title: gui.Tr.LcEnteRefName,
|
title: gui.Tr.LcEnteRefName,
|
||||||
|
findSuggestionsFunc: gui.getRefsSuggestionsFunc(),
|
||||||
handleConfirm: func(response string) error {
|
handleConfirm: func(response string) error {
|
||||||
gui.State.Modes.Diffing.Ref = strings.TrimSpace(response)
|
gui.State.Modes.Diffing.Ref = strings.TrimSpace(response)
|
||||||
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
|
||||||
|
@ -659,8 +659,9 @@ func (gui *Gui) handlePullFiles() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
title: gui.Tr.EnterUpstream,
|
title: gui.Tr.EnterUpstream,
|
||||||
initialContent: "origin/" + currentBranch.Name,
|
initialContent: "origin/" + currentBranch.Name,
|
||||||
|
findSuggestionsFunc: gui.getRemoteBranchesSuggestionsFunc("/"),
|
||||||
handleConfirm: func(upstream string) error {
|
handleConfirm: func(upstream string) error {
|
||||||
if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil {
|
if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil {
|
||||||
errorMessage := err.Error()
|
errorMessage := err.Error()
|
||||||
@ -798,8 +799,9 @@ func (gui *Gui) pushFiles() error {
|
|||||||
return gui.push(pushOpts{setUpstream: true})
|
return gui.push(pushOpts{setUpstream: true})
|
||||||
} else {
|
} else {
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
title: gui.Tr.EnterUpstream,
|
title: gui.Tr.EnterUpstream,
|
||||||
initialContent: "origin " + currentBranch.Name,
|
initialContent: "origin " + currentBranch.Name,
|
||||||
|
findSuggestionsFunc: gui.getRemoteBranchesSuggestionsFunc(" "),
|
||||||
handleConfirm: func(upstream string) error {
|
handleConfirm: func(upstream string) error {
|
||||||
var upstreamBranch, upstreamRemote string
|
var upstreamBranch, upstreamRemote string
|
||||||
split := strings.Split(upstream, " ")
|
split := strings.Split(upstream, " ")
|
||||||
@ -884,8 +886,21 @@ func (gui *Gui) anyFilesWithMergeConflicts() bool {
|
|||||||
|
|
||||||
func (gui *Gui) handleCustomCommand() error {
|
func (gui *Gui) handleCustomCommand() error {
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
title: gui.Tr.CustomCommand,
|
title: gui.Tr.CustomCommand,
|
||||||
|
findSuggestionsFunc: gui.getCustomCommandsHistorySuggestionsFunc(),
|
||||||
handleConfirm: func(command string) error {
|
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))
|
gui.OnRunCommand(oscommands.NewCmdLogEntry(command, gui.Tr.Spans.CustomCommand, true))
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.OSCommand.PrepareShellSubProcess(command),
|
gui.OSCommand.PrepareShellSubProcess(command),
|
||||||
|
@ -36,7 +36,7 @@ func (gui *Gui) handleCreateFilteringMenuPanel() error {
|
|||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.prompt(promptOpts{
|
return gui.prompt(promptOpts{
|
||||||
findSuggestionsFunc: gui.getFilePathSuggestionsFunc(),
|
findSuggestionsFunc: gui.getFilePathSuggestionsFunc(),
|
||||||
title: gui.Tr.LcEnterFileName,
|
title: gui.Tr.EnterFileName,
|
||||||
handleConfirm: func(response string) error {
|
handleConfirm: func(response string) error {
|
||||||
return gui.setFiltering(strings.TrimSpace(response))
|
return gui.setFiltering(strings.TrimSpace(response))
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
"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 {
|
func (gui *Gui) getRemoteSuggestionsFunc() func(string) []*types.Suggestion {
|
||||||
remoteNames := gui.getRemoteNames()
|
remoteNames := gui.getRemoteNames()
|
||||||
|
|
||||||
return func(input string) []*types.Suggestion {
|
return fuzzySearchFunc(remoteNames)
|
||||||
return matchesToSuggestions(
|
|
||||||
utils.FuzzySearch(input, remoteNames),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) getBranchNames() []string {
|
func (gui *Gui) getBranchNames() []string {
|
||||||
@ -61,7 +58,12 @@ func (gui *Gui) getBranchNameSuggestionsFunc() func(string) []*types.Suggestion
|
|||||||
branchNames := gui.getBranchNames()
|
branchNames := gui.getBranchNames()
|
||||||
|
|
||||||
return func(input string) []*types.Suggestion {
|
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))
|
suggestions := make([]*types.Suggestion, len(matchingBranchNames))
|
||||||
for i, branchName := range 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. 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
|
// 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.
|
// 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 {
|
func (gui *Gui) getFilePathSuggestionsFunc() func(string) []*types.Suggestion {
|
||||||
_ = gui.WithWaitingStatus(gui.Tr.LcLoadingFileSuggestions, func() error {
|
_ = gui.WithWaitingStatus(gui.Tr.LcLoadingFileSuggestions, func() error {
|
||||||
trie := patricia.NewTrie()
|
trie := patricia.NewTrie()
|
||||||
@ -131,3 +135,56 @@ func (gui *Gui) getFilePathSuggestionsFunc() func(string) []*types.Suggestion {
|
|||||||
return suggestions
|
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.Credentials.Editable = true
|
||||||
|
|
||||||
gui.Views.Suggestions.Visible = false
|
gui.Views.Suggestions.Visible = false
|
||||||
|
gui.Views.Suggestions.ContainsList = true
|
||||||
|
|
||||||
gui.Views.Menu.Visible = false
|
gui.Views.Menu.Visible = false
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ func chineseTranslationSet() TranslationSet {
|
|||||||
LcFilterBy: "过滤",
|
LcFilterBy: "过滤",
|
||||||
LcExitFilterMode: "停止按路径过滤",
|
LcExitFilterMode: "停止按路径过滤",
|
||||||
LcFilterPathOption: "输入要过滤的路径",
|
LcFilterPathOption: "输入要过滤的路径",
|
||||||
LcEnterFileName: "输入路径:",
|
EnterFileName: "输入路径:",
|
||||||
FilteringMenuTitle: "正在过滤",
|
FilteringMenuTitle: "正在过滤",
|
||||||
MustExitFilterModeTitle: "命令不可用",
|
MustExitFilterModeTitle: "命令不可用",
|
||||||
MustExitFilterModePrompt: "命令在过滤模式下不可用。退出过滤模式?",
|
MustExitFilterModePrompt: "命令在过滤模式下不可用。退出过滤模式?",
|
||||||
@ -419,7 +419,7 @@ func chineseTranslationSet() TranslationSet {
|
|||||||
SubCommitsTitle: "子提交",
|
SubCommitsTitle: "子提交",
|
||||||
SubmodulesTitle: "子模块",
|
SubmodulesTitle: "子模块",
|
||||||
NavigationTitle: "列表面板导航",
|
NavigationTitle: "列表面板导航",
|
||||||
SuggestionsTitle: "意见建议",
|
SuggestionsCheatsheetTitle: "意见建议",
|
||||||
PushingTagStatus: "推送标签",
|
PushingTagStatus: "推送标签",
|
||||||
PullRequestURLCopiedToClipboard: "抓取请求网址已复制到剪贴板",
|
PullRequestURLCopiedToClipboard: "抓取请求网址已复制到剪贴板",
|
||||||
CommitMessageCopiedToClipboard: "提交消息复制到剪贴板",
|
CommitMessageCopiedToClipboard: "提交消息复制到剪贴板",
|
||||||
|
@ -327,7 +327,7 @@ func dutchTranslationSet() TranslationSet {
|
|||||||
LcFilterBy: "filter bij",
|
LcFilterBy: "filter bij",
|
||||||
LcExitFilterMode: "stop met filteren bij pad",
|
LcExitFilterMode: "stop met filteren bij pad",
|
||||||
LcFilterPathOption: "vulin pad om op te filteren",
|
LcFilterPathOption: "vulin pad om op te filteren",
|
||||||
LcEnterFileName: "vulin path:",
|
EnterFileName: "Vulin path:",
|
||||||
FilteringMenuTitle: "Filteren",
|
FilteringMenuTitle: "Filteren",
|
||||||
MustExitFilterModeTitle: "Command niet beschikbaar",
|
MustExitFilterModeTitle: "Command niet beschikbaar",
|
||||||
MustExitFilterModePrompt: "Command niet beschikbaar in filter modus. Sluit filter modus?",
|
MustExitFilterModePrompt: "Command niet beschikbaar in filter modus. Sluit filter modus?",
|
||||||
|
@ -342,7 +342,7 @@ type TranslationSet struct {
|
|||||||
LcFilterBy string
|
LcFilterBy string
|
||||||
LcExitFilterMode string
|
LcExitFilterMode string
|
||||||
LcFilterPathOption string
|
LcFilterPathOption string
|
||||||
LcEnterFileName string
|
EnterFileName string
|
||||||
FilteringMenuTitle string
|
FilteringMenuTitle string
|
||||||
MustExitFilterModeTitle string
|
MustExitFilterModeTitle string
|
||||||
MustExitFilterModePrompt string
|
MustExitFilterModePrompt string
|
||||||
@ -404,6 +404,8 @@ type TranslationSet struct {
|
|||||||
SubCommitsTitle string
|
SubCommitsTitle string
|
||||||
SubmodulesTitle string
|
SubmodulesTitle string
|
||||||
NavigationTitle 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
|
SuggestionsTitle string
|
||||||
ExtrasTitle string
|
ExtrasTitle string
|
||||||
PushingTagStatus string
|
PushingTagStatus string
|
||||||
@ -867,7 +869,7 @@ func englishTranslationSet() TranslationSet {
|
|||||||
LcFilterBy: "filter by",
|
LcFilterBy: "filter by",
|
||||||
LcExitFilterMode: "stop filtering by path",
|
LcExitFilterMode: "stop filtering by path",
|
||||||
LcFilterPathOption: "enter path to filter by",
|
LcFilterPathOption: "enter path to filter by",
|
||||||
LcEnterFileName: "enter path:",
|
EnterFileName: "Enter path:",
|
||||||
FilteringMenuTitle: "Filtering",
|
FilteringMenuTitle: "Filtering",
|
||||||
MustExitFilterModeTitle: "Command not available",
|
MustExitFilterModeTitle: "Command not available",
|
||||||
MustExitFilterModePrompt: "Command not available in filtered mode. Exit filtered mode?",
|
MustExitFilterModePrompt: "Command not available in filtered mode. Exit filtered mode?",
|
||||||
@ -930,7 +932,8 @@ func englishTranslationSet() TranslationSet {
|
|||||||
SubCommitsTitle: "Sub-commits",
|
SubCommitsTitle: "Sub-commits",
|
||||||
SubmodulesTitle: "Submodules",
|
SubmodulesTitle: "Submodules",
|
||||||
NavigationTitle: "List Panel Navigation",
|
NavigationTitle: "List Panel Navigation",
|
||||||
SuggestionsTitle: "Suggestions",
|
SuggestionsCheatsheetTitle: "Suggestions",
|
||||||
|
SuggestionsTitle: "Suggestions (press %s to focus)",
|
||||||
ExtrasTitle: "Extras",
|
ExtrasTitle: "Extras",
|
||||||
PushingTagStatus: "pushing tag",
|
PushingTagStatus: "pushing tag",
|
||||||
PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard",
|
PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard",
|
||||||
|
@ -116,3 +116,31 @@ func StringArraysOverlap(strArrA []string, strArrB []string) bool {
|
|||||||
|
|
||||||
return false
|
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,
|
"search": tr.SearchTitle,
|
||||||
"secondary": tr.SecondaryTitle,
|
"secondary": tr.SecondaryTitle,
|
||||||
"stash": tr.StashTitle,
|
"stash": tr.StashTitle,
|
||||||
"suggestions": tr.SuggestionsTitle,
|
"suggestions": tr.SuggestionsCheatsheetTitle,
|
||||||
"extras": tr.ExtrasTitle,
|
"extras": tr.ExtrasTitle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user