CodeMirror provides extensive coordinate mapping and layout information for precise positioning and measurement.
interface Rect {
left: number;
right: number;
top: number;
bottom: number;
}
interface BlockInfo {
from: number;
to: number;
length: number;
height: number;
top: number;
type: BlockType;
}class EditorView {
posAtCoords(coords: {x: number, y: number}, precise?: boolean): number | null;
coordsAtPos(pos: number, side?: -1 | 1): Rect | null;
coordsForChar(pos: number): {left: number, right: number, top: number, bottom: number};
lineBlockAt(pos: number): BlockInfo;
lineBlockAtHeight(height: number): BlockInfo;
blockAtHeight(height: number): BlockInfo;
readonly documentTop: number;
readonly documentPadding: {top: number, bottom: number};
readonly viewportLineBlocks: readonly BlockInfo[];
}view.dom.addEventListener("click", (event) => {
const pos = view.posAtCoords({x: event.clientX, y: event.clientY});
if (pos !== null) {
console.log(`Clicked at document position ${pos}`);
// Get line information
const line = view.state.doc.lineAt(pos);
console.log(`Line ${line.number}: "${line.text}"`);
}
});// Ensure position is visible
const targetPos = 1000;
const coords = view.coordsAtPos(targetPos);
if (coords) {
view.scrollDOM.scrollTop = coords.top - view.scrollDOM.clientHeight / 2;
}The layer system provides positioned overlay functionality for creating custom visual elements.
function layer(config: LayerConfig): Extension;
interface LayerConfig {
above?: boolean;
markers: (view: EditorView) => readonly LayerMarker[] | RangeSet<LayerMarker>;
update?: (update: ViewUpdate, markers: readonly LayerMarker[]) => readonly LayerMarker[];
class?: string;
}
interface LayerMarker {
draw(): HTMLElement | null;
update?(dom: HTMLElement, view: EditorView): boolean;
eq(other: LayerMarker): boolean;
destroy?(dom: HTMLElement): void;
}
class RectangleMarker implements LayerMarker {
constructor(className: string, rect: Rect);
draw(): HTMLElement;
eq(other: LayerMarker): boolean;
}// Create a simple overlay layer
const highlightLayer = layer({
above: true,
class: "highlight-layer",
markers(view) {
const markers = [];
// Add rectangle markers for highlights
const selection = view.state.selection.main;
if (!selection.empty) {
const coords = view.coordsAtPos(selection.from);
if (coords) {
markers.push(new RectangleMarker("selection-highlight", coords));
}
}
return markers;
}
});