A CodeMirror instance represents an editor. This is the object that user code is usually dealing with.
173307
function CodeMirror(place, options) {
    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);

    this.options = options = options ? copyObj(options) : {};
    // Determine effective options based on given values and defaults.
    copyObj(defaults, options, false);
    setGuttersForLineNumbers(options);

    var doc = options.value;
    if (typeof doc == "string") doc = new Doc(doc, options.mode);
    this.doc = doc;

    var display = this.display = new Display(place, doc);
    display.wrapper.CodeMirror = this;
    updateGutters(this);
    themeChanged(this);
    if (options.lineWrapping)
      this.display.wrapper.className += " CodeMirror-wrap";
    if (options.autofocus && !mobile) focusInput(this);
    initScrollbars(this);

    this.state = {
      keyMaps: [],  // stores maps added by addKeyMap
      overlays: [], // highlighting overlays, as added by addOverlay
      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
      overwrite: false, focused: false,
      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
      pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput
      draggingText: false,
      highlight: new Delayed(), // stores highlight worker timeout
      keySeq: null  // Unfinished key sequence
    };

    // Override magic textarea content restore that IE sometimes does
    // on our hidden textarea on reload
    if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);

    registerEventHandlers(this);
    ensureGlobalHandlers();

    startOperation(this);
    this.curOp.forceUpdate = true;
    attachDoc(this, doc);

    if ((options.autofocus && !mobile) || activeElt() == display.input)
      setTimeout(bind(onFocus, this), 20);
    else
      onBlur(this);

    for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
      optionHandlers[opt](this, options[opt], Init);
    maybeUpdateLineNumberWidth(this);
    if (options.finishInit) options.finishInit(this);
    for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
    endOperation(this);
    // Suppress optimizelegibility in Webkit, since it breaks text
    // measuring on line wrapping boundaries.
    if (webkit && options.lineWrapping &&
        getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
      display.lineDiv.style.textRendering = "auto";
  }
486633
function drawImage(editor) {
	var cm = editor.codemirror;
	var stat = getState(cm);
	var options = editor.options;
	var url = "http://";
	if(options.promptURLs) {
		url = prompt(options.promptTexts.image);
		if(!url) {
			return false;
		}
	}
	_replaceSelection(cm, stat.image, options.insertTexts.image, url);
}
619724
private static Visibility getEffectiveVisibilityForNonOverriddenProperty(
      Node getprop,
      ObjectType objectType,
      @Nullable Visibility fileOverviewVisibility,
      @Nullable CodingConvention codingConvention) {
    String propertyName = getprop.getLastChild().getString();
    if (codingConvention != null && codingConvention.isPrivate(propertyName)) {
      return Visibility.PRIVATE;
    }
    Visibility raw = Visibility.INHERITED;
    if (objectType != null) {
      raw = objectType.getOwnPropertyJSDocInfo(propertyName).getVisibility();
    }
    JSType type = getprop.getJSType();
    boolean createdFromGoogProvide = (type != null && type.isLiteralObject());
    // Ignore @fileoverview visibility when computing the effective visibility
    // for properties created by goog.provide.
    //
    // ProcessClosurePrimitives rewrites goog.provide()s as object literal
    // declarations, but the exact form depends on the ordering of the
    // input files. If goog.provide('a.b.c') occurs in the inputs before
    // goog.provide('a'), it is rewritten like
    //
    // var a={};a.b={}a.b.c={};
    //
    // If the file containing goog.provide('a.b.c') also declares
    // a @fileoverview visibility, it must not apply to b, as this would make
    // every a.b.* namespace effectively package-private.
    return (raw != Visibility.INHERITED
        || fileOverviewVisibility == null
        || createdFromGoogProvide)
        ? raw
        : fileOverviewVisibility;
  }
1168111
function Editor(el, model) {
  EditorInterface.call(this);
  this.el_ = el;

  // TODO: Use shadow DOM.
  _.assign(this.el_.style, constants.editorStyle);

  // Register input handlers.
  this.boundHandleMouseMove_ = this.handleMouseMove_.bind(this);
  document.addEventListener('keypress', this.handleKeyPress_.bind(this));
  document.addEventListener('keydown', this.handleKeyDown_.bind(this));
  document.addEventListener('mousedown', this.handleMouseDown_.bind(this));
  document.addEventListener('mouseup', this.handleMouseUp_.bind(this));
  window.addEventListener('blur', this.blur.bind(this));

  this.reset(model);
}
416252
function duplicateText(editor) {
        editor = editor || EditorManager.getFocusedEditor();
        if (!editor) {
            return;
        }

        var selections = editor.getSelections(),
            delimiter = "",
            edits = [],
            rangeSels = [],
            cursorSels = [],
            doc = editor.document;

        // When there are multiple selections, we want to handle all the cursors first (duplicating
        // their lines), then all the ranges (duplicating the ranges).
        _.each(selections, function (sel) {
            if (CodeMirror.cmpPos(sel.start, sel.end) === 0) {
                cursorSels.push(sel);
            } else {
                rangeSels.push(sel);
            }
        });

        var cursorLineSels = editor.convertToLineSelections(cursorSels);
        _.each(cursorLineSels, function (lineSel, index) {
            var sel = lineSel.selectionForEdit;
            if (sel.end.line === editor.lineCount()) {
                delimiter = "\n";
            }
            // Don't need to explicitly track selections since we are doing the edits in such a way that
            // the existing selections will get appropriately updated.
            edits.push({edit: {text: doc.getRange(sel.start, sel.end) + delimiter, start: sel.start }});
        });
        _.each(rangeSels, function (sel) {
            edits.push({edit: {text: doc.getRange(sel.start, sel.end), start: sel.start }});
        });

        doc.doMultipleEdits(edits);
    }
1141755
function Viewport(inspector) {
  // Initialize raycaster and picking in differentpmodule.
  const mouseCursor = initRaycaster(inspector);
  const sceneEl = inspector.sceneEl;

  let originalCamera = inspector.cameras.original;
  sceneEl.addEventListener('camera-set-active', event => {
    // If we're in edit mode, save the newly active camera and activate when exiting.
    if (inspector.opened) {
      originalCamera = event.detail.cameraEl;
    }
  });

  // Helpers.
  const sceneHelpers = inspector.sceneHelpers;
  const grid = new THREE.GridHelper(30, 60, 0xaaaaaa, 0x262626);
  sceneHelpers.add(grid);

  const selectionBox = new THREE.BoxHelper();
  selectionBox.material.depthTest = false;
  selectionBox.material.transparent = true;
  selectionBox.material.color.set(0x1faaf2);
  selectionBox.visible = false;
  sceneHelpers.add(selectionBox);

  function updateHelpers(object) {
    object.traverse(node => {
      if (inspector.helpers[node.uuid]) {
        inspector.helpers[node.uuid].update();
      }
    });
  }

  const camera = inspector.camera;
  const transformControls = new THREE.TransformControls(
    camera,
    inspector.container
  );
  transformControls.size = 0.75;
  transformControls.addEventListener('objectChange', evt => {
    const object = transformControls.object;
    if (object === undefined) {
      return;
    }

    selectionBox.setFromObject(object).update();

    updateHelpers(object);

    Events.emit('refreshsidebarobject3d', object);

    // Emit update event for watcher.
    let component;
    let value;
    if (evt.mode === 'translate') {
      component = 'position';
      value = `${object.position.x} ${object.position.y} ${object.position.z}`;
    } else if (evt.mode === 'rotate') {
      component = 'rotation';
      const d = THREE.Math.radToDeg;
      value = `${d(object.rotation.x)} ${d(object.rotation.y)} ${d(
        object.rotation.z
      )}`;
    } else if (evt.mode === 'scale') {
      component = 'scale';
      value = `${object.scale.x} ${object.scale.y} ${object.scale.z}`;
    }
    Events.emit('entityupdate', {
      component: component,
      entity: transformControls.object.el,
      property: '',
      value: value
    });

    Events.emit('entitytransformed', transformControls.object.el);
  });

  transformControls.addEventListener('mouseDown', () => {
    controls.enabled = false;
  });

  transformControls.addEventListener('mouseUp', () => {
    controls.enabled = true;
  });

  sceneHelpers.add(transformControls);

  Events.on('entityupdate', detail => {
    if (inspector.selectedEntity.object3DMap['mesh']) {
      selectionBox.update(inspector.selected);
    }
  });

  // Controls need to be added *after* main logic.
  const controls = new THREE.EditorControls(camera, inspector.container);
  controls.center.set(0, 1.6, 0);
  controls.rotationSpeed = 0.0035;
  controls.zoomSpeed = 0.05;
  controls.setAspectRatio(sceneEl.canvas.width / sceneEl.canvas.height);

  Events.on('cameratoggle', data => {
    controls.setCamera(data.camera);
    transformControls.setCamera(data.camera);
  });

  function disableControls() {
    mouseCursor.disable();
    transformControls.dispose();
    controls.enabled = false;
  }

  function enableControls() {
    mouseCursor.enable();
    transformControls.activate();
    controls.enabled = true;
  }
  enableControls();

  Events.on('inspectorcleared', () => {
    controls.center.set(0, 0, 0);
  });

  Events.on('transformmodechange', mode => {
    transformControls.setMode(mode);
  });

  Events.on('snapchanged', dist => {
    transformControls.setTranslationSnap(dist);
  });

  Events.on('transformspacechanged', space => {
    transformControls.setSpace(space);
  });

  Events.on('objectselect', object => {
    selectionBox.visible = false;
    transformControls.detach();
    if (object && object.el) {
      if (object.el.getObject3D('mesh')) {
        selectionBox.setFromObject(object).update();
        selectionBox.visible = true;
      }

      transformControls.attach(object);
    }
  });

  Events.on('objectfocus', object => {
    controls.focus(object);
    transformControls.update();
  });

  Events.on('geometrychanged', object => {
    if (object !== null) {
      selectionBox.setFromObject(object).update();
    }
  });

  Events.on('entityupdate', detail => {
    const object = detail.entity.object3D;
    if (inspector.selected === object) {
      // Hack because object3D always has geometry :(
      if (
        object.geometry &&
        ((object.geometry.vertices && object.geometry.vertices.length > 0) ||
          (object.geometry.attributes &&
            object.geometry.attributes.position &&
            object.geometry.attributes.position.array.length))
      ) {
        selectionBox.setFromObject(object).update();
      }
    }

    transformControls.update();
    if (object instanceof THREE.PerspectiveCamera) {
      object.updateProjectionMatrix();
    }

    updateHelpers(object);
  });

  Events.on('windowresize', () => {
    camera.aspect =
      inspector.container.offsetWidth / inspector.container.offsetHeight;
    camera.updateProjectionMatrix();
  });

  Events.on('gridvisibilitychanged', showGrid => {
    grid.visible = showGrid;
  });

  Events.on('togglegrid', () => {
    grid.visible = !grid.visible;
  });

  Events.on('inspectortoggle', active => {
    if (active) {
      enableControls();
      AFRAME.scenes[0].camera = inspector.camera;
      Array.prototype.slice
        .call(document.querySelectorAll('.a-enter-vr,.rs-base'))
        .forEach(element => {
          element.style.display = 'none';
        });
    } else {
      disableControls();
      inspector.cameras.original.setAttribute('camera', 'active', 'true');
      AFRAME.scenes[0].camera = inspector.cameras.original.getObject3D('camera');
      Array.prototype.slice
        .call(document.querySelectorAll('.a-enter-vr,.rs-base'))
        .forEach(element => {
          element.style.display = 'block';
        });
    }
    ga('send', 'event', 'Viewport', 'toggleEditor', active);
  });
}
192797
def editor_example():
    
    sensors = [Sensors.PIXEL_CAMERA, Sensors.LOCATION_SENSOR, Sensors.VELOCITY_SENSOR]
    agent = AgentDefinition("uav0", agents.UavAgent, sensors)
    env = HolodeckEnvironment(agent, start_world=False)
    env.agents["uav0"].set_control_scheme(1)
    command = [0, 0, 10, 50]

    for i in range(10):
        env.reset()
        for _ in range(1000):
            state, reward, terminal, _ = env.step(command)
681450
function( editor ) {
			var elementPath = editor.elementPath(),
				activePath = elementPath && elementPath.elements,
				pathMember, ret;

			// IE8: upon initialization if there is no path elementPath() returns null.
			if ( elementPath ) {
				for ( var i = 0; i < activePath.length; i++ ) {
					pathMember = activePath[ i ];

					if ( !ret && pathMember.getName() == 'span' && pathMember.hasAttribute( 'dir' ) && pathMember.hasAttribute( 'lang' ) )
						ret = pathMember;
				}
			}

			return ret;
		}
955003
def showEditor(self):
        """"""
        if self.editor is not None:
            editor = self.editor()
            editor.setModel(self)
            factory = get_stimulus_factory(self._stim.stimType())
            editor.editingFinished.connect(factory.update)
            return editor
        else:
            logger = logging.getLogger('main')
            logger.warning('Erm, no editor available :(')
793572
def set_editor(self, editor, refresh=True):
        
        self.editor = editor
        # Note: This is necessary to test widgets/editor.py
        # in Qt builds that don't have web widgets
        try:
            from qtpy.QtWebEngineWidgets import QWebEngineView
        except ImportError:
            QWebEngineView = type(None)
        self.words_button.setVisible(not isinstance(editor, QWebEngineView))
        self.re_button.setVisible(not isinstance(editor, QWebEngineView))
        from spyder.plugins.editor.widgets.codeeditor import CodeEditor
        self.is_code_editor = isinstance(editor, CodeEditor)
        self.highlight_button.setVisible(self.is_code_editor)
        if refresh:
            self.refresh()
        if self.isHidden() and editor is not None:
            self.clear_matches()
815993
function prepareEditorForProvider(hostEditor, pos) {
        var colorRegEx, cursorLine, match, sel, start, end, endPos, marker;

        sel = hostEditor.getSelection();
        if (sel.start.line !== sel.end.line) {
            return null;
        }

        colorRegEx = new RegExp(ColorUtils.COLOR_REGEX);
        cursorLine = hostEditor.document.getLine(pos.line);

        // Loop through each match of colorRegEx and stop when the one that contains pos is found.
        do {
            match = colorRegEx.exec(cursorLine);
            if (match) {
                start = match.index;
                end = start + match[0].length;
            }
        } while (match && (pos.ch < start || pos.ch > end));

        if (!match) {
            return null;
        }

        // Adjust pos to the beginning of the match so that the inline editor won't get
        // dismissed while we're updating the color with the new values from user's inline editing.
        pos.ch = start;
        endPos = {line: pos.line, ch: end};

        marker = hostEditor._codeMirror.markText(pos, endPos);
        hostEditor.setSelection(pos, endPos);

        return {
            color: match[0],
            marker: marker
        };
    }
935367
protected ClassElement mirrorToClassElement(TypeMirror returnType, JavaVisitorContext visitorContext) {
        if (returnType instanceof NoType) {
            return new JavaVoidElement();
        } else if (returnType instanceof DeclaredType) {
            DeclaredType dt = (DeclaredType) returnType;
            Element e = dt.asElement();
            List<? extends TypeMirror> typeArguments = dt.getTypeArguments();
            if (e instanceof TypeElement) {
                TypeElement typeElement = (TypeElement) e;
                if (JavaModelUtils.resolveKind(typeElement, ElementKind.ENUM).isPresent()) {
                    return new JavaEnumElement(
                            typeElement,
                            visitorContext.getAnnotationUtils().getAnnotationMetadata(typeElement),
                            visitorContext,
                            typeArguments
                    );
                } else {
                    return new JavaClassElement(
                            typeElement,
                            visitorContext.getAnnotationUtils().getAnnotationMetadata(typeElement),
                            visitorContext,
                            typeArguments
                    );
                }
            }
        } else if (returnType instanceof TypeVariable) {
            TypeVariable tv = (TypeVariable) returnType;
            TypeMirror upperBound = tv.getUpperBound();
            ClassElement classElement = mirrorToClassElement(upperBound, visitorContext);
            if (classElement != null) {
                return classElement;
            } else {
                return mirrorToClassElement(tv.getLowerBound(), visitorContext);
            }
        } else if (returnType instanceof ArrayType) {
            ArrayType at = (ArrayType) returnType;
            TypeMirror componentType = at.getComponentType();
            ClassElement arrayType = mirrorToClassElement(componentType, visitorContext);
            if (arrayType != null) {
                if (arrayType instanceof JavaPrimitiveElement) {
                    JavaPrimitiveElement jpe = (JavaPrimitiveElement) arrayType;
                    return jpe.toArray();
                } else {
                    return new JavaClassElement((TypeElement) arrayType.getNativeType(), arrayType, visitorContext) {
                        @Override
                        public boolean isArray() {
                            return true;
                        }
                    };
                }
            }
        } else if (returnType instanceof PrimitiveType) {
            PrimitiveType pt = (PrimitiveType) returnType;
            return JavaPrimitiveElement.valueOf(pt.getKind().name());
        }
        return null;
    }
843290
function setCodeMirror (options) {
    var opts = $.extend({}, codeMirrorDefaultOptions, options);
    return CodeMirror.fromTextArea (document.getElementById ('entry-markdown'), opts);
  }
564945
function CodeManager (_traceManager) {
  this.event = new EventManager()
  this.isLoading = false
  this.traceManager = _traceManager
  this.codeResolver = new CodeResolver({web3: this.traceManager.web3})
}
866681
function _onKeyEvent(instance, event) {
            self.trigger("keyEvent", self, event);  // deprecated
            self.trigger(event.type, self, event);
            return event.defaultPrevented;   // false tells CodeMirror we didn't eat the event
        }
849244
Object resolveTypeReference(TypeMirror type) {
        Object result = Void.TYPE;
        if (type.getKind().isPrimitive()) {
            result = resolvePrimitiveTypeReference(type);
        } else if (type.getKind() == ARRAY) {
            ArrayType arrayType = (ArrayType) type;
            TypeMirror componentType = arrayType.getComponentType();
            if (componentType.getKind().isPrimitive()) {
                result = classOfPrimitiveArrayFor(resolvePrimitiveTypeReference(componentType).getName());
            } else {
                final TypeMirror erased = typeUtils.erasure(componentType);
                final Element e = typeUtils.asElement(erased);
                if (e instanceof TypeElement) {
                    result = resolveTypeReferenceForTypeElement((TypeElement) e) + "[]";
                }
            }
        } else if (type.getKind() != VOID && type.getKind() != ERROR) {
            final TypeMirror erased = typeUtils.erasure(type);
            final Element element = typeUtils.asElement(erased);
            if (element instanceof TypeElement) {
                TypeElement te = (TypeElement) element;
                result = resolveTypeReferenceForTypeElement(te);
            }
        }
        return result;
    }
194483
function toggleCodeBlock(editor) {
	var fenceCharsToInsert = editor.options.blockStyles.code;

	function fencing_line(line) {
		/* return true, if this is a ``` or ~~~ line */
		if(typeof line !== "object") {
			throw "fencing_line() takes a 'line' object (not a line number, or line text).  Got: " + typeof line + ": " + line;
		}
		return line.styles && line.styles[2] && line.styles[2].indexOf("formatting-code-block") !== -1;
	}

	function token_state(token) {
		// base goes an extra level deep when mode backdrops are used, e.g. spellchecker on
		return token.state.base.base || token.state.base;
	}

	function code_type(cm, line_num, line, firstTok, lastTok) {
		/*
		 * Return "single", "indented", "fenced" or false
		 *
		 * cm and line_num are required.  Others are optional for efficiency
		 *   To check in the middle of a line, pass in firstTok yourself.
		 */
		line = line || cm.getLineHandle(line_num);
		firstTok = firstTok || cm.getTokenAt({
			line: line_num,
			ch: 1
		});
		lastTok = lastTok || (!!line.text && cm.getTokenAt({
			line: line_num,
			ch: line.text.length - 1
		}));
		var types = firstTok.type ? firstTok.type.split(" ") : [];
		if(lastTok && token_state(lastTok).indentedCode) {
			// have to check last char, since first chars of first line aren"t marked as indented
			return "indented";
		} else if(types.indexOf("comment") === -1) {
			// has to be after "indented" check, since first chars of first indented line aren"t marked as such
			return false;
		} else if(token_state(firstTok).fencedChars || token_state(lastTok).fencedChars || fencing_line(line)) {
			return "fenced";
		} else {
			return "single";
		}
	}

	function insertFencingAtSelection(cm, cur_start, cur_end, fenceCharsToInsert) {
		var start_line_sel = cur_start.line + 1,
			end_line_sel = cur_end.line + 1,
			sel_multi = cur_start.line !== cur_end.line,
			repl_start = fenceCharsToInsert + "\n",
			repl_end = "\n" + fenceCharsToInsert;
		if(sel_multi) {
			end_line_sel++;
		}
		// handle last char including \n or not
		if(sel_multi && cur_end.ch === 0) {
			repl_end = fenceCharsToInsert + "\n";
			end_line_sel--;
		}
		_replaceSelection(cm, false, [repl_start, repl_end]);
		cm.setSelection({
			line: start_line_sel,
			ch: 0
		}, {
			line: end_line_sel,
			ch: 0
		});
	}

	var cm = editor.codemirror,
		cur_start = cm.getCursor("start"),
		cur_end = cm.getCursor("end"),
		tok = cm.getTokenAt({
			line: cur_start.line,
			ch: cur_start.ch || 1
		}), // avoid ch 0 which is a cursor pos but not token
		line = cm.getLineHandle(cur_start.line),
		is_code = code_type(cm, cur_start.line, line, tok);
	var block_start, block_end, lineCount;

	if(is_code === "single") {
		// similar to some SimpleMDE _toggleBlock logic
		var start = line.text.slice(0, cur_start.ch).replace("`", ""),
			end = line.text.slice(cur_start.ch).replace("`", "");
		cm.replaceRange(start + end, {
			line: cur_start.line,
			ch: 0
		}, {
			line: cur_start.line,
			ch: 99999999999999
		});
		cur_start.ch--;
		if(cur_start !== cur_end) {
			cur_end.ch--;
		}
		cm.setSelection(cur_start, cur_end);
		cm.focus();
	} else if(is_code === "fenced") {
		if(cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
			// use selection

			// find the fenced line so we know what type it is (tilde, backticks, number of them)
			for(block_start = cur_start.line; block_start >= 0; block_start--) {
				line = cm.getLineHandle(block_start);
				if(fencing_line(line)) {
					break;
				}
			}
			var fencedTok = cm.getTokenAt({
				line: block_start,
				ch: 1
			});
			var fence_chars = token_state(fencedTok).fencedChars;
			var start_text, start_line;
			var end_text, end_line;
			// check for selection going up against fenced lines, in which case we don't want to add more fencing
			if(fencing_line(cm.getLineHandle(cur_start.line))) {
				start_text = "";
				start_line = cur_start.line;
			} else if(fencing_line(cm.getLineHandle(cur_start.line - 1))) {
				start_text = "";
				start_line = cur_start.line - 1;
			} else {
				start_text = fence_chars + "\n";
				start_line = cur_start.line;
			}
			if(fencing_line(cm.getLineHandle(cur_end.line))) {
				end_text = "";
				end_line = cur_end.line;
				if(cur_end.ch === 0) {
					end_line += 1;
				}
			} else if(cur_end.ch !== 0 && fencing_line(cm.getLineHandle(cur_end.line + 1))) {
				end_text = "";
				end_line = cur_end.line + 1;
			} else {
				end_text = fence_chars + "\n";
				end_line = cur_end.line + 1;
			}
			if(cur_end.ch === 0) {
				// full last line selected, putting cursor at beginning of next
				end_line -= 1;
			}
			cm.operation(function() {
				// end line first, so that line numbers don't change
				cm.replaceRange(end_text, {
					line: end_line,
					ch: 0
				}, {
					line: end_line + (end_text ? 0 : 1),
					ch: 0
				});
				cm.replaceRange(start_text, {
					line: start_line,
					ch: 0
				}, {
					line: start_line + (start_text ? 0 : 1),
					ch: 0
				});
			});
			cm.setSelection({
				line: start_line + (start_text ? 1 : 0),
				ch: 0
			}, {
				line: end_line + (start_text ? 1 : -1),
				ch: 0
			});
			cm.focus();
		} else {
			// no selection, search for ends of this fenced block
			var search_from = cur_start.line;
			if(fencing_line(cm.getLineHandle(cur_start.line))) { // gets a little tricky if cursor is right on a fenced line
				if(code_type(cm, cur_start.line + 1) === "fenced") {
					block_start = cur_start.line;
					search_from = cur_start.line + 1; // for searching for "end"
				} else {
					block_end = cur_start.line;
					search_from = cur_start.line - 1; // for searching for "start"
				}
			}
			if(block_start === undefined) {
				for(block_start = search_from; block_start >= 0; block_start--) {
					line = cm.getLineHandle(block_start);
					if(fencing_line(line)) {
						break;
					}
				}
			}
			if(block_end === undefined) {
				lineCount = cm.lineCount();
				for(block_end = search_from; block_end < lineCount; block_end++) {
					line = cm.getLineHandle(block_end);
					if(fencing_line(line)) {
						break;
					}
				}
			}
			cm.operation(function() {
				cm.replaceRange("", {
					line: block_start,
					ch: 0
				}, {
					line: block_start + 1,
					ch: 0
				});
				cm.replaceRange("", {
					line: block_end - 1,
					ch: 0
				}, {
					line: block_end,
					ch: 0
				});
			});
			cm.focus();
		}
	} else if(is_code === "indented") {
		if(cur_start.line !== cur_end.line || cur_start.ch !== cur_end.ch) {
			// use selection
			block_start = cur_start.line;
			block_end = cur_end.line;
			if(cur_end.ch === 0) {
				block_end--;
			}
		} else {
			// no selection, search for ends of this indented block
			for(block_start = cur_start.line; block_start >= 0; block_start--) {
				line = cm.getLineHandle(block_start);
				if(line.text.match(/^\s*$/)) {
					// empty or all whitespace - keep going
					continue;
				} else {
					if(code_type(cm, block_start, line) !== "indented") {
						block_start += 1;
						break;
					}
				}
			}
			lineCount = cm.lineCount();
			for(block_end = cur_start.line; block_end < lineCount; block_end++) {
				line = cm.getLineHandle(block_end);
				if(line.text.match(/^\s*$/)) {
					// empty or all whitespace - keep going
					continue;
				} else {
					if(code_type(cm, block_end, line) !== "indented") {
						block_end -= 1;
						break;
					}
				}
			}
		}
		// if we are going to un-indent based on a selected set of lines, and the next line is indented too, we need to
		// insert a blank line so that the next line(s) continue to be indented code
		var next_line = cm.getLineHandle(block_end + 1),
			next_line_last_tok = next_line && cm.getTokenAt({
				line: block_end + 1,
				ch: next_line.text.length - 1
			}),
			next_line_indented = next_line_last_tok && token_state(next_line_last_tok).indentedCode;
		if(next_line_indented) {
			cm.replaceRange("\n", {
				line: block_end + 1,
				ch: 0
			});
		}

		for(var i = block_start; i <= block_end; i++) {
			cm.indentLine(i, "subtract"); // TODO: this doesn't get tracked in the history, so can't be undone :(
		}
		cm.focus();
	} else {
		// insert code formatting
		var no_sel_and_starting_of_line = (cur_start.line === cur_end.line && cur_start.ch === cur_end.ch && cur_start.ch === 0);
		var sel_multi = cur_start.line !== cur_end.line;
		if(no_sel_and_starting_of_line || sel_multi) {
			insertFencingAtSelection(cm, cur_start, cur_end, fenceCharsToInsert);
		} else {
			_replaceSelection(cm, false, ["`", "`"]);
		}
	}
}