( mcpClients: MCPServerConnection[], onSelect: (selection: IDESelection) => void, )
| 57 | * with MCP client notification handlers |
| 58 | */ |
| 59 | export function useIdeSelection( |
| 60 | mcpClients: MCPServerConnection[], |
| 61 | onSelect: (selection: IDESelection) => void, |
| 62 | ): void { |
| 63 | const handlersRegistered = useRef(false) |
| 64 | const currentIDERef = useRef<ConnectedMCPServer | null>(null) |
| 65 | |
| 66 | useEffect(() => { |
| 67 | // Find the IDE client from the MCP clients list |
| 68 | const ideClient = getConnectedIdeClient(mcpClients) |
| 69 | |
| 70 | // If the IDE client changed, we need to re-register handlers. |
| 71 | // Normalize undefined to null so the initial ref value (null) matches |
| 72 | // "no IDE found" (undefined), avoiding spurious resets on every MCP update. |
| 73 | if (currentIDERef.current !== (ideClient ?? null)) { |
| 74 | handlersRegistered.current = false |
| 75 | currentIDERef.current = ideClient || null |
| 76 | // Reset the selection when the IDE client changes. |
| 77 | onSelect({ |
| 78 | lineCount: 0, |
| 79 | lineStart: undefined, |
| 80 | text: undefined, |
| 81 | filePath: undefined, |
| 82 | }) |
| 83 | } |
| 84 | |
| 85 | // Skip if we've already registered handlers for the current IDE or if there's no IDE client |
| 86 | if (handlersRegistered.current || !ideClient) { |
| 87 | return |
| 88 | } |
| 89 | |
| 90 | // Handler function for selection changes |
| 91 | const selectionChangeHandler = (data: SelectionData) => { |
| 92 | if (data.selection?.start && data.selection?.end) { |
| 93 | const { start, end } = data.selection |
| 94 | let lineCount = end.line - start.line + 1 |
| 95 | // If on the first character of the line, do not count the line |
| 96 | // as being selected. |
| 97 | if (end.character === 0) { |
| 98 | lineCount-- |
| 99 | } |
| 100 | const selection = { |
| 101 | lineCount, |
| 102 | lineStart: start.line, |
| 103 | text: data.text, |
| 104 | filePath: data.filePath, |
| 105 | } |
| 106 | |
| 107 | onSelect(selection) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Register notification handler for selection_changed events |
| 112 | ideClient.client.setNotificationHandler( |
| 113 | SelectionChangedSchema(), |
| 114 | notification => { |
| 115 | if (currentIDERef.current !== ideClient) { |
| 116 | return |
no test coverage detected