Skip to content

Commit c042bae

Browse files
committed
remove some unnecessary useEffect/useMemo calls
1 parent 88684ac commit c042bae

File tree

2 files changed

+49
-80
lines changed

2 files changed

+49
-80
lines changed

cli/src/components/multiline-input.tsx

Lines changed: 44 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@ import {
55
useCallback,
66
useEffect,
77
useImperativeHandle,
8-
useMemo,
98
useRef,
109
useState,
1110
} from 'react'
1211

1312
import { InputCursor } from './input-cursor'
1413
import { useOpentuiPaste } from '../hooks/use-opentui-paste'
1514
import { useTheme } from '../hooks/use-theme'
16-
import { logger } from '../utils/logger'
1715
import { clamp } from '../utils/math'
1816
import { calculateNewCursorPosition } from '../utils/word-wrap-utils'
1917

2018
import type { InputValue } from '../state/chat-store'
2119
import type {
2220
KeyEvent,
23-
LineInfo,
2421
PasteEvent,
2522
ScrollBoxRenderable,
23+
TextBufferView,
2624
TextRenderable,
2725
} from '@opentui/core'
2826

@@ -131,11 +129,6 @@ export const MultilineInput = forwardRef<
131129
const scrollBoxRef = useRef<ScrollBoxRenderable | null>(null)
132130
const [measuredCols, setMeasuredCols] = useState<number | null>(null)
133131
const [lastActivity, setLastActivity] = useState(Date.now())
134-
const lineInfoRef = useRef<LineInfo>({
135-
lineStarts: [],
136-
lineWidths: [],
137-
maxLineWidth: 0,
138-
})
139132

140133
// Update last activity on value or cursor changes
141134
useEffect(() => {
@@ -144,19 +137,13 @@ export const MultilineInput = forwardRef<
144137

145138
const textRef = useRef<TextRenderable | null>(null)
146139

147-
if (textRef.current) {
148-
lineInfoRef.current = (textRef.current as any).textBufferView.lineInfo
149-
}
140+
const lineInfo = textRef.current
141+
? (
142+
(textRef.current satisfies TextRenderable as any)
143+
.textBufferView as TextBufferView
144+
).lineInfo
145+
: null
150146

151-
const getEffectiveCols = useCallback(() => {
152-
// Prefer measured viewport columns; fallback to a conservative
153-
// estimate: outer width minus border(2) minus padding(2) = 4.
154-
const fallbackCols = Math.max(1, width - 4)
155-
const cols = measuredCols ?? fallbackCols
156-
// No extra negative fudge; use the true measured width to avoid
157-
// early wrap by a few characters.
158-
return Math.max(1, cols)
159-
}, [measuredCols, width])
160147
useImperativeHandle(
161148
forwardedRef,
162149
() => ({
@@ -190,12 +177,14 @@ export const MultilineInput = forwardRef<
190177
),
191178
)
192179

193-
const cursorRow = Math.max(
194-
0,
195-
lineInfoRef.current.lineStarts.findLastIndex(
196-
(lineStart) => lineStart <= cursorPosition,
197-
),
198-
)
180+
const cursorRow = lineInfo
181+
? Math.max(
182+
0,
183+
lineInfo.lineStarts.findLastIndex(
184+
(lineStart) => lineStart <= cursorPosition,
185+
),
186+
)
187+
: 0
199188

200189
// Auto-scroll to cursor when content changes
201190
useEffect(() => {
@@ -270,43 +259,32 @@ export const MultilineInput = forwardRef<
270259
renderCursorPosition += displayValue[i] === '\t' ? TAB_WIDTH : 1
271260
}
272261

273-
const { beforeCursor, afterCursor, activeChar, shouldHighlight } =
274-
useMemo(() => {
275-
if (!showCursor) {
276-
return {
277-
beforeCursor: '',
278-
afterCursor: '',
279-
activeChar: ' ',
280-
shouldHighlight: false,
281-
}
262+
const { beforeCursor, afterCursor, activeChar, shouldHighlight } = (() => {
263+
if (!showCursor) {
264+
return {
265+
beforeCursor: '',
266+
afterCursor: '',
267+
activeChar: ' ',
268+
shouldHighlight: false,
282269
}
270+
}
283271

284-
const beforeCursor = displayValueForRendering.slice(
285-
0,
286-
renderCursorPosition,
287-
)
288-
const afterCursor = displayValueForRendering.slice(renderCursorPosition)
289-
const activeChar = afterCursor.charAt(0) || ' '
290-
const shouldHighlight =
291-
!isPlaceholder &&
292-
renderCursorPosition < displayValueForRendering.length &&
293-
displayValue[cursorPosition] !== '\n' &&
294-
displayValue[cursorPosition] !== '\t'
272+
const beforeCursor = displayValueForRendering.slice(0, renderCursorPosition)
273+
const afterCursor = displayValueForRendering.slice(renderCursorPosition)
274+
const activeChar = afterCursor.charAt(0) || ' '
275+
const shouldHighlight =
276+
!isPlaceholder &&
277+
renderCursorPosition < displayValueForRendering.length &&
278+
displayValue[cursorPosition] !== '\n' &&
279+
displayValue[cursorPosition] !== '\t'
295280

296-
return {
297-
beforeCursor,
298-
afterCursor,
299-
activeChar,
300-
shouldHighlight,
301-
}
302-
}, [
303-
showCursor,
304-
displayValueForRendering,
305-
renderCursorPosition,
306-
cursorPosition,
307-
isPlaceholder,
308-
displayValue,
309-
])
281+
return {
282+
beforeCursor,
283+
afterCursor,
284+
activeChar,
285+
shouldHighlight,
286+
}
287+
})()
310288

311289
// Handle all keyboard input with advanced shortcuts
312290
useKeyboard(
@@ -701,7 +679,7 @@ export const MultilineInput = forwardRef<
701679
text: value,
702680
cursorPosition: calculateNewCursorPosition({
703681
cursorPosition,
704-
lineInfo: lineInfoRef.current,
682+
lineStarts: lineInfo?.lineStarts ?? [],
705683
cursorIsChar: !shouldHighlight,
706684
direction: 'up',
707685
}),
@@ -716,7 +694,7 @@ export const MultilineInput = forwardRef<
716694
text: value,
717695
cursorPosition: calculateNewCursorPosition({
718696
cursorPosition,
719-
lineInfo: lineInfoRef.current,
697+
lineStarts: lineInfo?.lineStarts ?? [],
720698
cursorIsChar: !shouldHighlight,
721699
direction: 'down',
722700
}),
@@ -758,7 +736,7 @@ export const MultilineInput = forwardRef<
758736
value,
759737
cursorPosition,
760738
shouldHighlight,
761-
lineInfoRef.current,
739+
lineInfo,
762740
onChange,
763741
onSubmit,
764742
onKeyIntercept,
@@ -768,12 +746,12 @@ export const MultilineInput = forwardRef<
768746
),
769747
)
770748

771-
const layoutMetrics = useMemo(() => {
749+
const layoutMetrics = (() => {
772750
const safeMaxHeight = Math.max(1, maxHeight)
773751
const effectiveMinHeight = Math.max(1, Math.min(minHeight, safeMaxHeight))
774752

775753
const totalLines =
776-
measuredCols === 0 ? 0 : lineInfoRef.current.lineStarts.length
754+
measuredCols === 0 || lineInfo === null ? 0 : lineInfo.lineStarts.length
777755

778756
// Add bottom gutter when cursor is on line 2 of exactly 2 lines
779757
const gutterEnabled =
@@ -790,7 +768,7 @@ export const MultilineInput = forwardRef<
790768
heightLines,
791769
gutterEnabled,
792770
}
793-
}, [maxHeight, minHeight, lineInfoRef.current, cursorRow])
771+
})()
794772

795773
const inputColor = isPlaceholder
796774
? theme.muted

cli/src/utils/word-wrap-utils.ts

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import type { LineInfo } from '@opentui/core'
2-
31
function cursorUp(params: {
4-
lineInfo: LineInfo
2+
lineStarts: number[]
53
cursorPosition: number
64
}): number {
7-
const {
8-
lineInfo: { lineStarts },
9-
cursorPosition,
10-
} = params
5+
const { lineStarts, cursorPosition } = params
116
const lineIndex = lineStarts.findLastIndex((start) => start <= cursorPosition)
127

138
if (lineIndex === -1 || lineIndex === 0) {
@@ -19,15 +14,11 @@ function cursorUp(params: {
1914
}
2015

2116
function cursorDown(params: {
22-
lineInfo: LineInfo
17+
lineStarts: number[]
2318
cursorPosition: number
2419
cursorIsChar: boolean
2520
}): number {
26-
const {
27-
lineInfo: { lineStarts },
28-
cursorPosition,
29-
cursorIsChar,
30-
} = params
21+
const { lineStarts, cursorPosition, cursorIsChar } = params
3122
const lineIndex = lineStarts.findLastIndex((start) => start <= cursorPosition)
3223

3324
if (lineIndex === -1 || lineIndex === lineStarts.length - 1) {
@@ -45,7 +36,7 @@ function cursorDown(params: {
4536

4637
export function calculateNewCursorPosition(params: {
4738
cursorPosition: number
48-
lineInfo: LineInfo
39+
lineStarts: number[]
4940
cursorIsChar: boolean
5041
direction: 'up' | 'down'
5142
}): number {

0 commit comments

Comments
 (0)