diff --git a/.golangci.yml b/.golangci.yml index d9c67792eaa..258660b6299 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -20,7 +20,11 @@ linters: linters-settings: exhaustive: default-signifies-exhaustive: true - + staticcheck: + # SA1019 is for checking that we're not using fields marked as deprecated + # in a comment. It decides this in a loose way so I'm silencing it. Also because + # it's tripping on our own structs. + checks: ["all", "-SA1019"] nakedret: # the gods will judge me but I just don't like naked returns at all max-func-lines: 0 diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index aa454219fe1..027835693bd 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -5,131 +5,252 @@ import ( ) type UserConfig struct { - Gui GuiConfig `yaml:"gui"` - Git GitConfig `yaml:"git"` - Update UpdateConfig `yaml:"update"` - Refresher RefresherConfig `yaml:"refresher"` - ConfirmOnQuit bool `yaml:"confirmOnQuit"` - QuitOnTopLevelReturn bool `yaml:"quitOnTopLevelReturn"` - Keybinding KeybindingConfig `yaml:"keybinding"` - // OS determines what defaults are set for opening files and links - OS OSConfig `yaml:"os,omitempty"` - DisableStartupPopups bool `yaml:"disableStartupPopups"` - CustomCommands []CustomCommand `yaml:"customCommands"` - Services map[string]string `yaml:"services"` - NotARepository string `yaml:"notARepository"` - PromptToReturnFromSubprocess bool `yaml:"promptToReturnFromSubprocess"` + // Config relating to the Lazygit UI + Gui GuiConfig `yaml:"gui"` + // Config relating to git + Git GitConfig `yaml:"git"` + // Periodic update checks + Update UpdateConfig `yaml:"update"` + // Background refreshes + Refresher RefresherConfig `yaml:"refresher"` + // If true, show a confirmation popup before quitting Lazygit + ConfirmOnQuit bool `yaml:"confirmOnQuit"` + // If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close + QuitOnTopLevelReturn bool `yaml:"quitOnTopLevelReturn"` + // Keybindings + Keybinding KeybindingConfig `yaml:"keybinding"` + // Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc + OS OSConfig `yaml:"os,omitempty"` + // If true, don't display introductory popups upon opening Lazygit. + // 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"` + // 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. + // - 'prompt': (default) ask whether to initialize a new repo or open in the most recent repo + // - 'create': initialize a new repo + // - 'skip': open most recent repo + // - 'quit': exit Lazygit + NotARepository string `yaml:"notARepository"` + // 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"` } type RefresherConfig struct { + // File/submodule refresh interval in seconds. + // Auto-refresh can be disabled via option 'git.autoRefresh'. RefreshInterval int `yaml:"refreshInterval"` - FetchInterval int `yaml:"fetchInterval"` + // Re-fetch interval in seconds. + // Auto-fetch can be disabled via option 'git.autoFetch'. + FetchInterval int `yaml:"fetchInterval"` } type GuiConfig struct { - AuthorColors map[string]string `yaml:"authorColors"` - BranchColors map[string]string `yaml:"branchColors"` - ScrollHeight int `yaml:"scrollHeight"` - ScrollPastBottom bool `yaml:"scrollPastBottom"` - ScrollOffMargin int `yaml:"scrollOffMargin"` - ScrollOffBehavior string `yaml:"scrollOffBehavior"` - MouseEvents bool `yaml:"mouseEvents"` - SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"` - SkipStashWarning bool `yaml:"skipStashWarning"` - SidePanelWidth float64 `yaml:"sidePanelWidth"` - ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"` - MainPanelSplitMode string `yaml:"mainPanelSplitMode"` - Language string `yaml:"language"` - TimeFormat string `yaml:"timeFormat"` - ShortTimeFormat string `yaml:"shortTimeFormat"` - Theme ThemeConfig `yaml:"theme"` - CommitLength CommitLengthConfig `yaml:"commitLength"` - SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"` - ShowListFooter bool `yaml:"showListFooter"` - ShowFileTree bool `yaml:"showFileTree"` - ShowRandomTip bool `yaml:"showRandomTip"` - ShowCommandLog bool `yaml:"showCommandLog"` - ShowBottomLine bool `yaml:"showBottomLine"` - ShowPanelJumps bool `yaml:"showPanelJumps"` - ShowIcons bool `yaml:"showIcons"` - NerdFontsVersion string `yaml:"nerdFontsVersion"` - ShowBranchCommitHash bool `yaml:"showBranchCommitHash"` - CommandLogSize int `yaml:"commandLogSize"` - SplitDiff string `yaml:"splitDiff"` - SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"` - WindowSize string `yaml:"windowSize"` - Border string `yaml:"border"` - AnimateExplosion bool `yaml:"animateExplosion"` + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color + AuthorColors map[string]string `yaml:"authorColors"` + // 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"` + // 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 + ScrollOffMargin int `yaml:"scrollOffMargin"` + // One of: 'margin' (default) | 'jump' + ScrollOffBehavior string `yaml:"scrollOffBehavior"` + // If true, capture mouse events. + // When mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS. + MouseEvents bool `yaml:"mouseEvents"` + // If true, do not show a warning when discarding changes in the staging view. + SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"` + // If true, do not show warning when applying/popping the stash + SkipStashWarning bool `yaml:"skipStashWarning"` + // If true, do not show a warning when attempting to commit without any staged files; instead stage all unstaged files. + SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"` + // If true, do not show a warning when rewording a commit via an external editor + 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"` + // 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. + // Options are: + // - '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"` + // One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' + Language string `yaml:"language"` + // 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"` + // Format used when displaying time if the time is less than 24 hours ago. + // Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format + ShortTimeFormat string `yaml:"shortTimeFormat"` + // Config relating to colors and styles. + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes + Theme ThemeConfig `yaml:"theme"` + // Config relating to the commit length indicator + CommitLength CommitLengthConfig `yaml:"commitLength"` + // If true, show the '5 of 20' footer at the bottom of list views + ShowListFooter bool `yaml:"showListFooter"` + // If true, display the files in the file views as a tree. If false, display the files as a flat list. + // This can be toggled from within Lazygit with the '~' key, but that will not change the default. + ShowFileTree bool `yaml:"showFileTree"` + // If true, show a random tip in the command log when Lazygit starts + ShowRandomTip bool `yaml:"showRandomTip"` + // If true, show the command log + ShowCommandLog bool `yaml:"showCommandLog"` + // 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. + ShowBottomLine bool `yaml:"showBottomLine"` + // If true, show jump-to-window keybindings in window titles. + ShowPanelJumps bool `yaml:"showPanelJumps"` + // Deprecated: use nerdFontsVersion instead + ShowIcons bool `yaml:"showIcons"` + // Nerd fonts version to use. + // One of: '2' | '3' | empty string (default) + // If empty, do not show icons. + NerdFontsVersion string `yaml:"nerdFontsVersion"` + // 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"` + // 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"` + // 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"` + // Window border style. + // One of 'rounded' (default) | 'single' | 'double' | 'hidden' + Border string `yaml:"border"` + // If true, show a seriously epic explosion animation when nuking the working tree. + AnimateExplosion bool `yaml:"animateExplosion"` } type ThemeConfig struct { - ActiveBorderColor []string `yaml:"activeBorderColor"` - InactiveBorderColor []string `yaml:"inactiveBorderColor"` + // Border color of focused window + ActiveBorderColor []string `yaml:"activeBorderColor"` + // Border color of non-focused windows + InactiveBorderColor []string `yaml:"inactiveBorderColor"` + // Border color of focused window when searching in that window SearchingActiveBorderColor []string `yaml:"searchingActiveBorderColor"` - OptionsTextColor []string `yaml:"optionsTextColor"` - SelectedLineBgColor []string `yaml:"selectedLineBgColor"` - SelectedRangeBgColor []string `yaml:"selectedRangeBgColor"` - CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor"` - CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor"` - MarkedBaseCommitBgColor []string `yaml:"markedBaseCommitBgColor"` - MarkedBaseCommitFgColor []string `yaml:"markedBaseCommitFgColor"` - UnstagedChangesColor []string `yaml:"unstagedChangesColor"` - DefaultFgColor []string `yaml:"defaultFgColor"` + // Color of keybindings help text in the bottom line + OptionsTextColor []string `yaml:"optionsTextColor"` + // Background color of selected line. + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line + SelectedLineBgColor []string `yaml:"selectedLineBgColor"` + // Background color of selected range + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line + SelectedRangeBgColor []string `yaml:"selectedRangeBgColor"` + // Foreground color of copied commit + CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor"` + // Background color of copied commit + CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor"` + // 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"` + // Default text color + DefaultFgColor []string `yaml:"defaultFgColor"` } type CommitLengthConfig struct { + // If true, show an indicator of commit message length Show bool `yaml:"show"` } type GitConfig struct { - Paging PagingConfig `yaml:"paging"` - Commit CommitConfig `yaml:"commit"` - Merging MergingConfig `yaml:"merging"` - MainBranches []string `yaml:"mainBranches"` - SkipHookPrefix string `yaml:"skipHookPrefix"` - AutoFetch bool `yaml:"autoFetch"` - AutoRefresh bool `yaml:"autoRefresh"` - FetchAll bool `yaml:"fetchAll"` - BranchLogCmd string `yaml:"branchLogCmd"` - AllBranchesLogCmd string `yaml:"allBranchesLogCmd"` - OverrideGpg bool `yaml:"overrideGpg"` - DisableForcePushing bool `yaml:"disableForcePushing"` - CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"` - // this should really be under 'gui', not 'git' - ParseEmoji bool `yaml:"parseEmoji"` - Log LogConfig `yaml:"log"` + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md + Paging PagingConfig `yaml:"paging"` + // Config relating to committing + Commit CommitConfig `yaml:"commit"` + // Config relating to merging + Merging MergingConfig `yaml:"merging"` + // list of branches that are considered 'main' branches, used when displaying commits + MainBranches []string `yaml:"mainBranches"` + // 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 + AutoFetch bool `yaml:"autoFetch"` + // If true, periodically refresh files and submodules + AutoRefresh bool `yaml:"autoRefresh"` + // If true, pass the --all arg to git fetch + FetchAll bool `yaml:"fetchAll"` + // Command used when displaying the current branch git log in the main window + BranchLogCmd string `yaml:"branchLogCmd"` + // Command used to display git log of all branches in the main window + AllBranchesLogCmd string `yaml:"allBranchesLogCmd"` + // If true, do not spawn a separate process when using GPG + OverrideGpg bool `yaml:"overrideGpg"` + // If true, do not allow force pushes + DisableForcePushing bool `yaml:"disableForcePushing"` + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix + CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"` + // If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀 + // (This should really be under 'gui', not 'git') + ParseEmoji bool `yaml:"parseEmoji"` + // Config for showing the log in the commits view + Log LogConfig `yaml:"log"` } type PagingConfig struct { - ColorArg string `yaml:"colorArg"` - Pager string `yaml:"pager"` - UseConfig bool `yaml:"useConfig"` + // 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"` + // e.g. + // diff-so-fancy + // delta --dark --paging=never + // ydiff -p cat -s --wrap --width={{columnWidth}} + Pager string `yaml:"pager"` + // 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' ExternalDiffCommand string `yaml:"externalDiffCommand"` } type CommitConfig struct { + // If true, pass '--signoff' flag when committing SignOff bool `yaml:"signOff"` } type MergingConfig struct { - ManualCommit bool `yaml:"manualCommit"` - Args string `yaml:"args"` + // If true, run merges in a subprocess so that if a commit message is required, Lazygit will not hang + // Only applicable to unix users. + ManualCommit bool `yaml:"manualCommit"` + // Extra args passed to `git merge`, e.g. --no-ff + Args string `yaml:"args"` } type LogConfig struct { - Order string `yaml:"order"` // one of date-order, author-date-order, topo-order - ShowGraph string `yaml:"showGraph"` // one of always, never, when-maximised - ShowWholeGraph bool `yaml:"showWholeGraph"` + // One of: 'date-order' | 'author-date-order' | 'topo-order' + // '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"` + // This determines whether the git graph is rendered in the commits panel + // One of 'always' | 'never' 'when-maximised' + ShowGraph string `yaml:"showGraph"` + // 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"` + // Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] " Replace string `yaml:"replace"` } type UpdateConfig struct { + // One of: 'prompt' (default) | 'background' | 'never' Method string `yaml:"method"` - Days int64 `yaml:"days"` + // Period in days between update checks + Days int64 `yaml:"days"` } type KeybindingConfig struct { @@ -367,7 +488,8 @@ type OSConfig struct { // Deprecated: use OpenLink instead. OpenLinkCommand string `yaml:"openLinkCommand,omitempty"` - // CopyToClipboardCmd is the command for copying to clipboard + // CopyToClipboardCmd is the command for copying to clipboard. + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard CopyToClipboardCmd string `yaml:"copyToClipboardCmd,omitempty"` } @@ -376,50 +498,79 @@ type CustomCommandAfterHook struct { } type CustomCommand struct { - Key string `yaml:"key"` - Context string `yaml:"context"` - Command string `yaml:"command"` - Subprocess bool `yaml:"subprocess"` - Prompts []CustomCommandPrompt `yaml:"prompts"` - LoadingText string `yaml:"loadingText"` - Description string `yaml:"description"` - Stream bool `yaml:"stream"` - ShowOutput bool `yaml:"showOutput"` - After CustomCommandAfterHook `yaml:"after"` + // 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"` + // The command to run (using Go template syntax for placeholder values) + Command string `yaml:"command"` + // 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"` + // 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 + Stream bool `yaml:"stream"` + // If true, show the command's output in a popup within Lazygit + ShowOutput bool `yaml:"showOutput"` + // Actions to take after the command has completed + After CustomCommandAfterHook `yaml:"after"` } type CustomCommandPrompt struct { - // one of 'input', 'menu', 'confirm', or 'menuFromCommand' - Type string `yaml:"type"` - Key string `yaml:"key"` + // One of: 'input' | 'menu' | 'confirm' | 'menuFromCommand' + Type string `yaml:"type"` + // 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 + Key string `yaml:"key"` + // The title to display in the popup panel Title string `yaml:"title"` - // these only apply to input prompts - InitialValue string `yaml:"initialValue"` - Suggestions CustomCommandSuggestions `yaml:"suggestions"` + // The initial value to appear in the text box. + // Only for input prompts. + InitialValue string `yaml:"initialValue"` + // Shows suggestions as the input is entered + // Only for input prompts. + Suggestions CustomCommandSuggestions `yaml:"suggestions"` - // this only applies to confirm prompts + // The message of the confirmation prompt. + // Only for confirm prompts. Body string `yaml:"body"` - // this only applies to menus + // Menu options. + // Only for menu prompts. Options []CustomCommandMenuOption - // this only applies to menuFromCommand - Command string `yaml:"command"` - Filter string `yaml:"filter"` + // The command to run to generate menu options + // Only for menuFromCommand prompts. + Command string `yaml:"command"` + // 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"` + // How to format matched groups from the filter to construct a menu item's value. + // Only for menuFromCommand prompts. ValueFormat string `yaml:"valueFormat"` + // Like valueFormat but for the labels. If `labelFormat` is not specified, `valueFormat` is shown instead. + // Only for menuFromCommand prompts. LabelFormat string `yaml:"labelFormat"` } type CustomCommandSuggestions struct { - Preset string `yaml:"preset"` + // Uses built-in logic to obtain the suggestions. One of 'authors' | 'branches' | 'files' | 'refs' | 'remotes' | 'remoteBranches' | 'tags' + Preset string `yaml:"preset"` + // Command to run such that each line in the output becomes a suggestion. Mutually exclusive with 'preset' field. Command string `yaml:"command"` } type CustomCommandMenuOption struct { - Name string `yaml:"name"` + // The first part of the label + Name string `yaml:"name"` + // The second part of the label Description string `yaml:"description"` - Value string `yaml:"value"` + // The value that will be used in the command + Value string `yaml:"value"` } func GetDefaultConfig() *UserConfig {