update method

  1. @override
(GitDiffModel, Cmd?) update(
  1. Msg msg
)
override

Updates the component state in response to a message.

Returns the updated component (often this) and an optional command.

Implementation

@override
(GitDiffModel, Cmd?) update(Msg msg) {
  // Intercept view-mode cycling key before delegating to the viewport.
  if (msg is KeyMsg && keyMatches(msg.key, [keyMap.cycleViewMode])) {
    final modes = DiffViewMode.values;
    final nextMode = modes[(viewMode.index + 1) % modes.length];
    // Reset horizontal offset when switching view modes.
    final rendered = _renderLines(_files, overrideViewMode: nextMode);
    final newViewport = _viewport.copyWith(
      width: width,
      height: height,
      lines: rendered,
    );
    return (
      copyWith(
        viewMode: nextMode,
        horizontalOffset: 0,
        renderedLines: rendered,
        viewport: newViewport,
      ),
      null,
    );
  }

  // In side-by-side mode with wrapping disabled, intercept left/right keys
  // to apply horizontal scrolling within each panel.  The viewport's own
  // xOffset can't help here because each composed line contains two fixed-
  // width panels separated by │ — scrolling the whole line would eat into
  // the gutter rather than scrolling panel content.
  if (!wrapLines && viewMode == DiffViewMode.sideBySide && msg is KeyMsg) {
    final vkm = _viewport.keyMap;
    final step = _viewport.horizontalStep;
    if (step > 0) {
      int? newOffset;
      if (keyMatches(msg.key, [vkm.left])) {
        newOffset = (horizontalOffset - step).clamp(0, horizontalOffset);
      } else if (keyMatches(msg.key, [vkm.right])) {
        newOffset = horizontalOffset + step;
      }
      if (newOffset != null && newOffset != horizontalOffset) {
        // Create model with new offset so _renderLines reads the right value.
        final updated = copyWith(horizontalOffset: newOffset);
        final rendered = updated._renderLines(_files);
        final newViewport = _viewport.copyWith(
          width: width,
          height: height,
          lines: rendered,
        );
        return (
          updated.copyWith(renderedLines: rendered, viewport: newViewport),
          null,
        );
      }
      // If we matched left/right but offset didn't change (clamped at 0),
      // consume the key to avoid the viewport scrolling the whole line.
      if (newOffset != null) return (this, null);
    }
  }

  final (newViewport, cmd) = _viewport.update(msg);
  if (identical(newViewport, _viewport)) {
    return (this, cmd);
  }
  return (copyWith(viewport: newViewport), cmd);
}