update method
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);
}