@@ -156,6 +156,19 @@ define(function (require, exports, module) {
156156 } ) ;
157157 }
158158
159+ /**
160+ * Helper function to return the fold text marker on a line in an editor
161+ * @param {CodeMirror } cm The CodeMirror instance for the active editor
162+ * @param {Number } line The line number representing the position of the fold marker
163+ * @returns {TextMarker } A CodeMirror TextMarker object
164+ */
165+ function getFoldOnLine ( cm , line ) {
166+ var pos = CodeMirror . Pos ( line ) ;
167+ var folds = cm . findMarksAt ( pos ) || [ ] ;
168+ folds = folds . filter ( isFold ) ;
169+ return folds . length ? folds [ 0 ] : undefined ;
170+ }
171+
159172 /**
160173 * Synchronises the code folding states in the CM doc to cm._lineFolds cache.
161174 * When an undo operation is done, if folded code fragments are restored, then
@@ -166,19 +179,15 @@ define(function (require, exports, module) {
166179 */
167180 function syncDocToFoldsCache ( cm , from , lineAdded ) {
168181 var minFoldSize = prefs . getSetting ( "minFoldSize" ) || 2 ;
169- var opts = cm . state . foldGutter . options || { } ;
170- var rf = opts . rangeFinder || CodeMirror . fold . auto ;
171- var i , pos , folds , fold , range ;
182+ var i , fold , range ;
172183 if ( lineAdded <= 0 ) {
173184 return ;
174185 }
175186
176187 for ( i = from ; i <= from + lineAdded ; i = i + 1 ) {
177- pos = CodeMirror . Pos ( i ) ;
178- folds = cm . doc . findMarksAt ( pos ) . filter ( isFold ) ;
179- fold = folds . length ? fold = folds [ 0 ] : undefined ;
188+ fold = getFoldOnLine ( cm , i ) ;
180189 if ( fold ) {
181- range = rf ( cm , CodeMirror . Pos ( i ) ) ;
190+ range = fold . find ( ) ;
182191 if ( range && range . to . line - range . from . line >= minFoldSize ) {
183192 cm . _lineFolds [ i ] = range ;
184193 i = range . to . line ;
@@ -187,18 +196,27 @@ define(function (require, exports, module) {
187196 }
188197 }
189198 }
199+ }
190200
201+ /**
202+ * Helper function to move a fold range object by the specified number of lines
203+ * @param {Object } range An object specifying the fold range to move. It contains {from, to} which are CodeMirror.Pos objects.
204+ * @param {Number } numLines A positive or negative number representing the numbe of lines to move the range by
205+ */
206+ function moveRange ( range , numLines ) {
207+ return { from : CodeMirror . Pos ( range . from . line + numLines , range . from . ch ) ,
208+ to : CodeMirror . Pos ( range . to . line + numLines , range . to . ch ) } ;
191209 }
192210
193211 /**
194212 * Updates the line folds cache usually when the document changes.
195213 * The following cases are accounted for:
196214 * 1. When the change does not add a new line to the document we check if the line being modified
197215 * is folded. If that is the case, changes to this line might affect the range stored in the cache
198- * so we update the range.
216+ * so we update the range using the range finder function .
199217 * 2. If lines have been added, we need to update the records for all lines in the folds cache
200218 * which are greater than the line position at which we are adding the new line(s). When existing
201- * folds exist above the addition we keep the original position in the cache.
219+ * folds are above the addition we keep the original position in the cache.
202220 * 3. If lines are being removed, we need to update the records for all lines in the folds cache which are
203221 * greater than the line position at which we are removing the new lines, while making sure to
204222 * not include any folded lines in the cache that are part of the removed chunk.
@@ -208,7 +226,7 @@ define(function (require, exports, module) {
208226 * This value is negative for deletions and positive for additions.
209227 */
210228 function updateFoldsCache ( cm , from , linesDiff ) {
211- var range ;
229+ var oldRange , newRange ;
212230 var minFoldSize = prefs . getSetting ( "minFoldSize" ) || 2 ;
213231 var foldedLines = Object . keys ( cm . _lineFolds ) . map ( function ( d ) {
214232 return + d ;
@@ -218,31 +236,31 @@ define(function (require, exports, module) {
218236
219237 if ( linesDiff === 0 ) {
220238 if ( foldedLines . indexOf ( from ) >= 0 ) {
221- range = rf ( cm , CodeMirror . Pos ( from ) ) ;
222- if ( range && range . to . line - range . from . line >= minFoldSize ) {
223- cm . _lineFolds [ from ] = range ;
239+ newRange = rf ( cm , CodeMirror . Pos ( from ) ) ;
240+ if ( newRange && newRange . to . line - newRange . from . line >= minFoldSize ) {
241+ cm . _lineFolds [ from ] = newRange ;
224242 } else {
225243 delete cm . _lineFolds [ from ] ;
226244 }
227245 }
228246 } else if ( foldedLines . length ) {
229247 var newFolds = { } ;
230248 foldedLines . forEach ( function ( line ) {
231- range = cm . _lineFolds [ line ] ;
249+ oldRange = cm . _lineFolds [ line ] ;
250+ //update range with lines-diff
251+ newRange = moveRange ( oldRange , linesDiff ) ;
232252 // for removed lines we want to check lines that lie outside the deleted range
233253 if ( linesDiff < 0 ) {
234254 if ( line < from ) {
235- newFolds [ line ] = range ;
255+ newFolds [ line ] = oldRange ;
236256 } else if ( line >= from + Math . abs ( linesDiff ) ) {
237- range = rf ( cm , CodeMirror . Pos ( line + linesDiff ) ) ;
238- newFolds [ line + linesDiff ] = range ;
257+ newFolds [ line + linesDiff ] = newRange ;
239258 }
240259 } else {
241260 if ( line < from ) {
242- newFolds [ line ] = range ;
243- } else {
244- range = rf ( cm , CodeMirror . Pos ( line + linesDiff ) ) ;
245- newFolds [ line + linesDiff ] = range ;
261+ newFolds [ line ] = oldRange ;
262+ } else if ( line >= from ) {
263+ newFolds [ line + linesDiff ] = newRange ;
246264 }
247265 }
248266 } ) ;
@@ -317,17 +335,29 @@ define(function (require, exports, module) {
317335 } , 400 ) ;
318336 }
319337
338+ /**
339+ * Triggered when the cursor moves in the editor and used to detect text selection changes
340+ * in the editor.
341+ * @param {!CodeMirror } cm the CodeMirror instance for the active editor
342+ */
343+ function onCursorActivity ( cm ) {
344+ var state = cm . state . foldGutter ;
345+ var vp = cm . getViewport ( ) ;
346+ window . clearTimeout ( state . changeUpdate ) ;
347+ state . changeUpdate = window . setTimeout ( function ( ) {
348+ //need to render the entire visible viewport to remove fold marks rendered from previous selections if any
349+ updateInViewport ( cm , vp . from , vp . to ) ;
350+ } , 400 ) ;
351+ }
352+
320353 /**
321354 * Triggered when a code segment is folded.
322355 * @param {!CodeMirror } cm the CodeMirror instance for the active editor
323356 * @param {!Object } from the ch and line position that designates the start of the region
324357 * @param {!Object } to the ch and line position that designates the end of the region
325358 */
326359 function onFold ( cm , from , to ) {
327- var state = cm . state . foldGutter , line = from . line ;
328- if ( line >= state . from && line < state . to ) {
329- updateFoldInfo ( cm , line , line + 1 ) ;
330- }
360+ updateFoldInfo ( cm , from . line , from . line + 1 ) ;
331361 }
332362
333363 /**
@@ -337,11 +367,7 @@ define(function (require, exports, module) {
337367 * @param {!{line:number, ch:number} } to the ch and line position that designates the end of the region
338368 */
339369 function onUnFold ( cm , from , to ) {
340- var state = cm . state . foldGutter , line = from . line ;
341- var vp = cm . getViewport ( ) ;
342- if ( line >= state . from && line < state . to ) {
343- updateFoldInfo ( cm , line , Math . min ( vp . to , to . line ) ) ;
344- }
370+ updateFoldInfo ( cm , from . line , from . line + 1 ) ;
345371 }
346372
347373 /**
@@ -356,6 +382,8 @@ define(function (require, exports, module) {
356382 cm . off ( "gutterClick" , old . onGutterClick ) ;
357383 cm . off ( "change" , onChange ) ;
358384 cm . off ( "viewportChange" , onViewportChange ) ;
385+ cm . off ( "cursorActivity" , onCursorActivity ) ;
386+
359387 cm . off ( "fold" , onFold ) ;
360388 cm . off ( "unfold" , onUnFold ) ;
361389 cm . off ( "swapDoc" , updateInViewport ) ;
@@ -366,6 +394,7 @@ define(function (require, exports, module) {
366394 cm . on ( "gutterClick" , val . onGutterClick ) ;
367395 cm . on ( "change" , onChange ) ;
368396 cm . on ( "viewportChange" , onViewportChange ) ;
397+ cm . on ( "cursorActivity" , onCursorActivity ) ;
369398 cm . on ( "fold" , onFold ) ;
370399 cm . on ( "unfold" , onUnFold ) ;
371400 cm . on ( "swapDoc" , updateInViewport ) ;
0 commit comments