Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions registry/cell/CodeCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type CodeMirrorEditorRef,
} from "@/registry/editor/codemirror-editor";
import type { SupportedLanguage } from "@/registry/editor/languages";
import { searchHighlight } from "@/registry/editor/search-highlight";
import { CellContainer } from "./CellContainer";
import { CompactExecutionButton } from "./CompactExecutionButton";
import type { JupyterOutput } from "./OutputArea";
Expand Down Expand Up @@ -84,6 +85,18 @@ interface CodeCellProps {
* Whether this is the last cell (affects Enter behavior)
*/
isLastCell?: boolean;
/**
* Search query for highlighting matches in editor and outputs
*/
searchQuery?: string;
/**
* Character offset of the active search match in the editor (-1 for none)
*/
searchActiveOffset?: number;
/**
* Callback when search match count changes (from outputs)
*/
onSearchMatchCount?: (count: number) => void;
/**
* Additional CodeMirror extensions
*/
Expand Down Expand Up @@ -147,6 +160,9 @@ export function CodeCell({
onInsertCellAfter,
onFormat,
isLastCell = false,
searchQuery,
searchActiveOffset = -1,
onSearchMatchCount,
extensions,
className,
}: CodeCellProps) {
Expand Down Expand Up @@ -199,6 +215,15 @@ export function CodeCell({
[navigationKeyMap],
);

// Combine user extensions with search highlighting
const editorExtensions = useMemo(
() => [
...(extensions ?? []),
...searchHighlight(searchQuery ?? "", searchActiveOffset),
],
[extensions, searchQuery, searchActiveOffset],
);

const handleExecute = useCallback(() => {
onExecute?.();
}, [onExecute]);
Expand Down Expand Up @@ -240,14 +265,21 @@ export function CodeCell({
language={language}
onValueChange={onUpdateSource}
keyMap={keyMap}
extensions={extensions}
extensions={editorExtensions}
placeholder="Enter code..."
className="min-h-[2rem]"
autoFocus={isFocused}
/>
</div>
}
outputContent={<OutputArea outputs={cell.outputs} preloadIframe />}
outputContent={
<OutputArea
outputs={cell.outputs}
preloadIframe
searchQuery={searchQuery}
onSearchMatchCount={onSearchMatchCount}
/>
}
hideOutput={cell.outputs.length === 0}
/>
);
Expand Down
20 changes: 20 additions & 0 deletions registry/cell/MarkdownCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
CodeMirrorEditor,
type CodeMirrorEditorRef,
} from "@/registry/editor/codemirror-editor";
import { searchHighlight } from "@/registry/editor/search-highlight";
import {
IsolatedFrame,
type IsolatedFrameHandle,
Expand Down Expand Up @@ -63,6 +64,10 @@ interface MarkdownCellProps {
* Whether this is the last cell (affects Enter behavior)
*/
isLastCell?: boolean;
/**
* Search query for highlighting matches in editor (edit mode) and rendered content (view mode)
*/
searchQuery?: string;
/**
* Additional class name for the container
*/
Expand Down Expand Up @@ -114,6 +119,7 @@ export function MarkdownCell({
onFocusNext,
onInsertCellAfter,
isLastCell = false,
searchQuery,
className,
}: MarkdownCellProps) {
// Start in edit mode if cell is empty
Expand Down Expand Up @@ -252,6 +258,19 @@ export function MarkdownCell({
[navigationKeyMap, cell.source],
);

// Search highlighting for edit mode
const editorExtensions = useMemo(
() => searchHighlight(searchQuery ?? ""),
[searchQuery],
);

// Sync search to iframe when searchQuery changes (view mode)
useEffect(() => {
if (!editing && frameRef.current?.isReady) {
frameRef.current.search(searchQuery ?? "");
}
}, [searchQuery, editing]);

// Focus editor when entering edit mode (after initial mount)
const initialMountRef = useRef(true);
useEffect(() => {
Expand Down Expand Up @@ -309,6 +328,7 @@ export function MarkdownCell({
onValueChange={onUpdateSource}
onBlur={handleBlur}
keyMap={keyMap}
extensions={editorExtensions}
placeholder="Enter markdown..."
className="min-h-[2rem]"
autoFocus={editing}
Expand Down