1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-23 12:18:51 +02:00

Add default lazygit config generation in Config.md from JSON schema (#3565)

- **PR Description**
This uses the JSON schema generated in
https://github.com/jesseduffield/lazygit/pull/3039 to generate and
replace the default lazygit config in Config.md when running `go
generate ./...`

Relevant issue: https://github.com/jesseduffield/lazygit/issues/3441

The generated config contains all the entries that have default values
set in `user_config.go`
This commit is contained in:
Stefan Haller 2024-05-19 14:11:23 +02:00 committed by GitHub
commit b75c177c31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 1393 additions and 517 deletions

View File

@ -29,268 +29,503 @@ to the top of your config file or via [Visual Studio Code settings.json config][
## Default ## Default
<!-- START CONFIG YAML: AUTOMATICALLY GENERATED with `go generate ./..., DO NOT UPDATE MANUALLY -->
```yaml ```yaml
# Config relating to the Lazygit UI
gui: gui:
# stuff relating to the UI # The number of lines you scroll by when scrolling the main window
windowSize: 'normal' # one of 'normal' | 'half' | 'full' default is 'normal' scrollHeight: 2
scrollHeight: 2 # how many lines you scroll by
scrollPastBottom: true # enable scrolling past the bottom # If true, allow scrolling past the bottom of the content in the main window
scrollOffMargin: 2 # how many lines to keep before/after the cursor when it reaches the top/bottom of the view; see 'Scroll-off Margin' section below scrollPastBottom: true
scrollOffBehavior: 'margin' # one of 'margin' | 'jump'; see 'Scroll-off Margin' section below
sidePanelWidth: 0.3333 # number from 0 to 1 # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#scroll-off-margin
expandFocusedSidePanel: false scrollOffMargin: 2
mainPanelSplitMode: 'flexible' # one of 'horizontal' | 'flexible' | 'vertical'
enlargedSideViewLocation: 'left' # one of 'left' | 'top' # One of: 'margin' (default) | 'jump'
language: 'auto' # one of 'auto' | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru' scrollOffBehavior: margin
timeFormat: '02 Jan 06' # https://pkg.go.dev/time#Time.Format
shortTimeFormat: '3:04PM' # 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: true
# 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: 0.3333
# 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: flexible
# How the window is split when in half screen mode (i.e. after hitting '+' once).
# Possible values:
# - 'left': split the window horizontally (side panel on the left, main view on the right)
# - 'top': split the window vertically (side panel on top, main view below)
enlargedSideViewLocation: left
# One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
language: auto
# Format used when displaying time e.g. commit time.
# Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format
timeFormat: 02 Jan 06
# 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: 3:04PM
# Config relating to colors and styles.
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes
theme: theme:
# Border color of focused window
activeBorderColor: activeBorderColor:
- green - green
- bold - bold
# Border color of non-focused windows
inactiveBorderColor: inactiveBorderColor:
- white - default
# Border color of focused window when searching in that window
searchingActiveBorderColor: searchingActiveBorderColor:
- cyan - cyan
- bold - bold
# Color of keybindings help text in the bottom line
optionsTextColor: optionsTextColor:
- blue - blue
# Background color of selected line.
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line
selectedLineBgColor: selectedLineBgColor:
- blue # set to `default` to have no background colour - blue
cherryPickedCommitBgColor:
- cyan # Foreground color of copied commit
cherryPickedCommitFgColor: cherryPickedCommitFgColor:
- blue - blue
# Background color of copied commit
cherryPickedCommitBgColor:
- cyan
# Foreground color of marked base commit (for rebase)
markedBaseCommitFgColor:
- blue
# Background color of marked base commit (for rebase)
markedBaseCommitBgColor:
- yellow
# Color for file with unstaged changes
unstagedChangesColor: unstagedChangesColor:
- red - red
# Default text color
defaultFgColor: defaultFgColor:
- default - default
# Config relating to the commit length indicator
commitLength: commitLength:
# If true, show an indicator of commit message length
show: true show: true
mouseEvents: true
skipDiscardChangeWarning: false # If true, show the '5 of 20' footer at the bottom of list views
skipStashWarning: false showListFooter: true
showFileTree: true # for rendering changes files in a tree format
showListFooter: true # for seeing the '5 of 20' message in list panels # 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: true
# If true, show a random tip in the command log when Lazygit starts
showRandomTip: true showRandomTip: true
showBranchCommitHash: false # show commit hashes alongside branch names
showBottomLine: true # for hiding the bottom information line (unless it has important information to tell you) # If true, show the command log
showPanelJumps: true # for showing the jump-to-panel keybindings as panel subtitles
showCommandLog: true showCommandLog: true
showIcons: false # deprecated: use nerdFontsVersion instead
nerdFontsVersion: "" # nerd fonts version to use ("2" or "3"); empty means don't show nerd font icons # 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.
showFileIcons: true # for hiding file icons in the file views showBottomLine: true
commitHashLength: 8 # length of commit hash in commits view. 0 shows '*' if NF icons aren't enabled
# If true, show jump-to-window keybindings in window titles.
showPanelJumps: true
# Nerd fonts version to use.
# One of: '2' | '3' | empty string (default)
# If empty, do not show icons.
nerdFontsVersion: ""
# If true (default), file icons are shown in the file views. Only relevant if NerdFontsVersion is not empty.
showFileIcons: true
# Length of commit hash in commits view. 0 shows '*' if NF icons aren't on.
commitHashLength: 8
# Height of the command log view
commandLogSize: 8 commandLogSize: 8
splitDiff: 'auto' # one of 'auto' | 'always'
skipRewordInEditorWarning: false # for skipping the confirmation before launching the reword editor # Whether to split the main window when viewing file changes.
border: 'rounded' # one of 'single' | 'double' | 'rounded' | 'hidden' # One of: 'auto' | 'always'
animateExplosion: true # shows an explosion animation when nuking the working tree # If 'auto', only split the main window when a file has both staged and unstaged changes
portraitMode: 'auto' # one of 'auto' | 'never' | 'always' splitDiff: auto
filterMode: 'substring' # one of 'substring' | 'fuzzy'; see 'Filtering' section below
# 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: normal
# Window border style.
# One of 'rounded' (default) | 'single' | 'double' | 'hidden'
border: rounded
# If true, show a seriously epic explosion animation when nuking the working tree.
animateExplosion: true
# Whether to stack UI components on top of each other.
# One of 'auto' (default) | 'always' | 'never'
portraitMode: auto
# How things are filtered when typing '/'.
# One of 'substring' (default) | 'fuzzy'
filterMode: substring
# Config relating to the spinner.
spinner: spinner:
frames: ['|', '/', '-', '\\'] # The frames of the spinner animation.
rate: 50 # spinner rate in milliseconds frames:
statusPanelView: 'dashboard' # one of 'dashboard' | 'allBranchesLog' - '|'
- /
- '-'
- \
# The "speed" of the spinner in milliseconds.
rate: 50
# Status panel view.
# One of 'dashboard' (default) | 'allBranchesLog'
statusPanelView: dashboard
# Config relating to git
git: git:
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md
paging: paging:
# 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: always colorArg: always
useConfig: false
# e.g.
# diff-so-fancy
# delta --dark --paging=never
# ydiff -p cat -s --wrap --width={{columnWidth}}
pager: ""
# e.g. 'difft --color=always'
externalDiffCommand: ""
# Config relating to committing
commit: commit:
signOff: false # Automatic WYSIWYG wrapping of the commit message as you type
autoWrapCommitMessage: true # automatic WYSIWYG wrapping of the commit message as you type autoWrapCommitMessage: true
autoWrapWidth: 72 # if autoWrapCommitMessage is true, the width to wrap to
# If autoWrapCommitMessage is true, the width to wrap to
autoWrapWidth: 72
# Config relating to merging
merging: merging:
# only applicable to unix users # Extra args passed to `git merge`, e.g. --no-ff
manualCommit: false args: ""
# extra args passed to `git merge`, e.g. --no-ff
args: '' # list of branches that are considered 'main' branches, used when displaying commits
mainBranches:
- master
- main
# 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: WIP
# If true, periodically fetch from remote
autoFetch: true
# If true, periodically refresh files and submodules
autoRefresh: true
# If true, pass the --all arg to git fetch
fetchAll: true
# Command used when displaying the current branch git log in the main window
branchLogCmd: git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --
# Command used to display git log of all branches in the main window
allBranchesLogCmd: git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
commitPrefix:
# pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*"
pattern: ""
# Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
replace: ""
# Config for showing the log in the commits view
log: log:
# one of date-order, author-date-order, topo-order or default. # 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 # 'topo-order' makes it easier to read the git log graph, but commits may not
# appear chronologically. See https://git-scm.com/docs/git-log#_commit_ordering # appear chronologically. See https://git-scm.com/docs/
# #
# Deprecated: Configure this with `Log menu -> Commit sort order` (<c-l> in the commits window by default). # Deprecated: Configure this with `Log menu -> Commit sort order` (<c-l> in the commits window by default).
order: 'topo-order' order: topo-order
# one of always, never, when-maximised
# this determines whether the git graph is rendered in the commits panel # This determines whether the git graph is rendered in the commits panel
# One of 'always' | 'never' | 'when-maximised'
# #
# Deprecated: Configure this with `Log menu -> Show git graph` (<c-l> in the commits window by default). # Deprecated: Configure this with `Log menu -> Show git graph` (<c-l> in the commits window by default).
showGraph: 'always' showGraph: always
# displays the whole git graph by default in the commits panel (equivalent to passing the `--all` argument to `git log`)
showWholeGraph: false # When copying commit hashes to the clipboard, truncate them to this
skipHookPrefix: WIP # length. Set to 40 to disable truncation.
# The main branches. We colour commits green if they belong to one of these branches, truncateCopiedCommitHashesTo: 12
# so that you can easily see which commits are unique to your branch (coloured in yellow)
mainBranches: [master, main] # Periodic update checks
autoFetch: true
autoRefresh: true
fetchAll: true # Pass --all flag when running git fetch. Set to false to fetch only origin (or the current branch's upstream remote if there is one)
branchLogCmd: 'git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --'
allBranchesLogCmd: 'git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium'
overrideGpg: false # prevents lazygit from spawning a separate process when using GPG
disableForcePushing: false
parseEmoji: false
truncateCopiedCommitHashesTo: 12 # When copying commit hashes to the clipboard, truncate them to this length. Set to 40 to disable truncation.
os:
copyToClipboardCmd: '' # See 'Custom Command for Copying to Clipboard' section
editPreset: '' # see 'Configuring File Editing' section
edit: ''
editAtLine: ''
editAtLineAndWait: ''
open: ''
openLink: ''
refresher:
refreshInterval: 10 # File/submodule refresh interval in seconds. Auto-refresh can be disabled via option 'git.autoRefresh'.
fetchInterval: 60 # Re-fetch interval in seconds. Auto-fetch can be disabled via option 'git.autoFetch'.
update: update:
method: prompt # can be: prompt | background | never # One of: 'prompt' (default) | 'background' | 'never'
days: 14 # how often an update is checked for method: prompt
confirmOnQuit: false
# determines whether hitting 'esc' will quit the application when there is nothing to cancel/close # Period in days between update checks
quitOnTopLevelReturn: false days: 14
disableStartupPopups: false
notARepository: 'prompt' # one of: 'prompt' | 'create' | 'skip' | 'quit' # Background refreshes
promptToReturnFromSubprocess: true # display confirmation when subprocess terminates refresher:
# File/submodule refresh interval in seconds.
# Auto-refresh can be disabled via option 'git.autoRefresh'.
refreshInterval: 10
# Re-fetch interval in seconds.
# Auto-fetch can be disabled via option 'git.autoFetch'.
fetchInterval: 60
# Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc
os:
# Command for editing a file. Should contain "{{filename}}".
edit: ""
# Command for editing a file at a given line number. Should contain
# "{{filename}}", and may optionally contain "{{line}}".
editAtLine: ""
# Same as EditAtLine, except that the command needs to wait until the
# window is closed.
editAtLineAndWait: ""
# For opening a directory in an editor
openDirInEditor: ""
# A built-in preset that sets all of the above settings. Supported presets
# are defined in the getPreset function in editor_presets.go.
editPreset: ""
# Command for opening a file, as if the file is double-clicked. Should
# contain "{{filename}}", but doesn't support "{{line}}".
open: ""
# Command for opening a link. Should contain "{{link}}".
openLink: ""
# EditCommand is the command for editing a file.
# Deprecated: use Edit instead. Note that semantics are different:
# EditCommand is just the command itself, whereas Edit contains a
# "{{filename}}" variable.
editCommand: ""
# EditCommandTemplate is the command template for editing a file
# Deprecated: use EditAtLine instead.
editCommandTemplate: ""
# OpenCommand is the command for opening a file
# Deprecated: use Open instead.
openCommand: ""
# OpenLinkCommand is the command for opening a link
# Deprecated: use OpenLink instead.
openLinkCommand: ""
# 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: ""
# 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: prompt
# If true, display a confirmation when subprocess terminates. This allows you to view the output of the subprocess before returning to Lazygit.
promptToReturnFromSubprocess: true
# Keybindings
keybinding: keybinding:
universal: universal:
quit: 'q' quit: q
quit-alt1: '<c-c>' # alternative/alias of quit quit-alt1: <c-c>
return: '<esc>' # return to previous menu, will quit if there's nowhere to return return: <esc>
quitWithoutChangingDirectory: 'Q' quitWithoutChangingDirectory: Q
togglePanel: '<tab>' # goto the next panel togglePanel: <tab>
prevItem: '<up>' # go one line up prevItem: <up>
nextItem: '<down>' # go one line down nextItem: <down>
prevItem-alt: 'k' # go one line up prevItem-alt: k
nextItem-alt: 'j' # go one line down nextItem-alt: j
prevPage: ',' # go to next page in list prevPage: ','
nextPage: '.' # go to previous page in list nextPage: .
gotoTop: '<' # go to top of list scrollLeft: H
gotoBottom: '>' # go to bottom of list scrollRight: L
scrollLeft: 'H' # scroll left within list view gotoTop: <
scrollRight: 'L' # scroll right within list view gotoBottom: '>'
prevBlock: '<left>' # goto the previous block / panel toggleRangeSelect: v
nextBlock: '<right>' # goto the next block / panel rangeSelectDown: <s-down>
prevBlock-alt: 'h' # goto the previous block / panel rangeSelectUp: <s-up>
nextBlock-alt: 'l' # goto the next block / panel prevBlock: <left>
jumpToBlock: ['1', '2', '3', '4', '5'] # goto the Nth block / panel nextBlock: <right>
nextMatch: 'n' prevBlock-alt: h
prevMatch: 'N' nextBlock-alt: l
optionMenu: <disabled> # show help menu nextBlock-alt2: <tab>
optionMenu-alt1: '?' # show help menu prevBlock-alt2: <backtab>
select: '<space>' jumpToBlock:
goInto: '<enter>' - "1"
openRecentRepos: '<c-r>' - "2"
confirm: '<enter>' - "3"
remove: 'd' - "4"
new: 'n' - "5"
edit: 'e' nextMatch: "n"
openFile: 'o' prevMatch: "N"
scrollUpMain: '<pgup>' # main panel scroll up startSearch: /
scrollDownMain: '<pgdown>' # main panel scroll down optionMenu: <disabled>
scrollUpMain-alt1: 'K' # main panel scroll up optionMenu-alt1: '?'
scrollDownMain-alt1: 'J' # main panel scroll down select: <space>
scrollUpMain-alt2: '<c-u>' # main panel scroll up goInto: <enter>
scrollDownMain-alt2: '<c-d>' # main panel scroll down confirm: <enter>
confirmInEditor: <a-enter>
remove: d
new: "n"
edit: e
openFile: o
scrollUpMain: <pgup>
scrollDownMain: <pgdown>
scrollUpMain-alt1: K
scrollDownMain-alt1: J
scrollUpMain-alt2: <c-u>
scrollDownMain-alt2: <c-d>
executeCustomCommand: ':' executeCustomCommand: ':'
createRebaseOptionsMenu: 'm' createRebaseOptionsMenu: m
pushFiles: 'P'
pullFiles: 'p' # 'Files' appended for legacy reasons
refresh: 'R' pushFiles: P
createPatchOptionsMenu: '<c-p>'
# 'Files' appended for legacy reasons
pullFiles: p
refresh: R
createPatchOptionsMenu: <c-p>
nextTab: ']' nextTab: ']'
prevTab: '[' prevTab: '['
nextScreenMode: '+' nextScreenMode: +
prevScreenMode: '_' prevScreenMode: _
undo: 'z' undo: z
redo: '<c-z>' redo: <c-z>
filteringMenu: '<c-s>' filteringMenu: <c-s>
diffingMenu: 'W' diffingMenu: W
diffingMenu-alt: '<c-e>' # deprecated diffingMenu-alt: <c-e>
copyToClipboard: '<c-o>' copyToClipboard: <c-o>
submitEditorText: '<enter>' openRecentRepos: <c-r>
submitEditorText: <enter>
extrasMenu: '@' extrasMenu: '@'
toggleWhitespaceInDiffView: '<c-w>' toggleWhitespaceInDiffView: <c-w>
increaseContextInDiffView: '}' increaseContextInDiffView: '}'
decreaseContextInDiffView: '{' decreaseContextInDiffView: '{'
toggleRangeSelect: 'v' openDiffTool: <c-t>
rangeSelectUp: '<s-up>'
rangeSelectDown: '<s-down>'
status: status:
checkForUpdate: 'u' checkForUpdate: u
recentRepos: '<enter>' recentRepos: <enter>
allBranchesLogGraph: a
files: files:
commitChanges: 'c' commitChanges: c
commitChangesWithoutHook: 'w' # commit changes without pre-commit hook commitChangesWithoutHook: w
amendLastCommit: 'A' amendLastCommit: A
commitChangesWithEditor: 'C' commitChangesWithEditor: C
findBaseCommitForFixup: '<c-f>' findBaseCommitForFixup: <c-f>
confirmDiscard: 'x' confirmDiscard: x
ignoreFile: 'i' ignoreFile: i
refreshFiles: 'r' refreshFiles: r
stashAllChanges: 's' stashAllChanges: s
viewStashOptions: 'S' viewStashOptions: S
toggleStagedAll: 'a' # stage/unstage all toggleStagedAll: a
viewResetOptions: 'D' viewResetOptions: D
fetch: 'f' fetch: f
toggleTreeView: '`' toggleTreeView: '`'
openMergeTool: 'M' openMergeTool: M
openStatusFilter: '<c-b>' openStatusFilter: <c-b>
copyFileInfoToClipboard: "y"
branches: branches:
createPullRequest: 'o' createPullRequest: o
viewPullRequestOptions: 'O' viewPullRequestOptions: O
checkoutBranchByName: 'c' copyPullRequestURL: <c-y>
forceCheckoutBranch: 'F' checkoutBranchByName: c
rebaseBranch: 'r' forceCheckoutBranch: F
renameBranch: 'R' rebaseBranch: r
mergeIntoCurrentBranch: 'M' renameBranch: R
viewGitFlowOptions: 'i' mergeIntoCurrentBranch: M
fastForward: 'f' # fast-forward this branch from its upstream viewGitFlowOptions: i
createTag: 'T' fastForward: f
pushTag: 'P' createTag: T
setUpstream: 'u' # set as upstream of checked-out branch pushTag: P
fetchRemote: 'f' setUpstream: u
fetchRemote: f
sortOrder: s
worktrees:
viewWorktreeOptions: w
commits: commits:
squashDown: 's' squashDown: s
renameCommit: 'r' renameCommit: r
renameCommitWithEditor: 'R' renameCommitWithEditor: R
viewResetOptions: 'g' viewResetOptions: g
markCommitAsFixup: 'f' markCommitAsFixup: f
createFixupCommit: 'F' # create fixup commit for this commit createFixupCommit: F
squashAboveCommits: 'S' squashAboveCommits: S
moveDownCommit: '<c-j>' # move commit down one moveDownCommit: <c-j>
moveUpCommit: '<c-k>' # move commit up one moveUpCommit: <c-k>
amendToCommit: 'A' amendToCommit: A
amendAttributeMenu: 'a' resetCommitAuthor: a
pickCommit: 'p' # pick commit (when mid-rebase) pickCommit: p
revertCommit: 't' revertCommit: t
cherryPickCopy: 'C' cherryPickCopy: C
pasteCommits: 'V' pasteCommits: V
tagCommit: 'T' markCommitAsBaseForRebase: B
checkoutCommit: '<space>' tagCommit: T
resetCherryPick: '<c-R>' checkoutCommit: <space>
copyCommitMessageToClipboard: '<c-y>' resetCherryPick: <c-R>
openLogMenu: '<c-l>' copyCommitAttributeToClipboard: "y"
viewBisectOptions: 'b' openLogMenu: <c-l>
stash: openInBrowser: o
popStash: 'g' viewBisectOptions: b
renameStash: 'r' startInteractiveRebase: i
commitFiles:
checkoutCommitFile: 'c'
main:
toggleSelectHunk: 'a'
pickBothHunks: 'b'
submodules:
init: 'i'
update: 'u'
bulkMenu: 'b'
commitMessage:
commitMenu: '<c-o>'
amendAttribute: amendAttribute:
addCoAuthor: 'c' resetAuthor: a
resetAuthor: 'a' setAuthor: A
setAuthor: 'A' addCoAuthor: c
stash:
popStash: g
renameStash: r
commitFiles:
checkoutCommitFile: c
main:
toggleSelectHunk: a
pickBothHunks: b
editSelectHunk: E
submodules:
init: i
update: u
bulkMenu: b
commitMessage:
commitMenu: <c-o>
``` ```
<!-- END CONFIG YAML -->
## Platform Defaults ## Platform Defaults

1
go.mod
View File

@ -11,6 +11,7 @@ require (
github.com/gdamore/tcell/v2 v2.7.4 github.com/gdamore/tcell/v2 v2.7.4
github.com/go-errors/errors v1.5.1 github.com/go-errors/errors v1.5.1
github.com/gookit/color v1.4.2 github.com/gookit/color v1.4.2
github.com/iancoleman/orderedmap v0.3.0
github.com/imdario/mergo v0.3.11 github.com/imdario/mergo v0.3.11
github.com/integrii/flaggy v1.4.0 github.com/integrii/flaggy v1.4.0
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68

2
go.sum
View File

@ -171,6 +171,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/orderedmap v0.3.0 h1:5cbR2grmZR/DiVt+VJopEhtVs9YGInGIxAoMJn+Ichc=
github.com/iancoleman/orderedmap v0.3.0/go.mod h1:XuLcCUkdL5owUCQeF2Ue9uuw1EptkJDkXXS7VoV7XGE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=

View File

@ -19,8 +19,6 @@ type UserConfig struct {
ConfirmOnQuit bool `yaml:"confirmOnQuit"` ConfirmOnQuit bool `yaml:"confirmOnQuit"`
// If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close // If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close
QuitOnTopLevelReturn bool `yaml:"quitOnTopLevelReturn"` 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 // Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc
OS OSConfig `yaml:"os,omitempty"` OS OSConfig `yaml:"os,omitempty"`
// If true, don't display introductory popups upon opening Lazygit. // If true, don't display introductory popups upon opening Lazygit.
@ -38,6 +36,8 @@ type UserConfig struct {
NotARepository string `yaml:"notARepository" jsonschema:"enum=prompt,enum=create,enum=skip,enum=quit"` 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. // 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"` PromptToReturnFromSubprocess bool `yaml:"promptToReturnFromSubprocess"`
// Keybindings
Keybinding KeybindingConfig `yaml:"keybinding"`
} }
type RefresherConfig struct { type RefresherConfig struct {
@ -252,7 +252,7 @@ type PagingConfig struct {
// diff-so-fancy // diff-so-fancy
// delta --dark --paging=never // delta --dark --paging=never
// ydiff -p cat -s --wrap --width={{columnWidth}} // ydiff -p cat -s --wrap --width={{columnWidth}}
Pager PagerType `yaml:"pager" jsonschema:"minLength=1"` Pager PagerType `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). // 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"` UseConfig bool `yaml:"useConfig"`
// e.g. 'difft --color=always' // e.g. 'difft --color=always'
@ -294,9 +294,9 @@ type LogConfig struct {
type CommitPrefixConfig struct { type CommitPrefixConfig struct {
// pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*" // pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*"
Pattern string `yaml:"pattern" jsonschema:"example=^\\w+\\/(\\w+-\\w+).*,minLength=1"` Pattern string `yaml:"pattern" jsonschema:"example=^\\w+\\/(\\w+-\\w+).*"`
// Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] " // Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
Replace string `yaml:"replace" jsonschema:"example=[$1] ,minLength=1"` Replace string `yaml:"replace" jsonschema:"example=[$1]"`
} }
type UpdateConfig struct { type UpdateConfig struct {
@ -684,6 +684,7 @@ func GetDefaultConfig() *UserConfig {
CommandLogSize: 8, CommandLogSize: 8,
SplitDiff: "auto", SplitDiff: "auto",
SkipRewordInEditorWarning: false, SkipRewordInEditorWarning: false,
WindowSize: "normal",
Border: "rounded", Border: "rounded",
AnimateExplosion: true, AnimateExplosion: true,
PortraitMode: "auto", PortraitMode: "auto",
@ -737,6 +738,12 @@ func GetDefaultConfig() *UserConfig {
}, },
ConfirmOnQuit: false, ConfirmOnQuit: false,
QuitOnTopLevelReturn: false, QuitOnTopLevelReturn: false,
OS: OSConfig{},
DisableStartupPopups: false,
CustomCommands: []CustomCommand(nil),
Services: map[string]string(nil),
NotARepository: "prompt",
PromptToReturnFromSubprocess: true,
Keybinding: KeybindingConfig{ Keybinding: KeybindingConfig{
Universal: KeybindingUniversalConfig{ Universal: KeybindingUniversalConfig{
Quit: "q", Quit: "q",
@ -903,11 +910,5 @@ func GetDefaultConfig() *UserConfig {
CommitMenu: "<c-o>", CommitMenu: "<c-o>",
}, },
}, },
OS: OSConfig{},
DisableStartupPopups: false,
CustomCommands: []CustomCommand(nil),
Services: map[string]string(nil),
NotARepository: "prompt",
PromptToReturnFromSubprocess: true,
} }
} }

View File

@ -0,0 +1,269 @@
package jsonschema
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
"github.com/iancoleman/orderedmap"
"github.com/jesseduffield/lazycore/pkg/utils"
"github.com/samber/lo"
"gopkg.in/yaml.v3"
)
type Node struct {
Name string
Description string
Default any
Children []*Node
}
const (
IndentLevel = 2
DocumentationCommentStart = "<!-- START CONFIG YAML: AUTOMATICALLY GENERATED with `go generate ./..., DO NOT UPDATE MANUALLY -->\n"
DocumentationCommentEnd = "<!-- END CONFIG YAML -->"
DocumentationCommentStartLen = len(DocumentationCommentStart)
)
func insertBlankLines(buffer bytes.Buffer) bytes.Buffer {
lines := strings.Split(strings.TrimRight(buffer.String(), "\n"), "\n")
var newBuffer bytes.Buffer
previousIndent := -1
wasComment := false
for _, line := range lines {
trimmedLine := strings.TrimLeft(line, " ")
indent := len(line) - len(trimmedLine)
isComment := strings.HasPrefix(trimmedLine, "#")
if isComment && !wasComment && indent <= previousIndent {
newBuffer.WriteString("\n")
}
newBuffer.WriteString(line)
newBuffer.WriteString("\n")
previousIndent = indent
wasComment = isComment
}
return newBuffer
}
func prepareMarshalledConfig(buffer bytes.Buffer) []byte {
buffer = insertBlankLines(buffer)
// Remove all `---` lines
lines := strings.Split(strings.TrimRight(buffer.String(), "\n"), "\n")
var newBuffer bytes.Buffer
for _, line := range lines {
if strings.TrimSpace(line) != "---" {
newBuffer.WriteString(line)
newBuffer.WriteString("\n")
}
}
config := newBuffer.Bytes()
// Add markdown yaml block tag
config = append([]byte("```yaml\n"), config...)
config = append(config, []byte("```\n")...)
return config
}
func setComment(yamlNode *yaml.Node, description string) {
// Workaround for the way yaml formats the HeadComment if it contains
// blank lines: it renders these without a leading "#", but we want a
// leading "#" even on blank lines. However, yaml respects it if the
// HeadComment already contains a leading "#", so we prefix all lines
// (including blank ones) with "#".
yamlNode.HeadComment = strings.Join(
lo.Map(strings.Split(description, "\n"), func(s string, _ int) string {
if s == "" {
return "#" // avoid trailing space on blank lines
}
return "# " + s
}),
"\n")
}
func (n *Node) MarshalYAML() (interface{}, error) {
node := yaml.Node{
Kind: yaml.MappingNode,
}
keyNode := yaml.Node{
Kind: yaml.ScalarNode,
Value: n.Name,
}
if n.Description != "" {
setComment(&keyNode, n.Description)
}
if n.Default != nil {
valueNode := yaml.Node{
Kind: yaml.ScalarNode,
}
err := valueNode.Encode(n.Default)
if err != nil {
return nil, err
}
node.Content = append(node.Content, &keyNode, &valueNode)
} else if len(n.Children) > 0 {
childrenNode := yaml.Node{
Kind: yaml.MappingNode,
}
for _, child := range n.Children {
childYaml, err := child.MarshalYAML()
if err != nil {
return nil, err
}
childKey := yaml.Node{
Kind: yaml.ScalarNode,
Value: child.Name,
}
if child.Description != "" {
setComment(&childKey, child.Description)
}
childYaml = childYaml.(*yaml.Node)
childrenNode.Content = append(childrenNode.Content, childYaml.(*yaml.Node).Content...)
}
node.Content = append(node.Content, &keyNode, &childrenNode)
}
return &node, nil
}
func getDescription(v *orderedmap.OrderedMap) string {
description, ok := v.Get("description")
if !ok {
description = ""
}
return description.(string)
}
func getDefault(v *orderedmap.OrderedMap) (error, any) {
defaultValue, ok := v.Get("default")
if ok {
return nil, defaultValue
}
dataType, ok := v.Get("type")
if ok {
dataTypeString := dataType.(string)
if dataTypeString == "string" {
return nil, ""
}
}
return errors.New("Failed to get default value"), nil
}
func parseNode(parent *Node, name string, value *orderedmap.OrderedMap) {
description := getDescription(value)
err, defaultValue := getDefault(value)
if err == nil {
leaf := &Node{Name: name, Description: description, Default: defaultValue}
parent.Children = append(parent.Children, leaf)
}
properties, ok := value.Get("properties")
if !ok {
return
}
orderedProperties := properties.(orderedmap.OrderedMap)
node := &Node{Name: name, Description: description}
parent.Children = append(parent.Children, node)
keys := orderedProperties.Keys()
for _, name := range keys {
value, _ := orderedProperties.Get(name)
typedValue := value.(orderedmap.OrderedMap)
parseNode(node, name, &typedValue)
}
}
func writeToConfigDocs(config []byte) error {
configPath := utils.GetLazyRootDirectory() + "/docs/Config.md"
markdown, err := os.ReadFile(configPath)
if err != nil {
return fmt.Errorf("Error reading Config.md file %w", err)
}
startConfigSectionIndex := bytes.Index(markdown, []byte(DocumentationCommentStart))
if startConfigSectionIndex == -1 {
return errors.New("Default config starting comment not found")
}
endConfigSectionIndex := bytes.Index(markdown[startConfigSectionIndex+DocumentationCommentStartLen:], []byte(DocumentationCommentEnd))
if endConfigSectionIndex == -1 {
return errors.New("Default config closing comment not found")
}
endConfigSectionIndex = endConfigSectionIndex + startConfigSectionIndex + DocumentationCommentStartLen
newMarkdown := make([]byte, 0, len(markdown)-endConfigSectionIndex+startConfigSectionIndex+len(config))
newMarkdown = append(newMarkdown, markdown[:startConfigSectionIndex+DocumentationCommentStartLen]...)
newMarkdown = append(newMarkdown, config...)
newMarkdown = append(newMarkdown, markdown[endConfigSectionIndex:]...)
if err := os.WriteFile(configPath, newMarkdown, 0o644); err != nil {
return fmt.Errorf("Error writing to file %w", err)
}
return nil
}
func GenerateConfigDocs() {
content, err := os.ReadFile(GetSchemaDir() + "/config.json")
if err != nil {
panic("Error reading config.json")
}
schema := orderedmap.New()
err = json.Unmarshal(content, &schema)
if err != nil {
panic("Failed to unmarshal config.json")
}
root, ok := schema.Get("properties")
if !ok {
panic("properties key not found in schema")
}
orderedRoot := root.(orderedmap.OrderedMap)
rootNode := Node{}
for _, name := range orderedRoot.Keys() {
value, _ := orderedRoot.Get(name)
typedValue := value.(orderedmap.OrderedMap)
parseNode(&rootNode, name, &typedValue)
}
var buffer bytes.Buffer
encoder := yaml.NewEncoder(&buffer)
encoder.SetIndent(IndentLevel)
for _, child := range rootNode.Children {
err := encoder.Encode(child)
if err != nil {
panic("Failed to Marshal document")
}
}
encoder.Close()
config := prepareMarshalledConfig(buffer)
err = writeToConfigDocs(config)
if err != nil {
panic(err)
}
}

View File

@ -11,4 +11,5 @@ import (
func main() { func main() {
fmt.Printf("Generating jsonschema in %s...\n", jsonschema.GetSchemaDir()) fmt.Printf("Generating jsonschema in %s...\n", jsonschema.GetSchemaDir())
jsonschema.GenerateSchema() jsonschema.GenerateSchema()
jsonschema.GenerateConfigDocs()
} }

View File

@ -341,7 +341,8 @@
"half", "half",
"full" "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'" "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'",
"default": "normal"
}, },
"border": { "border": {
"type": "string", "type": "string",
@ -428,7 +429,6 @@
}, },
"pager": { "pager": {
"type": "string", "type": "string",
"minLength": 1,
"description": "e.g.\ndiff-so-fancy\ndelta --dark --paging=never\nydiff -p cat -s --wrap --width={{columnWidth}}", "description": "e.g.\ndiff-so-fancy\ndelta --dark --paging=never\nydiff -p cat -s --wrap --width={{columnWidth}}",
"default": "", "default": "",
"examples": [ "examples": [
@ -543,7 +543,6 @@
"properties": { "properties": {
"pattern": { "pattern": {
"type": "string", "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+).*\"", "description": "pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use \"^\\\\w+\\\\/(\\\\w+-\\\\w+).*\"",
"examples": [ "examples": [
"^\\w+\\/(\\w+-\\w+).*" "^\\w+\\/(\\w+-\\w+).*"
@ -551,7 +550,6 @@
}, },
"replace": { "replace": {
"type": "string", "type": "string",
"minLength": 1,
"description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"", "description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"",
"examples": [ "examples": [
"[$1]" "[$1]"
@ -567,7 +565,6 @@
"properties": { "properties": {
"pattern": { "pattern": {
"type": "string", "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+).*\"", "description": "pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use \"^\\\\w+\\\\/(\\\\w+-\\\\w+).*\"",
"examples": [ "examples": [
"^\\w+\\/(\\w+-\\w+).*" "^\\w+\\/(\\w+-\\w+).*"
@ -575,7 +572,6 @@
}, },
"replace": { "replace": {
"type": "string", "type": "string",
"minLength": 1,
"description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"", "description": "Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use \"[$1] \"",
"examples": [ "examples": [
"[$1]" "[$1]"
@ -684,6 +680,291 @@
"type": "boolean", "type": "boolean",
"description": "If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close" "description": "If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close"
}, },
"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
},
"keybinding": { "keybinding": {
"properties": { "properties": {
"universal": { "universal": {
@ -1333,291 +1614,6 @@
"additionalProperties": false, "additionalProperties": false,
"type": "object", "type": "object",
"description": "Keybindings" "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, "additionalProperties": false,

21
vendor/github.com/iancoleman/orderedmap/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Ian Coleman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, Subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or Substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

266
vendor/github.com/iancoleman/orderedmap/orderedmap.go generated vendored Normal file
View File

@ -0,0 +1,266 @@
package orderedmap
import (
"bytes"
"encoding/json"
"sort"
)
type Pair struct {
key string
value interface{}
}
func (kv *Pair) Key() string {
return kv.key
}
func (kv *Pair) Value() interface{} {
return kv.value
}
type ByPair struct {
Pairs []*Pair
LessFunc func(a *Pair, j *Pair) bool
}
func (a ByPair) Len() int { return len(a.Pairs) }
func (a ByPair) Swap(i, j int) { a.Pairs[i], a.Pairs[j] = a.Pairs[j], a.Pairs[i] }
func (a ByPair) Less(i, j int) bool { return a.LessFunc(a.Pairs[i], a.Pairs[j]) }
type OrderedMap struct {
keys []string
values map[string]interface{}
escapeHTML bool
}
func New() *OrderedMap {
o := OrderedMap{}
o.keys = []string{}
o.values = map[string]interface{}{}
o.escapeHTML = true
return &o
}
func (o *OrderedMap) SetEscapeHTML(on bool) {
o.escapeHTML = on
}
func (o *OrderedMap) Get(key string) (interface{}, bool) {
val, exists := o.values[key]
return val, exists
}
func (o *OrderedMap) Set(key string, value interface{}) {
_, exists := o.values[key]
if !exists {
o.keys = append(o.keys, key)
}
o.values[key] = value
}
func (o *OrderedMap) Delete(key string) {
// check key is in use
_, ok := o.values[key]
if !ok {
return
}
// remove from keys
for i, k := range o.keys {
if k == key {
o.keys = append(o.keys[:i], o.keys[i+1:]...)
break
}
}
// remove from values
delete(o.values, key)
}
func (o *OrderedMap) Keys() []string {
return o.keys
}
func (o *OrderedMap) Values() map[string]interface{} {
return o.values
}
// SortKeys Sort the map keys using your sort func
func (o *OrderedMap) SortKeys(sortFunc func(keys []string)) {
sortFunc(o.keys)
}
// Sort Sort the map using your sort func
func (o *OrderedMap) Sort(lessFunc func(a *Pair, b *Pair) bool) {
pairs := make([]*Pair, len(o.keys))
for i, key := range o.keys {
pairs[i] = &Pair{key, o.values[key]}
}
sort.Sort(ByPair{pairs, lessFunc})
for i, pair := range pairs {
o.keys[i] = pair.key
}
}
func (o *OrderedMap) UnmarshalJSON(b []byte) error {
if o.values == nil {
o.values = map[string]interface{}{}
}
err := json.Unmarshal(b, &o.values)
if err != nil {
return err
}
dec := json.NewDecoder(bytes.NewReader(b))
if _, err = dec.Token(); err != nil { // skip '{'
return err
}
o.keys = make([]string, 0, len(o.values))
return decodeOrderedMap(dec, o)
}
func decodeOrderedMap(dec *json.Decoder, o *OrderedMap) error {
hasKey := make(map[string]bool, len(o.values))
for {
token, err := dec.Token()
if err != nil {
return err
}
if delim, ok := token.(json.Delim); ok && delim == '}' {
return nil
}
key := token.(string)
if hasKey[key] {
// duplicate key
for j, k := range o.keys {
if k == key {
copy(o.keys[j:], o.keys[j+1:])
break
}
}
o.keys[len(o.keys)-1] = key
} else {
hasKey[key] = true
o.keys = append(o.keys, key)
}
token, err = dec.Token()
if err != nil {
return err
}
if delim, ok := token.(json.Delim); ok {
switch delim {
case '{':
if values, ok := o.values[key].(map[string]interface{}); ok {
newMap := OrderedMap{
keys: make([]string, 0, len(values)),
values: values,
escapeHTML: o.escapeHTML,
}
if err = decodeOrderedMap(dec, &newMap); err != nil {
return err
}
o.values[key] = newMap
} else if oldMap, ok := o.values[key].(OrderedMap); ok {
newMap := OrderedMap{
keys: make([]string, 0, len(oldMap.values)),
values: oldMap.values,
escapeHTML: o.escapeHTML,
}
if err = decodeOrderedMap(dec, &newMap); err != nil {
return err
}
o.values[key] = newMap
} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
return err
}
case '[':
if values, ok := o.values[key].([]interface{}); ok {
if err = decodeSlice(dec, values, o.escapeHTML); err != nil {
return err
}
} else if err = decodeSlice(dec, []interface{}{}, o.escapeHTML); err != nil {
return err
}
}
}
}
}
func decodeSlice(dec *json.Decoder, s []interface{}, escapeHTML bool) error {
for index := 0; ; index++ {
token, err := dec.Token()
if err != nil {
return err
}
if delim, ok := token.(json.Delim); ok {
switch delim {
case '{':
if index < len(s) {
if values, ok := s[index].(map[string]interface{}); ok {
newMap := OrderedMap{
keys: make([]string, 0, len(values)),
values: values,
escapeHTML: escapeHTML,
}
if err = decodeOrderedMap(dec, &newMap); err != nil {
return err
}
s[index] = newMap
} else if oldMap, ok := s[index].(OrderedMap); ok {
newMap := OrderedMap{
keys: make([]string, 0, len(oldMap.values)),
values: oldMap.values,
escapeHTML: escapeHTML,
}
if err = decodeOrderedMap(dec, &newMap); err != nil {
return err
}
s[index] = newMap
} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
return err
}
} else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil {
return err
}
case '[':
if index < len(s) {
if values, ok := s[index].([]interface{}); ok {
if err = decodeSlice(dec, values, escapeHTML); err != nil {
return err
}
} else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil {
return err
}
} else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil {
return err
}
case ']':
return nil
}
}
}
}
func (o OrderedMap) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
buf.WriteByte('{')
encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(o.escapeHTML)
for i, k := range o.keys {
if i > 0 {
buf.WriteByte(',')
}
// add key
if err := encoder.Encode(k); err != nil {
return nil, err
}
buf.WriteByte(':')
// add value
if err := encoder.Encode(o.values[k]); err != nil {
return nil, err
}
}
buf.WriteByte('}')
return buf.Bytes(), nil
}

81
vendor/github.com/iancoleman/orderedmap/readme.md generated vendored Normal file
View File

@ -0,0 +1,81 @@
# orderedmap
[![Build Status](https://travis-ci.com/iancoleman/orderedmap.svg)](https://travis-ci.com/iancoleman/orderedmap)
A golang data type equivalent to python's collections.OrderedDict
Retains order of keys in maps
Can be JSON serialized / deserialized
# Usage
```go
package main
import (
"encoding/json"
"github.com/iancoleman/orderedmap"
)
func main() {
// use New() instead of o := map[string]interface{}{}
o := orderedmap.New()
// use SetEscapeHTML() to whether escape problematic HTML characters or not, defaults is true
o.SetEscapeHTML(false)
// use Set instead of o["a"] = 1
o.Set("a", 1)
// add some value with special characters
o.Set("b", "\\.<>[]{}_-")
// use Get instead of i, ok := o["a"]
val, ok := o.Get("a")
// use Keys instead of for k, v := range o
keys := o.Keys()
for _, k := range keys {
v, _ := o.Get(k)
}
// use o.Delete instead of delete(o, key)
o.Delete("a")
// serialize to a json string using encoding/json
bytes, err := json.Marshal(o)
prettyBytes, err := json.MarshalIndent(o, "", " ")
// deserialize a json string using encoding/json
// all maps (including nested maps) will be parsed as orderedmaps
s := `{"a": 1}`
err := json.Unmarshal([]byte(s), &o)
// sort the keys
o.SortKeys(sort.Strings)
// sort by Pair
o.Sort(func(a *orderedmap.Pair, b *orderedmap.Pair) bool {
return a.Value().(float64) < b.Value().(float64)
})
}
```
# Caveats
* OrderedMap only takes strings for the key, as per [the JSON spec](http://json.org/).
# Tests
```
go test
```
# Alternatives
None of the alternatives offer JSON serialization.
* [cevaris/ordered_map](https://github.com/cevaris/ordered_map)
* [mantyr/iterator](https://github.com/mantyr/iterator)

3
vendor/modules.txt vendored
View File

@ -110,6 +110,9 @@ github.com/gobwas/glob/util/strings
# github.com/gookit/color v1.4.2 # github.com/gookit/color v1.4.2
## explicit; go 1.12 ## explicit; go 1.12
github.com/gookit/color github.com/gookit/color
# github.com/iancoleman/orderedmap v0.3.0
## explicit; go 1.16
github.com/iancoleman/orderedmap
# github.com/imdario/mergo v0.3.11 # github.com/imdario/mergo v0.3.11
## explicit; go 1.13 ## explicit; go 1.13
github.com/imdario/mergo github.com/imdario/mergo