// This "script" generates a file called Keybindings_{{.LANG}}.md // in current working directory. // // The content of this generated file is a keybindings cheatsheet. // // To generate cheatsheet in english run: // LANG=en go run scripts/generate_cheatsheet.go package main import ( "fmt" "log" "os" "sort" "strings" "github.com/jesseduffield/lazygit/pkg/app" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/gui" ) type bindingSection struct { title string bindings []*gui.Binding } func main() { langs := []string{"pl", "nl", "en"} mConfig, _ := config.NewAppConfig("", "", "", "", "", true) for _, lang := range langs { os.Setenv("LC_ALL", lang) mApp, _ := app.NewApp(mConfig) file, err := os.Create(getProjectRoot() + "/docs/keybindings/Keybindings_" + lang + ".md") if err != nil { panic(err) } bindingSections := getBindingSections(mApp) content := formatSections(mApp, bindingSections) writeString(file, content) } } func writeString(file *os.File, str string) { _, err := file.WriteString(str) if err != nil { log.Fatal(err) } } func localisedTitle(mApp *app.App, str string) string { viewTitle := strings.Title(str) + "Title" return mApp.Tr.SLocalize(viewTitle) } func formatTitle(title string) string { return fmt.Sprintf("\n## %s\n\n", title) } func formatBinding(binding *gui.Binding) string { if binding.Alternative != "" { return fmt.Sprintf(" %s: %s (%s)\n", gui.GetKeyDisplay(binding.Key), binding.Description, binding.Alternative) } return fmt.Sprintf(" %s: %s\n", gui.GetKeyDisplay(binding.Key), binding.Description) } func getBindingSections(mApp *app.App) []*bindingSection { bindingSections := []*bindingSection{} bindings := mApp.Gui.GetInitialKeybindings() type contextAndViewType struct { context string viewName string } contextAndViewBindingMap := map[contextAndViewType][]*gui.Binding{} for _, binding := range bindings { contexts := []string{} if len(binding.Contexts) == 0 { contexts = append(contexts, "") } else { contexts = append(contexts, binding.Contexts...) } for _, context := range contexts { key := contextAndViewType{context: context, viewName: binding.ViewName} existing := contextAndViewBindingMap[key] if existing == nil { contextAndViewBindingMap[key] = []*gui.Binding{binding} } else { contextAndViewBindingMap[key] = append(contextAndViewBindingMap[key], binding) } } } type groupedBindingsType struct { contextAndView contextAndViewType bindings []*gui.Binding } groupedBindings := make([]groupedBindingsType, len(contextAndViewBindingMap)) for contextAndView, contextBindings := range contextAndViewBindingMap { groupedBindings = append(groupedBindings, groupedBindingsType{contextAndView: contextAndView, bindings: contextBindings}) } sort.Slice(groupedBindings, func(i, j int) bool { first := groupedBindings[i].contextAndView second := groupedBindings[j].contextAndView if first.viewName == "" { return true } if second.viewName == "" { return false } return first.viewName < second.viewName || (first.viewName == second.viewName && first.context < second.context) }) for _, group := range groupedBindings { contextAndView := group.contextAndView contextBindings := group.bindings mApp.Log.Warn("viewname: " + contextAndView.viewName + ", context: " + contextAndView.context) viewName := contextAndView.viewName if viewName == "" { viewName = "global" } translatedView := localisedTitle(mApp, viewName) var title string if contextAndView.context == "" { addendum := " " + mApp.Tr.SLocalize("Panel") if viewName == "global" { addendum = "" } title = fmt.Sprintf("%s%s", translatedView, addendum) } else { translatedContextName := localisedTitle(mApp, contextAndView.context) title = fmt.Sprintf("%s %s (%s)", translatedView, mApp.Tr.SLocalize("Panel"), translatedContextName) } for _, binding := range contextBindings { bindingSections = addBinding(title, bindingSections, binding) } } return bindingSections } func addBinding(title string, bindingSections []*bindingSection, binding *gui.Binding) []*bindingSection { if binding.Description == "" && binding.Alternative == "" { return bindingSections } for _, section := range bindingSections { if title == section.title { section.bindings = append(section.bindings, binding) return bindingSections } } section := &bindingSection{ title: title, bindings: []*gui.Binding{binding}, } return append(bindingSections, section) } func formatSections(mApp *app.App, bindingSections []*bindingSection) string { content := fmt.Sprintf("# Lazygit %s\n", mApp.Tr.SLocalize("Keybindings")) for _, section := range bindingSections { content += formatTitle(section.title) content += "
\n" for _, binding := range section.bindings { content += formatBinding(binding) } content += "\n" } return content } func getProjectRoot() string { dir, err := os.Getwd() if err != nil { panic(err) } return strings.Split(dir, "lazygit")[0] + "lazygit" }