home / skills / gwenwindflower / .charmschool / lazygit-custom-commands

lazygit-custom-commands skill

/agents/claude/skills/lazygit-custom-commands

This skill helps you build and troubleshoot lazygit custom commands in config.yml, accelerating prompt-driven workflows and context-aware keybindings.

npx playbooks add skill gwenwindflower/.charmschool --skill lazygit-custom-commands

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.8 KB
---
name: lazygit-custom-commands
description: Build and troubleshoot lazygit customCommands in config.yml. Use for prompt-driven commands, context-specific keybindings, commandMenus, template-based construction, and conventional-commit style workflows.
---

# Lazygit Custom Commands

## Fields

`context` and `command` are required (except `commandMenu` entries — see below).

| Field | Notes |
| --- | --- |
| `key` | Hotkey — omit to expose via `?` menu only |
| `context` | Required. Comma-separated for multi: `'commits, subCommits'` |
| `command` | Required. Go template string |
| `description` | Shown in UI and `?` menu |
| `loadingText` | Progress label while running |
| `output` | `none` \| `terminal` \| `log` \| `logWithPty` \| `popup` |
| `outputTitle` | Title for `popup` output |
| `after` | `checkForConflicts` |
| `prompts` | List of prompt configs (see below) |

Keys: single letters or special forms like `<c-t>`, `<f5>`, `<esc>`.

## Contexts

`status`, `files`, `worktrees`, `localBranches`, `remotes`, `remoteBranches`, `tags`, `commits`, `reflogCommits`, `subCommits`, `commitFiles`, `stash`, `global`

## Prompts

All prompts share: `type`, `title`, `key`. Answers referenced as `{{.Form.<Key>}}`.

### input

```yaml
- type: 'input'
  key: 'Scope'
  title: 'Scope (optional):'
  initialValue: ''
  suggestions:
    preset: 'branches'  # authors|branches|files|refs|remotes|remoteBranches|tags
    # OR: command: 'my-cmd'  (mutually exclusive with preset)
```

### confirm

```yaml
- type: 'confirm'
  key: 'Confirm'
  title: 'Force-push to remote?'
  body: 'This will rewrite history on the remote branch.'
```

### menu

Options: `value` required, `name` (display label — shows `value` if omitted), `description`, `key` (direct-select).

```yaml
- type: 'menu'
  key: 'Type'
  title: 'Commit type:'
  options:
    - value: 'feat'
      name: 'Feature'
      description: 'New functionality'
      key: 'f'
    - value: 'fix'
      key: 'x'
    - value: 'chore'
```

### menuFromCommand

```yaml
- type: 'menuFromCommand'
  key: 'Branch'
  title: 'Remote branch:'
  command: 'git branch -r --list {{.SelectedRemote.Name}}/*'
  filter: '.*{{.SelectedRemote.Name}}/(?P<branch>.*)'  # named groups: ?P<name>, unnamed: group_1, group_2...
  valueFormat: '{{.branch}}'
  labelFormat: '{{.branch | green}}'
```

Without `filter`/`valueFormat`/`labelFormat`, each output line is both value and label.

## Template data

Objects available in `command` and prompts:

`SelectedFile` (files) · `SelectedLocalBranch` (localBranches) · `SelectedRemote` (remotes) · `SelectedRemoteBranch` (remoteBranches) · `SelectedTag` (tags) · `SelectedCommit` (commits) · `SelectedCommitRange` (commits) · `SelectedStashEntry` (stash) · `SelectedCommitFile` (commitFiles) · `SelectedWorktree` (worktrees) · `SelectedPath` · `CheckedOutBranch` (global)

Notable fields: `SelectedFile.Name`, `SelectedFile.HasUnstagedChanges`, `SelectedRemote.Name`, `SelectedCommitRange.From`/`.To`.

Helpers: `quote` (safe shell quoting), `runCommand` (interpolate single-line command output).

Template example with a conditional:

```yaml
command: "git {{if .SelectedFile.HasUnstagedChanges}}add{{else}}reset{{end}} {{.SelectedFile.Name | quote}}"
```

Prefer Go template conditionals (`if`, `else if`, `eq`) over shell parsing complexity.

## commandMenu

Groups commands under one top-level key. Only `key` and `description` allowed at the top level — full fields go on entries:

```yaml
customCommands:
  - key: 'X'
    description: 'Patch workflows'
    commandMenu:
      - key: 'c'
        context: 'commits, subCommits'
        description: 'Copy range to clipboard'
        command: 'git format-patch --stdout {{.SelectedCommitRange.From}}^..{{.SelectedCommitRange.To}} | pbcopy'
      - key: 'v'
        context: 'commits'
        description: 'Apply from clipboard'
        command: 'pbpaste | git am'
```

## Keybinding rules

- Custom key collides with built-in in the same context → custom wins
- Custom key is `global`, built-in exists for the active specific context → built-in wins

## Debug

Set `output: popup` and wrap `command` in `echo` to preview template resolution without executing.

## Output conventions

Return paste-ready YAML with correct indentation and explicit `context`. Verify keybinding collisions and `.Form.<Key>` references before finalizing.

## External resources

> Only fetch these if something specific isn't covered above — the spec is long and will waste a ton of context window tokens if you pull it in wholesale unnecessarily.

- [Custom Command Keybindings spec](https://raw.githubusercontent.com/jesseduffield/lazygit/master/docs/Custom_Command_Keybindings.md) — authoritative field reference
- [Custom Commands Compendium](https://github.com/jesseduffield/lazygit/wiki/Custom-Commands-Compendium) — real-world examples (conventional commits, tig, remote checkout, pull/fetch helpers)

Overview

This skill helps you build and troubleshoot lazygit customCommands in config.yml, focusing on prompt-driven commands, context-aware keybindings, command menus, and template-based construction. It guides creation of conventional-commit workflows, context-specific actions, and safe debugging patterns so your terminal workflows stay predictable and repeatable.

How this skill works

It inspects and validates custom command fields: context, command templates, keys, prompts, output modes, and commandMenu grouping. It checks template data usage (.Selected... objects and .Form.<Key> references), keybinding collisions, and recommends debug output modes to preview expanded commands without executing them. It also generates paste-ready YAML snippets and highlights common pitfalls.

When to use it

  • Add contextual shortcuts for status, files, commits, or branches.
  • Create prompt-driven commit templates (conventional commits) or multi-step flows.
  • Group related actions under a commandMenu with a single top-level key.
  • Troubleshoot template interpolation, quoting, and prompt key references.
  • Validate keybindings to avoid unintended collisions with built-in keys.

Best practices

  • Always include explicit context (no implicit/global unless intended).
  • Use Go template helpers (quote, runCommand) and conditionals instead of complex shell parsing.
  • Preview templates by setting output: popup and wrapping command in echo before running destructive commands.
  • Use short single-letter or special-key keys, and omit key to expose via the ? menu only.
  • Reference prompt answers as {{.Form.<Key>}} and verify case-sensitive key names in prompts.

Example use cases

  • Conventional-commit helper: prompt for type, scope, and description then run git commit with formatted message.
  • Patch workflows: top-level commandMenu key groups apply/export patch actions for commits.
  • Remote branch menuFromCommand to list remote branches, filter and select for push/checkout.
  • File-based toggle: conditional command that adds or resets a selected file depending on unstaged changes.
  • Debug template rendering: echo the interpolated command in a popup to inspect variables like SelectedCommitRange.From/To.

FAQ

What fields are always required?

context and command are required for individual entries; commandMenu entries require a top-level key and description but each nested entry still needs context and command.

How do I preview a template without running it?

Set output: popup and wrap the command in echo so the resolved template is shown in a popup instead of executing.