vscode#CompletionItemKind TypeScript Examples

The following examples show how to use vscode#CompletionItemKind. 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: ALDocCommentProvider.ts    From vscode-alxmldocumentation with MIT License 6 votes vote down vote up
/**
     * 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;
        }

    }
Example #2
Source File: NextObjectIdCompletionItem.ts    From al-objid with MIT License 6 votes vote down vote up
constructor(
        type: string,
        objectId: NextObjectIdInfo,
        app: ALApp,
        position: Position,
        uri: Uri,
        nextIdContext: NextIdContext,
        range?: NinjaALRange
    ) {
        super(`${objectId.id}${nextIdContext.injectSemicolon ? ";" : ""}`, CompletionItemKind.Constant);

        this._injectSemicolon = nextIdContext.injectSemicolon;
        this._range = range;

        this.sortText = nextIdContext.additional ? `0.${nextIdContext.additional.ordinal / 1000}` : "0";
        this.command = this.getCompletionCommand(position, uri, type, app, objectId);
        this.documentation = this.getCompletionDocumentation(type, objectId);
        this.insertText = `${objectId.id}${this._injectSemicolon ? ";" : ""}`;
        this.detail = "AL Object ID Ninja";
        this.label = range && range.description ? `${objectId.id} (${range.description})` : this.insertText;
        this.kind = CompletionItemKind.Constant;
    }
Example #3
Source File: completionProvider.spec.ts    From memo with MIT License 6 votes vote down vote up
describe('resolveCompletionItem()', () => {
  beforeEach(closeEditorsAndCleanWorkspace);

  afterEach(closeEditorsAndCleanWorkspace);

  it('should add documentation for a markdown completion item', async () => {
    const noteName = `note-${rndName()}`;

    const noteUri = await createFile(`${noteName}.md`, 'Test documentation');

    const completionItem: MemoCompletionItem = new CompletionItem(
      noteName,
      CompletionItemKind.File,
    );

    completionItem.fsPath = noteUri!.fsPath;

    expect(
      ((await resolveCompletionItem(completionItem)).documentation as MarkdownString).value,
    ).toBe('Test documentation');
  });

  it('should add documentation for an image completion item', async () => {
    const imageName = `image-${rndName()}`;

    const imageUri = await createFile(`${imageName}.png`);

    const completionItem: MemoCompletionItem = new CompletionItem(
      imageName,
      CompletionItemKind.File,
    );

    completionItem.fsPath = imageUri!.fsPath;

    expect(
      ((await resolveCompletionItem(completionItem)).documentation as MarkdownString).value,
    ).toBe(`![](${Uri.file(completionItem.fsPath).toString()})`);
  });
});
Example #4
Source File: path-completion.test.ts    From coffeesense with MIT License 6 votes vote down vote up
describe('Should do path completion for import', () => {
	const doc_uri = getDocUri('completion/path.coffee')

	it('completes local file names when importing', async () => {
		await testCompletion({ doc_uri, position: position(0, 20), expected_items: [
			{
				label: 'item.coffee',
				kind: CompletionItemKind.File
			}
		], allow_unspecified: true })
	})
})
Example #5
Source File: sourceAutocompletionProvider.ts    From vscode-dbt-power-user with MIT License 6 votes vote down vote up
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);
    });
  }
Example #6
Source File: spSymbolProvider.ts    From sourcepawn-vscode with MIT License 6 votes vote down vote up
allowedKinds = [
  CompletionItemKind.Function,
  CompletionItemKind.Class,
  CompletionItemKind.Struct,
  CompletionItemKind.Enum,
  CompletionItemKind.Constant,
  CompletionItemKind.Variable,
  CompletionItemKind.TypeParameter,
]
Example #7
Source File: ALDocCommentProvider.ts    From vscode-alxmldocumentation with MIT License 6 votes vote down vote up
/**
     * 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);
    }
Example #8
Source File: element-completion-item-povider.ts    From element-ui-helper with MIT License 6 votes vote down vote up
/**
   * 获取属性值的提示信息
   *
   * @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
  }
Example #9
Source File: spEnumStructItem.ts    From sourcepawn-vscode with MIT License 5 votes vote down vote up
kind = CompletionItemKind.Struct;
Example #10
Source File: lexCompletions.ts    From yash with MIT License 5 votes vote down vote up
export function doLEXCompletion(document: TextDocument, position: Position, lexDocument: LexDocument): CompletionItem[] | CompletionList {
    const offset = document.offsetAt(position);
    const text = document.getText();
    const embedded = lexDocument.getEmbeddedCode(offset);
    if (embedded !== undefined) {
        return [];
    }

    const scanner = createScanner(text, offset - 1);
    if (scanner.scan() === TokenType.Percent) {
        if (position.character === 1 && offset < lexDocument.rulesRange[0])
            return keywords.map((keyword) => {
                const completion = new CompletionItem(keyword);
                completion.detail = "keyword";
                completion.kind = CompletionItemKind.Constructor;
                return completion;
            });
        return [];
    }

    const word = document.getText(document.getWordRangeAtPosition(position)).toUpperCase();

    const line = document.lineAt(position.line).text.substring(0, position.character);
    const result: CompletionItem[] = [];
    if (offset < lexDocument.rulesRange[0]) {
        // if before rules zone, definition need to be on the right
        const ok = line.match(/^\w+.*({\w*}?)+/);
        if (ok) {
            Object.keys(lexDocument.defines).filter(t=>t.toUpperCase().startsWith(word)).forEach((key) => {
                const completion = new CompletionItem(key);
                completion.detail = "definition";
                completion.kind = CompletionItemKind.Class;
                result.push(completion);
            })
        }
    } else if (offset < lexDocument.rulesRange[1]) {
        const res = line.match(/^[^\s]*(?:{\w*}?)+$/);
        if (res) {
            if (res[0].length >= position.character) {
                Object.keys(lexDocument.defines).filter(t=>t.toUpperCase().startsWith(word)).forEach((key) => {
                    const completion = new CompletionItem(key);
                    completion.detail = "definition";
                    completion.kind = CompletionItemKind.Class;
                    result.push(completion);
                })
            }
        } else {
            if (line.match(/^<[\w,]*>[^\s]*(?:{\w*}?)+$/)) {
                Object.keys(lexDocument.defines).filter(t=>t.toUpperCase().startsWith(word)).forEach((key) => {
                    const completion = new CompletionItem(key);
                    completion.detail = "definition";
                    completion.kind = CompletionItemKind.Class;
                    result.push(completion);
                })
            } else if (line.match(/^<[\w,]*$/)) { // TODO: fix completion for {} after <>

                Object.keys(lexDocument.states).filter(t=>t.toUpperCase().startsWith(word)).forEach((key) => {
                    const completion = new CompletionItem(key);
                    completion.detail = "initial state";
                    completion.kind = CompletionItemKind.Class;
                    result.push(completion);
                })
            }
        }
    }
    return result;
}
Example #11
Source File: ccEvents.ts    From sourcepawn-vscode with MIT License 5 votes vote down vote up
kind: CompletionItemKind = CompletionItemKind.Keyword
Example #12
Source File: completionProvider.ts    From dendron with GNU Affero General Public License v3.0 4 votes vote down vote up
provideCompletionItems = sentryReportingCallback(
  (document: TextDocument, position: Position) => {
    const ctx = "provideCompletionItems";

    // No-op if we're not in a Dendron Workspace
    if (!DendronExtension.isActive()) {
      return;
    }

    const line = document.lineAt(position).text;
    Logger.debug({ ctx, position, msg: "enter" });

    let found: RegExpMatchArray | undefined;
    const matches = line.matchAll(NOTE_AUTOCOMPLETEABLE_REGEX);
    for (const match of matches) {
      if (_.isUndefined(match.groups) || _.isUndefined(match.index)) continue;
      const { entireLink } = match.groups;
      if (
        match.index <= position.character &&
        position.character <= match.index + entireLink.length
      ) {
        found = match;
      }
    }
    if (
      _.isUndefined(found) ||
      _.isUndefined(found.index) ||
      _.isUndefined(found.groups)
    )
      return;
    Logger.debug({ ctx, found });

    if (
      (found.groups.hash || found.groups.hashNoSpace) &&
      found.index + (found.groups.beforeAnchor?.length || 0) >
        position.character
    ) {
      Logger.info({ ctx, msg: "letting block autocomplete take over" });
      return;
    }

    let start: number;
    let end: number;
    if (found.groups.hashTag || found.groups.userTag) {
      // This is a hashtag or user tag
      start = found.index + 1 /* for the # or @ symbol */;
      end =
        start +
        (found.groups.tagContents?.length ||
          found.groups.userTagContents?.length ||
          0);
    } else {
      // This is a wikilink or a reference
      start = found.index + (found.groups.beforeNote?.length || 0);
      end =
        start +
        (found.groups.note?.length || found.groups.noteNoSpace?.length || 0);
    }
    const range = new Range(position.line, start, position.line, end);

    const { engine } = getDWorkspace();
    const { notes, wsRoot } = engine;
    const completionItems: CompletionItem[] = [];
    const currentVault = WSUtils.getNoteFromDocument(document)?.vault;
    Logger.debug({
      ctx,
      range,
      notesLength: notes.length,
      currentVault,
      wsRoot,
    });

    _.values(notes).map((note, index) => {
      const item: CompletionItem = {
        label: note.fname,
        insertText: note.fname,
        kind: CompletionItemKind.File,
        sortText: padWithZero(index),
        detail: VaultUtils.getName(note.vault),
        range,
      };

      if (found?.groups?.hashTag) {
        // We are completing a hashtag, so only do completion for tag notes.
        if (!note.fname.startsWith(TAGS_HIERARCHY)) return;
        // Since this is a hashtag, `tags.foo` becomes `#foo`.
        item.label = `${note.fname.slice(TAGS_HIERARCHY.length)}`;
        item.insertText = item.label;
        // hashtags don't support xvault links, so we skip any special xvault handling
      } else if (found?.groups?.userTag) {
        // We are completing a user tag, so only do completion for user notes.
        if (!note.fname.startsWith(USERS_HIERARCHY)) return;
        // Since this is a hashtag, `tags.foo` becomes `#foo`.
        item.label = `${note.fname.slice(USERS_HIERARCHY.length)}`;
        item.insertText = item.label;
        // user tags don't support xvault links, so we skip any special xvault handling
      } else {
        if (found?.groups?.noBracket !== undefined) {
          // If the brackets are missing, then insert them too
          item.insertText = `${item.insertText}]]`;
        }
        if (
          currentVault &&
          !VaultUtils.isEqual(currentVault, note.vault, wsRoot)
        ) {
          // For notes from other vaults than the current note, sort them after notes from the current vault.
          // x will get sorted after numbers, so these will appear after notes without x
          item.sortText = "x" + item.sortText;

          const sameNameNotes = NoteUtils.getNotesByFnameFromEngine({
            fname: note.fname,
            engine,
          }).length;
          if (sameNameNotes > 1) {
            // There are multiple notes with the same name in multiple vaults,
            // and this note is in a different vault than the current note.
            // To generate a link to this note, we have to do an xvault link.
            item.insertText = `${VaultUtils.toURIPrefix(note.vault)}/${
              item.insertText
            }`;
          }
        }
      }
      completionItems.push(item);
    });
    Logger.info({ ctx, completionItemsLength: completionItems.length });
    return completionItems;
  }
)
Example #13
Source File: spCompletionProvider.ts    From sourcepawn-vscode with MIT License 4 votes vote down vote up
export function completionProvider(
  itemsRepo: ItemsRepository,
  document: TextDocument,
  position: Position,
  token: CancellationToken
): CompletionList {
  const text = document
    .lineAt(position.line)
    .text.substring(0, position.character);

  // If the trigger char is a space, check if there is a
  // "new" behind, and deal with the associated constructor.
  if (text[text.length - 1] === " ") {
    if (position.character > 0) {
      const line = document
        .lineAt(position.line)
        .text.substring(0, position.character);

      let match = line.match(
        /(\w*)\s+([\w.\(\)]+)(?:\[[\w+ \d]+\])*\s*\=\s*new\s+(\w*)$/
      );
      if (match) {
        let type: string | undefined;

        if (!match[1]) {
          // If the variable is not declared here, look up its type, as it
          // has not yet been parsed.
          let allItems = itemsRepo.getAllItems(document.uri);
          const lastFunc = getLastFunc(position, document, allItems);
          let newPos = new Position(1, match[2].length + 1);
          const lastEnumStructOrMethodMap = getLastEnumStructNameOrMethodMap(
            position,
            document.uri.fsPath,
            allItems
          );
          let { variableType, words } = getTypeOfVariable(
            // Hack to use getTypeOfVariable
            match[2] + ".",
            newPos,
            allItems,
            lastFunc,
            lastEnumStructOrMethodMap
          );
          type = variableType;
        } else {
          // If the variable is declared here, search its type directly.
          type = itemsRepo
            .getAllItems(document.uri)
            .find(
              (item) =>
                item.kind === CompletionItemKind.Class && item.name === match[1]
            ).name;
        }

        // Filter the item to only keep the constructors.
        let items = itemsRepo
          .getAllItems(document.uri)
          .filter((item) => item.kind === CompletionItemKind.Constructor);
        return new CompletionList(
          items.map((e) => {
            // Show the associated type's constructor first.
            if (e.name === type) {
              let tmp = e.toCompletionItem();
              tmp.preselect = true;
              return tmp;
            }
            return e.toCompletionItem();
          })
        );
      }
    }
    return new CompletionList();
  }

  // Check if we are dealing with an include.
  let match = text.match(/^\s*#\s*include\s*(?:\<([^>]*)\>?)/);
  let useAp = false;
  if (!match) {
    match = text.match(/^\s*#\s*include\s*(?:\"([^\"]*)\"?)/);
    useAp = true;
  }
  if (match) {
    return getIncludeFileCompletionList(
      itemsRepo.documents,
      document,
      match[1],
      useAp
    );
  }
  match = text.match(
    /^\s*(?:HookEvent|HookEventEx)\s*\(\s*(\"[^\"]*|\'[^\']*)$/
  );
  if (match) {
    return itemsRepo.getEventCompletions();
  }
  if (['"', "'", "<", "/", "\\"].includes(text[text.length - 1]))
    return undefined;
  if (/[^:]\:$/.test(text)) {
    return undefined;
  }
  return getCompletionListFromPosition(itemsRepo, document, position);
}
Example #14
Source File: completionHelper.ts    From coffeesense with MIT License 4 votes vote down vote up
export async function testCompletion({ doc_uri, position, expected_items: expectedItems, match_fn: matchFn, allow_globals, unexpected_items, allow_unspecified }: {
  doc_uri: vscode.Uri,
  position: vscode.Position,
  expected_items: (string | ExpectedCompletionItem)[],
  unexpected_items?: string[],
  allow_unspecified?: boolean,
  allow_globals?: boolean,
  match_fn?: (ei: string | ExpectedCompletionItem) => (result: CompletionItem) => boolean,
}) {
  await showFile(doc_uri);

  const result = (await vscode.commands.executeCommand(
    'vscode.executeCompletionItemProvider',
    doc_uri,
    position
  )) as vscode.CompletionList;

  if(!allow_unspecified && !allow_globals)
    //@ts-ignore
    assert.equal(expectedItems.length, result.items.filter(i => i.label.label !== '#region' && i.label.label !== '#endregion' && i.label !== '#region' && i.label !== '#endregion').length)

  if(!allow_globals) {
    // We never want to see global suggestions, like DOM:
    // This is because 1. it can yield false positives from import suggestions
    // for fields that should have been suggested from other sources instead, and
    // 2. it almost always means that some scoping is wrong.
    assert.ok(! result.items.some(i => i.label === 'AbortController' || i.label === 'encodeURIComponent'))
    // With lodash, there can be as many as 396 (2022-03)
    assert.ok(result.items.length < 450)
  }

  if(unexpected_items?.length)
    // @ts-ignore
    assert.ok(! result.items.some(i => unexpected_items.includes(i.label.label? i.label.label : i.label)))

  expectedItems.forEach(ei => {
    let match_index = -1
    if (typeof ei === 'string') {
      match_index = result.items.findIndex(i => {
          return i.label === ei &&
            // Omit standard matches like variable as these primarily yield false positives.
            // If these are really required, they can be passed separately.
            [CompletionItemKind.Function, CompletionItemKind.Property, CompletionItemKind.Field].includes(i.kind || -1)
        })
      assert.ok(match_index > -1,
        `Can't find matching item for\n${JSON.stringify(ei, null, 2)}\nSeen items:\n${JSON.stringify(
          result.items,
          null,
          2
        )}`
      );
    } else {
      const match_index = matchFn ? result.items.findIndex(matchFn(ei)) : result.items.findIndex(i => i.label === ei.label);
      const match = result.items[match_index]
      if (!match) {
        assert.fail(
          `Can't find matching item for\n${JSON.stringify(ei, null, 2)}\nSeen items:\n${JSON.stringify(
            result.items,
            null,
            2
          )}`
        );
      }

      assert.equal(match.label, ei.label);
      if (ei.kind) {
        assert.equal(match.kind, ei.kind);
      }
      if (ei.detail) {
        assert.equal(match.detail, ei.detail);
      }

      if (ei.documentation) {
        if (typeof match.documentation === 'string') {
          assert.equal(normalizeNewline(match.documentation), normalizeNewline(ei.documentation as string));
        } else {
          if (ei.documentation && (ei.documentation as MarkdownString).value && match.documentation) {
            assert.equal(
              normalizeNewline((match.documentation as vscode.MarkdownString).value),
              normalizeNewline((ei.documentation as MarkdownString).value)
            );
          }
        }
      }

      if (ei.documentationStart) {
        if (typeof match.documentation === 'string') {
          assert.ok(
            match.documentation.startsWith(ei.documentationStart),
            `${match.documentation}\ndoes not start with\n${ei.documentationStart}`
          );
        } else {
          assert.ok(
            (match.documentation as vscode.MarkdownString).value.startsWith(ei.documentationStart),
            `${(match.documentation as vscode.MarkdownString).value}\ndoes not start with\n${ei.documentationStart}`
          );
        }
      }

      if (ei.documentationFragment) {
        if (typeof match.documentation === 'string') {
          assert.ok(
            match.documentation.includes(ei.documentationFragment),
            `${match.documentation}\ndoes not include\n${ei.documentationFragment}`
          );
        } else {
          assert.ok(
            (match.documentation as vscode.MarkdownString).value.includes(ei.documentationFragment),
            `${(match.documentation as vscode.MarkdownString).value}\ndoes not include\n${ei.documentationFragment}`
          );
        }
      }

      if (ei.insertTextValue) {
        if (match.insertText instanceof vscode.SnippetString) {
          assert.strictEqual(match.insertText.value, ei.insertTextValue);
        } else {
          assert.strictEqual(match.insertText, ei.insertTextValue);
        }
      }

      if (ei.textEdit) {
        assert.strictEqual(match.textEdit?.newText, ei.textEdit.newText)
        assert.strictEqual(match.textEdit?.range.start.line, ei.textEdit.range.start.line)
        assert.strictEqual(match.textEdit?.range.start.character, ei.textEdit.range.start.character)
        assert.strictEqual(match.textEdit?.range.end.line, ei.textEdit.range.end.line)
        assert.strictEqual(match.textEdit?.range.end.character, ei.textEdit.range.end.character)
      }
    }

    if(!allow_unspecified)
      assert.ok(match_index < expectedItems.length, `Expected item found but after unspecified items! match_index ${match_index} >= expectedItems.length ${expectedItems.length}`)
  });
}
Example #15
Source File: completionProvider.ts    From memo with MIT License 4 votes vote down vote up
provideCompletionItems = (document: TextDocument, position: Position) => {
  const linePrefix = document.lineAt(position).text.substr(0, position.character);

  const isResourceAutocomplete = linePrefix.match(/\!\[\[\w*$/);
  const isDocsAutocomplete = linePrefix.match(/\[\[\w*$/);

  if (!isDocsAutocomplete && !isResourceAutocomplete) {
    return undefined;
  }

  const completionItems: MemoCompletionItem[] = [];

  const uris: Uri[] = [
    ...(isResourceAutocomplete
      ? [...cache.getWorkspaceCache().imageUris, ...cache.getWorkspaceCache().markdownUris]
      : []),
    ...(!isResourceAutocomplete
      ? [
          ...cache.getWorkspaceCache().markdownUris,
          ...cache.getWorkspaceCache().imageUris,
          ...cache.getWorkspaceCache().otherUris,
        ]
      : []),
  ];

  const urisByPathBasename = groupBy(uris, ({ fsPath }) => path.basename(fsPath).toLowerCase());

  uris.forEach((uri, index) => {
    const workspaceFolder = workspace.getWorkspaceFolder(uri);

    if (!workspaceFolder) {
      return;
    }

    const longRef = fsPathToRef({
      path: uri.fsPath,
      basePath: workspaceFolder.uri.fsPath,
      keepExt: containsImageExt(uri.fsPath) || containsOtherKnownExts(uri.fsPath),
    });

    const shortRef = fsPathToRef({
      path: uri.fsPath,
      keepExt: containsImageExt(uri.fsPath) || containsOtherKnownExts(uri.fsPath),
    });

    const urisGroup = urisByPathBasename[path.basename(uri.fsPath).toLowerCase()] || [];

    const isFirstUriInGroup =
      urisGroup.findIndex((uriParam) => uriParam.fsPath === uri.fsPath) === 0;

    if (!longRef || !shortRef) {
      return;
    }

    const item = new CompletionItem(longRef, CompletionItemKind.File) as MemoCompletionItem;

    const linksFormat = getMemoConfigProperty('links.format', 'short');

    item.insertText = linksFormat === 'long' || !isFirstUriInGroup ? longRef : shortRef;

    // prepend index with 0, so a lexicographic sort doesn't mess things up
    item.sortText = padWithZero(index);

    item.fsPath = uri.fsPath;

    completionItems.push(item);
  });

  const danglingRefs = cache.getWorkspaceCache().danglingRefs;

  const completionItemsLength = completionItems.length;

  danglingRefs.forEach((ref, index) => {
    const item = new CompletionItem(ref, CompletionItemKind.File);

    item.insertText = ref;

    // prepend index with 0, so a lexicographic sort doesn't mess things up
    item.sortText = padWithZero(completionItemsLength + index);

    completionItems.push(item);
  });

  return completionItems;
}
Example #16
Source File: completionProviders.ts    From vscode-todo-md with MIT License 4 votes vote down vote up
/**
 * Update editor autocomplete/suggest
 */
export function updateCompletions() {
	Global.tagAutocompleteDisposable?.dispose();
	Global.projectAutocompleteDisposable?.dispose();
	Global.contextAutocompleteDisposable?.dispose();
	Global.generalAutocompleteDisposable?.dispose();
	Global.specialTagsAutocompleteDisposable?.dispose();

	Global.tagAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const wordAtCursor = getWordAtPosition(document, position);
				if (!wordAtCursor || !wordAtCursor.startsWith('#')) {
					return undefined;
				}
				const tagCompletions = [];
				const tags = unique($state.tags.concat(Object.keys($state.suggestTags)));
				for (const tag of tags) {
					const tagCompletion = new CompletionItem(tag, CompletionItemKind.Field);
					const documentation = new MarkdownString($state.suggestTags[tag], true);
					documentation.isTrusted = true;
					tagCompletion.documentation = documentation;
					tagCompletion.insertText = `${tag} `;
					tagCompletions.push(tagCompletion);
				}

				return tagCompletions;
			},
		},
		'#',
	);
	Global.projectAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const wordAtCursor = getWordAtPosition(document, position);
				if (!wordAtCursor || !wordAtCursor.startsWith('+')) {
					return undefined;
				}
				const projectCompletions = [];
				const projects = unique($state.projects.concat(Object.keys($state.suggestProjects)));
				for (const project of projects) {
					const projectCompletion = new CompletionItem(project, CompletionItemKind.Field);
					const documentation = new MarkdownString($state.suggestProjects[project], true);
					documentation.isTrusted = true;
					projectCompletion.documentation = documentation;
					projectCompletion.insertText = `${project} `;
					projectCompletions.push(projectCompletion);
				}

				return projectCompletions;
			},
		},
		'+',
	);
	Global.contextAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const wordAtCursor = getWordAtPosition(document, position);
				if (!wordAtCursor || !wordAtCursor.startsWith('@')) {
					return undefined;
				}
				const contextCompletions = [];
				const contexts = unique($state.contexts.concat(Object.keys($state.suggestContexts)));
				for (const context of contexts) {
					const contextCompletion = new CompletionItem(context, CompletionItemKind.Field);
					const documentation = new MarkdownString($state.suggestContexts[context], true);
					documentation.isTrusted = true;
					contextCompletion.documentation = documentation;
					contextCompletion.insertText = `${context} `;
					contextCompletions.push(contextCompletion);
				}

				return contextCompletions;
			},
		},
		'@',
	);
	Global.generalAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const today = new CompletionItem('TODAY', CompletionItemKind.Constant);
				today.insertText = getDateInISOFormat(new Date());

				const setDueDateToday = new CompletionItem('SET_DUE_TODAY', CompletionItemKind.Constant);
				setDueDateToday.insertText = helpCreateSpecialTag(SpecialTagName.Due, getDateInISOFormat(new Date()));

				const setDueDateTomorrow = new CompletionItem('SET_DUE_TOMORROW', CompletionItemKind.Constant);
				setDueDateTomorrow.insertText = helpCreateSpecialTag(SpecialTagName.Due, getDateInISOFormat(dayjs().add(1, 'day')));

				const setDueDateYesterday = new CompletionItem('SET_DUE_YESTERDAY', CompletionItemKind.Constant);
				setDueDateYesterday.insertText = helpCreateSpecialTag(SpecialTagName.Due, getDateInISOFormat(dayjs().subtract(1, 'day')));

				const setDueDateThisWeek = new CompletionItem('SET_DUE_THIS_WEEK', CompletionItemKind.Constant);
				setDueDateThisWeek.insertText = helpCreateSpecialTag(SpecialTagName.Due, helpCreateDueDate('this week'));

				const setDueDateNextWeek = new CompletionItem('SET_DUE_NEXT_WEEK', CompletionItemKind.Constant);
				setDueDateNextWeek.insertText = helpCreateSpecialTag(SpecialTagName.Due, helpCreateDueDate('next week'));

				const weekdayCompletions: CompletionItem[] = weekdayNamesLong.map(weekdayName => {
					const setDueDateWeekday = new CompletionItem(`SET_DUE_${weekdayName.toUpperCase()}`, CompletionItemKind.Constant);
					setDueDateWeekday.insertText = helpCreateSpecialTag(SpecialTagName.Due, helpCreateDueDate(weekdayName));
					return setDueDateWeekday;
				});

				return [
					...weekdayCompletions,
					today,
					setDueDateToday,
					setDueDateTomorrow,
					setDueDateYesterday,
					setDueDateThisWeek,
					setDueDateNextWeek,
				];
			},
		},
		'',
	);
	Global.specialTagsAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const charBeforeCursor = document.getText(new Range(position.line, position.character === 0 ? 0 : position.character - 1, position.line, position.character));
				if (charBeforeCursor !== '{') {
					return undefined;
				}
				const specialTags = [
					SpecialTagName.Collapsed,
					SpecialTagName.CompletionDate,
					SpecialTagName.Count,
					SpecialTagName.CreationDate,
					SpecialTagName.Due,
					SpecialTagName.Duration,
					SpecialTagName.Hidden,
					SpecialTagName.Overdue,
					SpecialTagName.Started,
				];

				const specialTagCompletionItems = [];

				for (const specialTag of specialTags) {
					const completionItem = new CompletionItem(specialTag, CompletionItemKind.Field);
					completionItem.detail = specialTagDescription[specialTag];
					specialTagCompletionItems.push(completionItem);
				}

				return specialTagCompletionItems;
			},
		},
		'{',
	);
	Global.setDueDateAutocompleteDisposable = languages.registerCompletionItemProvider(
		getTodoMdFileDocumentSelector(),
		{
			provideCompletionItems(document: TextDocument, position: Position) {
				const wordRange = getWordRangeAtPosition(document, position);
				const wordAtCursor = getWordAtPosition(document, position);
				if (!wordAtCursor) {
					return undefined;
				}

				if (wordAtCursor[wordAtCursor.length - 1] === '$') {
					const dueDate = helpCreateDueDate(wordAtCursor.slice(0, -1));
					if (!dueDate) {
						return [];
					}
					const completionItem = new CompletionItem(new DueDate(dueDate).closestDueDateInTheFuture, CompletionItemKind.Constant);
					completionItem.insertText = '';
					completionItem.filterText = wordAtCursor;
					completionItem.command = {
						command: 'todomd.setDueDateWithArgs',
						title: 'Set Due Date with arguments',
						arguments: [
							document,
							wordRange,
							dueDate,
						],
					};
					return [completionItem];
				} else {
					return [];
				}
			},
		},
		'$',
	);
}
Example #17
Source File: spSignatureProvider.ts    From sourcepawn-vscode with MIT License 4 votes vote down vote up
export function signatureProvider(
  itemsRepo: ItemsRepository,
  document: TextDocument,
  position: Position,
  token: CancellationToken
) {
  let blankReturn = {
    signatures: [],
    activeSignature: 0,
    activeParameter: 0,
  };
  let { croppedLine, parameterCount } = getSignatureAttributes(
    document,
    position
  );
  if (croppedLine === undefined) {
    return blankReturn;
  }

  // Check if it's a method
  let match = croppedLine.match(/\.(\w+)$/);
  if (match) {
    let methodName = match[1];
    let allItems = itemsRepo.getAllItems(document.uri);
    let lastFunc = getLastFunc(position, document, allItems);
    let newPos = new Position(1, croppedLine.length);
    const lastEnumStructOrMethodMap = getLastEnumStructNameOrMethodMap(
      position,
      document.uri.fsPath,
      allItems
    );
    let { variableType, words } = getTypeOfVariable(
      croppedLine,
      newPos,
      allItems,
      lastFunc,
      lastEnumStructOrMethodMap
    );
    let variableTypeItem = allItems.find(
      (e) =>
        [CompletionItemKind.Class, CompletionItemKind.Struct].includes(
          e.kind
        ) && e.name === variableType
    ) as MethodMapItem | EnumStructItem;

    let variableTypes: (MethodMapItem | EnumStructItem)[];
    if (variableTypeItem.kind === CompletionItemKind.Class) {
      variableTypes = getAllInheritances(
        variableTypeItem as MethodMapItem,
        allItems
      );
    } else {
      variableTypes = [variableTypeItem as EnumStructItem];
    }

    let items = itemsRepo
      .getAllItems(document.uri)
      .filter(
        (item) =>
          (item.kind === CompletionItemKind.Method ||
            item.kind === CompletionItemKind.Property) &&
          variableTypes.includes(item.parent as MethodMapItem) &&
          item.name === methodName
      );
    return {
      signatures: items.map((e) => e.toSignature()),
      activeParameter: parameterCount,
      activeSignature: 0,
    };
  }
  // Match for new keywords
  match = croppedLine.match(/new\s+(\w+)/);
  if (match) {
    let methodMapName = match[1];
    let items = itemsRepo
      .getAllItems(document.uri)
      .filter(
        (item) =>
          item.kind === CompletionItemKind.Constructor &&
          item.name === methodMapName
      );
    return {
      signatures: items.map((e) => e.toSignature()),
      activeParameter: parameterCount,
      activeSignature: 0,
    };
  }

  match = croppedLine.match(/(\w+)$/);
  if (!match) {
    return blankReturn;
  }
  if (["if", "for", "while", "case", "switch", "return"].includes(match[1])) {
    return blankReturn;
  }
  let items = itemsRepo
    .getAllItems(document.uri)
    .filter(
      (item) =>
        item.name === match[1] &&
        [CompletionItemKind.Function, CompletionItemKind.Interface].includes(
          item.kind
        )
    );
  if (items === undefined) {
    return blankReturn;
  }
  // Sort by size of description
  items = items.sort((a, b) => b.description.length - a.description.length);
  return {
    signatures: items.map((e) => e.toSignature()),
    activeParameter: parameterCount,
    activeSignature: 0,
  };
}