diff --git a/pkg/commands/git_commands/config.go b/pkg/commands/git_commands/config.go index de9707fe9ba5..014591556b52 100644 --- a/pkg/commands/git_commands/config.go +++ b/pkg/commands/git_commands/config.go @@ -53,7 +53,7 @@ func (self *ConfigCommands) GetPager(width int) string { "columnWidth": strconv.Itoa(width/2 - 6), } - pagerTemplate := self.UserConfig.Git.Paging.Pager + pagerTemplate := string(self.UserConfig.Git.Paging.Pager) return utils.ResolvePlaceholderString(pagerTemplate, templateValues) } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index de0495466f51..1ae89e5d6f8b 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -2,6 +2,8 @@ package config import ( "time" + + "github.com/karimkhaleel/jsonschema" ) type UserConfig struct { @@ -25,7 +27,7 @@ type UserConfig struct { // Lazygit sets this to true upon first runninng the program so that you don't see introductory popups every time you open the program. DisableStartupPopups bool `yaml:"disableStartupPopups"` // User-configured commands that can be invoked from within Lazygit - CustomCommands []CustomCommand `yaml:"customCommands"` + CustomCommands []CustomCommand `yaml:"customCommands" jsonschema:"uniqueItems=true"` // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-pull-request-urls Services map[string]string `yaml:"services"` // What to do when opening Lazygit outside of a git repo. @@ -33,7 +35,7 @@ type UserConfig struct { // - 'create': initialize a new repo // - 'skip': open most recent repo // - 'quit': exit Lazygit - NotARepository string `yaml:"notARepository"` + NotARepository string `yaml:"notARepository" jsonschema:"enum=prompt,enum=create,enum=skip,enum=quit"` // If true, display a confirmation when subprocess terminates. This allows you to view the output of the subprocess before returning to Lazygit. PromptToReturnFromSubprocess bool `yaml:"promptToReturnFromSubprocess"` } @@ -41,10 +43,10 @@ type UserConfig struct { type RefresherConfig struct { // File/submodule refresh interval in seconds. // Auto-refresh can be disabled via option 'git.autoRefresh'. - RefreshInterval int `yaml:"refreshInterval"` + RefreshInterval int `yaml:"refreshInterval" jsonschema:"minimum=0"` // Re-fetch interval in seconds. // Auto-fetch can be disabled via option 'git.autoFetch'. - FetchInterval int `yaml:"fetchInterval"` + FetchInterval int `yaml:"fetchInterval" jsonschema:"minimum=0"` } type GuiConfig struct { @@ -53,7 +55,7 @@ type GuiConfig struct { // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color BranchColors map[string]string `yaml:"branchColors"` // The number of lines you scroll by when scrolling the main window - ScrollHeight int `yaml:"scrollHeight"` + ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"` // If true, allow scrolling past the bottom of the content in the main window ScrollPastBottom bool `yaml:"scrollPastBottom"` // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#scroll-off-margin @@ -73,7 +75,7 @@ type GuiConfig struct { SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"` // Fraction of the total screen width to use for the left side section. You may want to pick a small number (e.g. 0.2) if you're using a narrow screen, so that you can see more of the main section. // Number from 0 to 1.0. - SidePanelWidth float64 `yaml:"sidePanelWidth"` + SidePanelWidth float64 `yaml:"sidePanelWidth" jsonschema:"maximum=1,minimum=0"` // If true, increase the height of the focused side window; creating an accordion effect. ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"` // Sometimes the main window is split in two (e.g. when the selected file has both staged and unstaged changes). This setting controls how the two sections are split. @@ -81,9 +83,9 @@ type GuiConfig struct { // - 'horizontal': split the window horizontally // - 'vertical': split the window vertically // - 'flexible': (default) split the window horizontally if the window is wide enough, otherwise split vertically - MainPanelSplitMode string `yaml:"mainPanelSplitMode"` + MainPanelSplitMode string `yaml:"mainPanelSplitMode" jsonschema:"enum=horizontal,enum=flexible,enum=vertical"` // One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' - Language string `yaml:"language"` + Language string `yaml:"language" jsonschema:"enum=auto,enum=en,enum=zh-TW,enum=zh-CN,enum=pl,enum=nl,enum=ja,enum=ko,enum=ru"` // Format used when displaying time e.g. commit time. // Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format TimeFormat string `yaml:"timeFormat"` @@ -113,21 +115,21 @@ type GuiConfig struct { // Nerd fonts version to use. // One of: '2' | '3' | empty string (default) // If empty, do not show icons. - NerdFontsVersion string `yaml:"nerdFontsVersion"` + NerdFontsVersion string `yaml:"nerdFontsVersion" jsonschema:"enum=2,enum=3,enum="` // If true, show commit hashes alongside branch names in the branches view. ShowBranchCommitHash bool `yaml:"showBranchCommitHash"` // Height of the command log view - CommandLogSize int `yaml:"commandLogSize"` + CommandLogSize int `yaml:"commandLogSize" jsonschema:"minimum=0"` // Whether to split the main window when viewing file changes. // One of: 'auto' | 'always' // If 'auto', only split the main window when a file has both staged and unstaged changes - SplitDiff string `yaml:"splitDiff"` + SplitDiff string `yaml:"splitDiff" jsonschema:"enum=auto,enum=always"` // Default size for focused window. Window size can be changed from within Lazygit with '+' and '_' (but this won't change the default). // One of: 'normal' (default) | 'half' | 'full' - WindowSize string `yaml:"windowSize"` + WindowSize string `yaml:"windowSize" jsonschema:"enum=normal,enum=half,enum=full"` // Window border style. // One of 'rounded' (default) | 'single' | 'double' | 'hidden' - Border string `yaml:"border"` + Border string `yaml:"border" jsonschema:"enum=single,enum=double,enum=rounded,enum=hidden"` // If true, show a seriously epic explosion animation when nuking the working tree. AnimateExplosion bool `yaml:"animateExplosion"` // Whether to stack UI components on top of each other. @@ -137,31 +139,31 @@ type GuiConfig struct { type ThemeConfig struct { // Border color of focused window - ActiveBorderColor []string `yaml:"activeBorderColor"` + ActiveBorderColor []string `yaml:"activeBorderColor" jsonschema:"minItems=1,uniqueItems=true"` // Border color of non-focused windows - InactiveBorderColor []string `yaml:"inactiveBorderColor"` + InactiveBorderColor []string `yaml:"inactiveBorderColor" jsonschema:"minItems=1,uniqueItems=true"` // Border color of focused window when searching in that window - SearchingActiveBorderColor []string `yaml:"searchingActiveBorderColor"` + SearchingActiveBorderColor []string `yaml:"searchingActiveBorderColor" jsonschema:"minItems=1,uniqueItems=true"` // Color of keybindings help text in the bottom line - OptionsTextColor []string `yaml:"optionsTextColor"` + OptionsTextColor []string `yaml:"optionsTextColor" jsonschema:"minItems=1,uniqueItems=true"` // Background color of selected line. // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line - SelectedLineBgColor []string `yaml:"selectedLineBgColor"` + SelectedLineBgColor []string `yaml:"selectedLineBgColor" jsonschema:"minItems=1,uniqueItems=true"` // Background color of selected range // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line - SelectedRangeBgColor []string `yaml:"selectedRangeBgColor"` + SelectedRangeBgColor []string `yaml:"selectedRangeBgColor" jsonschema:"minItems=1,uniqueItems=true"` // Foreground color of copied commit - CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor"` + CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor" jsonschema:"minItems=1,uniqueItems=true"` // Background color of copied commit - CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor"` + CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor" jsonschema:"minItems=1,uniqueItems=true"` // Foreground color of marked base commit (for rebase) MarkedBaseCommitFgColor []string `yaml:"markedBaseCommitFgColor"` // Background color of marked base commit (for rebase) MarkedBaseCommitBgColor []string `yaml:"markedBaseCommitBgColor"` // Color for file with unstaged changes - UnstagedChangesColor []string `yaml:"unstagedChangesColor"` + UnstagedChangesColor []string `yaml:"unstagedChangesColor" jsonschema:"minItems=1,uniqueItems=true"` // Default text color - DefaultFgColor []string `yaml:"defaultFgColor"` + DefaultFgColor []string `yaml:"defaultFgColor" jsonschema:"minItems=1,uniqueItems=true"` } type CommitLengthConfig struct { @@ -177,7 +179,7 @@ type GitConfig struct { // Config relating to merging Merging MergingConfig `yaml:"merging"` // list of branches that are considered 'main' branches, used when displaying commits - MainBranches []string `yaml:"mainBranches"` + MainBranches []string `yaml:"mainBranches" jsonschema:"uniqueItems=true"` // Prefix to use when skipping hooks. E.g. if set to 'WIP', then pre-commit hooks will be skipped when the commit message starts with 'WIP' SkipHookPrefix string `yaml:"skipHookPrefix"` // If true, periodically fetch from remote @@ -203,14 +205,24 @@ type GitConfig struct { Log LogConfig `yaml:"log"` } +type PagerType string + +func (PagerType) JSONSchemaExtend(schema *jsonschema.Schema) { + schema.Examples = []any{ + "delta --dark --paging=never", + "diff-so-fancy", + "ydiff -p cat -s --wrap --width={{columnWidth}}", + } +} + type PagingConfig struct { // Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never' - ColorArg string `yaml:"colorArg"` + ColorArg string `yaml:"colorArg" jsonschema:"enum=always,enum=never"` // e.g. // diff-so-fancy // delta --dark --paging=never // ydiff -p cat -s --wrap --width={{columnWidth}} - Pager string `yaml:"pager"` + Pager PagerType `yaml:"pager" jsonschema:"minLength=1"` // If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager). UseConfig bool `yaml:"useConfig"` // e.g. 'difft --color=always' @@ -227,33 +239,33 @@ type MergingConfig struct { // Only applicable to unix users. ManualCommit bool `yaml:"manualCommit"` // Extra args passed to `git merge`, e.g. --no-ff - Args string `yaml:"args"` + Args string `yaml:"args" jsonschema:"example=--no-ff"` } type LogConfig struct { - // One of: 'date-order' | 'author-date-order' | 'topo-order' + // One of: 'date-order' | 'author-date-order' | 'topo-order | default' // 'topo-order' makes it easier to read the git log graph, but commits may not // appear chronologically. See https://git-scm.com/docs/ - Order string `yaml:"order"` + Order string `yaml:"order" jsonschema:"enum=date-order,enum=author-date-order,enum=topo-order,enum=default"` // This determines whether the git graph is rendered in the commits panel - // One of 'always' | 'never' 'when-maximised' - ShowGraph string `yaml:"showGraph"` + // One of 'always' | 'never' | 'when-maximised' + ShowGraph string `yaml:"showGraph" jsonschema:"enum=always,enum=never,enum=when-maximised"` // displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`) ShowWholeGraph bool `yaml:"showWholeGraph"` } type CommitPrefixConfig struct { // pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*" - Pattern string `yaml:"pattern"` + Pattern string `yaml:"pattern" jsonschema:"example=^\\w+\\/(\\w+-\\w+).*,minLength=1"` // Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] " - Replace string `yaml:"replace"` + Replace string `yaml:"replace" jsonschema:"example=[$1] ,minLength=1"` } type UpdateConfig struct { // One of: 'prompt' (default) | 'background' | 'never' - Method string `yaml:"method"` + Method string `yaml:"method" jsonschema:"enum=prompt,enum=background,enum=never"` // Period in days between update checks - Days int64 `yaml:"days"` + Days int64 `yaml:"days" jsonschema:"minimum=0"` } type KeybindingConfig struct { @@ -459,7 +471,7 @@ type OSConfig struct { // A built-in preset that sets all of the above settings. Supported presets // are defined in the getPreset function in editor_presets.go. - EditPreset string `yaml:"editPreset,omitempty"` + EditPreset string `yaml:"editPreset,omitempty" jsonschema:"example=vim,example=nvim,example=emacs,example=nano,example=vscode,example=sublime,example=kakoune,example=helix,example=xcode"` // Command for opening a file, as if the file is double-clicked. Should // contain "{{filename}}", but doesn't support "{{line}}". @@ -504,15 +516,15 @@ type CustomCommand struct { // The key to trigger the command. Use a single letter or one of the values from https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybindings.md Key string `yaml:"key"` // The context in which to listen for the key - Context string `yaml:"context"` + Context string `yaml:"context" jsonschema:"enum=status,enum=files,enum=worktrees,enum=localBranches,enum=remotes,enum=remoteBranches,enum=tags,enum=commits,enum=reflogCommits,enum=subCommits,enum=commitFiles,enum=stash,enum=global"` // The command to run (using Go template syntax for placeholder values) - Command string `yaml:"command"` + Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"` // If true, run the command in a subprocess (e.g. if the command requires user input) Subprocess bool `yaml:"subprocess"` // A list of prompts that will request user input before running the final command Prompts []CustomCommandPrompt `yaml:"prompts"` // Text to display while waiting for command to finish - LoadingText string `yaml:"loadingText"` + LoadingText string `yaml:"loadingText" jsonschema:"example=Loading..."` // Label for the custom command when displayed in the keybindings menu Description string `yaml:"description"` // If true, stream the command's output to the Command Log panel @@ -540,7 +552,7 @@ type CustomCommandPrompt struct { // The message of the confirmation prompt. // Only for confirm prompts. - Body string `yaml:"body"` + Body string `yaml:"body" jsonschema:"example=Are you sure you want to push to the remote?"` // Menu options. // Only for menu prompts. @@ -548,23 +560,23 @@ type CustomCommandPrompt struct { // The command to run to generate menu options // Only for menuFromCommand prompts. - Command string `yaml:"command"` + Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"` // The regexp to run specifying groups which are going to be kept from the command's output. // Only for menuFromCommand prompts. - Filter string `yaml:"filter"` + Filter string `yaml:"filter" jsonschema:"example=.*{{.SelectedRemote.Name }}/(?P.*)"` // How to format matched groups from the filter to construct a menu item's value. // Only for menuFromCommand prompts. - ValueFormat string `yaml:"valueFormat"` + ValueFormat string `yaml:"valueFormat" jsonschema:"example={{ .branch }}"` // Like valueFormat but for the labels. If `labelFormat` is not specified, `valueFormat` is shown instead. // Only for menuFromCommand prompts. - LabelFormat string `yaml:"labelFormat"` + LabelFormat string `yaml:"labelFormat" jsonschema:"example={{ .branch | green }}"` } type CustomCommandSuggestions struct { // Uses built-in logic to obtain the suggestions. One of 'authors' | 'branches' | 'files' | 'refs' | 'remotes' | 'remoteBranches' | 'tags' - Preset string `yaml:"preset"` + Preset string `yaml:"preset" jsonschema:"enum=authors,enum=branches,enum=files,enum=refs,enum=remotes,enum=remoteBranches,enum=tags"` // Command to run such that each line in the output becomes a suggestion. Mutually exclusive with 'preset' field. - Command string `yaml:"command"` + Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"` } type CustomCommandMenuOption struct { @@ -573,7 +585,7 @@ type CustomCommandMenuOption struct { // The second part of the label Description string `yaml:"description"` // The value that will be used in the command - Value string `yaml:"value"` + Value string `yaml:"value" jsonschema:"example=feature,minLength=1"` } func GetDefaultConfig() *UserConfig { diff --git a/pkg/jsonschema/generate.go b/pkg/jsonschema/generate.go new file mode 100644 index 000000000000..38b582844242 --- /dev/null +++ b/pkg/jsonschema/generate.go @@ -0,0 +1,106 @@ +//go:generate go run generator.go + +package jsonschema + +import ( + "encoding/json" + "fmt" + "os" + "reflect" + + "github.com/jesseduffield/lazycore/pkg/utils" + "github.com/jesseduffield/lazygit/pkg/config" + "github.com/karimkhaleel/jsonschema" +) + +func GetSchemaDir() string { + return utils.GetLazyRootDirectory() + "/schema" +} + +func GenerateSchema() { + schema := customReflect(&config.UserConfig{}) + obj, _ := json.MarshalIndent(schema, "", " ") + + if err := os.WriteFile(GetSchemaDir()+"/config.json", obj, 0o644); err != nil { + fmt.Println("Error writing to file:", err) + return + } +} + +func customReflect(v *config.UserConfig) *jsonschema.Schema { + defaultConfig := config.GetDefaultConfig() + r := &jsonschema.Reflector{FieldNameTag: "yaml", RequiredFromJSONSchemaTags: true, DoNotReference: true} + if err := r.AddGoComments("github.com/jesseduffield/lazygit/pkg/config", "../config"); err != nil { + panic(err) + } + schema := r.Reflect(v) + + setDefaultVals(defaultConfig, schema) + + return schema +} + +func setDefaultVals(defaults any, schema *jsonschema.Schema) { + t := reflect.TypeOf(defaults) + v := reflect.ValueOf(defaults) + + if t.Kind() == reflect.Ptr || t.Kind() == reflect.Interface { + t = t.Elem() + v = v.Elem() + } + + for i := 0; i < t.NumField(); i++ { + value := v.Field(i).Interface() + parentKey := t.Field(i).Name + + key, ok := schema.OriginalPropertiesMapping[parentKey] + if !ok { + continue + } + + subSchema, ok := schema.Properties.Get(key) + if !ok { + continue + } + + if isStruct(value) { + setDefaultVals(value, subSchema) + } else if !isZeroValue(value) { + subSchema.Default = value + } + } +} + +func isZeroValue(v any) bool { + switch v := v.(type) { + case int, int32, int64, float32, float64: + return v == 0 + case string: + return v == "" + case bool: + return !v + case nil: + return true + } + + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Slice, reflect.Map: + return rv.Len() == 0 + case reflect.Ptr, reflect.Interface: + return rv.IsNil() + case reflect.Struct: + for i := 0; i < rv.NumField(); i++ { + if !isZeroValue(rv.Field(i).Interface()) { + return false + } + } + return true + default: + return false + } +} + +func isStruct(v any) bool { + return reflect.TypeOf(v).Kind() == reflect.Struct +} diff --git a/pkg/jsonschema/generator.go b/pkg/jsonschema/generator.go new file mode 100644 index 000000000000..263f4784bb32 --- /dev/null +++ b/pkg/jsonschema/generator.go @@ -0,0 +1,14 @@ +//go:build ignore + +package main + +import ( + "fmt" + + "github.com/jesseduffield/lazygit/pkg/jsonschema" +) + +func main() { + fmt.Printf("Generating jsonschema in %s...\n", jsonschema.GetSchemaDir()) + jsonschema.GenerateSchema() +} diff --git a/schema/config.json b/schema/config.json new file mode 100644 index 000000000000..2f1dba309db1 --- /dev/null +++ b/schema/config.json @@ -0,0 +1,1501 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/jesseduffield/lazygit/pkg/config/user-config", + "properties": { + "gui": { + "properties": { + "authorColors": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color" + }, + "branchColors": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color" + }, + "scrollHeight": { + "type": "integer", + "minimum": 1, + "description": "The number of lines you scroll by when scrolling the main window", + "default": 2 + }, + "scrollPastBottom": { + "type": "boolean", + "description": "If true, allow scrolling past the bottom of the content in the main window", + "default": true + }, + "scrollOffMargin": { + "type": "integer", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#scroll-off-margin", + "default": 2 + }, + "scrollOffBehavior": { + "type": "string", + "description": "One of: 'margin' (default) | 'jump'", + "default": "margin" + }, + "mouseEvents": { + "type": "boolean", + "description": "If true, capture mouse events.\nWhen mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.", + "default": true + }, + "skipDiscardChangeWarning": { + "type": "boolean", + "description": "If true, do not show a warning when discarding changes in the staging view." + }, + "skipStashWarning": { + "type": "boolean", + "description": "If true, do not show warning when applying/popping the stash" + }, + "skipNoStagedFilesWarning": { + "type": "boolean", + "description": "If true, do not show a warning when attempting to commit without any staged files; instead stage all unstaged files." + }, + "skipRewordInEditorWarning": { + "type": "boolean", + "description": "If true, do not show a warning when rewording a commit via an external editor" + }, + "sidePanelWidth": { + "type": "number", + "maximum": 1, + "minimum": 0, + "description": "Fraction of the total screen width to use for the left side section. You may want to pick a small number (e.g. 0.2) if you're using a narrow screen, so that you can see more of the main section.\nNumber from 0 to 1.0.", + "default": 0.3333 + }, + "expandFocusedSidePanel": { + "type": "boolean", + "description": "If true, increase the height of the focused side window; creating an accordion effect." + }, + "mainPanelSplitMode": { + "type": "string", + "enum": [ + "horizontal", + "flexible", + "vertical" + ], + "description": "Sometimes the main window is split in two (e.g. when the selected file has both staged and unstaged changes). This setting controls how the two sections are split.\nOptions are:\n- 'horizontal': split the window horizontally\n- 'vertical': split the window vertically\n- 'flexible': (default) split the window horizontally if the window is wide enough, otherwise split vertically", + "default": "flexible" + }, + "language": { + "type": "string", + "enum": [ + "auto", + "en", + "zh-TW", + "zh-CN", + "pl", + "nl", + "ja", + "ko", + "ru" + ], + "description": "One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'", + "default": "auto" + }, + "timeFormat": { + "type": "string", + "description": "Format used when displaying time e.g. commit time.\nUses Go's time format syntax: https://pkg.go.dev/time#Time.Format", + "default": "02 Jan 06" + }, + "shortTimeFormat": { + "type": "string", + "description": "Format used when displaying time if the time is less than 24 hours ago.\nUses Go's time format syntax: https://pkg.go.dev/time#Time.Format", + "default": "3:04PM" + }, + "theme": { + "properties": { + "activeBorderColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Border color of focused window", + "default": [ + "green", + "bold" + ] + }, + "inactiveBorderColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Border color of non-focused windows", + "default": [ + "default" + ] + }, + "searchingActiveBorderColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Border color of focused window when searching in that window", + "default": [ + "cyan", + "bold" + ] + }, + "optionsTextColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Color of keybindings help text in the bottom line", + "default": [ + "blue" + ] + }, + "selectedLineBgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Background color of selected line.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line", + "default": [ + "blue" + ] + }, + "selectedRangeBgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Background color of selected range\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line", + "default": [ + "blue" + ] + }, + "cherryPickedCommitFgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Foreground color of copied commit", + "default": [ + "blue" + ] + }, + "cherryPickedCommitBgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Background color of copied commit", + "default": [ + "cyan" + ] + }, + "markedBaseCommitFgColor": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Foreground color of marked base commit (for rebase)", + "default": [ + "blue" + ] + }, + "markedBaseCommitBgColor": { + "items": { + "type": "string" + }, + "type": "array", + "description": "Background color of marked base commit (for rebase)", + "default": [ + "yellow" + ] + }, + "unstagedChangesColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Color for file with unstaged changes", + "default": [ + "red" + ] + }, + "defaultFgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Default text color", + "default": [ + "default" + ] + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to colors and styles.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes" + }, + "commitLength": { + "properties": { + "show": { + "type": "boolean", + "description": "If true, show an indicator of commit message length", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to the commit length indicator" + }, + "showListFooter": { + "type": "boolean", + "description": "If true, show the '5 of 20' footer at the bottom of list views", + "default": true + }, + "showFileTree": { + "type": "boolean", + "description": "If true, display the files in the file views as a tree. If false, display the files as a flat list.\nThis can be toggled from within Lazygit with the '~' key, but that will not change the default.", + "default": true + }, + "showRandomTip": { + "type": "boolean", + "description": "If true, show a random tip in the command log when Lazygit starts", + "default": true + }, + "showCommandLog": { + "type": "boolean", + "description": "If true, show the command log", + "default": true + }, + "showBottomLine": { + "type": "boolean", + "description": "If true, show the bottom line that contains keybinding info and useful buttons. If false, this line will be hidden except to display a loader for an in-progress action.", + "default": true + }, + "showPanelJumps": { + "type": "boolean", + "description": "If true, show jump-to-window keybindings in window titles.", + "default": true + }, + "showIcons": { + "type": "boolean", + "description": "Deprecated: use nerdFontsVersion instead" + }, + "nerdFontsVersion": { + "type": "string", + "enum": [ + "2", + "3", + "" + ], + "description": "Nerd fonts version to use.\nOne of: '2' | '3' | empty string (default)\nIf empty, do not show icons." + }, + "showBranchCommitHash": { + "type": "boolean", + "description": "If true, show commit hashes alongside branch names in the branches view." + }, + "commandLogSize": { + "type": "integer", + "minimum": 0, + "description": "Height of the command log view", + "default": 8 + }, + "splitDiff": { + "type": "string", + "enum": [ + "auto", + "always" + ], + "description": "Whether to split the main window when viewing file changes.\nOne of: 'auto' | 'always'\nIf 'auto', only split the main window when a file has both staged and unstaged changes", + "default": "auto" + }, + "windowSize": { + "type": "string", + "enum": [ + "normal", + "half", + "full" + ], + "description": "Default size for focused window. Window size can be changed from within Lazygit with '+' and '_' (but this won't change the default).\nOne of: 'normal' (default) | 'half' | 'full'" + }, + "border": { + "type": "string", + "enum": [ + "single", + "double", + "rounded", + "hidden" + ], + "description": "Window border style.\nOne of 'rounded' (default) | 'single' | 'double' | 'hidden'", + "default": "rounded" + }, + "animateExplosion": { + "type": "boolean", + "description": "If true, show a seriously epic explosion animation when nuking the working tree.", + "default": true + }, + "portraitMode": { + "type": "string", + "description": "Whether to stack UI components on top of each other.\nOne of 'auto' (default) | 'always' | 'never'", + "default": "auto" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to the Lazygit UI" + }, + "git": { + "properties": { + "paging": { + "properties": { + "colorArg": { + "type": "string", + "enum": [ + "always", + "never" + ], + "description": "Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never'", + "default": "always" + }, + "pager": { + "type": "string", + "minLength": 1, + "description": "e.g.\ndiff-so-fancy\ndelta --dark --paging=never\nydiff -p cat -s --wrap --width={{columnWidth}}", + "default": "", + "examples": [ + "delta --dark --paging=never", + "diff-so-fancy", + "ydiff -p cat -s --wrap --width={{columnWidth}}" + ] + }, + "useConfig": { + "type": "boolean", + "description": "If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager)." + }, + "externalDiffCommand": { + "type": "string", + "description": "e.g. 'difft --color=always'" + } + }, + "additionalProperties": false, + "type": "object", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md" + }, + "commit": { + "properties": { + "signOff": { + "type": "boolean", + "description": "If true, pass '--signoff' flag when committing" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to committing" + }, + "merging": { + "properties": { + "manualCommit": { + "type": "boolean", + "description": "If true, run merges in a subprocess so that if a commit message is required, Lazygit will not hang\nOnly applicable to unix users." + }, + "args": { + "type": "string", + "description": "Extra args passed to `git merge`, e.g. --no-ff", + "examples": [ + "--no-ff" + ] + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to merging" + }, + "mainBranches": { + "items": { + "type": "string" + }, + "type": "array", + "uniqueItems": true, + "description": "list of branches that are considered 'main' branches, used when displaying commits", + "default": [ + "master", + "main" + ] + }, + "skipHookPrefix": { + "type": "string", + "description": "Prefix to use when skipping hooks. E.g. if set to 'WIP', then pre-commit hooks will be skipped when the commit message starts with 'WIP'", + "default": "WIP" + }, + "autoFetch": { + "type": "boolean", + "description": "If true, periodically fetch from remote", + "default": true + }, + "autoRefresh": { + "type": "boolean", + "description": "If true, periodically refresh files and submodules", + "default": true + }, + "fetchAll": { + "type": "boolean", + "description": "If true, pass the --all arg to git fetch", + "default": true + }, + "branchLogCmd": { + "type": "string", + "description": "Command used when displaying the current branch git log in the main window", + "default": "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --" + }, + "allBranchesLogCmd": { + "type": "string", + "description": "Command used to display git log of all branches in the main window", + "default": "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium" + }, + "overrideGpg": { + "type": "boolean", + "description": "If true, do not spawn a separate process when using GPG" + }, + "disableForcePushing": { + "type": "boolean", + "description": "If true, do not allow force pushes" + }, + "commitPrefixes": { + "additionalProperties": { + "properties": { + "pattern": { + "type": "string", + "minLength": 1, + "description": "pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use \"^\\\\w+\\\\/(\\\\w+-\\\\w+).*\"", + "examples": [ + "^\\w+\\/(\\w+-\\w+).*" + ] + }, + "replace": { + "type": "string", + "minLength": 1, + "description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"", + "examples": [ + "[$1] " + ] + } + }, + "additionalProperties": false, + "type": "object" + }, + "type": "object", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix" + }, + "parseEmoji": { + "type": "boolean", + "description": "If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀\n(This should really be under 'gui', not 'git')" + }, + "log": { + "properties": { + "order": { + "type": "string", + "enum": [ + "date-order", + "author-date-order", + "topo-order", + "default" + ], + "description": "One of: 'date-order' | 'author-date-order' | 'topo-order | default'\n'topo-order' makes it easier to read the git log graph, but commits may not\nappear chronologically. See https://git-scm.com/docs/", + "default": "topo-order" + }, + "showGraph": { + "type": "string", + "enum": [ + "always", + "never", + "when-maximised" + ], + "description": "This determines whether the git graph is rendered in the commits panel\nOne of 'always' | 'never' | 'when-maximised'", + "default": "when-maximised" + }, + "showWholeGraph": { + "type": "boolean", + "description": "displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`)" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config for showing the log in the commits view" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to git" + }, + "update": { + "properties": { + "method": { + "type": "string", + "enum": [ + "prompt", + "background", + "never" + ], + "description": "One of: 'prompt' (default) | 'background' | 'never'", + "default": "prompt" + }, + "days": { + "type": "integer", + "minimum": 0, + "description": "Period in days between update checks", + "default": 14 + } + }, + "additionalProperties": false, + "type": "object", + "description": "Periodic update checks" + }, + "refresher": { + "properties": { + "refreshInterval": { + "type": "integer", + "minimum": 0, + "description": "File/submodule refresh interval in seconds.\nAuto-refresh can be disabled via option 'git.autoRefresh'.", + "default": 10 + }, + "fetchInterval": { + "type": "integer", + "minimum": 0, + "description": "Re-fetch interval in seconds.\nAuto-fetch can be disabled via option 'git.autoFetch'.", + "default": 60 + } + }, + "additionalProperties": false, + "type": "object", + "description": "Background refreshes" + }, + "confirmOnQuit": { + "type": "boolean", + "description": "If true, show a confirmation popup before quitting Lazygit" + }, + "quitOnTopLevelReturn": { + "type": "boolean", + "description": "If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close" + }, + "keybinding": { + "properties": { + "universal": { + "properties": { + "quit": { + "type": "string", + "default": "q" + }, + "quit-alt1": { + "type": "string", + "default": "\u003cc-c\u003e" + }, + "return": { + "type": "string", + "default": "\u003cesc\u003e" + }, + "quitWithoutChangingDirectory": { + "type": "string", + "default": "Q" + }, + "togglePanel": { + "type": "string", + "default": "\u003ctab\u003e" + }, + "prevItem": { + "type": "string", + "default": "\u003cup\u003e" + }, + "nextItem": { + "type": "string", + "default": "\u003cdown\u003e" + }, + "prevItem-alt": { + "type": "string", + "default": "k" + }, + "nextItem-alt": { + "type": "string", + "default": "j" + }, + "prevPage": { + "type": "string", + "default": "," + }, + "nextPage": { + "type": "string", + "default": "." + }, + "scrollLeft": { + "type": "string", + "default": "H" + }, + "scrollRight": { + "type": "string", + "default": "L" + }, + "gotoTop": { + "type": "string", + "default": "\u003c" + }, + "gotoBottom": { + "type": "string", + "default": "\u003e" + }, + "prevBlock": { + "type": "string", + "default": "\u003cleft\u003e" + }, + "nextBlock": { + "type": "string", + "default": "\u003cright\u003e" + }, + "prevBlock-alt": { + "type": "string", + "default": "h" + }, + "nextBlock-alt": { + "type": "string", + "default": "l" + }, + "nextBlock-alt2": { + "type": "string", + "default": "\u003ctab\u003e" + }, + "prevBlock-alt2": { + "type": "string", + "default": "\u003cbacktab\u003e" + }, + "jumpToBlock": { + "items": { + "type": "string" + }, + "type": "array", + "default": [ + "1", + "2", + "3", + "4", + "5" + ] + }, + "nextMatch": { + "type": "string", + "default": "n" + }, + "prevMatch": { + "type": "string", + "default": "N" + }, + "startSearch": { + "type": "string", + "default": "/" + }, + "optionMenu": { + "type": "string", + "default": "\u003cdisabled\u003e" + }, + "optionMenu-alt1": { + "type": "string", + "default": "?" + }, + "select": { + "type": "string", + "default": "\u003cspace\u003e" + }, + "goInto": { + "type": "string", + "default": "\u003center\u003e" + }, + "confirm": { + "type": "string", + "default": "\u003center\u003e" + }, + "confirmInEditor": { + "type": "string", + "default": "\u003ca-enter\u003e" + }, + "remove": { + "type": "string", + "default": "d" + }, + "new": { + "type": "string", + "default": "n" + }, + "edit": { + "type": "string", + "default": "e" + }, + "openFile": { + "type": "string", + "default": "o" + }, + "scrollUpMain": { + "type": "string", + "default": "\u003cpgup\u003e" + }, + "scrollDownMain": { + "type": "string", + "default": "\u003cpgdown\u003e" + }, + "scrollUpMain-alt1": { + "type": "string", + "default": "K" + }, + "scrollDownMain-alt1": { + "type": "string", + "default": "J" + }, + "scrollUpMain-alt2": { + "type": "string", + "default": "\u003cc-u\u003e" + }, + "scrollDownMain-alt2": { + "type": "string", + "default": "\u003cc-d\u003e" + }, + "executeCustomCommand": { + "type": "string", + "default": ":" + }, + "createRebaseOptionsMenu": { + "type": "string", + "default": "m" + }, + "pushFiles": { + "type": "string", + "description": "'Files' appended for legacy reasons", + "default": "P" + }, + "pullFiles": { + "type": "string", + "description": "'Files' appended for legacy reasons", + "default": "p" + }, + "refresh": { + "type": "string", + "default": "R" + }, + "createPatchOptionsMenu": { + "type": "string", + "default": "\u003cc-p\u003e" + }, + "nextTab": { + "type": "string", + "default": "]" + }, + "prevTab": { + "type": "string", + "default": "[" + }, + "nextScreenMode": { + "type": "string", + "default": "+" + }, + "prevScreenMode": { + "type": "string", + "default": "_" + }, + "undo": { + "type": "string", + "default": "z" + }, + "redo": { + "type": "string", + "default": "\u003cc-z\u003e" + }, + "filteringMenu": { + "type": "string", + "default": "\u003cc-s\u003e" + }, + "diffingMenu": { + "type": "string", + "default": "W" + }, + "diffingMenu-alt": { + "type": "string", + "default": "\u003cc-e\u003e" + }, + "copyToClipboard": { + "type": "string", + "default": "\u003cc-o\u003e" + }, + "openRecentRepos": { + "type": "string", + "default": "\u003cc-r\u003e" + }, + "submitEditorText": { + "type": "string", + "default": "\u003center\u003e" + }, + "extrasMenu": { + "type": "string", + "default": "@" + }, + "toggleWhitespaceInDiffView": { + "type": "string", + "default": "\u003cc-w\u003e" + }, + "increaseContextInDiffView": { + "type": "string", + "default": "}" + }, + "decreaseContextInDiffView": { + "type": "string", + "default": "{" + } + }, + "additionalProperties": false, + "type": "object" + }, + "status": { + "properties": { + "checkForUpdate": { + "type": "string", + "default": "u" + }, + "recentRepos": { + "type": "string", + "default": "\u003center\u003e" + }, + "allBranchesLogGraph": { + "type": "string", + "default": "a" + } + }, + "additionalProperties": false, + "type": "object" + }, + "files": { + "properties": { + "commitChanges": { + "type": "string", + "default": "c" + }, + "commitChangesWithoutHook": { + "type": "string", + "default": "w" + }, + "amendLastCommit": { + "type": "string", + "default": "A" + }, + "commitChangesWithEditor": { + "type": "string", + "default": "C" + }, + "confirmDiscard": { + "type": "string", + "default": "x" + }, + "ignoreFile": { + "type": "string", + "default": "i" + }, + "refreshFiles": { + "type": "string", + "default": "r" + }, + "stashAllChanges": { + "type": "string", + "default": "s" + }, + "viewStashOptions": { + "type": "string", + "default": "S" + }, + "toggleStagedAll": { + "type": "string", + "default": "a" + }, + "viewResetOptions": { + "type": "string", + "default": "D" + }, + "fetch": { + "type": "string", + "default": "f" + }, + "toggleTreeView": { + "type": "string", + "default": "`" + }, + "openMergeTool": { + "type": "string", + "default": "M" + }, + "openStatusFilter": { + "type": "string", + "default": "\u003cc-b\u003e" + } + }, + "additionalProperties": false, + "type": "object" + }, + "branches": { + "properties": { + "createPullRequest": { + "type": "string", + "default": "o" + }, + "viewPullRequestOptions": { + "type": "string", + "default": "O" + }, + "copyPullRequestURL": { + "type": "string", + "default": "\u003cc-y\u003e" + }, + "checkoutBranchByName": { + "type": "string", + "default": "c" + }, + "forceCheckoutBranch": { + "type": "string", + "default": "F" + }, + "rebaseBranch": { + "type": "string", + "default": "r" + }, + "renameBranch": { + "type": "string", + "default": "R" + }, + "mergeIntoCurrentBranch": { + "type": "string", + "default": "M" + }, + "viewGitFlowOptions": { + "type": "string", + "default": "i" + }, + "fastForward": { + "type": "string", + "default": "f" + }, + "createTag": { + "type": "string", + "default": "T" + }, + "pushTag": { + "type": "string", + "default": "P" + }, + "setUpstream": { + "type": "string", + "default": "u" + }, + "fetchRemote": { + "type": "string", + "default": "f" + } + }, + "additionalProperties": false, + "type": "object" + }, + "worktrees": { + "properties": { + "viewWorktreeOptions": { + "type": "string", + "default": "w" + } + }, + "additionalProperties": false, + "type": "object" + }, + "commits": { + "properties": { + "squashDown": { + "type": "string", + "default": "s" + }, + "renameCommit": { + "type": "string", + "default": "r" + }, + "renameCommitWithEditor": { + "type": "string", + "default": "R" + }, + "viewResetOptions": { + "type": "string", + "default": "g" + }, + "markCommitAsFixup": { + "type": "string", + "default": "f" + }, + "createFixupCommit": { + "type": "string", + "default": "F" + }, + "squashAboveCommits": { + "type": "string", + "default": "S" + }, + "moveDownCommit": { + "type": "string", + "default": "\u003cc-j\u003e" + }, + "moveUpCommit": { + "type": "string", + "default": "\u003cc-k\u003e" + }, + "amendToCommit": { + "type": "string", + "default": "A" + }, + "resetCommitAuthor": { + "type": "string", + "default": "a" + }, + "pickCommit": { + "type": "string", + "default": "p" + }, + "revertCommit": { + "type": "string", + "default": "t" + }, + "cherryPickCopy": { + "type": "string", + "default": "c" + }, + "cherryPickCopyRange": { + "type": "string", + "default": "C" + }, + "pasteCommits": { + "type": "string", + "default": "v" + }, + "markCommitAsBaseForRebase": { + "type": "string", + "default": "B" + }, + "tagCommit": { + "type": "string", + "default": "T" + }, + "checkoutCommit": { + "type": "string", + "default": "\u003cspace\u003e" + }, + "resetCherryPick": { + "type": "string", + "default": "\u003cc-R\u003e" + }, + "copyCommitAttributeToClipboard": { + "type": "string", + "default": "y" + }, + "openLogMenu": { + "type": "string", + "default": "\u003cc-l\u003e" + }, + "openInBrowser": { + "type": "string", + "default": "o" + }, + "viewBisectOptions": { + "type": "string", + "default": "b" + } + }, + "additionalProperties": false, + "type": "object" + }, + "stash": { + "properties": { + "popStash": { + "type": "string", + "default": "g" + }, + "renameStash": { + "type": "string", + "default": "r" + } + }, + "additionalProperties": false, + "type": "object" + }, + "commitFiles": { + "properties": { + "checkoutCommitFile": { + "type": "string", + "default": "c" + } + }, + "additionalProperties": false, + "type": "object" + }, + "main": { + "properties": { + "toggleDragSelect": { + "type": "string", + "default": "v" + }, + "toggleDragSelect-alt": { + "type": "string", + "default": "V" + }, + "toggleSelectHunk": { + "type": "string", + "default": "a" + }, + "pickBothHunks": { + "type": "string", + "default": "b" + }, + "editSelectHunk": { + "type": "string", + "default": "E" + } + }, + "additionalProperties": false, + "type": "object" + }, + "submodules": { + "properties": { + "init": { + "type": "string", + "default": "i" + }, + "update": { + "type": "string", + "default": "u" + }, + "bulkMenu": { + "type": "string", + "default": "b" + } + }, + "additionalProperties": false, + "type": "object" + }, + "commitMessage": { + "properties": { + "switchToEditor": { + "type": "string", + "default": "\u003cc-o\u003e" + } + }, + "additionalProperties": false, + "type": "object" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Keybindings" + }, + "os": { + "properties": { + "edit": { + "type": "string", + "description": "Command for editing a file. Should contain \"{{filename}}\"." + }, + "editAtLine": { + "type": "string", + "description": "Command for editing a file at a given line number. Should contain\n\"{{filename}}\", and may optionally contain \"{{line}}\"." + }, + "editAtLineAndWait": { + "type": "string", + "description": "Same as EditAtLine, except that the command needs to wait until the\nwindow is closed." + }, + "editInTerminal": { + "type": "boolean", + "description": "Whether lazygit suspends until an edit process returns\nPointer to bool so that we can distinguish unset (nil) from false.\nWe're naming this `editInTerminal` for backwards compatibility" + }, + "openDirInEditor": { + "type": "string", + "description": "For opening a directory in an editor" + }, + "editPreset": { + "type": "string", + "description": "A built-in preset that sets all of the above settings. Supported presets\nare defined in the getPreset function in editor_presets.go.", + "examples": [ + "vim", + "nvim", + "emacs", + "nano", + "vscode", + "sublime", + "kakoune", + "helix", + "xcode" + ] + }, + "open": { + "type": "string", + "description": "Command for opening a file, as if the file is double-clicked. Should\ncontain \"{{filename}}\", but doesn't support \"{{line}}\"." + }, + "openLink": { + "type": "string", + "description": "Command for opening a link. Should contain \"{{link}}\"." + }, + "editCommand": { + "type": "string", + "description": "EditCommand is the command for editing a file.\nDeprecated: use Edit instead. Note that semantics are different:\nEditCommand is just the command itself, whereas Edit contains a\n\"{{filename}}\" variable." + }, + "editCommandTemplate": { + "type": "string", + "description": "EditCommandTemplate is the command template for editing a file\nDeprecated: use EditAtLine instead." + }, + "openCommand": { + "type": "string", + "description": "OpenCommand is the command for opening a file\nDeprecated: use Open instead." + }, + "openLinkCommand": { + "type": "string", + "description": "OpenLinkCommand is the command for opening a link\nDeprecated: use OpenLink instead." + }, + "copyToClipboardCmd": { + "type": "string", + "description": "CopyToClipboardCmd is the command for copying to clipboard.\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc" + }, + "disableStartupPopups": { + "type": "boolean", + "description": "If true, don't display introductory popups upon opening Lazygit.\nLazygit sets this to true upon first runninng the program so that you don't see introductory popups every time you open the program." + }, + "customCommands": { + "items": { + "properties": { + "key": { + "type": "string", + "description": "The key to trigger the command. Use a single letter or one of the values from https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybindings.md" + }, + "context": { + "type": "string", + "enum": [ + "status", + "files", + "worktrees", + "localBranches", + "remotes", + "remoteBranches", + "tags", + "commits", + "reflogCommits", + "subCommits", + "commitFiles", + "stash", + "global" + ], + "description": "The context in which to listen for the key" + }, + "command": { + "type": "string", + "description": "The command to run (using Go template syntax for placeholder values)", + "examples": [ + "git fetch {{.Form.Remote}} {{.Form.Branch}} \u0026\u0026 git checkout FETCH_HEAD" + ] + }, + "subprocess": { + "type": "boolean", + "description": "If true, run the command in a subprocess (e.g. if the command requires user input)" + }, + "prompts": { + "items": { + "properties": { + "type": { + "type": "string", + "description": "One of: 'input' | 'menu' | 'confirm' | 'menuFromCommand'" + }, + "key": { + "type": "string", + "description": "Used to reference the entered value from within the custom command. E.g. a prompt with `key: 'Branch'` can be referred to as `{{.Form.Branch}}` in the command" + }, + "title": { + "type": "string", + "description": "The title to display in the popup panel" + }, + "initialValue": { + "type": "string", + "description": "The initial value to appear in the text box.\nOnly for input prompts." + }, + "suggestions": { + "properties": { + "preset": { + "type": "string", + "enum": [ + "authors", + "branches", + "files", + "refs", + "remotes", + "remoteBranches", + "tags" + ], + "description": "Uses built-in logic to obtain the suggestions. One of 'authors' | 'branches' | 'files' | 'refs' | 'remotes' | 'remoteBranches' | 'tags'" + }, + "command": { + "type": "string", + "description": "Command to run such that each line in the output becomes a suggestion. Mutually exclusive with 'preset' field.", + "examples": [ + "git fetch {{.Form.Remote}} {{.Form.Branch}} \u0026\u0026 git checkout FETCH_HEAD" + ] + } + }, + "additionalProperties": false, + "type": "object", + "description": "Shows suggestions as the input is entered\nOnly for input prompts." + }, + "body": { + "type": "string", + "description": "The message of the confirmation prompt.\nOnly for confirm prompts.", + "examples": [ + "Are you sure you want to push to the remote?" + ] + }, + "Options": { + "items": { + "properties": { + "name": { + "type": "string", + "description": "The first part of the label" + }, + "description": { + "type": "string", + "description": "The second part of the label" + }, + "value": { + "type": "string", + "minLength": 1, + "description": "The value that will be used in the command", + "examples": [ + "feature" + ] + } + }, + "additionalProperties": false, + "type": "object" + }, + "type": "array", + "description": "Menu options.\nOnly for menu prompts." + }, + "command": { + "type": "string", + "description": "The command to run to generate menu options\nOnly for menuFromCommand prompts.", + "examples": [ + "git fetch {{.Form.Remote}} {{.Form.Branch}} \u0026\u0026 git checkout FETCH_HEAD" + ] + }, + "filter": { + "type": "string", + "description": "The regexp to run specifying groups which are going to be kept from the command's output.\nOnly for menuFromCommand prompts.", + "examples": [ + ".*{{.SelectedRemote.Name }}/(?P\u003cbranch\u003e.*)" + ] + }, + "valueFormat": { + "type": "string", + "description": "How to format matched groups from the filter to construct a menu item's value.\nOnly for menuFromCommand prompts.", + "examples": [ + "{{ .branch }}" + ] + }, + "labelFormat": { + "type": "string", + "description": "Like valueFormat but for the labels. If `labelFormat` is not specified, `valueFormat` is shown instead.\nOnly for menuFromCommand prompts.", + "examples": [ + "{{ .branch | green }}" + ] + } + }, + "additionalProperties": false, + "type": "object" + }, + "type": "array", + "description": "A list of prompts that will request user input before running the final command" + }, + "loadingText": { + "type": "string", + "description": "Text to display while waiting for command to finish", + "examples": [ + "Loading..." + ] + }, + "description": { + "type": "string", + "description": "Label for the custom command when displayed in the keybindings menu" + }, + "stream": { + "type": "boolean", + "description": "If true, stream the command's output to the Command Log panel" + }, + "showOutput": { + "type": "boolean", + "description": "If true, show the command's output in a popup within Lazygit" + }, + "after": { + "properties": { + "checkForConflicts": { + "type": "boolean" + } + }, + "additionalProperties": false, + "type": "object", + "description": "Actions to take after the command has completed" + } + }, + "additionalProperties": false, + "type": "object" + }, + "type": "array", + "uniqueItems": true, + "description": "User-configured commands that can be invoked from within Lazygit" + }, + "services": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-pull-request-urls" + }, + "notARepository": { + "type": "string", + "enum": [ + "prompt", + "create", + "skip", + "quit" + ], + "description": "What to do when opening Lazygit outside of a git repo.\n- 'prompt': (default) ask whether to initialize a new repo or open in the most recent repo\n- 'create': initialize a new repo\n- 'skip': open most recent repo\n- 'quit': exit Lazygit", + "default": "prompt" + }, + "promptToReturnFromSubprocess": { + "type": "boolean", + "description": "If true, display a confirmation when subprocess terminates. This allows you to view the output of the subprocess before returning to Lazygit.", + "default": true + } + }, + "additionalProperties": false, + "type": "object" +} \ No newline at end of file