@@ -111,31 +111,40 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
111111 const prevBreakingOffsetsVisibleColumn = previousBreakingData . breakingOffsetsVisibleColumn ;
112112
113113 let breakingColumn = firstLineBreakingColumn ;
114+ let lastBreakingOffsetVisibleColumn = 0 ;
114115 const prevLen = prevBreakingOffsets . length ;
115116 let prevIndex = 0 ;
116- while ( prevIndex < prevLen ) {
117117
118- // Allow for prevIndex to be -1 (for the case where we hit a tab when walking backwards from the first break)
119- let breakOffset = prevIndex < 0 ? 0 : prevBreakingOffsets [ prevIndex ] ;
120- let breakOffsetVisibleColumn = prevIndex < 0 ? 0 : prevBreakingOffsetsVisibleColumn [ prevIndex ] ;
121-
122- if ( breakOffsetVisibleColumn === breakingColumn ) {
123- // perfect fit, nothing to do
124- breakingOffsets [ breakingOffsetsCount ] = breakOffset ;
125- breakingOffsetsVisibleColumn [ breakingOffsetsCount ] = breakOffsetVisibleColumn ;
126- breakingOffsetsCount ++ ;
127- breakingColumn = breakOffsetVisibleColumn + wrappedLineBreakingColumn ;
118+ if ( prevIndex >= 0 ) {
119+ let currentDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex ] - breakingColumn ) ;
120+ while ( prevIndex + 1 < prevLen ) {
121+ const potentialDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex + 1 ] - breakingColumn ) ;
122+ if ( potentialDiff >= currentDiff ) {
123+ break ;
124+ }
125+ currentDiff = potentialDiff ;
128126 prevIndex ++ ;
129- } else if ( breakOffsetVisibleColumn < breakingColumn ) {
130- // try to add more characters
131- const initialBreakOffset = breakOffset ;
132- let visibleColumn = breakOffsetVisibleColumn ;
133- breakOffset = 0 ;
127+ }
128+ }
129+
130+ while ( prevIndex < prevLen ) {
131+ // Allow for prevIndex to be -1 (for the case where we hit a tab when walking backwards from the first break)
132+ const prevBreakOffset = prevIndex < 0 ? 0 : prevBreakingOffsets [ prevIndex ] ;
133+ const prevBreakoffsetVisibleColumn = prevIndex < 0 ? 0 : prevBreakingOffsetsVisibleColumn [ prevIndex ] ; ;
134134
135- let prevCharCode = lineText . charCodeAt ( initialBreakOffset - 1 ) ;
135+ let breakOffset = 0 ;
136+ let breakOffsetVisibleColumn = 0 ;
137+
138+ let forcedBreakOffset = 0 ;
139+ let forcedBreakOffsetVisibleColumn = 0 ;
140+
141+ // initially, we search as much as possible to the right (if it fits)
142+ if ( prevBreakoffsetVisibleColumn <= breakingColumn ) {
143+ let visibleColumn = prevBreakoffsetVisibleColumn ;
144+ let prevCharCode = lineText . charCodeAt ( prevBreakOffset - 1 ) ;
136145 let prevCharCodeClass = classifier . get ( prevCharCode ) ;
137- let mustBreak = false ;
138- for ( let i = initialBreakOffset ; i < len ; i ++ ) {
146+ let entireLineFits = true ;
147+ for ( let i = prevBreakOffset ; i < len ; i ++ ) {
139148 const charCode = lineText . charCodeAt ( i ) ;
140149 const charCodeClass = classifier . get ( charCode ) ;
141150
@@ -145,6 +154,7 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
145154 prevCharCode = charCode ;
146155 prevCharCodeClass = charCodeClass ;
147156 continue ;
157+
148158 }
149159
150160 if ( canBreak ( prevCharCodeClass , charCodeClass ) ) {
@@ -157,48 +167,40 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
157167
158168 if ( visibleColumn > breakingColumn ) {
159169 // We need to break at least before character at `i`:
170+ forcedBreakOffset = i ;
171+ forcedBreakOffsetVisibleColumn = visibleColumn - charWidth ;
160172
161- if ( breakOffset === 0 || visibleColumn - breakOffsetVisibleColumn > wrappedLineBreakingColumn ) {
162- // Cannot break at `breakOffset`, must break at `i`
163- breakOffset = i ;
164- breakOffsetVisibleColumn = visibleColumn - charWidth ;
173+ if ( visibleColumn - breakOffsetVisibleColumn > wrappedLineBreakingColumn ) {
174+ // Cannot break at `breakOffset` => reset it if it was set
175+ breakOffset = 0 ;
165176 }
166177
167- mustBreak = true ;
178+ entireLineFits = false ;
168179 break ;
169180 }
170181
171182 prevCharCode = charCode ;
172183 prevCharCodeClass = charCodeClass ;
173184 }
174185
175- if ( ! mustBreak ) {
186+ if ( entireLineFits ) {
176187 // there is no more need to break => stop the outer loop!
177188 // Add last segment
178189 breakingOffsets [ breakingOffsetsCount ] = prevBreakingOffsets [ prevBreakingOffsets . length - 1 ] ;
179190 breakingOffsetsVisibleColumn [ breakingOffsetsCount ] = prevBreakingOffsetsVisibleColumn [ prevBreakingOffsets . length - 1 ] ;
180191 break ;
181192 }
193+ }
182194
183- breakingOffsets [ breakingOffsetsCount ] = breakOffset ;
184- breakingOffsetsVisibleColumn [ breakingOffsetsCount ] = breakOffsetVisibleColumn ;
185- breakingOffsetsCount ++ ;
186- breakingColumn = breakOffsetVisibleColumn + wrappedLineBreakingColumn ;
187- prevIndex ++ ;
188- } else if ( breakOffsetVisibleColumn > breakingColumn ) {
189- const initialBreakOffset = breakOffset ;
190- let visibleColumn = breakOffsetVisibleColumn ;
191- breakOffset = 0 ;
192-
193- let charCode = lineText . charCodeAt ( initialBreakOffset ) ;
195+ if ( breakOffset === 0 ) {
196+ // must search left
197+ let visibleColumn = prevBreakoffsetVisibleColumn ;
198+ let charCode = lineText . charCodeAt ( prevBreakOffset ) ;
194199 let charCodeClass = classifier . get ( charCode ) ;
195- let hitTab = false ;
196-
197- let firstValidBreakOffset = 0 ;
198- let firstValidBreakOffsetVisibleColumn = 0 ;
199- for ( let i = initialBreakOffset - 1 ; i >= 0 ; i -- ) {
200- let prevCharCode = lineText . charCodeAt ( i ) ;
201- let prevCharCodeClass = classifier . get ( prevCharCode ) ;
200+ let hitATabCharacter = false ;
201+ for ( let i = prevBreakOffset - 1 ; i >= 0 ; i -- ) {
202+ const prevCharCode = lineText . charCodeAt ( i ) ;
203+ const prevCharCodeClass = classifier . get ( prevCharCode ) ;
202204
203205 if ( strings . isHighSurrogate ( prevCharCode ) ) {
204206 // A surrogate pair must always be considered as a single unit, so it is never to be broken
@@ -210,16 +212,16 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
210212
211213 if ( prevCharCode === CharCode . Tab ) {
212214 // cannot determine the width of a tab when going backwards, so we must go forwards
213- hitTab = true ;
215+ hitATabCharacter = true ;
214216 break ;
215217 }
216218
217219 const charWidth = ( strings . isFullWidthCharacter ( prevCharCode ) ? columnsForFullWidthChar : 1 ) ;
218220
219221 if ( visibleColumn <= breakingColumn ) {
220- if ( firstValidBreakOffset === 0 ) {
221- firstValidBreakOffset = i + 1 ;
222- firstValidBreakOffsetVisibleColumn = visibleColumn ;
222+ if ( forcedBreakOffset === 0 ) {
223+ forcedBreakOffset = i + 1 ;
224+ forcedBreakOffsetVisibleColumn = visibleColumn ;
223225 }
224226
225227 if ( visibleColumn <= breakingColumn - wrappedLineBreakingColumn ) {
@@ -239,36 +241,37 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
239241 charCodeClass = prevCharCodeClass ;
240242 }
241243
242- if ( hitTab ) {
243- // cannot determine the width of a tab when going backwards, so we must go forwards
244+ if ( hitATabCharacter ) {
245+ // cannot determine the width of a tab when going backwards, so we must go forwards from the previous break
244246 prevIndex -- ;
245247 continue ;
246248 }
249+ }
247250
248- if ( breakOffset === 0 ) {
249- // Could not find a good breaking point
250- breakOffset = firstValidBreakOffset ;
251- breakOffsetVisibleColumn = firstValidBreakOffsetVisibleColumn ;
252- }
251+ if ( breakOffset === 0 ) {
252+ // Could not find a good breaking point
253+ breakOffset = forcedBreakOffset ;
254+ breakOffsetVisibleColumn = forcedBreakOffsetVisibleColumn ;
255+ }
256+
257+ breakingOffsets [ breakingOffsetsCount ] = breakOffset ;
258+ breakingOffsetsVisibleColumn [ breakingOffsetsCount ] = breakOffsetVisibleColumn ;
259+ breakingOffsetsCount ++ ;
260+ breakingColumn = breakOffsetVisibleColumn + wrappedLineBreakingColumn ;
253261
254- breakingOffsets [ breakingOffsetsCount ] = breakOffset ;
255- breakingOffsetsVisibleColumn [ breakingOffsetsCount ] = breakOffsetVisibleColumn ;
256- breakingOffsetsCount ++ ;
257- breakingColumn = breakOffsetVisibleColumn + wrappedLineBreakingColumn ;
262+ while ( prevIndex < 0 || ( prevIndex < prevLen && prevBreakingOffsetsVisibleColumn [ prevIndex ] < breakOffsetVisibleColumn ) ) {
263+ prevIndex ++ ;
258264 }
259265
260- if ( prevIndex < 0 ) {
261- prevIndex = 0 ;
262- } else {
263- let currentDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex ] - breakingColumn ) ;
264- while ( prevIndex + 1 < prevLen ) {
265- const potentialDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex + 1 ] - breakingColumn ) ;
266- if ( potentialDiff >= currentDiff ) {
267- break ;
268- }
269- currentDiff = potentialDiff ;
270- prevIndex ++ ;
266+ let currentDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex ] - breakingColumn ) ;
267+ // let lastBreakingColumn
268+ while ( prevIndex + 1 < prevLen ) {
269+ const potentialDiff = Math . abs ( prevBreakingOffsetsVisibleColumn [ prevIndex + 1 ] - breakingColumn ) ;
270+ if ( potentialDiff >= currentDiff ) {
271+ break ;
271272 }
273+ currentDiff = potentialDiff ;
274+ prevIndex ++ ;
272275 }
273276 }
274277
@@ -284,11 +287,19 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
284287 } catch ( err ) {
285288 console . log ( `BREAKING!!` ) ;
286289 console . log ( err ) ;
290+ console . log ( `previous breaks: ${ JSON . stringify ( prevBreakingOffsets ) } , breakingOffsetsVisibleColumn: ${ JSON . stringify ( prevBreakingOffsetsVisibleColumn ) } ` ) ;
291+ console . log ( `expected breakOffsets: ${ JSON . stringify ( expected ?. breakOffsets ) } , breakingOffsetsVisibleColumn: ${ JSON . stringify ( expected ?. breakingOffsetsVisibleColumn ) } ` ) ;
292+ console . log ( `actual breakOffsets: ${ JSON . stringify ( actual ?. breakOffsets ) } , breakingOffsetsVisibleColumn: ${ JSON . stringify ( actual ?. breakingOffsetsVisibleColumn ) } ` ) ;
293+
294+ console . log ( `actual str: ${ toAnnotatedText ( lineText , actual ) } ` ) ;
295+
296+
287297 console . log ( `
288298 assertIncrementalLineMapping(
289299 factory, ${ str ( lineText ) } , 4,
290300 ${ previousBreakingData . breakingColumn } , ${ str ( toAnnotatedText ( lineText , previousBreakingData ) ) } ,
291- ${ expected ! . breakingColumn } , ${ str ( toAnnotatedText ( lineText , expected ) ) }
301+ ${ expected ! . breakingColumn } , ${ str ( toAnnotatedText ( lineText , expected ) ) } ,
302+ WrappingIndent.${ hardWrappingIndent === WrappingIndent . None ? 'None' : hardWrappingIndent === WrappingIndent . Same ? 'Same' : hardWrappingIndent === WrappingIndent . Indent ? 'Indent' : 'DeepIndent' }
292303 );
293304` ) ;
294305 function str ( strr : string ) {
@@ -381,6 +392,8 @@ function createLineMapping(classifier: WrappingCharacterClassifier, previousBrea
381392 return new LineBreakingData ( firstLineBreakingColumn , breakingOffsets , breakingOffsetsVisibleColumn , wrappedTextIndentLength ) ;
382393}
383394
395+ function
396+
384397// class BreakSearchResult {
385398
386399// public static INSTANCE = new BreakSearchResult();
0 commit comments