({
initialText = '',
initialCursorOffset = 0,
viewport,
stdin,
setRawMode,
onChange,
isValidPath,
shellModeActive = false,
}: UseTextBufferProps)
| 954 | // --- End of reducer logic --- |
| 955 | |
| 956 | export function useTextBuffer({ |
| 957 | initialText = '', |
| 958 | initialCursorOffset = 0, |
| 959 | viewport, |
| 960 | stdin, |
| 961 | setRawMode, |
| 962 | onChange, |
| 963 | isValidPath, |
| 964 | shellModeActive = false, |
| 965 | }: UseTextBufferProps): TextBuffer { |
| 966 | const initialState = useMemo((): TextBufferState => { |
| 967 | const lines = initialText.split('\n'); |
| 968 | const [initialCursorRow, initialCursorCol] = calculateInitialCursorPosition( |
| 969 | lines.length === 0 ? [''] : lines, |
| 970 | initialCursorOffset, |
| 971 | ); |
| 972 | return { |
| 973 | lines: lines.length === 0 ? [''] : lines, |
| 974 | cursorRow: initialCursorRow, |
| 975 | cursorCol: initialCursorCol, |
| 976 | preferredCol: null, |
| 977 | undoStack: [], |
| 978 | redoStack: [], |
| 979 | clipboard: null, |
| 980 | selectionAnchor: null, |
| 981 | viewportWidth: viewport.width, |
| 982 | }; |
| 983 | }, [initialText, initialCursorOffset, viewport.width]); |
| 984 | |
| 985 | const [state, dispatch] = useReducer(textBufferReducer, initialState); |
| 986 | const { lines, cursorRow, cursorCol, preferredCol, selectionAnchor } = state; |
| 987 | |
| 988 | const text = useMemo(() => lines.join('\n'), [lines]); |
| 989 | |
| 990 | const visualLayout = useMemo( |
| 991 | () => |
| 992 | calculateVisualLayout(lines, [cursorRow, cursorCol], state.viewportWidth), |
| 993 | [lines, cursorRow, cursorCol, state.viewportWidth], |
| 994 | ); |
| 995 | |
| 996 | const { visualLines, visualCursor } = visualLayout; |
| 997 | |
| 998 | const [visualScrollRow, setVisualScrollRow] = useState<number>(0); |
| 999 | |
| 1000 | useEffect(() => { |
| 1001 | if (onChange) { |
| 1002 | onChange(text); |
| 1003 | } |
| 1004 | }, [text, onChange]); |
| 1005 | |
| 1006 | useEffect(() => { |
| 1007 | dispatch({ type: 'set_viewport_width', payload: viewport.width }); |
| 1008 | }, [viewport.width]); |
| 1009 | |
| 1010 | // Update visual scroll (vertical) |
| 1011 | useEffect(() => { |
| 1012 | const { height } = viewport; |
| 1013 | let newVisualScrollRow = visualScrollRow; |
no test coverage detected