Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 1x 1x 1x 96x 96x 1x 105x 9x 9x 7x 7x 7x 7x 9x 5x 9x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 9x 1x 1x 9x 105x 1x 13x 13x 2x 13x 2x 13x 2x 13x 2x 13x 5x 13x 13x | import { hoverTooltip } from '@codemirror/view';
import type { EditorView } from '@codemirror/view';
import {
AstWalker,
NodeType,
SpelExpressionParser,
VariableReference,
PropertyOrFieldReference,
BeanReference,
TypeReference,
} from '@agentix-e/spel-ts';
import type { SpelNodeImpl } from '@agentix-e/spel-ts';
/**
* Adapter: spel-ts AstWalker → CM6 hoverTooltip.
*/
export function spelHover() {
return hoverTooltip(createHoverSource());
}
/**
* Create the hover tooltip source function for CM6.
* Exported for testing.
*/
export function createHoverSource() {
return (view: EditorView, pos: number) => {
const expression = view.state.sliceDoc();
if (expression.trim().length === 0) return null;
try {
const parser = new SpelExpressionParser();
const ast = parser.parseRaw(expression);
const node = AstWalker.findNodeAt(ast, pos);
if (!node) return null;
const info = getNodeInfo(node);
if (!info) return null;
return {
pos: node.startPos,
end: node.endPos,
create() {
const dom = document.createElement('div');
dom.style.cssText = 'padding: 4px 8px; font-size: 13px; max-width: 300px;';
dom.textContent = info;
return { dom };
},
};
} catch {
return null;
}
};
}
/**
* Get hover tooltip text for a given AST node.
* Exported for testing.
*/
export function getNodeInfo(node: SpelNodeImpl): string | null {
switch (node.nodeType) {
case NodeType.VARIABLE_REFERENCE:
return `Variable: #${(node as VariableReference).getVariableName()}`;
case NodeType.PROPERTY_OR_FIELD_REFERENCE:
return `Property: .${(node as PropertyOrFieldReference).getName()}`;
case NodeType.BEAN_REFERENCE:
return `Spring Bean: @${(node as BeanReference).getBeanName()}`;
case NodeType.TYPE_REFERENCE:
return `Type: T(${(node as TypeReference).getTypeName()})`;
default:
return null;
}
}
|