Skip to content

Commit f3a313a

Browse files
committed
Extract breaking conditions
1 parent 4f52d50 commit f3a313a

1 file changed

Lines changed: 34 additions & 17 deletions

File tree

src/vs/editor/common/viewModel/characterHardWrappingLineMapper.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,30 +126,34 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
126126
let breakOffset = 0;
127127
let breakOffsetVisibleColumn = 0;
128128
const len = lineText.length;
129+
const len1 = len - 1;
129130

130131
let breakingColumn = firstLineBreakingColumn;
132+
let prevCharCode = CharCode.Null;
133+
let prevCharCodeClass = CharacterClass.NONE;
134+
let charCode = CharCode.Null;
135+
let charCodeClass = CharacterClass.NONE;
136+
let nextCharCode = (len > 0 ? lineText.charCodeAt(0) : CharCode.Null);
137+
let nextCharCodeClass = classifier.get(nextCharCode);
138+
131139
for (let i = 0; i < len; i++) {
132140
// At this point, there is a certainty that the character before `i` fits on the current line,
133141
// but the character at `i` might not fit
134142

135-
const charCode = lineText.charCodeAt(i);
143+
prevCharCode = charCode;
144+
prevCharCodeClass = charCodeClass;
145+
charCode = nextCharCode;
146+
charCodeClass = nextCharCodeClass;
147+
nextCharCode = (i < len1 ? lineText.charCodeAt(i + 1) : CharCode.Null);
148+
nextCharCodeClass = classifier.get(nextCharCode);
136149

137150
if (strings.isLowSurrogate(charCode)) {
138151
// A surrogate pair must always be considered as a single unit, so it is never to be broken
139152
visibleColumn += 1;
140153
continue;
141154
}
142155

143-
const charCodeClass = classifier.get(charCode);
144-
145-
if (
146-
(charCodeClass === CharacterClass.BREAK_BEFORE)
147-
|| (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && i > 0 && classifier.get(lineText.charCodeAt(i - 1)) !== CharacterClass.BREAK_BEFORE)
148-
) {
149-
// This is a character that indicates that a break should happen before it
150-
// (or) CJK breaking : before break : Kinsoku Shori : Don't break after a leading character, like an open bracket
151-
// Since we are certain the character before `i` fits, there's no extra checking needed,
152-
// just mark it as a nice breaking opportunity
156+
if (prevCharCode !== CharCode.Null && canBreakBefore(charCodeClass, prevCharCodeClass)) {
153157
breakOffset = i;
154158
breakOffsetVisibleColumn = visibleColumn;
155159
}
@@ -180,12 +184,7 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
180184
}
181185

182186
// At this point, there is a certainty that the character at `i` fits on the current line
183-
if (
184-
(charCodeClass === CharacterClass.BREAK_AFTER && (hardWrappingIndent === WrappingIndent.None || i >= firstNonWhitespaceIndex))
185-
|| (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && i + 1 < len && classifier.get(lineText.charCodeAt(i + 1)) !== CharacterClass.BREAK_AFTER)
186-
) {
187-
// This is a character that indicates that a break should happen after it
188-
// (or) CJK breaking : after break : Kinsoku Shori : Don't break before a trailing character, like a period
187+
if (nextCharCode !== CharCode.Null && canBreakAfter(charCodeClass, nextCharCodeClass)) {
189188
breakOffset = i + 1;
190189
breakOffsetVisibleColumn = visibleColumn;
191190
}
@@ -206,3 +205,21 @@ export class CharacterHardWrappingLineMapperFactory implements ILineMapperFactor
206205
function tabCharacterWidth(visibleColumn: number, tabSize: number): number {
207206
return (tabSize - (visibleColumn % tabSize));
208207
}
208+
209+
function canBreakBefore(charCodeClass: CharacterClass, prevCharCodeClass: CharacterClass): boolean {
210+
// This is a character that indicates that a break should happen before it
211+
// (or) CJK breaking : before break : Kinsoku Shori : Don't break after a leading character, like an open bracket
212+
return (
213+
(charCodeClass === CharacterClass.BREAK_BEFORE)
214+
|| (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && prevCharCodeClass !== CharacterClass.BREAK_BEFORE)
215+
);
216+
}
217+
218+
function canBreakAfter(charCodeClass: CharacterClass, nextCharCodeClass: CharacterClass): boolean {
219+
// This is a character that indicates that a break should happen after it
220+
// (or) CJK breaking : after break : Kinsoku Shori : Don't break before a trailing character, like a period
221+
return (
222+
(charCodeClass === CharacterClass.BREAK_AFTER)
223+
|| (charCodeClass === CharacterClass.BREAK_IDEOGRAPHIC && nextCharCodeClass !== CharacterClass.BREAK_AFTER)
224+
);
225+
}

0 commit comments

Comments
 (0)