MCPcopy Index your code
hub / github.com/codeaashu/claude-code / render

Method render

src/ink/log-update.ts:123–467  ·  view source on GitHub ↗
(
    prev: Frame,
    next: Frame,
    altScreen = false,
    decstbmSafe = true,
  )

Source from the content-addressed store, hash-verified

121 }
122
123 render(
124 prev: Frame,
125 next: Frame,
126 altScreen = false,
127 decstbmSafe = true,
128 ): Diff {
129 if (!this.options.isTTY) {
130 return this.renderFullFrame(next)
131 }
132
133 const startTime = performance.now()
134 const stylePool = this.options.stylePool
135
136 // Since we assume the cursor is at the bottom on the screen, we only need
137 // to clear when the viewport gets shorter (i.e. the cursor position drifts)
138 // or when it gets thinner (and text wraps). We _could_ figure out how to
139 // not reset here but that would involve predicting the current layout
140 // _after_ the viewport change which means calcuating text wrapping.
141 // Resizing is a rare enough event that it's not practically a big issue.
142 if (
143 next.viewport.height < prev.viewport.height ||
144 (prev.viewport.width !== 0 && next.viewport.width !== prev.viewport.width)
145 ) {
146 return fullResetSequence_CAUSES_FLICKER(next, 'resize', stylePool)
147 }
148
149 // DECSTBM scroll optimization: when a ScrollBox's scrollTop changed,
150 // shift content with a hardware scroll (CSI top;bot r + CSI n S/T)
151 // instead of rewriting the whole scroll region. The shiftRows on
152 // prev.screen simulates the shift so the diff loop below naturally
153 // finds only the rows that scrolled IN as diffs. prev.screen is
154 // about to become backFrame (reused next render) so mutation is safe.
155 // CURSOR_HOME after RESET_SCROLL_REGION is defensive — DECSTBM reset
156 // homes cursor per spec but terminal implementations vary.
157 //
158 // decstbmSafe: caller passes false when the DECSTBM→diff sequence
159 // can't be made atomic (no DEC 2026 / BSU/ESU). Without atomicity the
160 // outer terminal renders the intermediate state — region scrolled,
161 // edge rows not yet painted — a visible vertical jump on every frame
162 // where scrollTop moves. Falling through to the diff loop writes all
163 // shifted rows: more bytes, no intermediate state. next.screen from
164 // render-node-to-output's blit+shift is correct either way.
165 let scrollPatch: Diff = []
166 if (altScreen && next.scrollHint && decstbmSafe) {
167 const { top, bottom, delta } = next.scrollHint
168 if (
169 top >= 0 &&
170 bottom < prev.screen.height &&
171 bottom < next.screen.height
172 ) {
173 shiftRows(prev.screen, top, bottom, delta)
174 scrollPatch = [
175 {
176 type: 'stdout',
177 content:
178 setScrollRegion(top + 1, bottom + 1) +
179 (delta > 0 ? csiScrollUp(delta) : csiScrollDown(-delta)) +
180 RESET_SCROLL_REGION +

Callers

nothing calls this directly

Calls 15

renderFullFrameMethod · 0.95
txnMethod · 0.95
shiftRowsFunction · 0.85
setScrollRegionFunction · 0.85
logForDebuggingFunction · 0.85
diffEachFunction · 0.85
readLineFunction · 0.85
isEmptyCellAtFunction · 0.85
moveCursorToFunction · 0.85
transitionHyperlinkFunction · 0.85
writeCellWithStyleStrFunction · 0.85

Tested by

no test coverage detected