Skip to content

Add adaptive diff context size based on selection type (files vs directories) #4760

@douglance

Description

@douglance

Problem

Currently, lazygit uses a single global diffContextSize setting that applies uniformly to all diff views. This creates a usability trade-off:

  • High context values (e.g., diffContextSize: 1000) show entire files when reviewing individual changes, but become overwhelming when browsing multiple files or directories
  • Low context values (e.g., diffContextSize: 3) are great for quick overviews but lack sufficient context when doing detailed code review

Users must manually adjust context using {/} keys or compromise with a middle-ground value that isn't optimal for any scenario.

Proposed Solution

Add configuration options to automatically adjust diff context size based on the current context type:

git:
  # Backward compatible - existing configs continue working
  diffContextSize: 3  # default fallback
  
  # New adaptive context configuration
  adaptiveContext:
    enabled: true
    contexts:
      files: 1000        # when viewing individual files
      commits: 10        # when viewing commit diffs
      stash: 5           # when viewing stash diffs
      staging: 20        # when in staging/patch mode
      patchBuilding: 50  # when building custom patches

Use Cases

  1. File Review: When in the files panel reviewing a single file change, show maximum context (entire file) for thorough code review
  2. Commit History: When browsing commit diffs, show moderate context to understand changes without overwhelming detail
  3. Staging: When staging hunks, show enough context to understand the change scope
  4. Stash Review: When reviewing stashed changes, show minimal context for quick scanning

Behavior Examples

  • Navigate to files panel and select src/components/Button.tsxdiffContextSize: 1000 (full file context)
  • Navigate to commits panel and select a commit → diffContextSize: 10 (moderate context)
  • Enter staging mode → diffContextSize: 20 (staging-appropriate context)
  • Browse stash entries → diffContextSize: 5 (minimal context for overview)

Technical Implementation

Based on codebase analysis, this enhancement would involve:

1. Config Structure Changes (pkg/config/user_config.go)

type AdaptiveContextConfig struct {
    Enabled      bool   `yaml:"enabled"`
    Files        uint64 `yaml:"files"`
    Commits      uint64 `yaml:"commits"`
    Stash        uint64 `yaml:"stash"`
    Staging      uint64 `yaml:"staging"`
    PatchBuilding uint64 `yaml:"patchBuilding"`
}

type GitConfig struct {
    // Existing field for backward compatibility
    DiffContextSize uint64 `yaml:"diffContextSize"`
    // New adaptive config
    AdaptiveContext AdaptiveContextConfig `yaml:"adaptiveContext"`
}

2. Context-Aware Size Resolution (pkg/gui/controllers/context_lines_controller.go)

func (self *ContextLinesController) getContextSizeForCurrentContext() uint64 {
    adaptiveConfig := self.c.UserConfig().Git.AdaptiveContext
    if !adaptiveConfig.Enabled {
        return self.c.UserConfig().Git.DiffContextSize
    }
    
    currentContext := self.currentSidePanel().GetKey()
    switch currentContext {
    case context.FILES_CONTEXT_KEY:
        return adaptiveConfig.Files
    case context.LOCAL_COMMITS_CONTEXT_KEY, context.SUB_COMMITS_CONTEXT_KEY:
        return adaptiveConfig.Commits
    case context.STASH_CONTEXT_KEY:
        return adaptiveConfig.Stash
    case context.STAGING_MAIN_CONTEXT_KEY, context.STAGING_SECONDARY_CONTEXT_KEY:
        return adaptiveConfig.Staging
    case context.PATCH_BUILDING_MAIN_CONTEXT_KEY:
        return adaptiveConfig.PatchBuilding
    default:
        return self.c.UserConfig().Git.DiffContextSize
    }
}

3. Integration Points

The existing {/} keybindings would modify context-specific values when adaptive mode is enabled, allowing per-context customization.

Benefits

  1. Better UX: Automatic context switching eliminates the need for manual adjustments
  2. Workflow Optimization: Different contexts get appropriately sized diff views
  3. Backward Compatible: Existing configurations continue working unchanged
  4. Configurable: Users can fine-tune context sizes per workflow
  5. Performance: Avoids showing excessive context when not needed

Alternative Approaches Considered

  • View Modes: Different preset "modes" (review/browse/overview) with different contexts
  • Smart Context: Dynamic sizing based on file size/change density
  • Manual Keybindings: Custom commands for context switching (less automatic)

The proposed solution provides the best balance of automation, customization, and backward compatibility.

This enhancement would significantly improve the lazygit user experience for both detailed code review and quick change browsing workflows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions