vscode#CompletionItemProvider TypeScript Examples

The following examples show how to use vscode#CompletionItemProvider. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: spDocCompletions.ts    From sourcepawn-vscode with MIT License 6 votes vote down vote up
export class JsDocCompletionProvider implements CompletionItemProvider {
  public async provideCompletionItems(
    document: TextDocument,
    position: Position,
    token: CancellationToken
  ): Promise<CompletionItem[] | undefined> {
    if (!document) {
      return undefined;
    }
    let { signature, indent } = await getFullParams(document, position);
    if (signature === undefined) {
      return undefined;
    }

    let functionDesc = signature.parameters.map((e) => e.label.toString());

    let DocCompletionItem = new SpDocCompletionItem(
      position,
      functionDesc,
      indent
    );
    return [DocCompletionItem];
  }
}
Example #2
Source File: microProfileCompletionItemProvider.ts    From vscode-microprofile with Apache License 2.0 6 votes vote down vote up
/**
 * Provides context-aware completion suggestions for Java files in MicroProfile projects
 */
export class MicroProfileCompletionItemProvider implements CompletionItemProvider<CompletionItem> {

  provideCompletionItems(
      document: TextDocument,
      position: Position,
      _token: CancellationToken,
      _context: CompletionContext): ProviderResult<CompletionItem[] | CompletionList<CompletionItem>> {
    return commands.executeCommand("java.execute.workspaceCommand", JAVA_COMPLETION_REQUEST, adaptToMicroProfileCompletionParams(document, position));
  }

}
Example #3
Source File: macroAutocompletionProvider.ts    From vscode-dbt-power-user with MIT License 5 votes vote down vote up
@provideSingleton(MacroAutocompletionProvider) // TODO autocomplete doesn't work when mistype, delete and retype
export class MacroAutocompletionProvider
  implements CompletionItemProvider, Disposable {
  private macrosAutocompleteMap: Map<string, CompletionItem[]> = new Map();
  private disposables: Disposable[] = [];

  constructor(private dbtProjectContainer: DBTProjectContainer) {
    this.disposables.push(
      dbtProjectContainer.onManifestChanged((event) =>
        this.onManifestCacheChanged(event)
      )
    );
  }

  dispose() {
    this.disposables.forEach((disposable) => disposable.dispose());
  }

  provideCompletionItems(
    document: TextDocument,
    position: Position,
    token: CancellationToken,
    context: CompletionContext
  ): ProviderResult<CompletionItem[] | CompletionList<CompletionItem>> {
    const range = document.getWordRangeAtPosition(position);
    if (range && isEnclosedWithinCodeBlock(document, range)) {
      return this.getAutoCompleteItems(document.uri);
    }
    return undefined;
  }

  private onManifestCacheChanged(event: ManifestCacheChangedEvent): void {
    event.added?.forEach((added) => {
      this.macrosAutocompleteMap.set(
        added.projectRoot.fsPath,
        Array.from(added.macroMetaMap.keys()).map(
          (macro) => new CompletionItem(macro, CompletionItemKind.File)
        )
      );
    });
    event.removed?.forEach((removed) => {
      this.macrosAutocompleteMap.delete(removed.projectRoot.fsPath);
    });
  }

  private getAutoCompleteItems = (currentFilePath: Uri) => {
    const projectRootpath = this.dbtProjectContainer.getProjectRootpath(
      currentFilePath
    );
    if (projectRootpath === undefined) {
      return;
    }
    return this.macrosAutocompleteMap.get(projectRootpath.fsPath);
  };
}
Example #4
Source File: modelAutocompletionProvider.ts    From vscode-dbt-power-user with MIT License 5 votes vote down vote up
@provideSingleton(ModelAutocompletionProvider) // TODO autocomplete doesn't work when mistype, delete and retype
export class ModelAutocompletionProvider
  implements CompletionItemProvider, Disposable {
  private static readonly ENDS_WITH_REF = /ref\(['|"]$/;
  private modelAutocompleteMap: Map<string, CompletionItem[]> = new Map();
  private disposables: Disposable[] = [];

  constructor(private dbtProjectContainer: DBTProjectContainer) {
    this.disposables.push(
      dbtProjectContainer.onManifestChanged((event) =>
        this.onManifestCacheChanged(event)
      )
    );
  }

  dispose() {
    this.disposables.forEach((disposable) => disposable.dispose());
  }

  provideCompletionItems(
    document: TextDocument,
    position: Position,
    token: CancellationToken,
    context: CompletionContext
  ): ProviderResult<CompletionItem[] | CompletionList<CompletionItem>> {
    const linePrefix = document
      .lineAt(position)
      .text.substr(0, position.character);
    if (
      linePrefix.match(ModelAutocompletionProvider.ENDS_WITH_REF) &&
      isEnclosedWithinCodeBlock(document, position)
    ) {
      return this.getAutoCompleteItems(document.uri);
    }

    return undefined;
  }

  private onManifestCacheChanged(event: ManifestCacheChangedEvent): void {
    event.added?.forEach((added) => {
      const models = added.nodeMetaMap.keys();
      this.modelAutocompleteMap.set(
        added.projectRoot.fsPath,
        Array.from(models).map(
          (model) => new CompletionItem(model, CompletionItemKind.File)
        )
      );
    });
    event.removed?.forEach((removed) => {
      this.modelAutocompleteMap.delete(removed.projectRoot.fsPath);
    });
  }

  private getAutoCompleteItems = (currentFilePath: Uri) => {
    const projectRootpath = this.dbtProjectContainer.getProjectRootpath(
      currentFilePath
    );
    if (projectRootpath === undefined) {
      return;
    }
    return this.modelAutocompleteMap.get(projectRootpath.fsPath);
  };
}
Example #5
Source File: ALDocCommentProvider.ts    From vscode-alxmldocumentation with MIT License 4 votes vote down vote up
export class ALDocCommentProvider implements CompletionItemProvider {
    private alXmlDocCompletionItems: Array<CompletionItem> = [];

    /**
     * Provide XML Documentation Completion Items (IntelliSense) based on triggering position.
     * @param document Actual Document.
     * @param position Trigger Position.
     * @param token CancellationToken.
     * @param context CompletionContext.
     */
    async provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): Promise<CompletionItem[] | CompletionList<CompletionItem> | null | undefined> {        
        this.alXmlDocCompletionItems = [];

        if (!Configuration.IntelliSenseDocumentationIsEnabled(document.uri)) {
            return;
        }
        
        if (context.triggerCharacter === undefined) {
            return;
        }
        
        let activeLine = ALSyntaxUtil.SplitALCodeToLines(document.getText())[position.line];
        if (activeLine.match(/^[ \t]*\/{3}[ \t]*$/) === null) {
            return;
        }        

        let alObject: ALObject | null = await ALSyntaxUtil.GetALObject(document);
        if (alObject === null) {
            return;
        }

        if (alObject.LineNo > position.line) {     
            this.ProvideALObjectCompletionItems(alObject);
        } else {
            // find procedure
            let alProcedure: ALProcedure | undefined = alObject.Procedures?.find(alProcedure => (alProcedure.LineNo > position.line));
            if (!alProcedure) {
                return;
            }
            
            await this.ProvideALProcedureCompletionItems(alObject, alProcedure);
        }

        return this.alXmlDocCompletionItems;
    }

    /**
     * Provide XML Documentation Completion Items for AL Procedure.
     * @param alObject ALObject.
     * @param alProcedure ALProcedure.
     */
    async ProvideALProcedureCompletionItems(alObject: ALObject, alProcedure: ALProcedure) {
        this.AddXmlDocCompletionItem(alProcedure);

        try {
            if ((alObject.ExtensionType === ALObjectExtensionType.Implement) && (alObject.ExtensionObject !== undefined)) {                
                this.AddInheritXmlDocCompletionItem(alObject, alProcedure);

                let inheritObjLocation: Array<Location> | undefined = await ALSyntaxUtil.GetObjectDefinition(ALObjectType.Interface, alObject.ExtensionObject);
                if ((inheritObjLocation === undefined) || (inheritObjLocation.length === 0)) {
                    return;
                }
                await this.AddXmlDocFromInterfaceCompletionItem(inheritObjLocation, alProcedure);
            }
        } catch {
            return;
        }
    }

    /**
     * Add Completion Item for class XML Documentation snippet.
     * @param alProcedure ALProcedure to document.
     */
    private AddXmlDocCompletionItem(alProcedure: ALProcedure) {
        const completionItem: CompletionItem = new CompletionItem(
            'AL XML Documentation Comment',
            CompletionItemKind.Text
        );

        let snippetText: string = ALDocCommentUtil.GetProcedureDocumentation(alProcedure);

        const snippet: SnippetString = new SnippetString(snippetText.replace('///', '')); // delete leading '///'. The trigger character is already in the document when the completion provider is triggered.
        completionItem.insertText = snippet;
        completionItem.documentation = snippetText;
        completionItem.detail = 'XML documentation comment to document AL procedures.';
        completionItem.sortText = '1';

        this.alXmlDocCompletionItems.push(completionItem);
    }

    /**
     * Add Completion Item for copying XML Documentation from Interface Procedure.
     * @param inheritObjLocation Location of Interface Object.
     * @param alProcedure AL Procedure to document.
     */
    private async AddXmlDocFromInterfaceCompletionItem(inheritObjLocation: Location[], alProcedure: ALProcedure) {
        try {
            const alLangServer = new ALLangServerProxy();
            const alDefinition = await alLangServer.GetALObjectFromDefinition(inheritObjLocation[0].uri.toString(), inheritObjLocation[0].range.start);
            if ((alDefinition !== undefined) && (alDefinition.ALObject !== null)) {
                let inheritALProcedure: ALProcedure | undefined = alDefinition.ALObject.Procedures?.find(inheritALProcedure => (inheritALProcedure.Code === alProcedure?.Code));
                if (inheritALProcedure !== undefined) {

                    const inheritCompletionItem2: CompletionItem = new CompletionItem(
                        'AL XML Documentation Interface Comment',
                        CompletionItemKind.Text
                    );

                    let snippetText: string = ALDocCommentUtil.GetProcedureDocumentation(inheritALProcedure);

                    const snippet: SnippetString = new SnippetString(snippetText.replace('///', '')); // delete leading '///'. The trigger character is already in the document when the completion provider is triggered.
                    inheritCompletionItem2.insertText = snippet;
                    inheritCompletionItem2.documentation = snippetText;
                    inheritCompletionItem2.detail = 'XML documentation interface comment.';
                    inheritCompletionItem2.sortText = '1';

                    this.alXmlDocCompletionItems.push(inheritCompletionItem2);
                }
            }
        } catch(ex) {
            console.error(`[AddXmlDocFromInterfaceCompletionItem] - ${ex} Please report this error at https://github.com/365businessdev/vscode-alxmldocumentation/issues`);
            return undefined;
        }

    }

    /**
     * Add Completion Item for "inheritdoc" XML Comment.
     * @param alObject ALObject.
     * @param alProcedure AL Procedure to document.
     */
    private AddInheritXmlDocCompletionItem(alObject: ALObject, alProcedure: ALProcedure) {
        const inheritCompletionItem: CompletionItem = new CompletionItem(
            'Inherit AL XML Documentation Comment',
            CompletionItemKind.Text
        );

        inheritCompletionItem.detail = 'XML documentation comment to document inherit AL procedures.';
        let snippetText: string = `/// <inheritdoc cref="${alProcedure.Code}"/>`;
        const snippet: SnippetString = new SnippetString(snippetText.replace('///', '')); // delete leading '///'. The trigger character is already in the document when the completion provider is triggered.
        inheritCompletionItem.insertText = snippet;
        inheritCompletionItem.documentation = snippetText;
        inheritCompletionItem.sortText = '1';
        this.alXmlDocCompletionItems.push(inheritCompletionItem);
    }

    /**
     * Provide XML Documentation Completion Items for AL Object.
     * @param alObject ALObject.
     */
    private ProvideALObjectCompletionItems(alObject: ALObject) {               
        const completionItem: CompletionItem = new CompletionItem(
            'AL XML Documentation Comment',
            CompletionItemKind.Text
        );

        let snippetText: string = ALDocCommentUtil.GetObjectDocumentation(alObject);
        const snippet: SnippetString = new SnippetString(snippetText.replace('///', '')); // delete leading '///'. The trigger character is already in the document when the completion provider is triggered.
        completionItem.insertText = snippet;

        completionItem.detail = 'XML documentation comment to document AL objects.';
        completionItem.documentation = snippetText;
        completionItem.sortText = '1';

        this.alXmlDocCompletionItems.push(completionItem);

        return this.alXmlDocCompletionItems;
    }
    
}
Example #6
Source File: element-completion-item-povider.ts    From element-ui-helper with MIT License 4 votes vote down vote up
export class ElementCompletionItemProvider implements CompletionItemProvider<CompletionItem> {
  private _document!: TextDocument
  private _position!: Position
  private token!: CancellationToken
  private tagReg: RegExp = /<([\w-]+)\s*/g
  private attrReg: RegExp = /(?:\(|\s*)([\w-]+)=['"][^'"]*/
  private tagStartReg: RegExp = /<([\w-]*)$/
  private pugTagStartReg: RegExp = /^\s*[\w-]*$/
  private size!: number
  private quotes!: string

  /**
   * 获取前置标签
   */
  getPreTag(): TagObject | undefined {
    let line = this._position.line
    let tag: TagObject | string | undefined
    let txt = this.getTextBeforePosition(this._position)

    while (this._position.line - line < 10 && line >= 0) {
      if (line !== this._position.line) {
        txt = this._document.lineAt(line).text
      }
      tag = this.matchTag(this.tagReg, txt, line)
      if (tag === 'break') {
        return undefined
      }
      if (tag) {
        return <TagObject>tag
      }
      line--
    }
    return undefined
  }

  /**
   * 获取前置属性
   */
  getPreAttr(): string {
    let txt = this.getTextBeforePosition(this._position).replace(/"[^'"]*(\s*)[^'"]*$/, '')
    let end = this._position.character
    let start = txt.lastIndexOf(' ', end) + 1
    let parsedTxt = this._document.getText(new Range(this._position.line, start, this._position.line, end))
    return this.matchAttr(this.attrReg, parsedTxt)
  }

  /**
   * 匹配属性
   *
   * @param reg 匹配模式
   * @param txt 匹配文本
   */
  matchAttr(reg: RegExp, txt: string): string {
    let match: RegExpExecArray | null
    match = reg.exec(txt)
    if (!/"[^"]*"/.test(txt) && match) {
      return match[1]
    }
    return ''
  }

  /**
   * 匹配标签
   * @param reg 匹配模式
   * @param txt 匹配文本
   * @param line 当前行
   */
  matchTag(reg: RegExp, txt: string, line: number): TagObject | string | undefined {
    let match: RegExpExecArray | null
    let arr: TagObject[] = []

    if (/<\/?[-\w]+[^<>]*>[\s\w]*<?\s*[\w-]*$/.test(txt) || (this._position.line === line && (/^\s*[^<]+\s*>[^</>]*$/.test(txt) || /[^<>]*<$/.test(txt[txt.length - 1])))) {
      return 'break'
    }
    while ((match = reg.exec(txt))) {
      arr.push({
        text: match[1],
        offset: this._document.offsetAt(new Position(line, match.index))
      })
    }
    return arr.pop()
  }

  /**
   * 获取当前位置之前的字符串
   *
   * @param position 位置
   */
  getTextBeforePosition(position: Position): string {
    var start = new Position(position.line, 0)
    var range = new Range(start, position)
    return this._document.getText(range)
  }

  /**
   * 是否位属性值的开始
   * @param tag 标签
   * @param attr 属性
   */
  isAttrValueStart(tag: Object | undefined, attr: string) {
    return !!tag && !!attr
  }

  /**
   * 是否位属性的开始
   * @param tag 标签
   */
  isAttrStart(tag: TagObject | undefined) {
    const preText = this.getTextBeforePosition(this._position)
    return tag && / :?[\w-]*$/.test(preText)
  }

  /**
   * 是否为方法的开始
   * @param tag 标签
   */
  isEventStart(tag: TagObject | undefined) {
    const preText = this.getTextBeforePosition(this._position)
    return tag && / @[\w-]*$/.test(preText)
  }

  /**
   * 获取属性值
   *
   * @param tag 标签
   * @param attr 属性
   */
  getAttrValues(tag: string, attr: string): string[] {
    const config = workspace.getConfiguration().get<ExtensionConfigutation>('element-ui-helper')
    const language = config?.language || ExtensionLanguage.cn
    const document: Record<string, any> = localDocument[language]
    const attributes: DocumentAttribute[] = document[tag].attributes || []
    const attribute: DocumentAttribute | undefined = attributes.find((attribute) => attribute.name === attr)
    if (!attribute) {
      return []
    }
    const values = attribute.value.split(/[,/\\]/).map((item) => item.trim())
    return values
  }

  /**
   * 获取属性值的提示信息
   *
   * @param tag 标签
   * @param attr 属性
   */
  getAttrValueCompletionItems(tag: string, attr: string): CompletionItem[] {
    let completionItems: CompletionItem[] = []
    const values = this.getAttrValues(tag, attr)
    values.forEach((value) => {
      if (/\w+/.test(value)) {
        completionItems.push({
          label: `${value}`,
          sortText: `0${value}`,
          detail: `${tag}-${attr}`,
          kind: CompletionItemKind.Value,
          insertText: value
        })
      }
    })
    return completionItems
  }

  /**
   * 获取事件名称提示
   *
   * @param tag 标签
   */
  getEventCompletionItems(tag: string): CompletionItem[] {
    let completionItems: CompletionItem[] = []
    const config = workspace.getConfiguration().get<ExtensionConfigutation>('element-ui-helper')
    const language = config?.language || ExtensionLanguage.cn
    const document: Record<string, any> = localDocument[language]
    const preText = this.getTextBeforePosition(this._position)
    const prefix = preText.replace(/.*@([\w-]*)$/, '$1')
    const events: DocumentEvent[] = document[tag]?.events || []
    const likeTag = events.filter((evnet: DocumentEvent) => evnet.name.includes(prefix))
    likeTag.forEach((event: DocumentEvent) => {
      const start = preText.lastIndexOf('@') + 1
      const end = start + prefix.length
      const startPos = new Position(this._position.line, start)
      const endPos = new Position(this._position.line, end)
      const range = new Range(startPos, endPos)
      completionItems.push({
        label: `${event.name}`,
        sortText: `0${event.name}`,
        detail: `${tag} Event`,
        documentation: event.description,
        kind: CompletionItemKind.Value,
        insertText: event.name,
        range
      })
    })
    return completionItems
  }

  /**
   * 获取属性的提示信息
   *
   * @param tag 标签
   */
  getAttrCompletionItems(tag: string): CompletionItem[] {
    let completionItems: CompletionItem[] = []
    const config = workspace.getConfiguration().get<ExtensionConfigutation>('element-ui-helper')
    const language = config?.language || ExtensionLanguage.cn
    const document: Record<string, any> = localDocument[language]
    const preText = this.getTextBeforePosition(this._position)
    const prefix = preText.replace(/.*[\s@:]/g, '')
    const attributes: DocumentAttribute[] = document[tag].attributes || []
    const likeTag = attributes.filter((attribute: DocumentAttribute) => attribute.name.includes(prefix))
    likeTag.forEach((attribute: DocumentAttribute) => {
      const start = Math.max(preText.lastIndexOf(' '), preText.lastIndexOf(':')) + 1
      const end = start + prefix.length
      const startPos = new Position(this._position.line, start)
      const endPos = new Position(this._position.line, end)
      const range = new Range(startPos, endPos)
      completionItems.push({
        label: `${attribute.name}`,
        sortText: `0${attribute.name}`,
        detail: `${tag} Attribute`,
        documentation: attribute.description,
        kind: CompletionItemKind.Value,
        insertText: attribute.name,
        range
      })
    })
    return completionItems
  }

  /**
   * 是否位标签的开始
   */
  isTagStart(): boolean {
    let txt = this.getTextBeforePosition(this._position)
    return this.tagStartReg.test(txt)
  }

  /**
   * 获取标签提示
   */
  getTagCompletionItems(tag: string): CompletionItem[] {
    let completionItems: CompletionItem[] = []
    const config = workspace.getConfiguration().get<ExtensionConfigutation>('element-ui-helper')
    const language = config?.language || ExtensionLanguage.cn
    const preText = this.getTextBeforePosition(this._position)
    const document: Record<string, any> = localDocument[language]
    Object.keys(document).forEach((key) => {
      const start = preText.lastIndexOf('<') + 1
      const end = preText.length - start + 1
      const startPos = new Position(this._position.line, start)
      const endPos = new Position(this._position.line, end)
      const range = new Range(startPos, endPos)
      completionItems.push({
        label: `${key}`,
        sortText: `0${key}`,
        detail: 'ElementUI Tag',
        kind: CompletionItemKind.Value,
        insertText: new SnippetString().appendText(`${key}`).appendTabstop().appendText('>').appendTabstop().appendText(`</${key}>`),
        range
      })
    })
    return completionItems
  }

  /**
   * 提供自动完成提示
   *
   * @param document 文档
   * @param position 位置
   * @param token token
   * @param context 上下文
   */
  provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): ProviderResult<CompletionItem[] | CompletionList<CompletionItem>> {
    this._document = document
    this._position = position
    this.token = token

    let tag: TagObject | undefined = this.getPreTag()
    let attr = this.getPreAttr()

    if (!tag || !/^[E|e]l/.test(tag.text || '')) {
      // 如果不是element的标签(E|el开头) 则返回 null 表示没有hover
      return null
    } else if (this.isAttrValueStart(tag, attr)) {
      // 如果是属性值的开始
      return this.getAttrValueCompletionItems(tag.text, attr)
    } else if (this.isEventStart(tag)) {
      // 优先判定事件
      return this.getEventCompletionItems(tag.text)
    } else if (this.isAttrStart(tag)) {
      // 判断属性
      return this.getAttrCompletionItems(tag.text)
    } else if (this.isTagStart()) {
      // 判断标签
      return this.getTagCompletionItems(tag.text)
    }

    return null
  }
}
Example #7
Source File: sourceAutocompletionProvider.ts    From vscode-dbt-power-user with MIT License 4 votes vote down vote up
@provideSingleton(SourceAutocompletionProvider) // TODO autocomplete doesn't work when mistype, delete and retype
export class SourceAutocompletionProvider
  implements CompletionItemProvider, Disposable {
  private static readonly GET_SOURCE_NAME = /(?!['"])(\w+)(?=['"])/;
  private static readonly ENDS_WITH_SOURCE = /source\(['|"]$/;
  private sourceAutocompleteNameItemsMap: Map<
    string,
    CompletionItem[]
  > = new Map();
  private sourceAutocompleteTableMap: Map<
    string,
    Map<string, CompletionItem[]>
  > = new Map();
  private disposables: Disposable[] = [];

  constructor(private dbtProjectContainer: DBTProjectContainer) {
    this.disposables.push(
      dbtProjectContainer.onManifestChanged((event) =>
        this.onManifestCacheChanged(event)
      )
    );
  }

  dispose() {
    this.disposables.forEach((disposable) => disposable.dispose());
  }

  provideCompletionItems(
    document: TextDocument,
    position: Position,
    token: CancellationToken,
    context: CompletionContext
  ): ProviderResult<CompletionItem[] | CompletionList<CompletionItem>> {
    const linePrefix = document
      .lineAt(position)
      .text.substr(0, position.character);
    if (!isEnclosedWithinCodeBlock(document, position)) {
      return undefined;
    }
    const projectRootpath = this.dbtProjectContainer.getProjectRootpath(
      document.uri
    );
    if (projectRootpath === undefined) {
      return;
    }

    if (linePrefix.match(SourceAutocompletionProvider.ENDS_WITH_SOURCE)) {
      return this.showSourceNameAutocompletionItems(projectRootpath);
    }

    if (
      linePrefix.match(SourceAutocompletionProvider.GET_SOURCE_NAME) &&
      linePrefix.includes("source")
    ) {
      return this.showTableNameAutocompletionItems(linePrefix, projectRootpath);
    }
    return undefined;
  }

  private onManifestCacheChanged(event: ManifestCacheChangedEvent): void {
    event.added?.forEach((added) => {
      this.sourceAutocompleteNameItemsMap.set(
        added.projectRoot.fsPath,
        Array.from(added.sourceMetaMap.keys()).map(
          (source) => new CompletionItem(source, CompletionItemKind.File)
        )
      );
      const sourceTableMap: Map<string, CompletionItem[]> = new Map();
      added.sourceMetaMap.forEach((value, key) => {
        const autocompleteItems = value.tables.map((item) => {
          return new CompletionItem(item.name, CompletionItemKind.File);
        });
        sourceTableMap.set(key, autocompleteItems);
      });
      this.sourceAutocompleteTableMap.set(
        added.projectRoot.fsPath,
        sourceTableMap
      );
    });
    event.removed?.forEach((removed) => {
      this.sourceAutocompleteNameItemsMap.delete(removed.projectRoot.fsPath);
      this.sourceAutocompleteTableMap.delete(removed.projectRoot.fsPath);
    });
  }

  private showSourceNameAutocompletionItems(projectRootpath: Uri) {
    return this.sourceAutocompleteNameItemsMap.get(projectRootpath.fsPath);
  }

  private showTableNameAutocompletionItems(
    linePrefix: string,
    projectRootpath: Uri
  ) {
    const sourceNameMatch = linePrefix.match(
      SourceAutocompletionProvider.GET_SOURCE_NAME
    );
    if (sourceNameMatch !== null) {
      const sourceTableMap = this.sourceAutocompleteTableMap.get(
        projectRootpath.fsPath
      );
      if (sourceTableMap === undefined) {
        return;
      }
      return sourceTableMap.get(sourceNameMatch[0]);
    }
  }
}