documentation: localize()

in src/services/htmlCompletion.ts [372:460]


							documentation: localize('entity.propose', `Character entity representing '${entities[entity]}'`),
							textEdit: TextEdit.replace(range, label),
							insertTextFormat: InsertTextFormat.PlainText
						});
					}
				}
			}
			return result;
		}

		function suggestDoctype(replaceStart: number, replaceEnd: number) {
			const range = getReplaceRange(replaceStart, replaceEnd);
			result.items.push({
				label: '!DOCTYPE',
				kind: CompletionItemKind.Property,
				documentation: 'A preamble for an HTML document.',
				textEdit: TextEdit.replace(range, '!DOCTYPE html>'),
				insertTextFormat: InsertTextFormat.PlainText
			});
		}

		let token = scanner.scan();

		while (token !== TokenType.EOS && scanner.getTokenOffset() <= offset) {
			switch (token) {
				case TokenType.StartTagOpen:
					if (scanner.getTokenEnd() === offset) {
						const endPos = scanNextForEndPos(TokenType.StartTag);
						if (position.line === 0) {
							suggestDoctype(offset, endPos);
						}
						return collectTagSuggestions(offset, endPos);
					}
					break;
				case TokenType.StartTag:
					if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) {
						return collectOpenTagSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd());
					}
					currentTag = scanner.getTokenText();
					break;
				case TokenType.AttributeName:
					if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) {
						return collectAttributeNameSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd());
					}
					currentAttributeName = scanner.getTokenText();
					break;
				case TokenType.DelimiterAssign:
					if (scanner.getTokenEnd() === offset) {
						const endPos = scanNextForEndPos(TokenType.AttributeValue);
						return collectAttributeValueSuggestions(offset, endPos);
					}
					break;
				case TokenType.AttributeValue:
					if (scanner.getTokenOffset() <= offset && offset <= scanner.getTokenEnd()) {
						return collectAttributeValueSuggestions(scanner.getTokenOffset(), scanner.getTokenEnd());
					}
					break;
				case TokenType.Whitespace:
					if (offset <= scanner.getTokenEnd()) {
						switch (scanner.getScannerState()) {
							case ScannerState.AfterOpeningStartTag:
								const startPos = scanner.getTokenOffset();
								const endTagPos = scanNextForEndPos(TokenType.StartTag);
								return collectTagSuggestions(startPos, endTagPos);
							case ScannerState.WithinTag:
							case ScannerState.AfterAttributeName:
								return collectAttributeNameSuggestions(scanner.getTokenEnd());
							case ScannerState.BeforeAttributeValue:
								return collectAttributeValueSuggestions(scanner.getTokenEnd());
							case ScannerState.AfterOpeningEndTag:
								return collectCloseTagSuggestions(scanner.getTokenOffset() - 1, false);
							case ScannerState.WithinContent:
								return collectInsideContent();
						}
					}
					break;
				case TokenType.EndTagOpen:
					if (offset <= scanner.getTokenEnd()) {
						const afterOpenBracket = scanner.getTokenOffset() + 1;
						const endOffset = scanNextForEndPos(TokenType.EndTag);
						return collectCloseTagSuggestions(afterOpenBracket, false, endOffset);
					}
					break;
				case TokenType.EndTag:
					if (offset <= scanner.getTokenEnd()) {
						let start = scanner.getTokenOffset() - 1;
						while (start >= 0) {
							const ch = text.charAt(start);
							if (ch === '/') {