public getCompletionsForSelector()

in src/services/cssCompletion.ts [724:811]


	public getCompletionsForSelector(ruleSet: nodes.RuleSet | null, isNested: boolean, result: CompletionList): CompletionList {
		const existingNode = this.findInNodePath(nodes.NodeType.PseudoSelector, nodes.NodeType.IdentifierSelector, nodes.NodeType.ClassSelector, nodes.NodeType.ElementNameSelector);
		if (!existingNode && this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
			// after the ':' of a pseudo selector, no node generated for just ':'
			this.currentWord = ':' + this.currentWord;
			if (this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
				this.currentWord = ':' + this.currentWord; // for '::'
			}
			this.defaultReplaceRange = Range.create(Position.create(this.position.line, this.position.character - this.currentWord.length), this.position);
		}

		const pseudoClasses = this.cssDataManager.getPseudoClasses();
		pseudoClasses.forEach(entry => {
			const insertText = moveCursorInsideParenthesis(entry.name);
			const item: CompletionItem = {
				label: entry.name,
				textEdit: TextEdit.replace(this.getCompletionRange(existingNode), insertText),
				documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
				tags: isDeprecated(entry) ? [CompletionItemTag.Deprecated] : [],
				kind: CompletionItemKind.Function,
				insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
			};
			if (strings.startsWith(entry.name, ':-')) {
				item.sortText = SortTexts.VendorPrefixed;
			}
			result.items.push(item);
		});

		const pseudoElements = this.cssDataManager.getPseudoElements();
		pseudoElements.forEach(entry => {
			const insertText = moveCursorInsideParenthesis(entry.name);
			const item: CompletionItem = {
				label: entry.name,
				textEdit: TextEdit.replace(this.getCompletionRange(existingNode), insertText),
				documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
				tags: isDeprecated(entry) ? [CompletionItemTag.Deprecated] : [],
				kind: CompletionItemKind.Function,
				insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
			};
			if (strings.startsWith(entry.name, '::-')) {
				item.sortText = SortTexts.VendorPrefixed;
			}
			result.items.push(item);
		});
		if (!isNested) { // show html tags only for top level
			for (const entry of languageFacts.html5Tags) {
				result.items.push({
					label: entry,
					textEdit: TextEdit.replace(this.getCompletionRange(existingNode), entry),
					kind: CompletionItemKind.Keyword
				});
			}
			for (const entry of languageFacts.svgElements) {
				result.items.push({
					label: entry,
					textEdit: TextEdit.replace(this.getCompletionRange(existingNode), entry),
					kind: CompletionItemKind.Keyword
				});
			}
		}

		const visited: { [name: string]: boolean } = {};
		visited[this.currentWord] = true;
		const docText = this.textDocument.getText();
		this.styleSheet.accept(n => {
			if (n.type === nodes.NodeType.SimpleSelector && n.length > 0) {
				const selector = docText.substr(n.offset, n.length);
				if (selector.charAt(0) === '.' && !visited[selector]) {
					visited[selector] = true;
					result.items.push({
						label: selector,
						textEdit: TextEdit.replace(this.getCompletionRange(existingNode), selector),
						kind: CompletionItemKind.Keyword
					});
				}
				return false;
			}
			return true;
		});

		if (ruleSet && ruleSet.isNested()) {
			const selector = ruleSet.getSelectors().findFirstChildBeforeOffset(this.offset);
			if (selector && ruleSet.getSelectors().getChildren().indexOf(selector) === 0) {
				this.getPropertyProposals(null, result);
			}
		}
		return result;
	}