import * as monaco from 'monaco-editor'; import type { editor } from 'monaco-editor'; import { parse } from '../parser'; import { locate } from '../parser/locate'; import type { LogQLFieldCompletionContext, LogQLLanguage, VendorConfig } from '../types'; import { buildCompletions } from './completions'; import type { MutableRefObject } from 'react'; import { getHistoryCompletionItems } from '../history'; export interface ProviderOptions { vendor: VendorConfig; getVariables: () => string[]; getLanguage: () => LogQLLanguage; getHistoryKey: () => string | undefined; getCanShowHistory: () => boolean; getFetchFieldNames: () => ((ctx: LogQLFieldCompletionContext) => Promise) | undefined; getFetchFieldValues: () => ((fieldName: string, ctx: LogQLFieldCompletionContext) => Promise) | undefined; editorRef: MutableRefObject; } export function getLogQLCompletionProvider(opts: ProviderOptions): monaco.languages.CompletionItemProvider { return { triggerCharacters: ['$', ':', '=', '|', '(', ' ', ',', '.'], provideCompletionItems: async (model, position) => { // Only serve requests from this editor's own model if (opts.editorRef.current?.getModel()?.id !== model.id) { return { suggestions: [] }; } const value = model.getValue(); const offset = model.getOffsetAt(position); const { ast, tokens } = parse(value); const situation = locate(offset, ast, tokens); const startPos = model.getPositionAt(situation.replaceRange.start); const endPos = model.getPositionAt(situation.replaceRange.end); const range: monaco.IRange = { startLineNumber: startPos.lineNumber, startColumn: startPos.column, endLineNumber: endPos.lineNumber, endColumn: endPos.column, }; const isHistoryContext = opts.getCanShowHistory() && situation.section === 'search' && offset === value.length; const fullRange: monaco.IRange = { startLineNumber: 1, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column, }; const suggestions = await buildCompletions({ vendor: opts.vendor, situation, range, variables: opts.getVariables(), language: opts.getLanguage(), history: isHistoryContext ? getHistoryCompletionItems(opts.getHistoryKey()) : [], historyRange: fullRange, fetchFieldNames: opts.getFetchFieldNames(), fetchFieldValues: opts.getFetchFieldValues(), }); return { suggestions }; }, }; }