function doFold(cm, pos, options, force) {
        options = options || {};
        force = force || "fold";
        if (typeof pos === "number") {
            pos = CodeMirror.Pos(pos, 0);
        }

        var finder = options.rangeFinder || CodeMirror.fold.auto,
            range,
            widget,
            textRange;

        function getRange(allowFolded) {
            var range = options.range || finder(cm, pos);
            if (!range || range.to.line - range.from.line < prefs.getSetting("minFoldSize")) {
                return null;
            }
            var marks = cm.findMarksAt(range.from),
                i,
                lastMark,
                foldMarks;
            for (i = 0; i < marks.length; ++i) {
                if (marks[i].__isFold && force !== "fold") {
                    if (!allowFolded) {
                        return null;
                    }
                    range.cleared = true;
                    marks[i].clear();
                }
            }
            //check for overlapping folds
            if (marks && marks.length) {
                foldMarks = marks.filter(function (d) {
                    return d.__isFold;
                });
                if (foldMarks && foldMarks.length) {
                    lastMark = foldMarks[foldMarks.length - 1].find();
                    if (lastMark && range.from.line <= lastMark.to.line && lastMark.to.line < range.to.line) {
                        return null;
                    }
                }
            }
            return range;
        }

        function makeWidget() {
            var widget = window.document.createElement("span");
            widget.className = "CodeMirror-foldmarker";
            return widget;
        }

        range = getRange(true);
        if (options.scanUp) {
            while (!range && pos.line > cm.firstLine()) {
                pos = CodeMirror.Pos(pos.line - 1, 0);
                range = getRange(false);
            }
        }
        if (!range || range.cleared || force === "unfold" || range.to.line - range.from.line < prefs.getSetting("minFoldSize")) {
            if (range) { range.cleared = false; }
            return;
        }

        widget = makeWidget();
        textRange = cm.markText(range.from, range.to, {
            replacedWith: widget,
            clearOnEnter: true,
            __isFold: true
        });

        CodeMirror.on(widget, "mousedown", function (e) {
            textRange.clear();
            e.preventDefault();
        });

        textRange.on("clear", function (from, to) {
            delete cm._lineFolds[from.line];
            CodeMirror.signal(cm, "unfold", cm, from, to);
        });

        if (force === "fold") {
            delete range.cleared;
            // In some cases such as in xml style files, the start of  line folds can span multiple lines.
            // For instance the attributes of an element can span multiple lines. In these cases when folding
            // we want to render a gutter marker for both the beginning and end of the opening xml tag.
            if (pos.line < range.from.line) {
                cm._lineFolds[range.from.line] = range;
            } else {
                cm._lineFolds[pos.line] = range;
            }
        } else {
            delete cm._lineFolds[pos.line];
        }

        CodeMirror.signal(cm, force, cm, range.from, range.to);
        return range;
    }
function doFold(cm, pos, options, force) {
        options = options || {};
        force = force || "fold";
        if (typeof pos === "number") {
            pos = CodeMirror.Pos(pos, 0);
        }

        var finder = options.rangeFinder || CodeMirror.fold.auto,
            range,
            widget,
            textRange;

        function getRange(allowFolded) {
            var range = options.range || finder(cm, pos);
            if (!range || range.to.line - range.from.line < prefs.getSetting("minFoldSize")) {
                return null;
            }
            var marks = cm.findMarksAt(range.from),
                i,
                lastMark,
                foldMarks;
            for (i = 0; i < marks.length; ++i) {
                if (marks[i].__isFold && force !== "fold") {
                    if (!allowFolded) {
                        return null;
                    }
                    range.cleared = true;
                    marks[i].clear();
                }
            }
            //check for overlapping folds
            if (marks && marks.length) {
                foldMarks = marks.filter(function (d) {
                    return d.__isFold;
                });
                if (foldMarks && foldMarks.length) {
                    lastMark = foldMarks[foldMarks.length - 1].find();
                    if (lastMark && range.from.line <= lastMark.to.line && lastMark.to.line < range.to.line) {
                        return null;
                    }
                }
            }
            return range;
        }

        function makeWidget() {
            var widget = window.document.createElement("span");
            widget.className = "CodeMirror-foldmarker";
            return widget;
        }

        range = getRange(true);
        if (options.scanUp) {
            while (!range && pos.line > cm.firstLine()) {
                pos = CodeMirror.Pos(pos.line - 1, 0);
                range = getRange(false);
            }
        }
        if (!range || range.cleared || force === "unfold" || range.to.line - range.from.line < prefs.getSetting("minFoldSize")) {
            if (range) { range.cleared = false; }
            return;
        }

        widget = makeWidget();
        textRange = cm.markText(range.from, range.to, {
            replacedWith: widget,
            clearOnEnter: true,
            __isFold: true
        });

        CodeMirror.on(widget, "mousedown", function (e) {
            textRange.clear();
            e.preventDefault();
        });

        textRange.on("clear", function (from, to) {
            delete cm._lineFolds[from.line];
            CodeMirror.signal(cm, "unfold", cm, from, to);
        });

        if (force === "fold") {
            delete range.cleared;
            // In some cases such as in xml style files, the start of  line folds can span multiple lines.
            // For instance the attributes of an element can span multiple lines. In these cases when folding
            // we want to render a gutter marker for both the beginning and end of the opening xml tag.
            if (pos.line < range.from.line) {
                cm._lineFolds[range.from.line] = range;
            } else {
                cm._lineFolds[pos.line] = range;
            }
        } else {
            delete cm._lineFolds[pos.line];
        }

        CodeMirror.signal(cm, force, cm, range.from, range.to);
        return range;
    }
function doFold ( cm , pos , options , force ) { options = options || { } ; force = force || "fold" ; if ( typeof pos === "number" ) { pos = CodeMirror . Pos ( pos , 0 ) ; } var finder = options . rangeFinder || CodeMirror . fold . auto , range , widget , textRange ; function getRange ( allowFolded ) { var range = options . range || finder ( cm , pos ) ; if ( ! range || range . to . line - range . from . line < prefs . getSetting ( "minFoldSize" ) ) { return null ; } var marks = cm . findMarksAt ( range . from ) , i , lastMark , foldMarks ; for ( i = 0 ; i < marks . length ; ++ i ) { if ( marks [ i ] . __isFold && force !== "fold" ) { if ( ! allowFolded ) { return null ; } range . cleared = true ; marks [ i ] . clear ( ) ; } } //check for overlapping folds if ( marks && marks . length ) { foldMarks = marks . filter ( function ( d ) { return d . __isFold ; } ) ; if ( foldMarks && foldMarks . length ) { lastMark = foldMarks [ foldMarks . length - 1 ] . find ( ) ; if ( lastMark && range . from . line <= lastMark . to . line && lastMark . to . line < range . to . line ) { return null ; } } } return range ; } function makeWidget ( ) { var widget = window . document . createElement ( "span" ) ; widget . className = "CodeMirror-foldmarker" ; return widget ; } range = getRange ( true ) ; if ( options . scanUp ) { while ( ! range && pos . line > cm . firstLine ( ) ) { pos = CodeMirror . Pos ( pos . line - 1 , 0 ) ; range = getRange ( false ) ; } } if ( ! range || range . cleared || force === "unfold" || range . to . line - range . from . line < prefs . getSetting ( "minFoldSize" ) ) { if ( range ) { range . cleared = false ; } return ; } widget = makeWidget ( ) ; textRange = cm . markText ( range . from , range . to , { replacedWith : widget , clearOnEnter : true , __isFold : true } ) ; CodeMirror . on ( widget , "mousedown" , function ( e ) { textRange . clear ( ) ; e . preventDefault ( ) ; } ) ; textRange . on ( "clear" , function ( from , to ) { delete cm . _lineFolds [ from . line ] ; CodeMirror . signal ( cm , "unfold" , cm , from , to ) ; } ) ; if ( force === "fold" ) { delete range . cleared ; // In some cases such as in xml style files, the start of  line folds can span multiple lines. // For instance the attributes of an element can span multiple lines. In these cases when folding // we want to render a gutter marker for both the beginning and end of the opening xml tag. if ( pos . line < range . from . line ) { cm . _lineFolds [ range . from . line ] = range ; } else { cm . _lineFolds [ pos . line ] = range ; } } else { delete cm . _lineFolds [ pos . line ] ; } CodeMirror . signal ( cm , force , cm , range . from , range . to ) ; return range ; }
Performs the folding and unfolding of code regions.
@param {CodeMirror} cm the CodeMirror instance
@param {number| Object} pos
Performs the folding and unfolding of code regions .
Folds the given position in the editor.