code: function onChange(cm, changeObj) {
          if (changeObj.origin === "setValue") {//text content has changed outside of brackets
              var folds = cm.getValidFolds(cm._lineFolds);
              cm._lineFolds = folds;
              Object.keys(folds).forEach(function (line) {
                  cm.foldCode(+line);
              });
          } else {
              var state = cm.state.foldGutter;
              var lineChanges = changeObj.text.length - changeObj.removed.length;
              // for undo actions that add new line(s) to the document first update the folds cache as normal
              // and then update the folds cache with any line folds that exist in the new lines
              if (changeObj.origin === "undo" && lineChanges > 0) {
                  updateFoldsCache(cm, changeObj.from.line, lineChanges);
                  syncDocToFoldsCache(cm, changeObj.from.line, lineChanges);
              } else {
                  updateFoldsCache(cm, changeObj.from.line, lineChanges);
              }
              if (lineChanges !== 0) {
                  updateFoldInfo(cm, Math.max(0, changeObj.from.line + lineChanges), Math.max(0, changeObj.from.line + lineChanges) + 1);
              }
              state.from = changeObj.from.line;
              state.to = 0;
              window.clearTimeout(state.changeUpdate);
              state.changeUpdate = window.setTimeout(function () {
                  updateInViewport(cm);
              }, 600);
          }
      }
docs: Triggered when the content of the document changes. When the entire content of the document
  is changed - e.g., changes made from a different editor, the same lineFolds are kept only if
  they are still valid in the context of the new document content.
  @param {!CodeMirror} cm the CodeMirror instance for the active editor
  @param {!Object} changeObj detailed information about the change that occurred in the document