LCOV - code coverage report
Current view: top level - dashql-app/src/session/editor - dashql_cursor_diagnostics.ts Coverage Total Hit
Test: DashQL 915828b Lines: 100.0 % 43 43
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : import * as dashql from '@ankoh/dashql-core';
       2              : 
       3              : import { Tooltip, showTooltip } from '@codemirror/view';
       4              : import { Transaction, StateField } from '@codemirror/state';
       5              : 
       6              : import { DashQLCompletionStatus, DashQLProcessorPlugin } from './dashql_processor.js';
       7              : import { editorDiagnostics } from './dashql_script_references.js';
       8              : 
       9              : interface CursorError {
      10              :     message: string;
      11              :     from: number;
      12              :     to: number;
      13              : }
      14              : 
      15            1 : function findErrorAtCursor(diagnostics: dashql.buffers.editor.EditorDiagnosticT[] | null, cursor: number): CursorError | null {
      16            1 :     for (const diagnostic of diagnostics ?? []) {
      17            1 :         const loc = diagnostic.textSpan;
      18            1 :         if (loc == null) continue;
      19            1 :         const from = Number(loc.offset);
      20            1 :         const to = Number(loc.offset + loc.length);
      21            1 :         if (from <= cursor && to >= cursor) {
      22            1 :             return { message: typeof diagnostic.message === 'string' ? diagnostic.message : '', from, to };
      23              :         }
      24            1 :     }
      25            1 :     return null;
      26            1 : }
      27              : 
      28            1 : function createTooltip(error: CursorError): Tooltip {
      29            1 :     return {
      30            1 :         pos: error.from,
      31            1 :         end: error.to,
      32            1 :         arrow: true,
      33            1 :         create: () => {
      34            1 :             const dom = document.createElement('div');
      35            1 :             dom.className = 'cm-tooltip-cursor-diagnostics';
      36            1 :             dom.textContent = error.message;
      37            1 :             return { dom };
      38            1 :         },
      39            1 :     };
      40            1 : }
      41              : 
      42              : interface CursorDiagnosticsSnapshot {
      43              :     update: dashql.buffers.editor.EditorDiagnosticT[] | null;
      44              :     pos: number;
      45              :     tooltip: Tooltip | null;
      46              : }
      47              : 
      48            1 : const CursorDiagnosticsField = StateField.define<CursorDiagnosticsSnapshot>({
      49            1 :     create: () => ({ update: null, pos: -1, tooltip: null }),
      50            1 :     update: (prev: CursorDiagnosticsSnapshot, transaction: Transaction) => {
      51            1 :         const pos = transaction.state.selection.main.head;
      52            1 :         const processor = transaction.state.field(DashQLProcessorPlugin);
      53            1 :         const update = editorDiagnostics(transaction.state);
      54              : 
      55              :         // Nothing changed?
      56            1 :         if (update === prev.update && pos === prev.pos) {
      57            1 :             return prev;
      58              :         }
      59              : 
      60              :         // Hide tooltip during active completion
      61            1 :         if (processor.scriptCompletion?.status == DashQLCompletionStatus.AVAILABLE) {
      62            1 :             return { update, pos, tooltip: null };
      63              :         }
      64              : 
      65            1 :         const error = findErrorAtCursor(update, pos);
      66            1 :         return { update, pos, tooltip: error ? createTooltip(error) : null };
      67            1 :     },
      68            1 :     provide: f => showTooltip.computeN([f], state => {
      69            1 :         const tooltip = state.field(f).tooltip;
      70            1 :         return tooltip ? [tooltip] : [];
      71            1 :     }),
      72            1 : });
      73              : 
      74            1 : export const DashQLCursorDiagnosticsPlugin = [CursorDiagnosticsField];
        

Generated by: LCOV version 2.0-1