monaco-editor11 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/css.worker-C7FogG4G.js +93 -0
- package/dist/assets/editor.worker-iXcRX1Tq.js +26 -0
- package/dist/assets/html.worker-C8VxctEJ.js +470 -0
- package/dist/assets/json.worker-CMC9kgPL.js +58 -0
- package/dist/assets/ts.worker-CtTJ3hNN.js +67731 -0
- package/dist/index.d.ts +0 -6
- package/dist/monaco-editor11.es.js +49 -78
- package/dist/monaco-editor11.umd.js +1 -50
- package/dist/monaco.d.ts +8 -0
- package/dist/workers/common/initialize.js +16 -0
- package/dist/workers/common/workers.js +141 -0
- package/dist/workers/editor/common/abstractSyntaxTokenBackend.js +128 -0
- package/dist/workers/editor/common/abstractText.js +89 -0
- package/dist/workers/editor/common/ast.js +485 -0
- package/dist/workers/editor/common/autoIndent.js +390 -0
- package/dist/workers/editor/common/beforeEditPositionMapper.js +110 -0
- package/dist/workers/editor/common/bracketPairsImpl.js +717 -0
- package/dist/workers/editor/common/bracketPairsTree.js +343 -0
- package/dist/workers/editor/common/brackets.js +108 -0
- package/dist/workers/editor/common/characterClassifier.js +59 -0
- package/dist/workers/editor/common/characterPair.js +40 -0
- package/dist/workers/editor/common/colorizedBracketPairsDecorationProvider.js +97 -0
- package/dist/workers/editor/common/columnRange.js +35 -0
- package/dist/workers/editor/common/combineTextEditInfos.js +124 -0
- package/dist/workers/editor/common/common.js +20 -0
- package/dist/workers/editor/common/computeMovedLines.js +249 -0
- package/dist/workers/editor/common/concat23Trees.js +192 -0
- package/dist/workers/editor/common/contiguousMultilineTokens.js +32 -0
- package/dist/workers/editor/common/contiguousMultilineTokensBuilder.js +23 -0
- package/dist/workers/editor/common/contiguousTokensEditing.js +128 -0
- package/dist/workers/editor/common/contiguousTokensStore.js +207 -0
- package/dist/workers/editor/common/coordinatesConverter.js +51 -0
- package/dist/workers/editor/common/cursor.js +899 -0
- package/dist/workers/editor/common/cursorAtomicMoveOperations.js +145 -0
- package/dist/workers/editor/common/cursorCollection.js +194 -0
- package/dist/workers/editor/common/cursorColumnSelection.js +93 -0
- package/dist/workers/editor/common/cursorColumns.js +112 -0
- package/dist/workers/editor/common/cursorCommon.js +250 -0
- package/dist/workers/editor/common/cursorContext.js +15 -0
- package/dist/workers/editor/common/cursorDeleteOperations.js +231 -0
- package/dist/workers/editor/common/cursorMoveCommands.js +676 -0
- package/dist/workers/editor/common/cursorMoveOperations.js +290 -0
- package/dist/workers/editor/common/cursorTypeEditOperations.js +968 -0
- package/dist/workers/editor/common/cursorTypeOperations.js +173 -0
- package/dist/workers/editor/common/cursorUtils.js +75 -0
- package/dist/workers/editor/common/cursorWordOperations.js +720 -0
- package/dist/workers/editor/common/defaultDocumentColorsComputer.js +138 -0
- package/dist/workers/editor/common/defaultLinesDiffComputer.js +188 -0
- package/dist/workers/editor/common/diffAlgorithm.js +139 -0
- package/dist/workers/editor/common/diffEditor.js +38 -0
- package/dist/workers/editor/common/dynamicProgrammingDiffing.js +101 -0
- package/dist/workers/editor/common/edit.js +183 -0
- package/dist/workers/editor/common/editOperation.js +36 -0
- package/dist/workers/editor/common/editStack.js +363 -0
- package/dist/workers/editor/common/editorAction.js +26 -0
- package/dist/workers/editor/common/editorBaseApi.js +43 -0
- package/dist/workers/editor/common/editorColorRegistry.js +102 -0
- package/dist/workers/editor/common/editorCommon.js +13 -0
- package/dist/workers/editor/common/editorConfigurationSchema.js +338 -0
- package/dist/workers/editor/common/editorContextKeys.js +84 -0
- package/dist/workers/editor/common/editorFeatures.js +17 -0
- package/dist/workers/editor/common/editorOptions.js +3440 -0
- package/dist/workers/editor/common/editorTheme.js +23 -0
- package/dist/workers/editor/common/editorWebWorker.js +299 -0
- package/dist/workers/editor/common/editorWorker.js +9 -0
- package/dist/workers/editor/common/editorWorkerHost.js +15 -0
- package/dist/workers/editor/common/editorZoom.js +26 -0
- package/dist/workers/editor/common/electricCharacter.js +55 -0
- package/dist/workers/editor/common/encodedTokenAttributes.js +79 -0
- package/dist/workers/editor/common/enterAction.js +53 -0
- package/dist/workers/editor/common/eolCounter.js +44 -0
- package/dist/workers/editor/common/findSectionHeaders.js +128 -0
- package/dist/workers/editor/common/fixBrackets.js +67 -0
- package/dist/workers/editor/common/fixedArray.js +70 -0
- package/dist/workers/editor/common/fontInfo.js +172 -0
- package/dist/workers/editor/common/fontInfoFromSettings.js +29 -0
- package/dist/workers/editor/common/getIconClasses.js +106 -0
- package/dist/workers/editor/common/getPositionOffsetTransformerFromTextModel.js +24 -0
- package/dist/workers/editor/common/glyphLanesModel.js +61 -0
- package/dist/workers/editor/common/guidesTextModelPart.js +405 -0
- package/dist/workers/editor/common/heuristicSequenceOptimizations.js +374 -0
- package/dist/workers/editor/common/indentRules.js +63 -0
- package/dist/workers/editor/common/indentation.js +39 -0
- package/dist/workers/editor/common/indentationGuesser.js +178 -0
- package/dist/workers/editor/common/indentationLineProcessor.js +193 -0
- package/dist/workers/editor/common/inlineDecorations.js +26 -0
- package/dist/workers/editor/common/inplaceReplaceSupport.js +87 -0
- package/dist/workers/editor/common/inputMode.js +22 -0
- package/dist/workers/editor/common/intervalTree.js +1002 -0
- package/dist/workers/editor/common/language.js +9 -0
- package/dist/workers/editor/common/languageBracketsConfiguration.js +133 -0
- package/dist/workers/editor/common/languageConfiguration.js +138 -0
- package/dist/workers/editor/common/languageConfigurationRegistry.js +361 -0
- package/dist/workers/editor/common/languageFeatureDebounce.js +137 -0
- package/dist/workers/editor/common/languageFeatureRegistry.js +180 -0
- package/dist/workers/editor/common/languageFeatures.js +9 -0
- package/dist/workers/editor/common/languageFeaturesService.js +47 -0
- package/dist/workers/editor/common/languageSelector.js +112 -0
- package/dist/workers/editor/common/languageService.js +92 -0
- package/dist/workers/editor/common/languages.js +522 -0
- package/dist/workers/editor/common/languagesAssociations.js +193 -0
- package/dist/workers/editor/common/languagesRegistry.js +237 -0
- package/dist/workers/editor/common/legacyLinesDiffComputer.js +468 -0
- package/dist/workers/editor/common/length.js +129 -0
- package/dist/workers/editor/common/lineDecorations.js +208 -0
- package/dist/workers/editor/common/lineEdit.js +75 -0
- package/dist/workers/editor/common/lineHeights.js +370 -0
- package/dist/workers/editor/common/linePart.js +25 -0
- package/dist/workers/editor/common/lineRange.js +312 -0
- package/dist/workers/editor/common/lineSequence.js +36 -0
- package/dist/workers/editor/common/lineTokens.js +405 -0
- package/dist/workers/editor/common/linesDiffComputer.js +29 -0
- package/dist/workers/editor/common/linesDiffComputers.js +13 -0
- package/dist/workers/editor/common/linesLayout.js +765 -0
- package/dist/workers/editor/common/linesSliceCharSequence.js +205 -0
- package/dist/workers/editor/common/linkComputer.js +269 -0
- package/dist/workers/editor/common/markerDecorations.js +9 -0
- package/dist/workers/editor/common/markerDecorationsService.js +248 -0
- package/dist/workers/editor/common/minimapTokensColorTracker.js +58 -0
- package/dist/workers/editor/common/mirrorTextModel.js +117 -0
- package/dist/workers/editor/common/model.js +9 -0
- package/dist/workers/editor/common/modelLineProjection.js +350 -0
- package/dist/workers/editor/common/modelLineProjectionData.js +297 -0
- package/dist/workers/editor/common/modelService.js +413 -0
- package/dist/workers/editor/common/modesRegistry.js +75 -0
- package/dist/workers/editor/common/monospaceLineBreaksComputer.js +473 -0
- package/dist/workers/editor/common/myersDiffAlgorithm.js +159 -0
- package/dist/workers/editor/common/nodeReader.js +127 -0
- package/dist/workers/editor/common/nullTokenize.js +29 -0
- package/dist/workers/editor/common/offsetRange.js +225 -0
- package/dist/workers/editor/common/onEnter.js +109 -0
- package/dist/workers/editor/common/oneCursor.js +117 -0
- package/dist/workers/editor/common/overviewZoneManager.js +176 -0
- package/dist/workers/editor/common/parser.js +121 -0
- package/dist/workers/editor/common/pieceTreeBase.js +1473 -0
- package/dist/workers/editor/common/pieceTreeTextBuffer.js +461 -0
- package/dist/workers/editor/common/pieceTreeTextBufferBuilder.js +140 -0
- package/dist/workers/editor/common/point.js +50 -0
- package/dist/workers/editor/common/position.js +142 -0
- package/dist/workers/editor/common/positionToOffset.js +17 -0
- package/dist/workers/editor/common/positionToOffsetImpl.js +98 -0
- package/dist/workers/editor/common/prefixSumComputer.js +226 -0
- package/dist/workers/editor/common/range.js +421 -0
- package/dist/workers/editor/common/rangeMapping.js +229 -0
- package/dist/workers/editor/common/rangeSingleLine.js +17 -0
- package/dist/workers/editor/common/rbTreeBase.js +362 -0
- package/dist/workers/editor/common/rect.js +163 -0
- package/dist/workers/editor/common/replaceCommand.js +158 -0
- package/dist/workers/editor/common/resolverService.js +5 -0
- package/dist/workers/editor/common/rgba.js +35 -0
- package/dist/workers/editor/common/richEditBrackets.js +356 -0
- package/dist/workers/editor/common/selection.js +145 -0
- package/dist/workers/editor/common/semanticTokensDto.js +82 -0
- package/dist/workers/editor/common/semanticTokensProviderStyling.js +263 -0
- package/dist/workers/editor/common/semanticTokensStyling.js +9 -0
- package/dist/workers/editor/common/semanticTokensStylingService.js +47 -0
- package/dist/workers/editor/common/shiftCommand.js +241 -0
- package/dist/workers/editor/common/smallImmutableSet.js +108 -0
- package/dist/workers/editor/common/sparseMultilineTokens.js +548 -0
- package/dist/workers/editor/common/sparseTokensStore.js +210 -0
- package/dist/workers/editor/common/standaloneEnums.js +1017 -0
- package/dist/workers/editor/common/standaloneStrings.js +42 -0
- package/dist/workers/editor/common/stringBuilder.js +122 -0
- package/dist/workers/editor/common/stringEdit.js +165 -0
- package/dist/workers/editor/common/supports.js +58 -0
- package/dist/workers/editor/common/surroundSelectionCommand.js +44 -0
- package/dist/workers/editor/common/textChange.js +248 -0
- package/dist/workers/editor/common/textEdit.js +269 -0
- package/dist/workers/editor/common/textLength.js +87 -0
- package/dist/workers/editor/common/textModel.js +2031 -0
- package/dist/workers/editor/common/textModelBracketPairs.js +45 -0
- package/dist/workers/editor/common/textModelDefaults.js +18 -0
- package/dist/workers/editor/common/textModelEditSource.js +166 -0
- package/dist/workers/editor/common/textModelEvents.js +216 -0
- package/dist/workers/editor/common/textModelGuides.js +40 -0
- package/dist/workers/editor/common/textModelPart.js +23 -0
- package/dist/workers/editor/common/textModelSearch.js +455 -0
- package/dist/workers/editor/common/textModelStringEdit.js +11 -0
- package/dist/workers/editor/common/textModelSync.impl.js +307 -0
- package/dist/workers/editor/common/textModelText.js +26 -0
- package/dist/workers/editor/common/textModelTokens.js +436 -0
- package/dist/workers/editor/common/textResourceConfiguration.js +6 -0
- package/dist/workers/editor/common/textToHtmlTokenizer.js +139 -0
- package/dist/workers/editor/common/tokenStore.js +407 -0
- package/dist/workers/editor/common/tokenWithTextArray.js +73 -0
- package/dist/workers/editor/common/tokenization.js +287 -0
- package/dist/workers/editor/common/tokenizationRegistry.js +123 -0
- package/dist/workers/editor/common/tokenizationTextModelPart.js +275 -0
- package/dist/workers/editor/common/tokenizer.js +301 -0
- package/dist/workers/editor/common/tokenizerSyntaxTokenBackend.js +261 -0
- package/dist/workers/editor/common/treeSitterLibraryService.js +9 -0
- package/dist/workers/editor/common/treeSitterSyntaxTokenBackend.js +167 -0
- package/dist/workers/editor/common/treeSitterThemeService.js +9 -0
- package/dist/workers/editor/common/treeSitterTokenizationImpl.js +713 -0
- package/dist/workers/editor/common/treeSitterTree.js +395 -0
- package/dist/workers/editor/common/treeViewsDnd.js +24 -0
- package/dist/workers/editor/common/treeViewsDndService.js +12 -0
- package/dist/workers/editor/common/trimTrailingWhitespaceCommand.js +98 -0
- package/dist/workers/editor/common/unicodeTextModelHighlighter.js +188 -0
- package/dist/workers/editor/common/utils.js +62 -0
- package/dist/workers/editor/common/viewContext.js +22 -0
- package/dist/workers/editor/common/viewEventHandler.js +186 -0
- package/dist/workers/editor/common/viewEvents.js +180 -0
- package/dist/workers/editor/common/viewLayout.js +368 -0
- package/dist/workers/editor/common/viewLineRenderer.js +948 -0
- package/dist/workers/editor/common/viewLinesViewportData.js +30 -0
- package/dist/workers/editor/common/viewModel.js +98 -0
- package/dist/workers/editor/common/viewModelDecoration.js +55 -0
- package/dist/workers/editor/common/viewModelDecorations.js +132 -0
- package/dist/workers/editor/common/viewModelEventDispatcher.js +398 -0
- package/dist/workers/editor/common/viewModelImpl.js +1163 -0
- package/dist/workers/editor/common/viewModelLines.js +938 -0
- package/dist/workers/editor/common/wordCharacterClassifier.js +87 -0
- package/dist/workers/editor/common/wordHelper.js +127 -0
- package/dist/workers/editor/editor.worker.js +11 -0
- package/dist/workers/language/css.worker.js +8 -0
- package/dist/workers/language/cssMode.js +198 -0
- package/dist/workers/language/cssWorker.js +183 -0
- package/dist/workers/language/html.worker.js +8 -0
- package/dist/workers/language/htmlMode.js +213 -0
- package/dist/workers/language/htmlWorker.js +126 -0
- package/dist/workers/language/json.worker.js +8 -0
- package/dist/workers/language/jsonMode.js +224 -0
- package/dist/workers/language/jsonWorker.js +187 -0
- package/dist/workers/language/languageFeatures.js +1009 -0
- package/dist/workers/language/lib.index.js +103 -0
- package/dist/workers/language/lib.js +1107 -0
- package/dist/workers/language/lspLanguageFeatures.js +716 -0
- package/dist/workers/language/monaco.contribution.js +144 -0
- package/dist/workers/language/tokenization.js +189 -0
- package/dist/workers/language/ts.worker.js +14 -0
- package/dist/workers/language/tsMode.js +212 -0
- package/dist/workers/language/tsWorker.js +352 -0
- package/dist/workers/language/typescriptServices.js +210154 -0
- package/dist/workers/language/typescriptServicesMetadata.js +3 -0
- package/dist/workers/language/workerManager.js +65 -0
- package/package.json +3 -2
|
@@ -0,0 +1,948 @@
|
|
|
1
|
+
import { localize } from '../../../nls.js';
|
|
2
|
+
import { containsRTL, firstNonWhitespaceIndex, lastNonWhitespaceIndex, isFullWidthCharacter } from '../../../base/common/strings.js';
|
|
3
|
+
import { StringBuilder } from '../core/stringBuilder.js';
|
|
4
|
+
import { LineDecoration, LineDecorationsNormalizer } from './lineDecorations.js';
|
|
5
|
+
import { LinePart } from './linePart.js';
|
|
6
|
+
import { TextDirection } from '../model.js';
|
|
7
|
+
|
|
8
|
+
/*---------------------------------------------------------------------------------------------
|
|
9
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
10
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
11
|
+
*--------------------------------------------------------------------------------------------*/
|
|
12
|
+
class RenderLineInput {
|
|
13
|
+
get isLTR() {
|
|
14
|
+
return !this.containsRTL && this.textDirection !== TextDirection.RTL;
|
|
15
|
+
}
|
|
16
|
+
constructor(useMonospaceOptimizations, canUseHalfwidthRightwardsArrow, lineContent, continuesWithWrappedLine, isBasicASCII, containsRTL, fauxIndentLength, lineTokens, lineDecorations, tabSize, startVisibleColumn, spaceWidth, middotWidth, wsmiddotWidth, stopRenderingLineAfter, renderWhitespace, renderControlCharacters, fontLigatures, selectionsOnLine, textDirection, verticalScrollbarSize, renderNewLineWhenEmpty = false) {
|
|
17
|
+
this.useMonospaceOptimizations = useMonospaceOptimizations;
|
|
18
|
+
this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow;
|
|
19
|
+
this.lineContent = lineContent;
|
|
20
|
+
this.continuesWithWrappedLine = continuesWithWrappedLine;
|
|
21
|
+
this.isBasicASCII = isBasicASCII;
|
|
22
|
+
this.containsRTL = containsRTL;
|
|
23
|
+
this.fauxIndentLength = fauxIndentLength;
|
|
24
|
+
this.lineTokens = lineTokens;
|
|
25
|
+
this.lineDecorations = lineDecorations.sort(LineDecoration.compare);
|
|
26
|
+
this.tabSize = tabSize;
|
|
27
|
+
this.startVisibleColumn = startVisibleColumn;
|
|
28
|
+
this.spaceWidth = spaceWidth;
|
|
29
|
+
this.stopRenderingLineAfter = stopRenderingLineAfter;
|
|
30
|
+
this.renderWhitespace = (renderWhitespace === 'all'
|
|
31
|
+
? 4 /* RenderWhitespace.All */
|
|
32
|
+
: renderWhitespace === 'boundary'
|
|
33
|
+
? 1 /* RenderWhitespace.Boundary */
|
|
34
|
+
: renderWhitespace === 'selection'
|
|
35
|
+
? 2 /* RenderWhitespace.Selection */
|
|
36
|
+
: renderWhitespace === 'trailing'
|
|
37
|
+
? 3 /* RenderWhitespace.Trailing */
|
|
38
|
+
: 0 /* RenderWhitespace.None */);
|
|
39
|
+
this.renderControlCharacters = renderControlCharacters;
|
|
40
|
+
this.fontLigatures = fontLigatures;
|
|
41
|
+
this.selectionsOnLine = selectionsOnLine && selectionsOnLine.sort((a, b) => a.start < b.start ? -1 : 1);
|
|
42
|
+
this.renderNewLineWhenEmpty = renderNewLineWhenEmpty;
|
|
43
|
+
this.textDirection = textDirection;
|
|
44
|
+
this.verticalScrollbarSize = verticalScrollbarSize;
|
|
45
|
+
const wsmiddotDiff = Math.abs(wsmiddotWidth - spaceWidth);
|
|
46
|
+
const middotDiff = Math.abs(middotWidth - spaceWidth);
|
|
47
|
+
if (wsmiddotDiff < middotDiff) {
|
|
48
|
+
this.renderSpaceWidth = wsmiddotWidth;
|
|
49
|
+
this.renderSpaceCharCode = 0x2E31; // U+2E31 - WORD SEPARATOR MIDDLE DOT
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.renderSpaceWidth = middotWidth;
|
|
53
|
+
this.renderSpaceCharCode = 0xB7; // U+00B7 - MIDDLE DOT
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
sameSelection(otherSelections) {
|
|
57
|
+
if (this.selectionsOnLine === null) {
|
|
58
|
+
return otherSelections === null;
|
|
59
|
+
}
|
|
60
|
+
if (otherSelections === null) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (otherSelections.length !== this.selectionsOnLine.length) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
for (let i = 0; i < this.selectionsOnLine.length; i++) {
|
|
67
|
+
if (!this.selectionsOnLine[i].equals(otherSelections[i])) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
equals(other) {
|
|
74
|
+
return (this.useMonospaceOptimizations === other.useMonospaceOptimizations
|
|
75
|
+
&& this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
|
|
76
|
+
&& this.lineContent === other.lineContent
|
|
77
|
+
&& this.continuesWithWrappedLine === other.continuesWithWrappedLine
|
|
78
|
+
&& this.isBasicASCII === other.isBasicASCII
|
|
79
|
+
&& this.containsRTL === other.containsRTL
|
|
80
|
+
&& this.fauxIndentLength === other.fauxIndentLength
|
|
81
|
+
&& this.tabSize === other.tabSize
|
|
82
|
+
&& this.startVisibleColumn === other.startVisibleColumn
|
|
83
|
+
&& this.spaceWidth === other.spaceWidth
|
|
84
|
+
&& this.renderSpaceWidth === other.renderSpaceWidth
|
|
85
|
+
&& this.renderSpaceCharCode === other.renderSpaceCharCode
|
|
86
|
+
&& this.stopRenderingLineAfter === other.stopRenderingLineAfter
|
|
87
|
+
&& this.renderWhitespace === other.renderWhitespace
|
|
88
|
+
&& this.renderControlCharacters === other.renderControlCharacters
|
|
89
|
+
&& this.fontLigatures === other.fontLigatures
|
|
90
|
+
&& LineDecoration.equalsArr(this.lineDecorations, other.lineDecorations)
|
|
91
|
+
&& this.lineTokens.equals(other.lineTokens)
|
|
92
|
+
&& this.sameSelection(other.selectionsOnLine)
|
|
93
|
+
&& this.textDirection === other.textDirection
|
|
94
|
+
&& this.verticalScrollbarSize === other.verticalScrollbarSize
|
|
95
|
+
&& this.renderNewLineWhenEmpty === other.renderNewLineWhenEmpty);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
class DomPosition {
|
|
99
|
+
constructor(partIndex, charIndex) {
|
|
100
|
+
this.partIndex = partIndex;
|
|
101
|
+
this.charIndex = charIndex;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Provides a both direction mapping between a line's character and its rendered position.
|
|
106
|
+
*/
|
|
107
|
+
class CharacterMapping {
|
|
108
|
+
static getPartIndex(partData) {
|
|
109
|
+
return (partData & 4294901760 /* CharacterMappingConstants.PART_INDEX_MASK */) >>> 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */;
|
|
110
|
+
}
|
|
111
|
+
static getCharIndex(partData) {
|
|
112
|
+
return (partData & 65535 /* CharacterMappingConstants.CHAR_INDEX_MASK */) >>> 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */;
|
|
113
|
+
}
|
|
114
|
+
constructor(length, partCount) {
|
|
115
|
+
this.length = length;
|
|
116
|
+
this._data = new Uint32Array(this.length);
|
|
117
|
+
this._horizontalOffset = new Uint32Array(this.length);
|
|
118
|
+
}
|
|
119
|
+
setColumnInfo(column, partIndex, charIndex, horizontalOffset) {
|
|
120
|
+
const partData = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */)
|
|
121
|
+
| (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0;
|
|
122
|
+
this._data[column - 1] = partData;
|
|
123
|
+
this._horizontalOffset[column - 1] = horizontalOffset;
|
|
124
|
+
}
|
|
125
|
+
getHorizontalOffset(column) {
|
|
126
|
+
if (this._horizontalOffset.length === 0) {
|
|
127
|
+
// No characters on this line
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
return this._horizontalOffset[column - 1];
|
|
131
|
+
}
|
|
132
|
+
charOffsetToPartData(charOffset) {
|
|
133
|
+
if (this.length === 0) {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
if (charOffset < 0) {
|
|
137
|
+
return this._data[0];
|
|
138
|
+
}
|
|
139
|
+
if (charOffset >= this.length) {
|
|
140
|
+
return this._data[this.length - 1];
|
|
141
|
+
}
|
|
142
|
+
return this._data[charOffset];
|
|
143
|
+
}
|
|
144
|
+
getDomPosition(column) {
|
|
145
|
+
const partData = this.charOffsetToPartData(column - 1);
|
|
146
|
+
const partIndex = CharacterMapping.getPartIndex(partData);
|
|
147
|
+
const charIndex = CharacterMapping.getCharIndex(partData);
|
|
148
|
+
return new DomPosition(partIndex, charIndex);
|
|
149
|
+
}
|
|
150
|
+
getColumn(domPosition, partLength) {
|
|
151
|
+
const charOffset = this.partDataToCharOffset(domPosition.partIndex, partLength, domPosition.charIndex);
|
|
152
|
+
return charOffset + 1;
|
|
153
|
+
}
|
|
154
|
+
partDataToCharOffset(partIndex, partLength, charIndex) {
|
|
155
|
+
if (this.length === 0) {
|
|
156
|
+
return 0;
|
|
157
|
+
}
|
|
158
|
+
const searchEntry = ((partIndex << 16 /* CharacterMappingConstants.PART_INDEX_OFFSET */)
|
|
159
|
+
| (charIndex << 0 /* CharacterMappingConstants.CHAR_INDEX_OFFSET */)) >>> 0;
|
|
160
|
+
let min = 0;
|
|
161
|
+
let max = this.length - 1;
|
|
162
|
+
while (min + 1 < max) {
|
|
163
|
+
const mid = ((min + max) >>> 1);
|
|
164
|
+
const midEntry = this._data[mid];
|
|
165
|
+
if (midEntry === searchEntry) {
|
|
166
|
+
return mid;
|
|
167
|
+
}
|
|
168
|
+
else if (midEntry > searchEntry) {
|
|
169
|
+
max = mid;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
min = mid;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (min === max) {
|
|
176
|
+
return min;
|
|
177
|
+
}
|
|
178
|
+
const minEntry = this._data[min];
|
|
179
|
+
const maxEntry = this._data[max];
|
|
180
|
+
if (minEntry === searchEntry) {
|
|
181
|
+
return min;
|
|
182
|
+
}
|
|
183
|
+
if (maxEntry === searchEntry) {
|
|
184
|
+
return max;
|
|
185
|
+
}
|
|
186
|
+
const minPartIndex = CharacterMapping.getPartIndex(minEntry);
|
|
187
|
+
const minCharIndex = CharacterMapping.getCharIndex(minEntry);
|
|
188
|
+
const maxPartIndex = CharacterMapping.getPartIndex(maxEntry);
|
|
189
|
+
let maxCharIndex;
|
|
190
|
+
if (minPartIndex !== maxPartIndex) {
|
|
191
|
+
// sitting between parts
|
|
192
|
+
maxCharIndex = partLength;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
maxCharIndex = CharacterMapping.getCharIndex(maxEntry);
|
|
196
|
+
}
|
|
197
|
+
const minEntryDistance = charIndex - minCharIndex;
|
|
198
|
+
const maxEntryDistance = maxCharIndex - charIndex;
|
|
199
|
+
if (minEntryDistance <= maxEntryDistance) {
|
|
200
|
+
return min;
|
|
201
|
+
}
|
|
202
|
+
return max;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
class RenderLineOutput {
|
|
206
|
+
constructor(characterMapping, containsForeignElements) {
|
|
207
|
+
this._renderLineOutputBrand = undefined;
|
|
208
|
+
this.characterMapping = characterMapping;
|
|
209
|
+
this.containsForeignElements = containsForeignElements;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function renderViewLine(input, sb) {
|
|
213
|
+
if (input.lineContent.length === 0) {
|
|
214
|
+
if (input.lineDecorations.length > 0) {
|
|
215
|
+
// This line is empty, but it contains inline decorations
|
|
216
|
+
sb.appendString(`<span>`);
|
|
217
|
+
let beforeCount = 0;
|
|
218
|
+
let afterCount = 0;
|
|
219
|
+
let containsForeignElements = 0 /* ForeignElementType.None */;
|
|
220
|
+
for (const lineDecoration of input.lineDecorations) {
|
|
221
|
+
if (lineDecoration.type === 1 /* InlineDecorationType.Before */ || lineDecoration.type === 2 /* InlineDecorationType.After */) {
|
|
222
|
+
sb.appendString(`<span class="`);
|
|
223
|
+
sb.appendString(lineDecoration.className);
|
|
224
|
+
sb.appendString(`"></span>`);
|
|
225
|
+
if (lineDecoration.type === 1 /* InlineDecorationType.Before */) {
|
|
226
|
+
containsForeignElements |= 1 /* ForeignElementType.Before */;
|
|
227
|
+
beforeCount++;
|
|
228
|
+
}
|
|
229
|
+
if (lineDecoration.type === 2 /* InlineDecorationType.After */) {
|
|
230
|
+
containsForeignElements |= 2 /* ForeignElementType.After */;
|
|
231
|
+
afterCount++;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
sb.appendString(`</span>`);
|
|
236
|
+
const characterMapping = new CharacterMapping(1, beforeCount + afterCount);
|
|
237
|
+
characterMapping.setColumnInfo(1, beforeCount, 0, 0);
|
|
238
|
+
return new RenderLineOutput(characterMapping, containsForeignElements);
|
|
239
|
+
}
|
|
240
|
+
// completely empty line
|
|
241
|
+
if (input.renderNewLineWhenEmpty) {
|
|
242
|
+
sb.appendString('<span><span>\n</span></span>');
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
sb.appendString('<span><span></span></span>');
|
|
246
|
+
}
|
|
247
|
+
return new RenderLineOutput(new CharacterMapping(0, 0), 0 /* ForeignElementType.None */);
|
|
248
|
+
}
|
|
249
|
+
return _renderLine(resolveRenderLineInput(input), sb);
|
|
250
|
+
}
|
|
251
|
+
class RenderLineOutput2 {
|
|
252
|
+
constructor(characterMapping, html, containsForeignElements) {
|
|
253
|
+
this.characterMapping = characterMapping;
|
|
254
|
+
this.html = html;
|
|
255
|
+
this.containsForeignElements = containsForeignElements;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function renderViewLine2(input) {
|
|
259
|
+
const sb = new StringBuilder(10000);
|
|
260
|
+
const out = renderViewLine(input, sb);
|
|
261
|
+
return new RenderLineOutput2(out.characterMapping, sb.build(), out.containsForeignElements);
|
|
262
|
+
}
|
|
263
|
+
class ResolvedRenderLineInput {
|
|
264
|
+
constructor(fontIsMonospace, canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, parts, containsForeignElements, fauxIndentLength, tabSize, startVisibleColumn, spaceWidth, renderSpaceCharCode, renderWhitespace, renderControlCharacters) {
|
|
265
|
+
this.fontIsMonospace = fontIsMonospace;
|
|
266
|
+
this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow;
|
|
267
|
+
this.lineContent = lineContent;
|
|
268
|
+
this.len = len;
|
|
269
|
+
this.isOverflowing = isOverflowing;
|
|
270
|
+
this.overflowingCharCount = overflowingCharCount;
|
|
271
|
+
this.parts = parts;
|
|
272
|
+
this.containsForeignElements = containsForeignElements;
|
|
273
|
+
this.fauxIndentLength = fauxIndentLength;
|
|
274
|
+
this.tabSize = tabSize;
|
|
275
|
+
this.startVisibleColumn = startVisibleColumn;
|
|
276
|
+
this.spaceWidth = spaceWidth;
|
|
277
|
+
this.renderSpaceCharCode = renderSpaceCharCode;
|
|
278
|
+
this.renderWhitespace = renderWhitespace;
|
|
279
|
+
this.renderControlCharacters = renderControlCharacters;
|
|
280
|
+
//
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function resolveRenderLineInput(input) {
|
|
284
|
+
const lineContent = input.lineContent;
|
|
285
|
+
let isOverflowing;
|
|
286
|
+
let overflowingCharCount;
|
|
287
|
+
let len;
|
|
288
|
+
if (input.stopRenderingLineAfter !== -1 && input.stopRenderingLineAfter < lineContent.length) {
|
|
289
|
+
isOverflowing = true;
|
|
290
|
+
overflowingCharCount = lineContent.length - input.stopRenderingLineAfter;
|
|
291
|
+
len = input.stopRenderingLineAfter;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
isOverflowing = false;
|
|
295
|
+
overflowingCharCount = 0;
|
|
296
|
+
len = lineContent.length;
|
|
297
|
+
}
|
|
298
|
+
let tokens = transformAndRemoveOverflowing(lineContent, input.containsRTL, input.lineTokens, input.fauxIndentLength, len);
|
|
299
|
+
if (input.renderControlCharacters && !input.isBasicASCII) {
|
|
300
|
+
// Calling `extractControlCharacters` before adding (possibly empty) line parts
|
|
301
|
+
// for inline decorations. `extractControlCharacters` removes empty line parts.
|
|
302
|
+
tokens = extractControlCharacters(lineContent, tokens);
|
|
303
|
+
}
|
|
304
|
+
if (input.renderWhitespace === 4 /* RenderWhitespace.All */ ||
|
|
305
|
+
input.renderWhitespace === 1 /* RenderWhitespace.Boundary */ ||
|
|
306
|
+
(input.renderWhitespace === 2 /* RenderWhitespace.Selection */ && !!input.selectionsOnLine) ||
|
|
307
|
+
(input.renderWhitespace === 3 /* RenderWhitespace.Trailing */ && !input.continuesWithWrappedLine)) {
|
|
308
|
+
tokens = _applyRenderWhitespace(input, lineContent, len, tokens);
|
|
309
|
+
}
|
|
310
|
+
let containsForeignElements = 0 /* ForeignElementType.None */;
|
|
311
|
+
if (input.lineDecorations.length > 0) {
|
|
312
|
+
for (let i = 0, len = input.lineDecorations.length; i < len; i++) {
|
|
313
|
+
const lineDecoration = input.lineDecorations[i];
|
|
314
|
+
if (lineDecoration.type === 3 /* InlineDecorationType.RegularAffectingLetterSpacing */) {
|
|
315
|
+
// Pretend there are foreign elements... although not 100% accurate.
|
|
316
|
+
containsForeignElements |= 1 /* ForeignElementType.Before */;
|
|
317
|
+
}
|
|
318
|
+
else if (lineDecoration.type === 1 /* InlineDecorationType.Before */) {
|
|
319
|
+
containsForeignElements |= 1 /* ForeignElementType.Before */;
|
|
320
|
+
}
|
|
321
|
+
else if (lineDecoration.type === 2 /* InlineDecorationType.After */) {
|
|
322
|
+
containsForeignElements |= 2 /* ForeignElementType.After */;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
tokens = _applyInlineDecorations(lineContent, len, tokens, input.lineDecorations);
|
|
326
|
+
}
|
|
327
|
+
if (!input.containsRTL) {
|
|
328
|
+
// We can never split RTL text, as it ruins the rendering
|
|
329
|
+
tokens = splitLargeTokens(lineContent, tokens, !input.isBasicASCII || input.fontLigatures);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
// Split the first token if it contains both leading whitespace and RTL text
|
|
333
|
+
tokens = splitLeadingWhitespaceFromRTL(lineContent, tokens);
|
|
334
|
+
}
|
|
335
|
+
return new ResolvedRenderLineInput(input.useMonospaceOptimizations, input.canUseHalfwidthRightwardsArrow, lineContent, len, isOverflowing, overflowingCharCount, tokens, containsForeignElements, input.fauxIndentLength, input.tabSize, input.startVisibleColumn, input.spaceWidth, input.renderSpaceCharCode, input.renderWhitespace, input.renderControlCharacters);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* In the rendering phase, characters are always looped until token.endIndex.
|
|
339
|
+
* Ensure that all tokens end before `len` and the last one ends precisely at `len`.
|
|
340
|
+
*/
|
|
341
|
+
function transformAndRemoveOverflowing(lineContent, lineContainsRTL, tokens, fauxIndentLength, len) {
|
|
342
|
+
const result = [];
|
|
343
|
+
let resultLen = 0;
|
|
344
|
+
// The faux indent part of the line should have no token type
|
|
345
|
+
if (fauxIndentLength > 0) {
|
|
346
|
+
result[resultLen++] = new LinePart(fauxIndentLength, '', 0, false);
|
|
347
|
+
}
|
|
348
|
+
let startOffset = fauxIndentLength;
|
|
349
|
+
for (let tokenIndex = 0, tokensLen = tokens.getCount(); tokenIndex < tokensLen; tokenIndex++) {
|
|
350
|
+
const endIndex = tokens.getEndOffset(tokenIndex);
|
|
351
|
+
if (endIndex <= fauxIndentLength) {
|
|
352
|
+
// The faux indent part of the line should have no token type
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
const type = tokens.getClassName(tokenIndex);
|
|
356
|
+
if (endIndex >= len) {
|
|
357
|
+
const tokenContainsRTL = (lineContainsRTL ? containsRTL(lineContent.substring(startOffset, len)) : false);
|
|
358
|
+
result[resultLen++] = new LinePart(len, type, 0, tokenContainsRTL);
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
const tokenContainsRTL = (lineContainsRTL ? containsRTL(lineContent.substring(startOffset, endIndex)) : false);
|
|
362
|
+
result[resultLen++] = new LinePart(endIndex, type, 0, tokenContainsRTL);
|
|
363
|
+
startOffset = endIndex;
|
|
364
|
+
}
|
|
365
|
+
return result;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* See https://github.com/microsoft/vscode/issues/6885.
|
|
369
|
+
* It appears that having very large spans causes very slow reading of character positions.
|
|
370
|
+
* So here we try to avoid that.
|
|
371
|
+
*/
|
|
372
|
+
function splitLargeTokens(lineContent, tokens, onlyAtSpaces) {
|
|
373
|
+
let lastTokenEndIndex = 0;
|
|
374
|
+
const result = [];
|
|
375
|
+
let resultLen = 0;
|
|
376
|
+
if (onlyAtSpaces) {
|
|
377
|
+
// Split only at spaces => we need to walk each character
|
|
378
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
379
|
+
const token = tokens[i];
|
|
380
|
+
const tokenEndIndex = token.endIndex;
|
|
381
|
+
if (lastTokenEndIndex + 50 /* Constants.LongToken */ < tokenEndIndex) {
|
|
382
|
+
const tokenType = token.type;
|
|
383
|
+
const tokenMetadata = token.metadata;
|
|
384
|
+
const tokenContainsRTL = token.containsRTL;
|
|
385
|
+
let lastSpaceOffset = -1;
|
|
386
|
+
let currTokenStart = lastTokenEndIndex;
|
|
387
|
+
for (let j = lastTokenEndIndex; j < tokenEndIndex; j++) {
|
|
388
|
+
if (lineContent.charCodeAt(j) === 32 /* CharCode.Space */) {
|
|
389
|
+
lastSpaceOffset = j;
|
|
390
|
+
}
|
|
391
|
+
if (lastSpaceOffset !== -1 && j - currTokenStart >= 50 /* Constants.LongToken */) {
|
|
392
|
+
// Split at `lastSpaceOffset` + 1
|
|
393
|
+
result[resultLen++] = new LinePart(lastSpaceOffset + 1, tokenType, tokenMetadata, tokenContainsRTL);
|
|
394
|
+
currTokenStart = lastSpaceOffset + 1;
|
|
395
|
+
lastSpaceOffset = -1;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if (currTokenStart !== tokenEndIndex) {
|
|
399
|
+
result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
result[resultLen++] = token;
|
|
404
|
+
}
|
|
405
|
+
lastTokenEndIndex = tokenEndIndex;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
// Split anywhere => we don't need to walk each character
|
|
410
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
411
|
+
const token = tokens[i];
|
|
412
|
+
const tokenEndIndex = token.endIndex;
|
|
413
|
+
const diff = (tokenEndIndex - lastTokenEndIndex);
|
|
414
|
+
if (diff > 50 /* Constants.LongToken */) {
|
|
415
|
+
const tokenType = token.type;
|
|
416
|
+
const tokenMetadata = token.metadata;
|
|
417
|
+
const tokenContainsRTL = token.containsRTL;
|
|
418
|
+
const piecesCount = Math.ceil(diff / 50 /* Constants.LongToken */);
|
|
419
|
+
for (let j = 1; j < piecesCount; j++) {
|
|
420
|
+
const pieceEndIndex = lastTokenEndIndex + (j * 50 /* Constants.LongToken */);
|
|
421
|
+
result[resultLen++] = new LinePart(pieceEndIndex, tokenType, tokenMetadata, tokenContainsRTL);
|
|
422
|
+
}
|
|
423
|
+
result[resultLen++] = new LinePart(tokenEndIndex, tokenType, tokenMetadata, tokenContainsRTL);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
result[resultLen++] = token;
|
|
427
|
+
}
|
|
428
|
+
lastTokenEndIndex = tokenEndIndex;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return result;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Splits leading whitespace from the first token if it contains RTL text.
|
|
435
|
+
*/
|
|
436
|
+
function splitLeadingWhitespaceFromRTL(lineContent, tokens) {
|
|
437
|
+
if (tokens.length === 0) {
|
|
438
|
+
return tokens;
|
|
439
|
+
}
|
|
440
|
+
const firstToken = tokens[0];
|
|
441
|
+
if (!firstToken.containsRTL) {
|
|
442
|
+
return tokens;
|
|
443
|
+
}
|
|
444
|
+
// Check if the first token starts with whitespace
|
|
445
|
+
const firstTokenEndIndex = firstToken.endIndex;
|
|
446
|
+
let firstNonWhitespaceIndex = 0;
|
|
447
|
+
for (let i = 0; i < firstTokenEndIndex; i++) {
|
|
448
|
+
const charCode = lineContent.charCodeAt(i);
|
|
449
|
+
if (charCode !== 32 /* CharCode.Space */ && charCode !== 9 /* CharCode.Tab */) {
|
|
450
|
+
firstNonWhitespaceIndex = i;
|
|
451
|
+
break;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (firstNonWhitespaceIndex === 0) {
|
|
455
|
+
// No leading whitespace
|
|
456
|
+
return tokens;
|
|
457
|
+
}
|
|
458
|
+
// Split the first token into leading whitespace and the rest
|
|
459
|
+
const result = [];
|
|
460
|
+
result.push(new LinePart(firstNonWhitespaceIndex, firstToken.type, firstToken.metadata, false));
|
|
461
|
+
result.push(new LinePart(firstTokenEndIndex, firstToken.type, firstToken.metadata, firstToken.containsRTL));
|
|
462
|
+
// Add remaining tokens
|
|
463
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
464
|
+
result.push(tokens[i]);
|
|
465
|
+
}
|
|
466
|
+
return result;
|
|
467
|
+
}
|
|
468
|
+
function isControlCharacter(charCode) {
|
|
469
|
+
if (charCode < 32) {
|
|
470
|
+
return (charCode !== 9 /* CharCode.Tab */);
|
|
471
|
+
}
|
|
472
|
+
if (charCode === 127) {
|
|
473
|
+
// DEL
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
if ((charCode >= 0x202A && charCode <= 0x202E)
|
|
477
|
+
|| (charCode >= 0x2066 && charCode <= 0x2069)
|
|
478
|
+
|| (charCode >= 0x200E && charCode <= 0x200F)
|
|
479
|
+
|| charCode === 0x061C) {
|
|
480
|
+
// Unicode Directional Formatting Characters
|
|
481
|
+
// LRE U+202A LEFT-TO-RIGHT EMBEDDING
|
|
482
|
+
// RLE U+202B RIGHT-TO-LEFT EMBEDDING
|
|
483
|
+
// PDF U+202C POP DIRECTIONAL FORMATTING
|
|
484
|
+
// LRO U+202D LEFT-TO-RIGHT OVERRIDE
|
|
485
|
+
// RLO U+202E RIGHT-TO-LEFT OVERRIDE
|
|
486
|
+
// LRI U+2066 LEFT-TO-RIGHT ISOLATE
|
|
487
|
+
// RLI U+2067 RIGHT-TO-LEFT ISOLATE
|
|
488
|
+
// FSI U+2068 FIRST STRONG ISOLATE
|
|
489
|
+
// PDI U+2069 POP DIRECTIONAL ISOLATE
|
|
490
|
+
// LRM U+200E LEFT-TO-RIGHT MARK
|
|
491
|
+
// RLM U+200F RIGHT-TO-LEFT MARK
|
|
492
|
+
// ALM U+061C ARABIC LETTER MARK
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
function extractControlCharacters(lineContent, tokens) {
|
|
498
|
+
const result = [];
|
|
499
|
+
let lastLinePart = new LinePart(0, '', 0, false);
|
|
500
|
+
let charOffset = 0;
|
|
501
|
+
for (const token of tokens) {
|
|
502
|
+
const tokenEndIndex = token.endIndex;
|
|
503
|
+
for (; charOffset < tokenEndIndex; charOffset++) {
|
|
504
|
+
const charCode = lineContent.charCodeAt(charOffset);
|
|
505
|
+
if (isControlCharacter(charCode)) {
|
|
506
|
+
if (charOffset > lastLinePart.endIndex) {
|
|
507
|
+
// emit previous part if it has text
|
|
508
|
+
lastLinePart = new LinePart(charOffset, token.type, token.metadata, token.containsRTL);
|
|
509
|
+
result.push(lastLinePart);
|
|
510
|
+
}
|
|
511
|
+
lastLinePart = new LinePart(charOffset + 1, 'mtkcontrol', token.metadata, false);
|
|
512
|
+
result.push(lastLinePart);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
if (charOffset > lastLinePart.endIndex) {
|
|
516
|
+
// emit previous part if it has text
|
|
517
|
+
lastLinePart = new LinePart(tokenEndIndex, token.type, token.metadata, token.containsRTL);
|
|
518
|
+
result.push(lastLinePart);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Whitespace is rendered by "replacing" tokens with a special-purpose `mtkw` type that is later recognized in the rendering phase.
|
|
525
|
+
* Moreover, a token is created for every visual indent because on some fonts the glyphs used for rendering whitespace (→ or ·) do not have the same width as .
|
|
526
|
+
* The rendering phase will generate `style="width:..."` for these tokens.
|
|
527
|
+
*/
|
|
528
|
+
function _applyRenderWhitespace(input, lineContent, len, tokens) {
|
|
529
|
+
const continuesWithWrappedLine = input.continuesWithWrappedLine;
|
|
530
|
+
const fauxIndentLength = input.fauxIndentLength;
|
|
531
|
+
const tabSize = input.tabSize;
|
|
532
|
+
const startVisibleColumn = input.startVisibleColumn;
|
|
533
|
+
const useMonospaceOptimizations = input.useMonospaceOptimizations;
|
|
534
|
+
const selections = input.selectionsOnLine;
|
|
535
|
+
const onlyBoundary = (input.renderWhitespace === 1 /* RenderWhitespace.Boundary */);
|
|
536
|
+
const onlyTrailing = (input.renderWhitespace === 3 /* RenderWhitespace.Trailing */);
|
|
537
|
+
const generateLinePartForEachWhitespace = (input.renderSpaceWidth !== input.spaceWidth);
|
|
538
|
+
const result = [];
|
|
539
|
+
let resultLen = 0;
|
|
540
|
+
let tokenIndex = 0;
|
|
541
|
+
let tokenType = tokens[tokenIndex].type;
|
|
542
|
+
let tokenContainsRTL = tokens[tokenIndex].containsRTL;
|
|
543
|
+
let tokenEndIndex = tokens[tokenIndex].endIndex;
|
|
544
|
+
const tokensLength = tokens.length;
|
|
545
|
+
let lineIsEmptyOrWhitespace = false;
|
|
546
|
+
let firstNonWhitespaceIndex$1 = firstNonWhitespaceIndex(lineContent);
|
|
547
|
+
let lastNonWhitespaceIndex$1;
|
|
548
|
+
if (firstNonWhitespaceIndex$1 === -1) {
|
|
549
|
+
lineIsEmptyOrWhitespace = true;
|
|
550
|
+
firstNonWhitespaceIndex$1 = len;
|
|
551
|
+
lastNonWhitespaceIndex$1 = len;
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
lastNonWhitespaceIndex$1 = lastNonWhitespaceIndex(lineContent);
|
|
555
|
+
}
|
|
556
|
+
let wasInWhitespace = false;
|
|
557
|
+
let currentSelectionIndex = 0;
|
|
558
|
+
let currentSelection = selections && selections[currentSelectionIndex];
|
|
559
|
+
let tmpIndent = startVisibleColumn % tabSize;
|
|
560
|
+
for (let charIndex = fauxIndentLength; charIndex < len; charIndex++) {
|
|
561
|
+
const chCode = lineContent.charCodeAt(charIndex);
|
|
562
|
+
if (currentSelection && currentSelection.endExclusive <= charIndex) {
|
|
563
|
+
currentSelectionIndex++;
|
|
564
|
+
currentSelection = selections && selections[currentSelectionIndex];
|
|
565
|
+
}
|
|
566
|
+
let isInWhitespace;
|
|
567
|
+
if (charIndex < firstNonWhitespaceIndex$1 || charIndex > lastNonWhitespaceIndex$1) {
|
|
568
|
+
// in leading or trailing whitespace
|
|
569
|
+
isInWhitespace = true;
|
|
570
|
+
}
|
|
571
|
+
else if (chCode === 9 /* CharCode.Tab */) {
|
|
572
|
+
// a tab character is rendered both in all and boundary cases
|
|
573
|
+
isInWhitespace = true;
|
|
574
|
+
}
|
|
575
|
+
else if (chCode === 32 /* CharCode.Space */) {
|
|
576
|
+
// hit a space character
|
|
577
|
+
if (onlyBoundary) {
|
|
578
|
+
// rendering only boundary whitespace
|
|
579
|
+
if (wasInWhitespace) {
|
|
580
|
+
isInWhitespace = true;
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
const nextChCode = (charIndex + 1 < len ? lineContent.charCodeAt(charIndex + 1) : 0 /* CharCode.Null */);
|
|
584
|
+
isInWhitespace = (nextChCode === 32 /* CharCode.Space */ || nextChCode === 9 /* CharCode.Tab */);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
else {
|
|
588
|
+
isInWhitespace = true;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
else {
|
|
592
|
+
isInWhitespace = false;
|
|
593
|
+
}
|
|
594
|
+
// If rendering whitespace on selection, check that the charIndex falls within a selection
|
|
595
|
+
if (isInWhitespace && selections) {
|
|
596
|
+
isInWhitespace = !!currentSelection && currentSelection.start <= charIndex && charIndex < currentSelection.endExclusive;
|
|
597
|
+
}
|
|
598
|
+
// If rendering only trailing whitespace, check that the charIndex points to trailing whitespace.
|
|
599
|
+
if (isInWhitespace && onlyTrailing) {
|
|
600
|
+
isInWhitespace = lineIsEmptyOrWhitespace || charIndex > lastNonWhitespaceIndex$1;
|
|
601
|
+
}
|
|
602
|
+
if (isInWhitespace && tokenContainsRTL) {
|
|
603
|
+
// If the token contains RTL text, breaking it up into multiple line parts
|
|
604
|
+
// to render whitespace might affect the browser's bidi layout.
|
|
605
|
+
//
|
|
606
|
+
// We render whitespace in such tokens only if the whitespace
|
|
607
|
+
// is the leading or the trailing whitespace of the line,
|
|
608
|
+
// which doesn't affect the browser's bidi layout.
|
|
609
|
+
if (charIndex >= firstNonWhitespaceIndex$1 && charIndex <= lastNonWhitespaceIndex$1) {
|
|
610
|
+
isInWhitespace = false;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if (wasInWhitespace) {
|
|
614
|
+
// was in whitespace token
|
|
615
|
+
if (!isInWhitespace || (!useMonospaceOptimizations && tmpIndent >= tabSize)) {
|
|
616
|
+
// leaving whitespace token or entering a new indent
|
|
617
|
+
if (generateLinePartForEachWhitespace) {
|
|
618
|
+
const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);
|
|
619
|
+
for (let i = lastEndIndex + 1; i <= charIndex; i++) {
|
|
620
|
+
result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
result[resultLen++] = new LinePart(charIndex, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);
|
|
625
|
+
}
|
|
626
|
+
tmpIndent = tmpIndent % tabSize;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
// was in regular token
|
|
631
|
+
if (charIndex === tokenEndIndex || (isInWhitespace && charIndex > fauxIndentLength)) {
|
|
632
|
+
result[resultLen++] = new LinePart(charIndex, tokenType, 0, tokenContainsRTL);
|
|
633
|
+
tmpIndent = tmpIndent % tabSize;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
if (chCode === 9 /* CharCode.Tab */) {
|
|
637
|
+
tmpIndent = tabSize;
|
|
638
|
+
}
|
|
639
|
+
else if (isFullWidthCharacter(chCode)) {
|
|
640
|
+
tmpIndent += 2;
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
tmpIndent++;
|
|
644
|
+
}
|
|
645
|
+
wasInWhitespace = isInWhitespace;
|
|
646
|
+
while (charIndex === tokenEndIndex) {
|
|
647
|
+
tokenIndex++;
|
|
648
|
+
if (tokenIndex < tokensLength) {
|
|
649
|
+
tokenType = tokens[tokenIndex].type;
|
|
650
|
+
tokenContainsRTL = tokens[tokenIndex].containsRTL;
|
|
651
|
+
tokenEndIndex = tokens[tokenIndex].endIndex;
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
let generateWhitespace = false;
|
|
659
|
+
if (wasInWhitespace) {
|
|
660
|
+
// was in whitespace token
|
|
661
|
+
if (continuesWithWrappedLine && onlyBoundary) {
|
|
662
|
+
const lastCharCode = (len > 0 ? lineContent.charCodeAt(len - 1) : 0 /* CharCode.Null */);
|
|
663
|
+
const prevCharCode = (len > 1 ? lineContent.charCodeAt(len - 2) : 0 /* CharCode.Null */);
|
|
664
|
+
const isSingleTrailingSpace = (lastCharCode === 32 /* CharCode.Space */ && (prevCharCode !== 32 /* CharCode.Space */ && prevCharCode !== 9 /* CharCode.Tab */));
|
|
665
|
+
if (!isSingleTrailingSpace) {
|
|
666
|
+
generateWhitespace = true;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
generateWhitespace = true;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (generateWhitespace) {
|
|
674
|
+
if (generateLinePartForEachWhitespace) {
|
|
675
|
+
const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);
|
|
676
|
+
for (let i = lastEndIndex + 1; i <= len; i++) {
|
|
677
|
+
result[resultLen++] = new LinePart(i, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
result[resultLen++] = new LinePart(len, 'mtkw', 1 /* LinePartMetadata.IS_WHITESPACE */, false);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
result[resultLen++] = new LinePart(len, tokenType, 0, tokenContainsRTL);
|
|
686
|
+
}
|
|
687
|
+
return result;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Inline decorations are "merged" on top of tokens.
|
|
691
|
+
* Special care must be taken when multiple inline decorations are at play and they overlap.
|
|
692
|
+
*/
|
|
693
|
+
function _applyInlineDecorations(lineContent, len, tokens, _lineDecorations) {
|
|
694
|
+
_lineDecorations.sort(LineDecoration.compare);
|
|
695
|
+
const lineDecorations = LineDecorationsNormalizer.normalize(lineContent, _lineDecorations);
|
|
696
|
+
const lineDecorationsLen = lineDecorations.length;
|
|
697
|
+
let lineDecorationIndex = 0;
|
|
698
|
+
const result = [];
|
|
699
|
+
let resultLen = 0;
|
|
700
|
+
let lastResultEndIndex = 0;
|
|
701
|
+
for (let tokenIndex = 0, len = tokens.length; tokenIndex < len; tokenIndex++) {
|
|
702
|
+
const token = tokens[tokenIndex];
|
|
703
|
+
const tokenEndIndex = token.endIndex;
|
|
704
|
+
const tokenType = token.type;
|
|
705
|
+
const tokenMetadata = token.metadata;
|
|
706
|
+
const tokenContainsRTL = token.containsRTL;
|
|
707
|
+
while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset < tokenEndIndex) {
|
|
708
|
+
const lineDecoration = lineDecorations[lineDecorationIndex];
|
|
709
|
+
if (lineDecoration.startOffset > lastResultEndIndex) {
|
|
710
|
+
lastResultEndIndex = lineDecoration.startOffset;
|
|
711
|
+
result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL);
|
|
712
|
+
}
|
|
713
|
+
if (lineDecoration.endOffset + 1 <= tokenEndIndex) {
|
|
714
|
+
// This line decoration ends before this token ends
|
|
715
|
+
lastResultEndIndex = lineDecoration.endOffset + 1;
|
|
716
|
+
result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL);
|
|
717
|
+
lineDecorationIndex++;
|
|
718
|
+
}
|
|
719
|
+
else {
|
|
720
|
+
// This line decoration continues on to the next token
|
|
721
|
+
lastResultEndIndex = tokenEndIndex;
|
|
722
|
+
result[resultLen++] = new LinePart(lastResultEndIndex, tokenType + ' ' + lineDecoration.className, tokenMetadata | lineDecoration.metadata, tokenContainsRTL);
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
if (tokenEndIndex > lastResultEndIndex) {
|
|
727
|
+
lastResultEndIndex = tokenEndIndex;
|
|
728
|
+
result[resultLen++] = new LinePart(lastResultEndIndex, tokenType, tokenMetadata, tokenContainsRTL);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
const lastTokenEndIndex = tokens[tokens.length - 1].endIndex;
|
|
732
|
+
if (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) {
|
|
733
|
+
while (lineDecorationIndex < lineDecorationsLen && lineDecorations[lineDecorationIndex].startOffset === lastTokenEndIndex) {
|
|
734
|
+
const lineDecoration = lineDecorations[lineDecorationIndex];
|
|
735
|
+
result[resultLen++] = new LinePart(lastResultEndIndex, lineDecoration.className, lineDecoration.metadata, false);
|
|
736
|
+
lineDecorationIndex++;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return result;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* This function is on purpose not split up into multiple functions to allow runtime type inference (i.e. performance reasons).
|
|
743
|
+
* Notice how all the needed data is fully resolved and passed in (i.e. no other calls).
|
|
744
|
+
*/
|
|
745
|
+
function _renderLine(input, sb) {
|
|
746
|
+
const fontIsMonospace = input.fontIsMonospace;
|
|
747
|
+
const canUseHalfwidthRightwardsArrow = input.canUseHalfwidthRightwardsArrow;
|
|
748
|
+
const containsForeignElements = input.containsForeignElements;
|
|
749
|
+
const lineContent = input.lineContent;
|
|
750
|
+
const len = input.len;
|
|
751
|
+
const isOverflowing = input.isOverflowing;
|
|
752
|
+
const overflowingCharCount = input.overflowingCharCount;
|
|
753
|
+
const parts = input.parts;
|
|
754
|
+
const fauxIndentLength = input.fauxIndentLength;
|
|
755
|
+
const tabSize = input.tabSize;
|
|
756
|
+
const startVisibleColumn = input.startVisibleColumn;
|
|
757
|
+
const spaceWidth = input.spaceWidth;
|
|
758
|
+
const renderSpaceCharCode = input.renderSpaceCharCode;
|
|
759
|
+
const renderWhitespace = input.renderWhitespace;
|
|
760
|
+
const renderControlCharacters = input.renderControlCharacters;
|
|
761
|
+
const characterMapping = new CharacterMapping(len + 1, parts.length);
|
|
762
|
+
let lastCharacterMappingDefined = false;
|
|
763
|
+
let charIndex = 0;
|
|
764
|
+
let visibleColumn = startVisibleColumn;
|
|
765
|
+
let charOffsetInPart = 0; // the character offset in the current part
|
|
766
|
+
let charHorizontalOffset = 0; // the character horizontal position in terms of chars relative to line start
|
|
767
|
+
let partDisplacement = 0;
|
|
768
|
+
sb.appendString('<span>');
|
|
769
|
+
for (let partIndex = 0, tokensLen = parts.length; partIndex < tokensLen; partIndex++) {
|
|
770
|
+
const part = parts[partIndex];
|
|
771
|
+
const partEndIndex = part.endIndex;
|
|
772
|
+
const partType = part.type;
|
|
773
|
+
const partContainsRTL = part.containsRTL;
|
|
774
|
+
const partRendersWhitespace = (renderWhitespace !== 0 /* RenderWhitespace.None */ && part.isWhitespace());
|
|
775
|
+
const partRendersWhitespaceWithWidth = partRendersWhitespace && !fontIsMonospace && (partType === 'mtkw' /*only whitespace*/ || !containsForeignElements);
|
|
776
|
+
const partIsEmptyAndHasPseudoAfter = (charIndex === partEndIndex && part.isPseudoAfter());
|
|
777
|
+
charOffsetInPart = 0;
|
|
778
|
+
sb.appendString('<span ');
|
|
779
|
+
if (partContainsRTL) {
|
|
780
|
+
sb.appendString('dir="rtl" style="unicode-bidi:isolate" ');
|
|
781
|
+
}
|
|
782
|
+
sb.appendString('class="');
|
|
783
|
+
sb.appendString(partRendersWhitespaceWithWidth ? 'mtkz' : partType);
|
|
784
|
+
sb.appendASCIICharCode(34 /* CharCode.DoubleQuote */);
|
|
785
|
+
if (partRendersWhitespace) {
|
|
786
|
+
let partWidth = 0;
|
|
787
|
+
{
|
|
788
|
+
let _charIndex = charIndex;
|
|
789
|
+
let _visibleColumn = visibleColumn;
|
|
790
|
+
for (; _charIndex < partEndIndex; _charIndex++) {
|
|
791
|
+
const charCode = lineContent.charCodeAt(_charIndex);
|
|
792
|
+
const charWidth = (charCode === 9 /* CharCode.Tab */ ? (tabSize - (_visibleColumn % tabSize)) : 1) | 0;
|
|
793
|
+
partWidth += charWidth;
|
|
794
|
+
if (_charIndex >= fauxIndentLength) {
|
|
795
|
+
_visibleColumn += charWidth;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
if (partRendersWhitespaceWithWidth) {
|
|
800
|
+
sb.appendString(' style="width:');
|
|
801
|
+
sb.appendString(String(spaceWidth * partWidth));
|
|
802
|
+
sb.appendString('px"');
|
|
803
|
+
}
|
|
804
|
+
sb.appendASCIICharCode(62 /* CharCode.GreaterThan */);
|
|
805
|
+
for (; charIndex < partEndIndex; charIndex++) {
|
|
806
|
+
characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, charHorizontalOffset);
|
|
807
|
+
partDisplacement = 0;
|
|
808
|
+
const charCode = lineContent.charCodeAt(charIndex);
|
|
809
|
+
let producedCharacters;
|
|
810
|
+
let charWidth;
|
|
811
|
+
if (charCode === 9 /* CharCode.Tab */) {
|
|
812
|
+
producedCharacters = (tabSize - (visibleColumn % tabSize)) | 0;
|
|
813
|
+
charWidth = producedCharacters;
|
|
814
|
+
if (!canUseHalfwidthRightwardsArrow || charWidth > 1) {
|
|
815
|
+
sb.appendCharCode(0x2192); // RIGHTWARDS ARROW
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
sb.appendCharCode(0xFFEB); // HALFWIDTH RIGHTWARDS ARROW
|
|
819
|
+
}
|
|
820
|
+
for (let space = 2; space <= charWidth; space++) {
|
|
821
|
+
sb.appendCharCode(0xA0); //
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
else { // must be CharCode.Space
|
|
825
|
+
producedCharacters = 2;
|
|
826
|
+
charWidth = 1;
|
|
827
|
+
sb.appendCharCode(renderSpaceCharCode); // · or word separator middle dot
|
|
828
|
+
sb.appendCharCode(0x200C); // ZERO WIDTH NON-JOINER
|
|
829
|
+
}
|
|
830
|
+
charOffsetInPart += producedCharacters;
|
|
831
|
+
charHorizontalOffset += charWidth;
|
|
832
|
+
if (charIndex >= fauxIndentLength) {
|
|
833
|
+
visibleColumn += charWidth;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
sb.appendASCIICharCode(62 /* CharCode.GreaterThan */);
|
|
839
|
+
for (; charIndex < partEndIndex; charIndex++) {
|
|
840
|
+
characterMapping.setColumnInfo(charIndex + 1, partIndex - partDisplacement, charOffsetInPart, charHorizontalOffset);
|
|
841
|
+
partDisplacement = 0;
|
|
842
|
+
const charCode = lineContent.charCodeAt(charIndex);
|
|
843
|
+
let producedCharacters = 1;
|
|
844
|
+
let charWidth = 1;
|
|
845
|
+
switch (charCode) {
|
|
846
|
+
case 9 /* CharCode.Tab */:
|
|
847
|
+
producedCharacters = (tabSize - (visibleColumn % tabSize));
|
|
848
|
+
charWidth = producedCharacters;
|
|
849
|
+
for (let space = 1; space <= producedCharacters; space++) {
|
|
850
|
+
sb.appendCharCode(0xA0); //
|
|
851
|
+
}
|
|
852
|
+
break;
|
|
853
|
+
case 32 /* CharCode.Space */:
|
|
854
|
+
sb.appendCharCode(0xA0); //
|
|
855
|
+
break;
|
|
856
|
+
case 60 /* CharCode.LessThan */:
|
|
857
|
+
sb.appendString('<');
|
|
858
|
+
break;
|
|
859
|
+
case 62 /* CharCode.GreaterThan */:
|
|
860
|
+
sb.appendString('>');
|
|
861
|
+
break;
|
|
862
|
+
case 38 /* CharCode.Ampersand */:
|
|
863
|
+
sb.appendString('&');
|
|
864
|
+
break;
|
|
865
|
+
case 0 /* CharCode.Null */:
|
|
866
|
+
if (renderControlCharacters) {
|
|
867
|
+
// See https://unicode-table.com/en/blocks/control-pictures/
|
|
868
|
+
sb.appendCharCode(9216);
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
sb.appendString('�');
|
|
872
|
+
}
|
|
873
|
+
break;
|
|
874
|
+
case 65279 /* CharCode.UTF8_BOM */:
|
|
875
|
+
case 8232 /* CharCode.LINE_SEPARATOR */:
|
|
876
|
+
case 8233 /* CharCode.PARAGRAPH_SEPARATOR */:
|
|
877
|
+
case 133 /* CharCode.NEXT_LINE */:
|
|
878
|
+
sb.appendCharCode(0xFFFD);
|
|
879
|
+
break;
|
|
880
|
+
default:
|
|
881
|
+
if (isFullWidthCharacter(charCode)) {
|
|
882
|
+
charWidth++;
|
|
883
|
+
}
|
|
884
|
+
// See https://unicode-table.com/en/blocks/control-pictures/
|
|
885
|
+
if (renderControlCharacters && charCode < 32) {
|
|
886
|
+
sb.appendCharCode(9216 + charCode);
|
|
887
|
+
}
|
|
888
|
+
else if (renderControlCharacters && charCode === 127) {
|
|
889
|
+
// DEL
|
|
890
|
+
sb.appendCharCode(9249);
|
|
891
|
+
}
|
|
892
|
+
else if (renderControlCharacters && isControlCharacter(charCode)) {
|
|
893
|
+
sb.appendString('[U+');
|
|
894
|
+
sb.appendString(to4CharHex(charCode));
|
|
895
|
+
sb.appendString(']');
|
|
896
|
+
producedCharacters = 8;
|
|
897
|
+
charWidth = producedCharacters;
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
sb.appendCharCode(charCode);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
charOffsetInPart += producedCharacters;
|
|
904
|
+
charHorizontalOffset += charWidth;
|
|
905
|
+
if (charIndex >= fauxIndentLength) {
|
|
906
|
+
visibleColumn += charWidth;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
if (partIsEmptyAndHasPseudoAfter) {
|
|
911
|
+
partDisplacement++;
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
partDisplacement = 0;
|
|
915
|
+
}
|
|
916
|
+
if (charIndex >= len && !lastCharacterMappingDefined && part.isPseudoAfter()) {
|
|
917
|
+
lastCharacterMappingDefined = true;
|
|
918
|
+
characterMapping.setColumnInfo(charIndex + 1, partIndex, charOffsetInPart, charHorizontalOffset);
|
|
919
|
+
}
|
|
920
|
+
sb.appendString('</span>');
|
|
921
|
+
}
|
|
922
|
+
if (!lastCharacterMappingDefined) {
|
|
923
|
+
// When getting client rects for the last character, we will position the
|
|
924
|
+
// text range at the end of the span, insteaf of at the beginning of next span
|
|
925
|
+
characterMapping.setColumnInfo(len + 1, parts.length - 1, charOffsetInPart, charHorizontalOffset);
|
|
926
|
+
}
|
|
927
|
+
if (isOverflowing) {
|
|
928
|
+
sb.appendString('<span class="mtkoverflow">');
|
|
929
|
+
sb.appendString(localize(796, "Show more ({0})", renderOverflowingCharCount(overflowingCharCount)));
|
|
930
|
+
sb.appendString('</span>');
|
|
931
|
+
}
|
|
932
|
+
sb.appendString('</span>');
|
|
933
|
+
return new RenderLineOutput(characterMapping, containsForeignElements);
|
|
934
|
+
}
|
|
935
|
+
function to4CharHex(n) {
|
|
936
|
+
return n.toString(16).toUpperCase().padStart(4, '0');
|
|
937
|
+
}
|
|
938
|
+
function renderOverflowingCharCount(n) {
|
|
939
|
+
if (n < 1024) {
|
|
940
|
+
return localize(797, "{0} chars", n);
|
|
941
|
+
}
|
|
942
|
+
if (n < 1024 * 1024) {
|
|
943
|
+
return `${(n / 1024).toFixed(1)} KB`;
|
|
944
|
+
}
|
|
945
|
+
return `${(n / 1024 / 1024).toFixed(1)} MB`;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export { CharacterMapping, DomPosition, RenderLineInput, RenderLineOutput, RenderLineOutput2, renderViewLine, renderViewLine2 };
|