diff --git a/docs/Config.md b/docs/Config.md index 857a4e359..d35455c84 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -37,12 +37,6 @@ This is only meant as a reference for what config options exist, and what their ```yaml # Config relating to the Lazygit UI gui: - # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color - authorColors: {} - - # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color - branchColorPatterns: {} - # Custom icons for filenames and file extensions # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color customIcons: @@ -78,7 +72,7 @@ gui: # If true, do not show a warning when amending a commit. skipAmendWarning: false - # If true, do not show a warning when discarding changes in the staging view. + # If true, do not show a warning when discarding changes from a focused diff. skipDiscardChangeWarning: false # If true, do not show warning when applying/popping the stash @@ -148,14 +142,13 @@ gui: # - 'top': split the window vertically (side panel on top, main view below) enlargedSideViewLocation: left - # If true, wrap lines in the staging view to the width of the view. This makes - # it much easier to work with diffs that have long lines, e.g. paragraphs of + # If true, wrap lines in focused diffs to the width of the view. This makes it + # much easier to work with diffs that have long lines, e.g. paragraphs of # markdown text. - wrapLinesInStagingView: true + wrapLinesInDiffView: true - # If true, hunk selection mode will be enabled by default when entering the - # staging view. - useHunkModeInStagingView: true + # If true, hunk selection mode will be enabled by default when focusing a diff. + useHunkModeInDiffView: true # One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' # | 'ru' | 'pt' @@ -169,6 +162,14 @@ gui: # Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format shortTimeFormat: 3:04PM + # Whether the terminal has a dark or a light background. This decides whether + # 'darkTheme' or 'lightTheme' applies, and the colors of authors are picked to + # stand out against it. + # One of: 'auto' (default) | 'dark' | 'light' + # With 'auto', lazygit asks the terminal, and assumes a dark background if the + # terminal doesn't tell. + colorScheme: auto + # Config relating to colors and styles. # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes theme: @@ -190,14 +191,22 @@ gui: optionsTextColor: - blue + # Color and attributes of the text of the selected line. The attributes are + # added to those of the text, and a color replaces the colors of the text. + # Set it to 'default' to leave the text as it is, e.g. if you don't want the + # selected line in bold. + selectedLineFgColor: + - bold + # Background color of selected line. + # Default: 'blue' if the terminal has a dark background, or a suitable RGB blue + # computed from the background color if it is light. # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line - selectedLineBgColor: - - blue + selectedLineBgColor: [] # Background color of selected line when view doesn't have focus. - inactiveViewSelectedLineBgColor: - - bold + # Default: a suitable RGB grey computed from the terminal's background color. + inactiveViewSelectedLineBgColor: [] # Foreground color of copied commit cherryPickedCommitFgColor: @@ -223,6 +232,22 @@ gui: defaultFgColor: - default + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color + authorColors: {} + + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color + branchColorPatterns: {} + + # Colors and styles that override those in 'theme' when the terminal has a dark + # background. It has the same fields as 'theme'. + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#themes-for-dark-and-light-backgrounds + darkTheme: {} + + # Colors and styles that override those in 'theme' when the terminal has a light + # background. It has the same fields as 'theme'. + # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#themes-for-dark-and-light-backgrounds + lightTheme: {} + # Config relating to the commit length indicator commitLength: # If true, show an indicator of commit message length @@ -275,6 +300,18 @@ gui: # NerdFontsVersion is not empty. showFileIcons: true + # How the commit graph is drawn. + # One of: 'auto' (default) | 'classic' | 'detailed' + # 'detailed' connects the lines to the commit circles, and shows exactly where + # branches fork off and merge. It draws the graph with the git branch drawing + # symbols (U+F5D0 to U+F60D), so it needs a terminal that draws these itself: + # kitty, Ghostty, WezTerm (nightly builds), Contour, or VS Code's terminal with + # GPU acceleration. Other terminals need a font that contains them, such as + # https://github.com/rbong/flog-symbols. + # 'auto' uses 'detailed' if lazygit recognizes the terminal as one that draws + # these symbols (kitty and Ghostty), and 'classic' otherwise. + commitGraphStyle: auto + # Length of author name in (non-expanded) commits view. 2 means show initials # only. commitAuthorShortLength: 2 @@ -443,7 +480,9 @@ git: # If not "none", lazygit will automatically fast-forward local branches to match # their upstream after fetching. Applies to branches that are not the currently # checked out branch, and only to those that are strictly behind their upstream - # (as opposed to diverged). + # (as opposed to diverged). A branch that is checked out in another worktree is + # fast-forwarded there, unless that worktree has changes to tracked files or is + # in the middle of a rebase or bisect. # Possible values: 'none' | 'onlyMainBranches' | 'allBranches' autoForwardBranches: onlyMainBranches @@ -670,6 +709,7 @@ keybinding: - "4" - "5" focusMainView: "0" + jumpToFile: nextMatch: "n" prevMatch: "N" startSearch: / @@ -817,6 +857,8 @@ keybinding: main: prevHunk: [, h] nextHunk: [, l] + prevFile: "N" + nextFile: "n" toggleSelectHunk: a pickBothHunks: b editSelectHunk: E @@ -907,7 +949,9 @@ It is used, for example, when pasting a commit message into the commit message p ## Configuring File Editing -There are two commands for opening files, `o` for "open" and `e` for "edit". `o` acts as if the file was double-clicked in the Finder/Explorer, so it also works for non-text files, whereas `e` opens the file in an editor. `e` can also jump to the right line in the file if you invoke it from the staging panel, for example. +There are two commands for opening files, `o` for "open" and `e` for "edit". `o` acts as if the file was double-clicked in the Finder/Explorer, so it also works for non-text files, whereas `e` opens the file in an editor. `e` can also jump to the right line in the file when you invoke it from a focused diff. + +You can also open a line in your editor with the mouse: alt-click or shift-click it. Both modifiers do the same thing, because some terminals only support one or the other. The click leaves the focus and the selection where they are, so it works while you are reading a diff from another panel, or while a popup is open. To tell lazygit which editor to use for the `e` command, the easiest way to do that is to provide an editPreset config, e.g. @@ -970,7 +1014,7 @@ When the selected line gets close to the bottom of the window and you hit down-a That's the behavior when `gui.scrollOffBehavior` is set to "margin" (the default). If you set `gui.scrollOffBehavior` to "jump", then upon reaching the last line of a view and hitting down-arrow the view will scroll by half a page so that the selection ends up in the middle of the view. This may feel a little jarring because the cursor jumps around when continuously moving down, but it has the advantage that the view doesn't scroll as often. -This setting applies both to all list views (e.g. commits and branches etc), and to the staging view. +This setting applies both to all list views (e.g. commits and branches etc), and to focused diffs. ## Filtering @@ -999,6 +1043,7 @@ The available attributes are: - bold - default +- dim # faint text; not supported by every terminal - reverse # useful for high-contrast - underline - strikethrough @@ -1023,28 +1068,61 @@ gui: - reverse ``` +The text of the selected line is bold by default. If you don't want that, set `selectedLineFgColor` to `default`: + +```yaml +gui: + theme: + selectedLineFgColor: + - default +``` + +## Themes for dark and light backgrounds + +The colors in `gui.theme` apply whether your terminal has a dark or a light background. If you want different colors for the two, set them in `gui.darkTheme` or `gui.lightTheme`. These have the same fields as `gui.theme`, and a field that you set in them overrides the one in `gui.theme`: + +```yaml +gui: + theme: + activeBorderColor: + - green + - bold + lightTheme: + activeBorderColor: + - blue + - bold +``` + +For `authorColors` and `branchColorPatterns`, each entry overrides the one with the same key in `gui.theme`, and the other entries of `gui.theme` still apply. Branch color patterns of `gui.darkTheme` or `gui.lightTheme` come before those of `gui.theme`. + +Lazygit asks the terminal whether its background is dark or light. If your terminal doesn't tell, lazygit assumes a dark background; set `gui.colorScheme` to `light` if yours is light. + ## Custom Author Color Lazygit will assign a random color for every commit author in the commits pane by default. +These colors are picked to be readable against the background of your terminal, and lazygit asks the terminal whether its background is dark or light. If your terminal doesn't tell, lazygit assumes a dark background; set `gui.colorScheme` to `light` if yours is light. + You can customize the color in case you're not happy with the randomly assigned one: ```yaml gui: - authorColors: - 'John Smith': 'red' # use red for John Smith - 'Alan Smithee': '#00ff00' # use green for Alan Smithee + theme: + authorColors: + 'John Smith': 'red' # use red for John Smith + 'Alan Smithee': '#00ff00' # use green for Alan Smithee ``` You can use wildcard to set a unified color in case your are lazy to customize the color for every author or you just want a single color for all/other authors: ```yaml gui: - authorColors: - # use red for John Smith - 'John Smith': 'red' - # use blue for other authors - '*': '#0000ff' + theme: + authorColors: + # use red for John Smith + 'John Smith': 'red' + # use blue for other authors + '*': '#0000ff' ``` ## Custom Branch Color @@ -1053,13 +1131,16 @@ You can customize the color of branches based on branch patterns (regular expres ```yaml gui: - branchColorPatterns: - '^docs/': '#11aaff' # use a light blue for branches beginning with 'docs/' - 'ISSUE-\d+': '#ff5733' # use a bright orange for branches containing 'ISSUE-' + theme: + branchColorPatterns: + '^docs/': '#11aaff' # use a light blue for branches beginning with 'docs/' + 'ISSUE-\d+': '#ff5733' # use a bright orange for branches containing 'ISSUE-' ``` Note that the regular expressions are not implicitly anchored to the beginning/end of the branch name. If you want to do that, add leading `^` and/or trailing `$` as needed. +If several patterns match a branch, the first one wins. + ## Custom Files Icon & Color You can customize the icon and color of files based on filenames or extensions: diff --git a/docs/Custom_DiffRenderers.md b/docs/Custom_DiffRenderers.md index 509f42ebf..05e806d40 100644 --- a/docs/Custom_DiffRenderers.md +++ b/docs/Custom_DiffRenderers.md @@ -23,22 +23,29 @@ Fields only for `extDiff`: - **command** The command line to use for the `diff.external` git config. If left empty, it uses the global value of git's `diff.external` config; this can be useful if you also want to use it for diffs on the command line, and it also has the advantage that you can configure it per file type in `.gitattributes`; see https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver. - You can include the `{{diffContext}}` template variable to pass lazygit's current diff context size (the value controlled by the `{`/`}` keybindings) to the diff tool. - Fields only for `rawGit`: - **args** The additional arguments to use in the `git diff` or `git show` call (e.g. `--color-words`), as an array of strings. +The `command` of a `stdinFilter` or `extDiff` renderer is a [Go template](https://pkg.go.dev/text/template) with these variables: + +- `{{width}}`: the width of the view that the diff is rendered into. +- `{{colorScheme}}`: `dark` or `light`, depending on whether the terminal has a dark or a light background. Lazygit asks the terminal about this; if yours doesn't tell, set `gui.colorScheme`. +- `{{columnWidth}}` (only for `stdinFilter`): the width of one side of a side-by-side rendering, e.g. for `ydiff -p cat -s -w {{columnWidth}}`. +- `{{diffContext}}` (only for `extDiff`): lazygit's current diff context size, the value controlled by the `{`/`}` keybindings. + +A variable can also be written with a leading dot, as in `{{.width}}`. The command can use template expressions too; for example, `delta --paging=never {{if gt .width 160}}--side-by-side{{end}}` shows the diff side by side only when there is room for it, or `delta --syntax-theme={{if eq .colorScheme "light"}}Github{{else}}Dracula{{end}}` picks a different syntax theme based on the background. + Here's an example for a multi-renderer setup: ```yaml git: diffRenderers: - - command: delta --dark --paging=never + - command: delta --{{colorScheme}} --paging=never - command: ydiff -p cat colorArg: never - type: extDiff - command: difft --color=always --context={{diffContext}} + command: difft --color=always --background={{colorScheme}} --context={{diffContext}} - type: rawGit args: [--color-words] name: color-words @@ -51,12 +58,14 @@ git: ```yaml git: diffRenderers: - - command: delta --dark --paging=never + - command: delta --{{colorScheme}} --paging=never ``` ![](https://i.imgur.com/QJpQkF3.png) -A cool feature of delta is --hyperlinks, which renders clickable links for the line numbers in the left margin, and lazygit supports these. To use them, set the `command:` field to `delta --dark --paging=never --line-numbers --hyperlinks --hyperlinks-file-link-format="lazygit-edit://{path}:{line}"`; this allows you to click on an underlined line number in the diff to jump right to that same line in your editor. +`--{{colorScheme}}` passes `--dark` or `--light` to delta, so that it matches the background of your terminal. + +A cool feature of delta is --hyperlinks, which renders clickable links for the line numbers in the left margin, and lazygit supports these. To use them, set the `command:` field to `delta --{{colorScheme}} --paging=never --line-numbers --hyperlinks --hyperlinks-file-link-format="lazygit-edit://{path}:{line}"`; this allows you to click on an underlined line number in the diff to jump right to that same line in your editor. Note that delta's `--navigate` option doesn't work in lazygit, for technical reasons. diff --git a/docs/Stacked_Branches.md b/docs/Stacked_Branches.md index cd573be26..f961e74fd 100644 --- a/docs/Stacked_Branches.md +++ b/docs/Stacked_Branches.md @@ -16,3 +16,36 @@ branches properly stacked onto it. Lazygit visualizes the individual branch heads in the stack by marking them with a cyan asterisk (or a cyan branch symbol if you are using [nerd fonts](Config.md#display-nerd-fonts-icons)). + +When you push the topmost branch of the stack with `P`, and the branches below +it have commits that haven't been pushed yet, lazygit offers to push them along +with it. After rebasing the stack this saves you from checking out and +force-pushing every branch one by one; you are asked to confirm the force push +once for all of them. Only branches that already have an upstream are included. +Each of them is pushed to where `git push` would push it if it were checked out, +so your push configuration applies to them as usual. + +When somebody else rebases the stack and force-pushes it, all your branches +show up as diverged, for example `↓5↑3`, even though the commits they are ahead +by are only the old versions of the ones that are now on the remote. Lazygit +tells this apart from a branch that carries work of your own, and shows the +divergence dimmed for such a branch. Pressing `f` on it resets it to its +upstream instead of refusing, so you don't have to check the branch out and pull +it. Lazygit only does this when every commit of the branch was on its remote +branch at some point. It finds that out from the reflog of the remote-tracking +branch. Reflogs are enabled by default, except in a bare repository; if you work +in one with linked worktrees, set `core.logAllRefUpdates` to true there to make +this work. + +`f` works on a [range selection](Range_Select.md) too, so you can select the +whole stack and bring all of it back in sync at once. If any of the selected +branches can't be updated, none of them is, so that you don't end up with half +of the stack updated. + +Alternatively, check out the topmost branch of the stack and pull it with `p`. +If branches below it can be updated this way, or are simply behind their +upstream, lazygit offers to update them along with it. Lazygit decides this +from the last fetch, so a branch whose changes on the remote haven't been +fetched yet isn't offered; with auto-fetch turned off, pull a second time after +the first pull has fetched them. Branches that are checked out in another +worktree are left alone. The topmost branch itself is pulled as usual. diff --git a/docs/dev/Codebase_Guide.md b/docs/dev/Codebase_Guide.md index 1692be33e..5ecff6e9b 100644 --- a/docs/dev/Codebase_Guide.md +++ b/docs/dev/Codebase_Guide.md @@ -31,7 +31,6 @@ * `pkg/gui/keybindings`: Contains code for mapping between keybindings and their labels * `pkg/gui/mergeconflicts`: Contains code relating to the handling of merge conflicts * `pkg/gui/modes`: Contains code relating to the state of different modes e.g. cherry picking mode, rebase mode. -* `pkg/gui/patch_exploring`: Contains code relating to the state of patch-oriented views like the staging view. * `pkg/gui/popup`: Contains code that lets you easily raise popups * `pkg/gui/presentation`: Contains presentation code i.e. code concerned with rendering content inside views * `pkg/gui/services/custom_commands`: Contains code related to user-defined custom commands. diff --git a/docs/dev/Demo_Recordings.md b/docs/dev/Demo_Recordings.md index 1068e688f..207500711 100644 --- a/docs/dev/Demo_Recordings.md +++ b/docs/dev/Demo_Recordings.md @@ -8,17 +8,21 @@ You'll want to familiarise yourself with how integration tests are written: see Ideally we'd run this whole thing through docker but we haven't got that working. So you will need: ``` -# for recording -npm i -g terminalizer -# for gif compression -npm i -g gifsicle -# for mp4 conversion -brew install ffmpeg +# for recording; vhs drives ttyd and ffmpeg under the hood +brew install ttyd ffmpeg + +# vhs 0.12.0 runs the tape, reports success and writes no video at all +# (https://github.com/charmbracelet/vhs/issues/787), so pin the release +# before it +go install github.com/charmbracelet/vhs@v0.11.0 # font with icons -wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.0.2/DejaVuSansMono.tar.xz && \ - tar -xf DejaVuSansMono.tar.xz -C /usr/local/share/fonts && \ - rm DejaVuSansMono.tar.xz +wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.0.2/SourceCodePro.tar.xz && \ + tar -xf SourceCodePro.tar.xz -C ~/Library/Fonts && \ + rm SourceCodePro.tar.xz + +# font with the branch drawing symbols of the commit graph +cp demo/fonts/FlogSymbolsDemo-*.ttf ~/Library/Fonts ``` ## Creating a demo @@ -49,34 +53,82 @@ The scripts and demo definitions live in the code branches but the output lives git worktree add .worktrees/assets assets ``` -Outputs will be stored in `.worktrees/assets/demos/`. We'll store three separate things: -* the yaml of the recording -* the original gif -* either the compressed gif or the mp4 depending on the output you chose (see below) +The mp4 of the recording will be stored in `.worktrees/assets/demo/`. ### Recording the demo Once you're happy with your demo you can record it using: ```sh -scripts/record_demo.sh [gif|mp4] +scripts/record_demo.sh # e.g. -scripts/record_demo.sh gif pkg/integration/tests/demo/interactive_rebase.go +scripts/record_demo.sh pkg/integration/tests/demo/interactive_rebase.go ``` -~~The gif format is for use in the first video of the readme (it has a larger size but has auto-play and looping)~~ -~~The mp4 format is for everything else (no looping, requires clicking, but smaller size).~~ +The terminal size, font and colours live in `demo/settings.tape`, which the +script sources into the tape it generates for the demo. -Turns out that you can't store mp4s in a repo and link them from a README so we're gonna just use gifs across the board for now. +While you are still working on how a demo looks, pass `--no-upload`. That +leaves the video in `demo/output` (which is git-ignored) and stops there, so +you can watch it without uploading anything or touching the assets worktree: + +```sh +scripts/record_demo.sh --no-upload pkg/integration/tests/demo/interactive_rebase.go +``` ### Including demos in README/docs -If you've followed the above steps you'll end up with your output in your assets worktree. +Recording a demo does three things with the mp4: it writes it to your assets +worktree, it uploads a copy to GitHub's attachment store, and it posts that +copy as a comment on the issue named by `PUBLISH_ISSUE` in the script. Then it +prints the tag to embed: -Within that worktree, stage all three output files and raise a PR against the assets branch. - -Then back in the code branch, in the doc, you can embed the recording like so: -```md -![Nuke working tree](../assets/demo/interactive_rebase-compressed.gif) +```html + ``` -This means we can update assets without needing to update the docs that embed them. +GitHub plays a video in a README only when it is served from its own attachment +store. If you commit a video to the assets branch and link it the way we link +the images, GitHub drops the whole `