(cell: CodeCellType, channel: SessionChannel, theme: ThemeType)
| 13 | |
| 14 | /** Hover extension for TS server information */ |
| 15 | export function tsHover(cell: CodeCellType, channel: SessionChannel, theme: ThemeType): Extension { |
| 16 | return hoverTooltip(async (view, pos) => { |
| 17 | if (cell.language !== 'typescript') { |
| 18 | return null; // bail early if not typescript |
| 19 | } |
| 20 | |
| 21 | const { from, to, text } = view.state.doc.lineAt(pos); |
| 22 | let start = pos; |
| 23 | let end = pos; |
| 24 | |
| 25 | while (start > from && /\w/.test(text[start - from - 1] ?? '')) start--; |
| 26 | while (end < to && /\w/.test(text[end - from] ?? '')) end++; |
| 27 | |
| 28 | return { |
| 29 | pos: start, |
| 30 | end: end, |
| 31 | create: () => { |
| 32 | const tooltipContainer = document.createElement('div'); |
| 33 | tooltipContainer.className = 'hidden'; |
| 34 | |
| 35 | function callback({ response }: TsServerQuickInfoResponsePayloadType) { |
| 36 | tooltipContainer.className = 'p-2 space-y-2 max-w-3xl max-h-96 overflow-scroll text-xs'; |
| 37 | const signatureNode = formatCode(response.displayString, theme); |
| 38 | tooltipContainer.appendChild(signatureNode); |
| 39 | |
| 40 | const documentationNode = formatDocumentation(response.documentation); |
| 41 | if (documentationNode !== null) { |
| 42 | tooltipContainer.appendChild(documentationNode); |
| 43 | } |
| 44 | |
| 45 | const tagsNode = formatTags(response.tags); |
| 46 | if (tagsNode !== null) { |
| 47 | tooltipContainer.appendChild(tagsNode); |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | return { |
| 52 | dom: tooltipContainer, |
| 53 | mount() { |
| 54 | channel.on('tsserver:cell:quickinfo:response', callback); |
| 55 | channel.push('tsserver:cell:quickinfo:request', { |
| 56 | cellId: cell.id, |
| 57 | request: { location: mapCMLocationToTsServer(cell.source, pos) }, |
| 58 | }); |
| 59 | }, |
| 60 | destroy() { |
| 61 | channel.off('tsserver:cell:quickinfo:response', callback); |
| 62 | }, |
| 63 | }; |
| 64 | }, |
| 65 | }; |
| 66 | }); |
| 67 | } |
| 68 | |
| 69 | function formatDocumentation(documentation: TsServerJSDocType): HTMLElement | null { |
| 70 | if (!documentation) { |
no outgoing calls
no test coverage detected