1{"version":3,"sources":["../../node_modules/codemirror/keymap/vim.js"],"names":["mod","exports","module","require","define","amd","CodeMirror","defaultKeymap","keys","type","toKeys","context","action","motion","motionArgs","linewise","toJumplist","forward","wordEnd","bigWord","inclusive","explicitRepeat","toFirstChar","repeatOffset","isEdit","actionArgs","after","matchIndent","sameLine","operator","operatorArgs","indentRight","toLower","operatorMotionArgs","visualLine","shouldMoveCursor","insertAt","interlaceInsertRepeat","blockwise","keepSpaces","replace","fullLine","exitVisualBlock","position","increase","backtrack","textObjectInner","searchArgs","querySrc","wholeWordOnly","defaultKeymapLength","length","defaultExCommandMap","name","shortName","possiblyAsync","excludeFromCommandHistory","Pos","Vim","enterVimMode","cm","setOption","signal","mode","on","onCursorActivity","maybeInitVimState","getInputField","getOnPasteFn","leaveVimMode","off","state","vim","detachVimMap","next","this","keyMap","rmClass","getWrapperElement","getOption","document","body","style","caretColor","disableFatCursorMark","attach","attachVimMap","prev","addClass","enableFatCursorMark","updateFatCursorMark","fatCursorMarks","clearFatCursorMark","ranges","listSelections","result","i","range","empty","lineLength","getLine","anchor","line","ch","push","markText","className","marks","clear","defineOption","val","Init","test","cmKey","key","undefined","vimKey","cmKeyToVimKey","cmd","findKey","modifiers","Shift","Ctrl","Alt","Cmd","Mod","specialKeys","Enter","Backspace","Delete","Insert","charAt","pieces","split","lastPiece","hasCharacter","piece","isUpperCase","toLowerCase","join","onPasteFn","insertMode","setCursor","offsetCursor","getCursor","actions","enterInsertMode","numberRegex","wordCharTest","isWordChar","bigWordCharTest","makeKeyRange","start","size","String","fromCharCode","upperCaseAlphabet","lowerCaseAlphabet","numbers","validMarks","concat","validRegisters","isLine","firstLine","lastLine","isLowerCase","k","isMatchableSymbol","indexOf","isNumber","isWhiteSpaceString","isEndOfSentenceSymbol","inArray","arr","options","defaultValue","aliases","callback","Error","value","cfg","option","scope","local","createCircularJumpList","pointer","head","tail","buffer","Array","add","oldCur","newCur","current","curMark","useNextSlot","cursor","trashMark","setBookmark","markPos","find","cursorEqual","move","offset","mark","inc","oldPointer","cachedCursor","createInsertModeChanges","c","changes","expectCursorActivityForChange","MacroModeState","latestRegister","isPlaying","isRecording","replaySearchQueries","onRecordingDone","lastInsertModeChanges","prototype","exitMacroRecordMode","macroModeState","vimGlobalState","enterMacroRecordMode","registerName","register","registerController","getRegister","openDialog","bottom","inputState","InputState","lastEditInputState","lastEditActionCommand","lastHPos","lastHSPos","lastMotion","fakeCursor","insertModeRepeat","visualMode","visualBlock","lastSelection","lastPastedText","sel","resetVimGlobalState","searchQuery","searchIsReversed","lastSubstituteReplacePart","jumpList","lastCharacterSearch","increment","selectedCharacter","RegisterController","searchHistoryController","HistoryController","exCommandHistoryController","optionName","lastInsertModeKeyTimer","vimApi","buildKeyMap","getRegisterController","resetVimGlobalState_","getVimGlobalState_","maybeInitVimState_","suppressErrorLogging","InsertModeKey","map","lhs","rhs","ctx","exCommandDispatcher","unmap","noremap","toCtxArray","ctxsToMap","actualLength","origLength","mapping","substr","newMapping","_mapCommand","mappedCtxs","filter","el","mapclear","userKeymap","slice","contexts","j","defineEx","prefix","func","exCommands","commandMap_","handleKey","origin","command","handleMacroRecording","clearInputState","logKey","handleEsc","exitVisualMode","exitInsertMode","doKeyToKey","match","exec","substring","index","handleKeyInsertMode","keyBuffer","keysAreChars","commandDispatcher","matchCommand","thisMatch","window","clearTimeout","setTimeout","selections","here","replaceRange","pop","handleKeyNonInsertMode","keysMatcher","pushRepeatDigit","operation","curOp","isVimOp","processCommand","e","console","handleEx","input","defineMotion","defineAction","defineOperator","mapCommand","defineRegister","prefixRepeat","motionRepeat","n","getRepeat","repeat","parseInt","reason","Register","text","insertModeChanges","searchQueries","setText","pushText","pushInsertModeChanges","pushSearchQuery","query","toString","registers","unnamedRegister","isValidRegister","shiftNumericRegisters_","append","historyBuffer","iterator","initialPrefix","nextMatch","up","dir","element","pushInput","splice","reset","matches","commandMatches","full","partial","bestMatch","character","lastChar","repeatOverride","processMotion","processOperator","processOperatorMotion","processAction","processSearch","processEx","copyArgs","evalInput","updateCmSelection","repeatIsExplicit","recordLastEdit","getSearchCursor","getSearchState","setReversed","promptPrefix","originalQuery","getQuery","originalScrollPos","getScrollInfo","handleQuery","ignoreCase","smartCase","updateSearchQuery","showConfirm","onPromptClose","scrollTo","left","top","logSearchQuery","onPromptKeyUp","close","keyName","target","selectionEnd","selectionStart","Math","min","parsedQuery","scrollIntoView","findNext","clearSearchHighlight","onPromptKeyDown","e_stop","focus","shift","showPrompt","onClose","desc","searchPromptDesc","onKeyUp","onKeyDown","word","expandWordUnderCursor","isKeyword","end","escapeRegex","exArgs","selectValueOnOpen","origHead","copyCursor","clipCursorToContent","origAnchor","oldHead","oldAnchor","newHead","newAnchor","noRepeat","motionResult","motions","recordJumpPosition","Infinity","updateMark","cursorIsBefore","lastSel","lineOffset","abs","chOffset","curStart","curEnd","cmSel","cursorMin","cursorMax","makeCmSelection","tmp","expandSelectionToLine","clipToLine","exclusive","setSelections","primary","operatorMoveTo","operators","actionCommand","moveToTopLine","_head","getUserVisibleLines","findFirstNonWhiteSpaceCharacter","moveToMiddleLine","floor","moveToBottomLine","expandToLine","_cm","cur","isReversed","highlightSearchMatches","goToMark","pos","getMarkPos","moveToOtherHighlightedEnd","jumpToMark","best","isWrongDirection","equal","between","cursorIsBetween","moveByCharacters","moveByLines","endCh","moveByDisplayLines","moveByScroll","moveToColumn","moveToEol","first","last","posV","findPosV","hasMarkedText","moveToStartOfLine","charCoords","res","hitSide","lastCharCoords","goalCoords","coordsChar","resCoords","moveByPage","moveByParagraph","findParagraph","moveBySentence","findSentence","scrollbox","clientHeight","defaultTextHeight","orig","dest","moveByWords","moveToWord","moveTillCharacter","moveToCharacter","recordLastCharacterSearch","moveToSymbol","findSymbol","keepHPos","retval","clipPos","moveToFirstNonWhiteSpaceCharacter","moveToMatchedSymbol","lineText","symbol","getTokenTypeAt","re","matched","findMatchingBracket","bracketRegex","to","moveToLineOrEdgeOfDocument","lineNum","textObjectManipulation","mirroredPairs","(",")","{","}","[","]","<",">","selfPaired","'","\"","`","selectCompanionObject","findBeginningAndEnd","expandTagUnderCursor","expandSelection","repeatLastCharacterSearch","lastSearch","moveH","fn","fillArray","times","change","args","finalHead","getRange","lastState","prevLineEnd","Number","MAX_VALUE","wasLastLine","commands","newlineAndIndent","setSelection","getSelection","replaceSelection","replacement","replaceSelections","delete","indent","startLine","endLine","indentLine","indentAuto","_args","execCommand","changeCase","getSelections","swapped","toSwap","toUpperCase","yank","endPos","jumpListWalk","scroll","lineHeight","delta","newPos","cursorCoords","ceil","newBottom","scrollToCursor","height","y","replayMacro","executeMacroRegister","toggleOverwrite","overwrite","max","getLastEditPos","onChange","onKeyEventTargetKeyDown","selectForInsert","toggleVisualMode","subMode","reselectLastSelection","_actionArgs","updateLastSelection","anchorMark","headMark","joinLines","finalCh","curFinalPos","newLineAndEnterInsertMode","newlineFn","newlineAndIndentContinueComment","paste","tabSize","whitespaceLength","str","tabs","spaces","currentLine","chompedText","wasChomped","firstIndent","wspace","newIndent","quotient","curPosFinal","idx","lastSelectionCurEnd","selectedArea","getSelectedAreaRange","selectedText","emptyStrings","selectBlock","posFromIndex","indexFromPos","lastCh","extendLineToColumn","undo","repeatFn","redo","setRegister","setMark","markName","replaceWith","replaceTo","replaceWithStr","incrementNumberToken","lineStr","numberStr","baseStr","digits","base","0b","0","","0x","number","zeroPadding","from","repeatLastEdit","includeLineBreak","maxCh","ret","prop","hasOwnProperty","offsetLine","offsetCh","commandMatch","pressed","mapped","prefixLen","pressedPrefix","mappedPrefix","cur1","cur2","arguments","apply","call","cur3","cur1before2","cur2before3","trim","s","column","isClipped","curHead","primIndex","getIndex","wasClipped","baseCh","headCh","newDir","lineHead","atAnchor","atHead","getCurrentSelectedAreaRange","getLastSelectedAreaRange","block","width","updateFakeCursor","headOffset","anchorOffset","right","getHead","moveHead","clearFakeCursor","selection","lines","firstNonWS","search","_forward","noSymbol","wordStart","findMatchingTag","findEnclosingTag","tags","open","symbolToMode","*","/","m","M","#","findSymbolModes","bracket","isComplete","nextCh","symb","depth","reverseSymb","section","init","curMoveThrough","comment","found","method","preprocess","token","lineCount","curCh","lineLen","findWord","emptyLineIsWord","charTests","stop","foundWord","words","eodCh","shortCircuit","firstWord","lastWord","charIdxInLine","includeChar","lastIndexOf","isEmpty","isBoundary","any","startState","nextChar","ln","curr","last_valid","skip_empty_lines","reverse","curr_index","bracketRegexp","openSym","curChar","scanForBracket","chars","len","firstIndex","SearchState","setQuery","getOverlay","searchOverlay","setOverlay","overlay","reversed","getScrollbarAnnotate","annotate","setScrollbarAnnotate","searchState_","dialog","template","shortText","prompt","splitBySlash","argString","splitBySeparator","findUnescapedSlashes","findUnescapedSeparators","separator","slashes","tokens","escapeNextChar","translateRegex","specials","unescape","out","specialComesNext","charUnescapes","\\n","\\r","\\t","translateRegexReplace","unescapes","\\/","\\\\","\\&","unescapeRegexReplace","stream","StringStream","output","eol","peek","matcher","parseQuery","lastSearchRegister","RegExp","regexPart","forceIgnoreCase","flagsPart","regexp","openNotification","duration","alert","makePrompt","raw","regexEqual","r1","r2","props","rawQuery","source","matchSol","sol","skipToEnd","backUp","highlightTimeout","searchState","removeOverlay","addOverlay","showMatchesOnScrollbar","isInRange","scrollInfo","occludeToleranceTop","occludeToleranceBottom","bottomY","done","doc","history","ExCommandDispatcher","buildCommandMap_","opt_params","that","_processCommand","commandHistoryRegister","previousCommand","inputStream","params","parseInput_","commandName","matchCommand_","parseCommandArgs_","toInput","eatWhile","eat","lineEnd","parseLineSpec_","numberMatch","parseLineSpecOffset_","offsetMatch","delim","argDelimiter","user","unshift","colorscheme","mapArgs","imap","nmap","vmap","set","setArgs","setCfg","expr","forceGet","optionIsBoolean","oldValue","message","setOptionReturn","setlocal","setglobal","regArgs","regInfo","sort","unique","pattern","parseArgs","eatSpace","opts","decimal","hex","octal","err","lineStart","radix","numPart","textPart","matchPart","compareFn","a","b","anum","bnum","comparePatternFn","textOld","global","matchedLines","content","nextCommand","substitute","replacePart","trailing","count","confirm","startPos","doReplace","write","save","nohlsearch","delmarks","sym","startMark","finishMark","charCodeAt","finish","searchCursor","exMode","lastPos","replaceAll","newText","_value","savedCallback","detach","insertModeChangeRegister","lastChange","logInsertModeChange","extra","fallthrough","imc","repeatInsertModeChanges","changeObj","ignoreCount","selectionCount","maybeReset","handleExternalSelection","widget","createElement","textContent","fakeCursorBookmark","somethingSelected","onKeyFound","lookupKey","repeatForInsert","isAction","cachedInputState","repeatCommand","repeatInsert","changeObject","keyHandler","binding"],"mappings":"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","file":"vim.min.js","sourcesContent":["// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: https://codemirror.net/LICENSE\n\n/**\n * Supported keybindings:\n * Too many to list. Refer to defaultKeymap below.\n *\n * Supported Ex commands:\n * Refer to defaultExCommandMap below.\n *\n * Registers: unnamed, -, a-z, A-Z, 0-9\n * (Does not respect the special case for number registers when delete\n * operator is made with these commands: %, (, ), , /, ?, n, N, {, } )\n * TODO: Implement the remaining registers.\n *\n * Marks: a-z, A-Z, and 0-9\n * TODO: Implement the remaining special marks. They have more complex\n * behavior.\n *\n * Events:\n * 'vim-mode-change' - raised on the editor anytime the current mode changes,\n * Event object: {mode: \"visual\", subMode: \"linewise\"}\n *\n * Code structure:\n * 1. Default keymap\n * 2. Variable declarations and short basic helpers\n * 3. Instance (External API) implementation\n * 4. Internal state tracking objects (input state, counter) implementation\n * and instantiation\n * 5. Key handler (the main command dispatcher) implementation\n * 6. Motion, operator, and action implementations\n * 7. Helper functions for the key handler, motions, operators, and actions\n * 8. Set up Vim to work as a keymap for CodeMirror.\n * 9. Ex command implementations.\n */\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../lib/codemirror\"), require(\"../addon/search/searchcursor\"), require(\"../addon/dialog/dialog\"), require(\"../addon/edit/matchbrackets.js\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../lib/codemirror\", \"../addon/search/searchcursor\", \"../addon/dialog/dialog\", \"../addon/edit/matchbrackets\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n 'use strict';\n\n var defaultKeymap = [\n // Key to key mapping. This goes first to make it possible to override\n // existing mappings.\n { keys: '<Left>', type: 'keyToKey', toKeys: 'h' },\n { keys: '<Right>', type: 'keyToKey', toKeys: 'l' },\n { keys: '<Up>', type: 'keyToKey', toKeys: 'k' },\n { keys: '<Down>', type: 'keyToKey', toKeys: 'j' },\n { keys: '<Space>', type: 'keyToKey', toKeys: 'l' },\n { keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},\n { keys: '<Del>', type: 'keyToKey', toKeys: 'x', context: 'normal'},\n { keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' },\n { keys: '<C-BS>', type: 'keyToKey', toKeys: 'B', context: 'normal' },\n { keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' },\n { keys: '<S-BS>', type: 'keyToKey', toKeys: 'b', context: 'normal' },\n { keys: '<C-n>', type: 'keyToKey', toKeys: 'j' },\n { keys: '<C-p>', type: 'keyToKey', toKeys: 'k' },\n { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>' },\n { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>' },\n { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },\n { keys: '<C-c>', type: 'keyToKey', toKeys: '<Esc>', context: 'insert' },\n { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' },\n { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'},\n { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' },\n { keys: 'S', type: 'keyToKey', toKeys: 'VdO', context: 'visual' },\n { keys: '<Home>', type: 'keyToKey', toKeys: '0' },\n { keys: '<End>', type: 'keyToKey', toKeys: '$' },\n { keys: '<PageUp>', type: 'keyToKey', toKeys: '<C-b>' },\n { keys: '<PageDown>', type: 'keyToKey', toKeys: '<C-f>' },\n { keys: '<CR>', type: 'keyToKey', toKeys: 'j^', context: 'normal' },\n { keys: '<Ins>', type: 'action', action: 'toggleOverwrite', context: 'insert' },\n // Motions\n { keys: 'H', type: 'motion', motion: 'moveToTopLine', motionArgs: { linewise: true, toJumplist: true }},\n { keys: 'M', type: 'motion', motion: 'moveToMiddleLine', motionArgs: { linewise: true, toJumplist: true }},\n { keys: 'L', type: 'motion', motion: 'moveToBottomLine', motionArgs: { linewise: true, toJumplist: true }},\n { keys: 'h', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: false }},\n { keys: 'l', type: 'motion', motion: 'moveByCharacters', motionArgs: { forward: true }},\n { keys: 'j', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, linewise: true }},\n { keys: 'k', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, linewise: true }},\n { keys: 'gj', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: true }},\n { keys: 'gk', type: 'motion', motion: 'moveByDisplayLines', motionArgs: { forward: false }},\n { keys: 'w', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false }},\n { keys: 'W', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: false, bigWord: true }},\n { keys: 'e', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, inclusive: true }},\n { keys: 'E', type: 'motion', motion: 'moveByWords', motionArgs: { forward: true, wordEnd: true, bigWord: true, inclusive: true }},\n { keys: 'b', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }},\n { keys: 'B', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false, bigWord: true }},\n { keys: 'ge', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, inclusive: true }},\n { keys: 'gE', type: 'motion', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: true, bigWord: true, inclusive: true }},\n { keys: '{', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: false, toJumplist: true }},\n { keys: '}', type: 'motion', motion: 'moveByParagraph', motionArgs: { forward: true, toJumplist: true }},\n { keys: '(', type: 'motion', motion: 'moveBySentence', motionArgs: { forward: false }},\n { keys: ')', type: 'motion', motion: 'moveBySentence', motionArgs: { forward: true }},\n { keys: '<C-f>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: true }},\n { keys: '<C-b>', type: 'motion', motion: 'moveByPage', motionArgs: { forward: false }},\n { keys: '<C-d>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: true, explicitRepeat: true }},\n { keys: '<C-u>', type: 'motion', motion: 'moveByScroll', motionArgs: { forward: false, explicitRepeat: true }},\n { keys: 'gg', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: false, explicitRepeat: true, linewise: true, toJumplist: true }},\n { keys: 'G', type: 'motion', motion: 'moveToLineOrEdgeOfDocument', motionArgs: { forward: true, explicitRepeat: true, linewise: true, toJumplist: true }},\n { keys: '0', type: 'motion', motion: 'moveToStartOfLine' },\n { keys: '^', type: 'motion', motion: 'moveToFirstNonWhiteSpaceCharacter' },\n { keys: '+', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true }},\n { keys: '-', type: 'motion', motion: 'moveByLines', motionArgs: { forward: false, toFirstChar:true }},\n { keys: '_', type: 'motion', motion: 'moveByLines', motionArgs: { forward: true, toFirstChar:true, repeatOffset:-1 }},\n { keys: '$', type: 'motion', motion: 'moveToEol', motionArgs: { inclusive: true }},\n { keys: '%', type: 'motion', motion: 'moveToMatchedSymbol', motionArgs: { inclusive: true, toJumplist: true }},\n { keys: 'f<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: true , inclusive: true }},\n { keys: 'F<character>', type: 'motion', motion: 'moveToCharacter', motionArgs: { forward: false }},\n { keys: 't<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: true, inclusive: true }},\n { keys: 'T<character>', type: 'motion', motion: 'moveTillCharacter', motionArgs: { forward: false }},\n { keys: ';', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: true }},\n { keys: ',', type: 'motion', motion: 'repeatLastCharacterSearch', motionArgs: { forward: false }},\n { keys: '\\'<character>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true, linewise: true}},\n { keys: '`<character>', type: 'motion', motion: 'goToMark', motionArgs: {toJumplist: true}},\n { keys: ']`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true } },\n { keys: '[`', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false } },\n { keys: ']\\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: true, linewise: true } },\n { keys: '[\\'', type: 'motion', motion: 'jumpToMark', motionArgs: { forward: false, linewise: true } },\n // the next two aren't motions but must come before more general motion declarations\n { keys: ']p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true, matchIndent: true}},\n { keys: '[p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true, matchIndent: true}},\n { keys: ']<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: true, toJumplist: true}},\n { keys: '[<character>', type: 'motion', motion: 'moveToSymbol', motionArgs: { forward: false, toJumplist: true}},\n { keys: '|', type: 'motion', motion: 'moveToColumn'},\n { keys: 'o', type: 'motion', motion: 'moveToOtherHighlightedEnd', context:'visual'},\n { keys: 'O', type: 'motion', motion: 'moveToOtherHighlightedEnd', motionArgs: {sameLine: true}, context:'visual'},\n // Operators\n { keys: 'd', type: 'operator', operator: 'delete' },\n { keys: 'y', type: 'operator', operator: 'yank' },\n { keys: 'c', type: 'operator', operator: 'change' },\n { keys: '=', type: 'operator', operator: 'indentAuto' },\n { keys: '>', type: 'operator', operator: 'indent', operatorArgs: { indentRight: true }},\n { keys: '<', type: 'operator', operator: 'indent', operatorArgs: { indentRight: false }},\n { keys: 'g~', type: 'operator', operator: 'changeCase' },\n { keys: 'gu', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, isEdit: true },\n { keys: 'gU', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, isEdit: true },\n { keys: 'n', type: 'motion', motion: 'findNext', motionArgs: { forward: true, toJumplist: true }},\n { keys: 'N', type: 'motion', motion: 'findNext', motionArgs: { forward: false, toJumplist: true }},\n // Operator-Motion dual commands\n { keys: 'x', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorMotionArgs: { visualLine: false }},\n { keys: 'X', type: 'operatorMotion', operator: 'delete', motion: 'moveByCharacters', motionArgs: { forward: false }, operatorMotionArgs: { visualLine: true }},\n { keys: 'D', type: 'operatorMotion', operator: 'delete', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},\n { keys: 'D', type: 'operator', operator: 'delete', operatorArgs: { linewise: true }, context: 'visual'},\n { keys: 'Y', type: 'operatorMotion', operator: 'yank', motion: 'expandToLine', motionArgs: { linewise: true }, context: 'normal'},\n { keys: 'Y', type: 'operator', operator: 'yank', operatorArgs: { linewise: true }, context: 'visual'},\n { keys: 'C', type: 'operatorMotion', operator: 'change', motion: 'moveToEol', motionArgs: { inclusive: true }, context: 'normal'},\n { keys: 'C', type: 'operator', operator: 'change', operatorArgs: { linewise: true }, context: 'visual'},\n { keys: '~', type: 'operatorMotion', operator: 'changeCase', motion: 'moveByCharacters', motionArgs: { forward: true }, operatorArgs: { shouldMoveCursor: true }, context: 'normal'},\n { keys: '~', type: 'operator', operator: 'changeCase', context: 'visual'},\n { keys: '<C-w>', type: 'operatorMotion', operator: 'delete', motion: 'moveByWords', motionArgs: { forward: false, wordEnd: false }, context: 'insert' },\n //ignore C-w in normal mode\n { keys: '<C-w>', type: 'idle', context: 'normal' },\n // Actions\n { keys: '<C-i>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: true }},\n { keys: '<C-o>', type: 'action', action: 'jumpListWalk', actionArgs: { forward: false }},\n { keys: '<C-e>', type: 'action', action: 'scroll', actionArgs: { forward: true, linewise: true }},\n { keys: '<C-y>', type: 'action', action: 'scroll', actionArgs: { forward: false, linewise: true }},\n { keys: 'a', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'charAfter' }, context: 'normal' },\n { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' },\n { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' },\n { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' },\n { keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' },\n { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' },\n { keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' },\n { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' },\n { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' },\n { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' },\n { keys: 'v', type: 'action', action: 'toggleVisualMode' },\n { keys: 'V', type: 'action', action: 'toggleVisualMode', actionArgs: { linewise: true }},\n { keys: '<C-v>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},\n { keys: '<C-q>', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }},\n { keys: 'gv', type: 'action', action: 'reselectLastSelection' },\n { keys: 'J', type: 'action', action: 'joinLines', isEdit: true },\n { keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true },\n { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }},\n { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }},\n { keys: 'r<character>', type: 'action', action: 'replace', isEdit: true },\n { keys: '@<character>', type: 'action', action: 'replayMacro' },\n { keys: 'q<character>', type: 'action', action: 'enterMacroRecordMode' },\n // Handle Replace-mode as a special case of insert mode.\n { keys: 'R', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { replace: true }, context: 'normal'},\n { keys: 'R', type: 'operator', operator: 'change', operatorArgs: { linewise: true, fullLine: true }, context: 'visual', exitVisualBlock: true},\n { keys: 'u', type: 'action', action: 'undo', context: 'normal' },\n { keys: 'u', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: true}, context: 'visual', isEdit: true },\n { keys: 'U', type: 'operator', operator: 'changeCase', operatorArgs: {toLower: false}, context: 'visual', isEdit: true },\n { keys: '<C-r>', type: 'action', action: 'redo' },\n { keys: 'm<character>', type: 'action', action: 'setMark' },\n { keys: '\"<character>', type: 'action', action: 'setRegister' },\n { keys: 'zz', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }},\n { keys: 'z.', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'center' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n { keys: 'zt', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }},\n { keys: 'z<CR>', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'top' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n { keys: 'z-', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }},\n { keys: 'zb', type: 'action', action: 'scrollToCursor', actionArgs: { position: 'bottom' }, motion: 'moveToFirstNonWhiteSpaceCharacter' },\n { keys: '.', type: 'action', action: 'repeatLastEdit' },\n { keys: '<C-a>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: true, backtrack: false}},\n { keys: '<C-x>', type: 'action', action: 'incrementNumberToken', isEdit: true, actionArgs: {increase: false, backtrack: false}},\n { keys: '<C-t>', type: 'action', action: 'indent', actionArgs: { indentRight: true }, context: 'insert' },\n { keys: '<C-d>', type: 'action', action: 'indent', actionArgs: { indentRight: false }, context: 'insert' },\n // Text object motions\n { keys: 'a<character>', type: 'motion', motion: 'textObjectManipulation' },\n { keys: 'i<character>', type: 'motion', motion: 'textObjectManipulation', motionArgs: { textObjectInner: true }},\n // Search\n { keys: '/', type: 'search', searchArgs: { forward: true, querySrc: 'prompt', toJumplist: true }},\n { keys: '?', type: 'search', searchArgs: { forward: false, querySrc: 'prompt', toJumplist: true }},\n { keys: '*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},\n { keys: '#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', wholeWordOnly: true, toJumplist: true }},\n { keys: 'g*', type: 'search', searchArgs: { forward: true, querySrc: 'wordUnderCursor', toJumplist: true }},\n { keys: 'g#', type: 'search', searchArgs: { forward: false, querySrc: 'wordUnderCursor', toJumplist: true }},\n // Ex command\n { keys: ':', type: 'ex' }\n ];\n var defaultKeymapLength = defaultKeymap.length;\n\n /**\n * Ex commands\n * Care must be taken when adding to the default Ex command map. For any\n * pair of commands that have a shared prefix, at least one of their\n * shortNames must not match the prefix of the other command.\n */\n var defaultExCommandMap = [\n { name: 'colorscheme', shortName: 'colo' },\n { name: 'map' },\n { name: 'imap', shortName: 'im' },\n { name: 'nmap', shortName: 'nm' },\n { name: 'vmap', shortName: 'vm' },\n { name: 'unmap' },\n { name: 'write', shortName: 'w' },\n { name: 'undo', shortName: 'u' },\n { name: 'redo', shortName: 'red' },\n { name: 'set', shortName: 'se' },\n { name: 'setlocal', shortName: 'setl' },\n { name: 'setglobal', shortName: 'setg' },\n { name: 'sort', shortName: 'sor' },\n { name: 'substitute', shortName: 's', possiblyAsync: true },\n { name: 'nohlsearch', shortName: 'noh' },\n { name: 'yank', shortName: 'y' },\n { name: 'delmarks', shortName: 'delm' },\n { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },\n { name: 'global', shortName: 'g' }\n ];\n\n var Pos = CodeMirror.Pos;\n\n var Vim = function() {\n function enterVimMode(cm) {\n cm.setOption('disableInput', true);\n cm.setOption('showCursorWhenSelecting', false);\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n cm.on('cursorActivity', onCursorActivity);\n maybeInitVimState(cm);\n CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));\n }\n\n function leaveVimMode(cm) {\n cm.setOption('disableInput', false);\n cm.off('cursorActivity', onCursorActivity);\n CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));\n cm.state.vim = null;\n }\n\n function detachVimMap(cm, next) {\n if (this == CodeMirror.keyMap.vim) {\n CodeMirror.rmClass(cm.getWrapperElement(), \"cm-fat-cursor\");\n if (cm.getOption(\"inputStyle\") == \"contenteditable\" && document.body.style.caretColor != null) {\n disableFatCursorMark(cm);\n cm.getInputField().style.caretColor = \"\";\n }\n }\n\n if (!next || next.attach != attachVimMap)\n leaveVimMode(cm);\n }\n function attachVimMap(cm, prev) {\n if (this == CodeMirror.keyMap.vim) {\n CodeMirror.addClass(cm.getWrapperElement(), \"cm-fat-cursor\");\n if (cm.getOption(\"inputStyle\") == \"contenteditable\" && document.body.style.caretColor != null) {\n enableFatCursorMark(cm);\n cm.getInputField().style.caretColor = \"transparent\";\n }\n }\n\n if (!prev || prev.attach != attachVimMap)\n enterVimMode(cm);\n }\n\n function updateFatCursorMark(cm) {\n if (!cm.state.fatCursorMarks) return;\n clearFatCursorMark(cm);\n var ranges = cm.listSelections(), result = []\n for (var i = 0; i < ranges.length; i++) {\n var range = ranges[i];\n if (range.empty()) {\n var lineLength = cm.getLine(range.anchor.line).length;\n if (range.anchor.ch < lineLength) {\n result.push(cm.markText(range.anchor, Pos(range.anchor.line, range.anchor.ch + 1),\n {className: \"cm-fat-cursor-mark\"}));\n } else {\n result.push(cm.markText(Pos(range.anchor.line, lineLength - 1),\n Pos(range.anchor.line, lineLength),\n {className: \"cm-fat-cursor-mark\"}));\n }\n }\n }\n cm.state.fatCursorMarks = result;\n }\n\n function clearFatCursorMark(cm) {\n var marks = cm.state.fatCursorMarks;\n if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear();\n }\n\n function enableFatCursorMark(cm) {\n cm.state.fatCursorMarks = [];\n updateFatCursorMark(cm)\n cm.on(\"cursorActivity\", updateFatCursorMark)\n }\n\n function disableFatCursorMark(cm) {\n clearFatCursorMark(cm);\n cm.off(\"cursorActivity\", updateFatCursorMark);\n // explicitly set fatCursorMarks to null because event listener above\n // can be invoke after removing it, if off is called from operation\n cm.state.fatCursorMarks = null;\n }\n\n // Deprecated, simply setting the keymap works again.\n CodeMirror.defineOption('vimMode', false, function(cm, val, prev) {\n if (val && cm.getOption(\"keyMap\") != \"vim\")\n cm.setOption(\"keyMap\", \"vim\");\n else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption(\"keyMap\")))\n cm.setOption(\"keyMap\", \"default\");\n });\n\n function cmKey(key, cm) {\n if (!cm) { return undefined; }\n if (this[key]) { return this[key]; }\n var vimKey = cmKeyToVimKey(key);\n if (!vimKey) {\n return false;\n }\n var cmd = CodeMirror.Vim.findKey(cm, vimKey);\n if (typeof cmd == 'function') {\n CodeMirror.signal(cm, 'vim-keypress', vimKey);\n }\n return cmd;\n }\n\n var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'};\n var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del',Insert:'Ins'};\n function cmKeyToVimKey(key) {\n if (key.charAt(0) == '\\'') {\n // Keypress character binding of format \"'a'\"\n return key.charAt(1);\n }\n var pieces = key.split(/-(?!$)/);\n var lastPiece = pieces[pieces.length - 1];\n if (pieces.length == 1 && pieces[0].length == 1) {\n // No-modifier bindings use literal character bindings above. Skip.\n return false;\n } else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) {\n // Ignore Shift+char bindings as they should be handled by literal character.\n return false;\n }\n var hasCharacter = false;\n for (var i = 0; i < pieces.length; i++) {\n var piece = pieces[i];\n if (piece in modifiers) { pieces[i] = modifiers[piece]; }\n else { hasCharacter = true; }\n if (piece in specialKeys) { pieces[i] = specialKeys[piece]; }\n }\n if (!hasCharacter) {\n // Vim does not support modifier only keys.\n return false;\n }\n // TODO: Current bindings expect the character to be lower case, but\n // it looks like vim key notation uses upper case.\n if (isUpperCase(lastPiece)) {\n pieces[pieces.length - 1] = lastPiece.toLowerCase();\n }\n return '<' + pieces.join('-') + '>';\n }\n\n function getOnPasteFn(cm) {\n var vim = cm.state.vim;\n if (!vim.onPasteFn) {\n vim.onPasteFn = function() {\n if (!vim.insertMode) {\n cm.setCursor(offsetCursor(cm.getCursor(), 0, 1));\n actions.enterInsertMode(cm, {}, vim);\n }\n };\n }\n return vim.onPasteFn;\n }\n\n var numberRegex = /[\\d]/;\n var wordCharTest = [CodeMirror.isWordChar, function(ch) {\n return ch && !CodeMirror.isWordChar(ch) && !/\\s/.test(ch);\n }], bigWordCharTest = [function(ch) {\n return /\\S/.test(ch);\n }];\n function makeKeyRange(start, size) {\n var keys = [];\n for (var i = start; i < start + size; i++) {\n keys.push(String.fromCharCode(i));\n }\n return keys;\n }\n var upperCaseAlphabet = makeKeyRange(65, 26);\n var lowerCaseAlphabet = makeKeyRange(97, 26);\n var numbers = makeKeyRange(48, 10);\n var validMarks = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['<', '>']);\n var validRegisters = [].concat(upperCaseAlphabet, lowerCaseAlphabet, numbers, ['-', '\"', '.', ':', '/']);\n\n function isLine(cm, line) {\n return line >= cm.firstLine() && line <= cm.lastLine();\n }\n function isLowerCase(k) {\n return (/^[a-z]$/).test(k);\n }\n function isMatchableSymbol(k) {\n return '()[]{}'.indexOf(k) != -1;\n }\n function isNumber(k) {\n return numberRegex.test(k);\n }\n function isUpperCase(k) {\n return (/^[A-Z]$/).test(k);\n }\n function isWhiteSpaceString(k) {\n return (/^\\s*$/).test(k);\n }\n function isEndOfSentenceSymbol(k) {\n return '.?!'.indexOf(k) != -1;\n }\n function inArray(val, arr) {\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] == val) {\n return true;\n }\n }\n return false;\n }\n\n var options = {};\n function defineOption(name, defaultValue, type, aliases, callback) {\n if (defaultValue === undefined && !callback) {\n throw Error('defaultValue is required unless callback is provided');\n }\n if (!type) { type = 'string'; }\n options[name] = {\n type: type,\n defaultValue: defaultValue,\n callback: callback\n };\n if (aliases) {\n for (var i = 0; i < aliases.length; i++) {\n options[aliases[i]] = options[name];\n }\n }\n if (defaultValue) {\n setOption(name, defaultValue);\n }\n }\n\n function setOption(name, value, cm, cfg) {\n var option = options[name];\n cfg = cfg || {};\n var scope = cfg.scope;\n if (!option) {\n return new Error('Unknown option: ' + name);\n }\n if (option.type == 'boolean') {\n if (value && value !== true) {\n return new Error('Invalid argument: ' + name + '=' + value);\n } else if (value !== false) {\n // Boolean options are set to true if value is not defined.\n value = true;\n }\n }\n if (option.callback) {\n if (scope !== 'local') {\n option.callback(value, undefined);\n }\n if (scope !== 'global' && cm) {\n option.callback(value, cm);\n }\n } else {\n if (scope !== 'local') {\n option.value = option.type == 'boolean' ? !!value : value;\n }\n if (scope !== 'global' && cm) {\n cm.state.vim.options[name] = {value: value};\n }\n }\n }\n\n function getOption(name, cm, cfg) {\n var option = options[name];\n cfg = cfg || {};\n var scope = cfg.scope;\n if (!option) {\n return new Error('Unknown option: ' + name);\n }\n if (option.callback) {\n var local = cm && option.callback(undefined, cm);\n if (scope !== 'global' && local !== undefined) {\n return local;\n }\n if (scope !== 'local') {\n return option.callback();\n }\n return;\n } else {\n var local = (scope !== 'global') && (cm && cm.state.vim.options[name]);\n return (local || (scope !== 'local') && option || {}).value;\n }\n }\n\n defineOption('filetype', undefined, 'string', ['ft'], function(name, cm) {\n // Option is local. Do nothing for global.\n if (cm === undefined) {\n return;\n }\n // The 'filetype' option proxies to the CodeMirror 'mode' option.\n if (name === undefined) {\n var mode = cm.getOption('mode');\n return mode == 'null' ? '' : mode;\n } else {\n var mode = name == '' ? 'null' : name;\n cm.setOption('mode', mode);\n }\n });\n\n var createCircularJumpList = function() {\n var size = 100;\n var pointer = -1;\n var head = 0;\n var tail = 0;\n var buffer = new Array(size);\n function add(cm, oldCur, newCur) {\n var current = pointer % size;\n var curMark = buffer[current];\n function useNextSlot(cursor) {\n var next = ++pointer % size;\n var trashMark = buffer[next];\n if (trashMark) {\n trashMark.clear();\n }\n buffer[next] = cm.setBookmark(cursor);\n }\n if (curMark) {\n var markPos = curMark.find();\n // avoid recording redundant cursor position\n if (markPos && !cursorEqual(markPos, oldCur)) {\n useNextSlot(oldCur);\n }\n } else {\n useNextSlot(oldCur);\n }\n useNextSlot(newCur);\n head = pointer;\n tail = pointer - size + 1;\n if (tail < 0) {\n tail = 0;\n }\n }\n function move(cm, offset) {\n pointer += offset;\n if (pointer > head) {\n pointer = head;\n } else if (pointer < tail) {\n pointer = tail;\n }\n var mark = buffer[(size + pointer) % size];\n // skip marks that are temporarily removed from text buffer\n if (mark && !mark.find()) {\n var inc = offset > 0 ? 1 : -1;\n var newCur;\n var oldCur = cm.getCursor();\n do {\n pointer += inc;\n mark = buffer[(size + pointer) % size];\n // skip marks that are the same as current position\n if (mark &&\n (newCur = mark.find()) &&\n !cursorEqual(oldCur, newCur)) {\n break;\n }\n } while (pointer < head && pointer > tail);\n }\n return mark;\n }\n function find(cm, offset) {\n var oldPointer = pointer;\n var mark = move(cm, offset);\n pointer = oldPointer;\n return mark && mark.find();\n }\n return {\n cachedCursor: undefined, //used for # and * jumps\n add: add,\n find: find,\n move: move\n };\n };\n\n // Returns an object to track the changes associated insert mode. It\n // clones the object that is passed in, or creates an empty object one if\n // none is provided.\n var createInsertModeChanges = function(c) {\n if (c) {\n // Copy construction\n return {\n changes: c.changes,\n expectCursorActivityForChange: c.expectCursorActivityForChange\n };\n }\n return {\n // Change list\n changes: [],\n // Set to true on change, false on cursorActivity.\n expectCursorActivityForChange: false\n };\n };\n\n function MacroModeState() {\n this.latestRegister = undefined;\n this.isPlaying = false;\n this.isRecording = false;\n this.replaySearchQueries = [];\n this.onRecordingDone = undefined;\n this.lastInsertModeChanges = createInsertModeChanges();\n }\n MacroModeState.prototype = {\n exitMacroRecordMode: function() {\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.onRecordingDone) {\n macroModeState.onRecordingDone(); // close dialog\n }\n macroModeState.onRecordingDone = undefined;\n macroModeState.isRecording = false;\n },\n enterMacroRecordMode: function(cm, registerName) {\n var register =\n vimGlobalState.registerController.getRegister(registerName);\n if (register) {\n register.clear();\n this.latestRegister = registerName;\n if (cm.openDialog) {\n this.onRecordingDone = cm.openDialog(\n '(recording)['+registerName+']', null, {bottom:true});\n }\n this.isRecording = true;\n }\n }\n };\n\n function maybeInitVimState(cm) {\n if (!cm.state.vim) {\n // Store instance state in the CodeMirror object.\n cm.state.vim = {\n inputState: new InputState(),\n // Vim's input state that triggered the last edit, used to repeat\n // motions and operators with '.'.\n lastEditInputState: undefined,\n // Vim's action command before the last edit, used to repeat actions\n // with '.' and insert mode repeat.\n lastEditActionCommand: undefined,\n // When using jk for navigation, if you move from a longer line to a\n // shorter line, the cursor may clip to the end of the shorter line.\n // If j is pressed again and cursor goes to the next line, the\n // cursor should go back to its horizontal position on the longer\n // line if it can. This is to keep track of the horizontal position.\n lastHPos: -1,\n // Doing the same with screen-position for gj/gk\n lastHSPos: -1,\n // The last motion command run. Cleared if a non-motion command gets\n // executed in between.\n lastMotion: null,\n marks: {},\n // Mark for rendering fake cursor for visual mode.\n fakeCursor: null,\n insertMode: false,\n // Repeat count for changes made in insert mode, triggered by key\n // sequences like 3,i. Only exists when insertMode is true.\n insertModeRepeat: undefined,\n visualMode: false,\n // If we are in visual line mode. No effect if visualMode is false.\n visualLine: false,\n visualBlock: false,\n lastSelection: null,\n lastPastedText: null,\n sel: {},\n // Buffer-local/window-local values of vim options.\n options: {}\n };\n }\n return cm.state.vim;\n }\n var vimGlobalState;\n function resetVimGlobalState() {\n vimGlobalState = {\n // The current search query.\n searchQuery: null,\n // Whether we are searching backwards.\n searchIsReversed: false,\n // Replace part of the last substituted pattern\n lastSubstituteReplacePart: undefined,\n jumpList: createCircularJumpList(),\n macroModeState: new MacroModeState,\n // Recording latest f, t, F or T motion command.\n lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''},\n registerController: new RegisterController({}),\n // search history buffer\n searchHistoryController: new HistoryController(),\n // ex Command history buffer\n exCommandHistoryController : new HistoryController()\n };\n for (var optionName in options) {\n var option = options[optionName];\n option.value = option.defaultValue;\n }\n }\n\n var lastInsertModeKeyTimer;\n var vimApi= {\n buildKeyMap: function() {\n // TODO: Convert keymap into dictionary format for fast lookup.\n },\n // Testing hook, though it might be useful to expose the register\n // controller anyways.\n getRegisterController: function() {\n return vimGlobalState.registerController;\n },\n // Testing hook.\n resetVimGlobalState_: resetVimGlobalState,\n\n // Testing hook.\n getVimGlobalState_: function() {\n return vimGlobalState;\n },\n\n // Testing hook.\n maybeInitVimState_: maybeInitVimState,\n\n suppressErrorLogging: false,\n\n InsertModeKey: InsertModeKey,\n map: function(lhs, rhs, ctx) {\n // Add user defined key bindings.\n exCommandDispatcher.map(lhs, rhs, ctx);\n },\n unmap: function(lhs, ctx) {\n exCommandDispatcher.unmap(lhs, ctx);\n },\n // Non-recursive map function.\n // NOTE: This will not create mappings to key maps that aren't present\n // in the default key map. See TODO at bottom of function.\n noremap: function(lhs, rhs, ctx) {\n function toCtxArray(ctx) {\n return ctx ? [ctx] : ['normal', 'insert', 'visual'];\n }\n var ctxsToMap = toCtxArray(ctx);\n // Look through all actual defaults to find a map candidate.\n var actualLength = defaultKeymap.length, origLength = defaultKeymapLength;\n for (var i = actualLength - origLength;\n i < actualLength && ctxsToMap.length;\n i++) {\n var mapping = defaultKeymap[i];\n // Omit mappings that operate in the wrong context(s) and those of invalid type.\n if (mapping.keys == rhs &&\n (!ctx || !mapping.context || mapping.context === ctx) &&\n mapping.type.substr(0, 2) !== 'ex' &&\n mapping.type.substr(0, 3) !== 'key') {\n // Make a shallow copy of the original keymap entry.\n var newMapping = {};\n for (var key in mapping) {\n newMapping[key] = mapping[key];\n }\n // Modify it point to the new mapping with the proper context.\n newMapping.keys = lhs;\n if (ctx && !newMapping.context) {\n newMapping.context = ctx;\n }\n // Add it to the keymap with a higher priority than the original.\n this._mapCommand(newMapping);\n // Record the mapped contexts as complete.\n var mappedCtxs = toCtxArray(mapping.context);\n ctxsToMap = ctxsToMap.filter(function(el) { return mappedCtxs.indexOf(el) === -1; });\n }\n }\n // TODO: Create non-recursive keyToKey mappings for the unmapped contexts once those exist.\n },\n // Remove all user-defined mappings for the provided context.\n mapclear: function(ctx) {\n // Partition the existing keymap into user-defined and true defaults.\n var actualLength = defaultKeymap.length,\n origLength = defaultKeymapLength;\n var userKeymap = defaultKeymap.slice(0, actualLength - origLength);\n defaultKeymap = defaultKeymap.slice(actualLength - origLength);\n if (ctx) {\n // If a specific context is being cleared, we need to keep mappings\n // from all other contexts.\n for (var i = userKeymap.length - 1; i >= 0; i--) {\n var mapping = userKeymap[i];\n if (ctx !== mapping.context) {\n if (mapping.context) {\n this._mapCommand(mapping);\n } else {\n // `mapping` applies to all contexts so create keymap copies\n // for each context except the one being cleared.\n var contexts = ['normal', 'insert', 'visual'];\n for (var j in contexts) {\n if (contexts[j] !== ctx) {\n var newMapping = {};\n for (var key in mapping) {\n newMapping[key] = mapping[key];\n }\n newMapping.context = contexts[j];\n this._mapCommand(newMapping);\n }\n }\n }\n }\n }\n }\n },\n // TODO: Expose setOption and getOption as instance methods. Need to decide how to namespace\n // them, or somehow make them work with the existing CodeMirror setOption/getOption API.\n setOption: setOption,\n getOption: getOption,\n defineOption: defineOption,\n defineEx: function(name, prefix, func){\n if (!prefix) {\n prefix = name;\n } else if (name.indexOf(prefix) !== 0) {\n throw new Error('(Vim.defineEx) \"'+prefix+'\" is not a prefix of \"'+name+'\", command not registered');\n }\n exCommands[name]=func;\n exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};\n },\n handleKey: function (cm, key, origin) {\n var command = this.findKey(cm, key, origin);\n if (typeof command === 'function') {\n return command();\n }\n },\n /**\n * This is the outermost function called by CodeMirror, after keys have\n * been mapped to their Vim equivalents.\n *\n * Finds a command based on the key (and cached keys if there is a\n * multi-key sequence). Returns `undefined` if no key is matched, a noop\n * function if a partial match is found (multi-key), and a function to\n * execute the bound command if a a key is matched. The function always\n * returns true.\n */\n findKey: function(cm, key, origin) {\n var vim = maybeInitVimState(cm);\n function handleMacroRecording() {\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.isRecording) {\n if (key == 'q') {\n macroModeState.exitMacroRecordMode();\n clearInputState(cm);\n return true;\n }\n if (origin != 'mapping') {\n logKey(macroModeState, key);\n }\n }\n }\n function handleEsc() {\n if (key == '<Esc>') {\n // Clear input state and get back to normal mode.\n clearInputState(cm);\n if (vim.visualMode) {\n exitVisualMode(cm);\n } else if (vim.insertMode) {\n exitInsertMode(cm);\n }\n return true;\n }\n }\n function doKeyToKey(keys) {\n // TODO: prevent infinite recursion.\n var match;\n while (keys) {\n // Pull off one command key, which is either a single character\n // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.\n match = (/<\\w+-.+?>|<\\w+>|./).exec(keys);\n key = match[0];\n keys = keys.substring(match.index + key.length);\n CodeMirror.Vim.handleKey(cm, key, 'mapping');\n }\n }\n\n function handleKeyInsertMode() {\n if (handleEsc()) { return true; }\n var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key;\n var keysAreChars = key.length == 1;\n var match = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert');\n // Need to check all key substrings in insert mode.\n while (keys.length > 1 && match.type != 'full') {\n var keys = vim.inputState.keyBuffer = keys.slice(1);\n var thisMatch = commandDispatcher.matchCommand(keys, defaultKeymap, vim.inputState, 'insert');\n if (thisMatch.type != 'none') { match = thisMatch; }\n }\n if (match.type == 'none') { clearInputState(cm); return false; }\n else if (match.type == 'partial') {\n if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }\n lastInsertModeKeyTimer = window.setTimeout(\n function() { if (vim.insertMode && vim.inputState.keyBuffer) { clearInputState(cm); } },\n getOption('insertModeEscKeysTimeout'));\n return !keysAreChars;\n }\n\n if (lastInsertModeKeyTimer) { window.clearTimeout(lastInsertModeKeyTimer); }\n if (keysAreChars) {\n var selections = cm.listSelections();\n for (var i = 0; i < selections.length; i++) {\n var here = selections[i].head;\n cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input');\n }\n vimGlobalState.macroModeState.lastInsertModeChanges.changes.pop();\n }\n clearInputState(cm);\n return match.command;\n }\n\n function handleKeyNonInsertMode() {\n if (handleMacroRecording() || handleEsc()) { return true; }\n\n var keys = vim.inputState.keyBuffer = vim.inputState.keyBuffer + key;\n if (/^[1-9]\\d*$/.test(keys)) { return true; }\n\n var keysMatcher = /^(\\d*)(.*)$/.exec(keys);\n if (!keysMatcher) { clearInputState(cm); return false; }\n var context = vim.visualMode ? 'visual' :\n 'normal';\n var match = commandDispatcher.matchCommand(keysMatcher[2] || keysMatcher[1], defaultKeymap, vim.inputState, context);\n if (match.type == 'none') { clearInputState(cm); return false; }\n else if (match.type == 'partial') { return true; }\n\n vim.inputState.keyBuffer = '';\n var keysMatcher = /^(\\d*)(.*)$/.exec(keys);\n if (keysMatcher[1] && keysMatcher[1] != '0') {\n vim.inputState.pushRepeatDigit(keysMatcher[1]);\n }\n return match.command;\n }\n\n var command;\n if (vim.insertMode) { command = handleKeyInsertMode(); }\n else { command = handleKeyNonInsertMode(); }\n if (command === false) {\n return !vim.insertMode && key.length === 1 ? function() { return true; } : undefined;\n } else if (command === true) {\n // TODO: Look into using CodeMirror's multi-key handling.\n // Return no-op since we are caching the key. Counts as handled, but\n // don't want act on it just yet.\n return function() { return true; };\n } else {\n return function() {\n return cm.operation(function() {\n cm.curOp.isVimOp = true;\n try {\n if (command.type == 'keyToKey') {\n doKeyToKey(command.toKeys);\n } else {\n commandDispatcher.processCommand(cm, vim, command);\n }\n } catch (e) {\n // clear VIM state in case it's in a bad state.\n cm.state.vim = undefined;\n maybeInitVimState(cm);\n if (!CodeMirror.Vim.suppressErrorLogging) {\n console['log'](e);\n }\n throw e;\n }\n return true;\n });\n };\n }\n },\n handleEx: function(cm, input) {\n exCommandDispatcher.processCommand(cm, input);\n },\n\n defineMotion: defineMotion,\n defineAction: defineAction,\n defineOperator: defineOperator,\n mapCommand: mapCommand,\n _mapCommand: _mapCommand,\n\n defineRegister: defineRegister,\n\n exitVisualMode: exitVisualMode,\n exitInsertMode: exitInsertMode\n };\n\n // Represents the current input state.\n function InputState() {\n this.prefixRepeat = [];\n this.motionRepeat = [];\n\n this.operator = null;\n this.operatorArgs = null;\n this.motion = null;\n this.motionArgs = null;\n this.keyBuffer = []; // For matching multi-key commands.\n this.registerName = null; // Defaults to the unnamed register.\n }\n InputState.prototype.pushRepeatDigit = function(n) {\n if (!this.operator) {\n this.prefixRepeat = this.prefixRepeat.concat(n);\n } else {\n this.motionRepeat = this.motionRepeat.concat(n);\n }\n };\n InputState.prototype.getRepeat = function() {\n var repeat = 0;\n if (this.prefixRepeat.length > 0 || this.motionRepeat.length > 0) {\n repeat = 1;\n if (this.prefixRepeat.length > 0) {\n repeat *= parseInt(this.prefixRepeat.join(''), 10);\n }\n if (this.motionRepeat.length > 0) {\n repeat *= parseInt(this.motionRepeat.join(''), 10);\n }\n }\n return repeat;\n };\n\n function clearInputState(cm, reason) {\n cm.state.vim.inputState = new InputState();\n CodeMirror.signal(cm, 'vim-command-done', reason);\n }\n\n /*\n * Register stores information about copy and paste registers. Besides\n * text, a register must store whether it is linewise (i.e., when it is\n * pasted, should it insert itself into a new line, or should the text be\n * inserted at the cursor position.)\n */\n function Register(text, linewise, blockwise) {\n this.clear();\n this.keyBuffer = [text || ''];\n this.insertModeChanges = [];\n this.searchQueries = [];\n this.linewise = !!linewise;\n this.blockwise = !!blockwise;\n }\n Register.prototype = {\n setText: function(text, linewise, blockwise) {\n this.keyBuffer = [text || ''];\n this.linewise = !!linewise;\n this.blockwise = !!blockwise;\n },\n pushText: function(text, linewise) {\n // if this register has ever been set to linewise, use linewise.\n if (linewise) {\n if (!this.linewise) {\n this.keyBuffer.push('\\n');\n }\n this.linewise = true;\n }\n this.keyBuffer.push(text);\n },\n pushInsertModeChanges: function(changes) {\n this.insertModeChanges.push(createInsertModeChanges(changes));\n },\n pushSearchQuery: function(query) {\n this.searchQueries.push(query);\n },\n clear: function() {\n this.keyBuffer = [];\n this.insertModeChanges = [];\n this.searchQueries = [];\n this.linewise = false;\n },\n toString: function() {\n return this.keyBuffer.join('');\n }\n };\n\n /**\n * Defines an external register.\n *\n * The name should be a single character that will be used to reference the register.\n * The register should support setText, pushText, clear, and toString(). See Register\n * for a reference implementation.\n */\n function defineRegister(name, register) {\n var registers = vimGlobalState.registerController.registers;\n if (!name || name.length != 1) {\n throw Error('Register name must be 1 character');\n }\n if (registers[name]) {\n throw Error('Register already defined ' + name);\n }\n registers[name] = register;\n validRegisters.push(name);\n }\n\n /*\n * vim registers allow you to keep many independent copy and paste buffers.\n * See http://usevim.com/2012/04/13/registers/ for an introduction.\n *\n * RegisterController keeps the state of all the registers. An initial\n * state may be passed in. The unnamed register '\"' will always be\n * overridden.\n */\n function RegisterController(registers) {\n this.registers = registers;\n this.unnamedRegister = registers['\"'] = new Register();\n registers['.'] = new Register();\n registers[':'] = new Register();\n registers['/'] = new Register();\n }\n RegisterController.prototype = {\n pushText: function(registerName, operator, text, linewise, blockwise) {\n if (linewise && text.charAt(text.length - 1) !== '\\n'){\n text += '\\n';\n }\n // Lowercase and uppercase registers refer to the same register.\n // Uppercase just means append.\n var register = this.isValidRegister(registerName) ?\n this.getRegister(registerName) : null;\n // if no register/an invalid register was specified, things go to the\n // default registers\n if (!register) {\n switch (operator) {\n case 'yank':\n // The 0 register contains the text from the most recent yank.\n this.registers['0'] = new Register(text, linewise, blockwise);\n break;\n case 'delete':\n case 'change':\n if (text.indexOf('\\n') == -1) {\n // Delete less than 1 line. Update the small delete register.\n this.registers['-'] = new Register(text, linewise);\n } else {\n // Shift down the contents of the numbered registers and put the\n // deleted text into register 1.\n this.shiftNumericRegisters_();\n this.registers['1'] = new Register(text, linewise);\n }\n break;\n }\n // Make sure the unnamed register is set to what just happened\n this.unnamedRegister.setText(text, linewise, blockwise);\n return;\n }\n\n // If we've gotten to this point, we've actually specified a register\n var append = isUpperCase(registerName);\n if (append) {\n register.pushText(text, linewise);\n } else {\n register.setText(text, linewise, blockwise);\n }\n // The unnamed register always has the same value as the last used\n // register.\n this.unnamedRegister.setText(register.toString(), linewise);\n },\n // Gets the register named @name. If one of @name doesn't already exist,\n // create it. If @name is invalid, return the unnamedRegister.\n getRegister: function(name) {\n if (!this.isValidRegister(name)) {\n return this.unnamedRegister;\n }\n name = name.toLowerCase();\n if (!this.registers[name]) {\n this.registers[name] = new Register();\n }\n return this.registers[name];\n },\n isValidRegister: function(name) {\n return name && inArray(name, validRegisters);\n },\n shiftNumericRegisters_: function() {\n for (var i = 9; i >= 2; i--) {\n this.registers[i] = this.getRegister('' + (i - 1));\n }\n }\n };\n function HistoryController() {\n this.historyBuffer = [];\n this.iterator = 0;\n this.initialPrefix = null;\n }\n HistoryController.prototype = {\n // the input argument here acts a user entered prefix for a small time\n // until we start autocompletion in which case it is the autocompleted.\n nextMatch: function (input, up) {\n var historyBuffer = this.historyBuffer;\n var dir = up ? -1 : 1;\n if (this.initialPrefix === null) this.initialPrefix = input;\n for (var i = this.iterator + dir; up ? i >= 0 : i < historyBuffer.length; i+= dir) {\n var element = historyBuffer[i];\n for (var j = 0; j <= element.length; j++) {\n if (this.initialPrefix == element.substring(0, j)) {\n this.iterator = i;\n return element;\n }\n }\n }\n // should return the user input in case we reach the end of buffer.\n if (i >= historyBuffer.length) {\n this.iterator = historyBuffer.length;\n return this.initialPrefix;\n }\n // return the last autocompleted query or exCommand as it is.\n if (i < 0 ) return input;\n },\n pushInput: function(input) {\n var index = this.historyBuffer.indexOf(input);\n if (index > -1) this.historyBuffer.splice(index, 1);\n if (input.length) this.historyBuffer.push(input);\n },\n reset: function() {\n this.initialPrefix = null;\n this.iterator = this.historyBuffer.length;\n }\n };\n var commandDispatcher = {\n matchCommand: function(keys, keyMap, inputState, context) {\n var matches = commandMatches(keys, keyMap, context, inputState);\n if (!matches.full && !matches.partial) {\n return {type: 'none'};\n } else if (!matches.full && matches.partial) {\n return {type: 'partial'};\n }\n\n var bestMatch;\n for (var i = 0; i < matches.full.length; i++) {\n var match = matches.full[i];\n if (!bestMatch) {\n bestMatch = match;\n }\n }\n if (bestMatch.keys.slice(-11) == '<character>') {\n var character = lastChar(keys);\n if (!character) return {type: 'none'};\n inputState.selectedCharacter = character;\n }\n return {type: 'full', command: bestMatch};\n },\n processCommand: function(cm, vim, command) {\n vim.inputState.repeatOverride = command.repeatOverride;\n switch (command.type) {\n case 'motion':\n this.processMotion(cm, vim, command);\n break;\n case 'operator':\n this.processOperator(cm, vim, command);\n break;\n case 'operatorMotion':\n this.processOperatorMotion(cm, vim, command);\n break;\n case 'action':\n this.processAction(cm, vim, command);\n break;\n case 'search':\n this.processSearch(cm, vim, command);\n break;\n case 'ex':\n case 'keyToEx':\n this.processEx(cm, vim, command);\n break;\n default:\n break;\n }\n },\n processMotion: function(cm, vim, command) {\n vim.inputState.motion = command.motion;\n vim.inputState.motionArgs = copyArgs(command.motionArgs);\n this.evalInput(cm, vim);\n },\n processOperator: function(cm, vim, command) {\n var inputState = vim.inputState;\n if (inputState.operator) {\n if (inputState.operator == command.operator) {\n // Typing an operator twice like 'dd' makes the operator operate\n // linewise\n inputState.motion = 'expandToLine';\n inputState.motionArgs = { linewise: true };\n this.evalInput(cm, vim);\n return;\n } else {\n // 2 different operators in a row doesn't make sense.\n clearInputState(cm);\n }\n }\n inputState.operator = command.operator;\n inputState.operatorArgs = copyArgs(command.operatorArgs);\n if (command.exitVisualBlock) {\n vim.visualBlock = false;\n updateCmSelection(cm);\n }\n if (vim.visualMode) {\n // Operating on a selection in visual mode. We don't need a motion.\n this.evalInput(cm, vim);\n }\n },\n processOperatorMotion: function(cm, vim, command) {\n var visualMode = vim.visualMode;\n var operatorMotionArgs = copyArgs(command.operatorMotionArgs);\n if (operatorMotionArgs) {\n // Operator motions may have special behavior in visual mode.\n if (visualMode && operatorMotionArgs.visualLine) {\n vim.visualLine = true;\n }\n }\n this.processOperator(cm, vim, command);\n if (!visualMode) {\n this.processMotion(cm, vim, command);\n }\n },\n processAction: function(cm, vim, command) {\n var inputState = vim.inputState;\n var repeat = inputState.getRepeat();\n var repeatIsExplicit = !!repeat;\n var actionArgs = copyArgs(command.actionArgs) || {};\n if (inputState.selectedCharacter) {\n actionArgs.selectedCharacter = inputState.selectedCharacter;\n }\n // Actions may or may not have motions and operators. Do these first.\n if (command.operator) {\n this.processOperator(cm, vim, command);\n }\n if (command.motion) {\n this.processMotion(cm, vim, command);\n }\n if (command.motion || command.operator) {\n this.evalInput(cm, vim);\n }\n actionArgs.repeat = repeat || 1;\n actionArgs.repeatIsExplicit = repeatIsExplicit;\n actionArgs.registerName = inputState.registerName;\n clearInputState(cm);\n vim.lastMotion = null;\n if (command.isEdit) {\n this.recordLastEdit(vim, inputState, command);\n }\n actions[command.action](cm, actionArgs, vim);\n },\n processSearch: function(cm, vim, command) {\n if (!cm.getSearchCursor) {\n // Search depends on SearchCursor.\n return;\n }\n var forward = command.searchArgs.forward;\n var wholeWordOnly = command.searchArgs.wholeWordOnly;\n getSearchState(cm).setReversed(!forward);\n var promptPrefix = (forward) ? '/' : '?';\n var originalQuery = getSearchState(cm).getQuery();\n var originalScrollPos = cm.getScrollInfo();\n function handleQuery(query, ignoreCase, smartCase) {\n vimGlobalState.searchHistoryController.pushInput(query);\n vimGlobalState.searchHistoryController.reset();\n try {\n updateSearchQuery(cm, query, ignoreCase, smartCase);\n } catch (e) {\n showConfirm(cm, 'Invalid regex: ' + query);\n clearInputState(cm);\n return;\n }\n commandDispatcher.processMotion(cm, vim, {\n type: 'motion',\n motion: 'findNext',\n motionArgs: { forward: true, toJumplist: command.searchArgs.toJumplist }\n });\n }\n function onPromptClose(query) {\n cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n handleQuery(query, true /** ignoreCase */, true /** smartCase */);\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.isRecording) {\n logSearchQuery(macroModeState, query);\n }\n }\n function onPromptKeyUp(e, query, close) {\n var keyName = CodeMirror.keyName(e), up, offset;\n if (keyName == 'Up' || keyName == 'Down') {\n up = keyName == 'Up' ? true : false;\n offset = e.target ? e.target.selectionEnd : 0;\n query = vimGlobalState.searchHistoryController.nextMatch(query, up) || '';\n close(query);\n if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);\n } else {\n if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift')\n vimGlobalState.searchHistoryController.reset();\n }\n var parsedQuery;\n try {\n parsedQuery = updateSearchQuery(cm, query,\n true /** ignoreCase */, true /** smartCase */);\n } catch (e) {\n // Swallow bad regexes for incremental search.\n }\n if (parsedQuery) {\n cm.scrollIntoView(findNext(cm, !forward, parsedQuery), 30);\n } else {\n clearSearchHighlight(cm);\n cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n }\n }\n function onPromptKeyDown(e, query, close) {\n var keyName = CodeMirror.keyName(e);\n if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' ||\n (keyName == 'Backspace' && query == '')) {\n vimGlobalState.searchHistoryController.pushInput(query);\n vimGlobalState.searchHistoryController.reset();\n updateSearchQuery(cm, originalQuery);\n clearSearchHighlight(cm);\n cm.scrollTo(originalScrollPos.left, originalScrollPos.top);\n CodeMirror.e_stop(e);\n clearInputState(cm);\n close();\n cm.focus();\n } else if (keyName == 'Up' || keyName == 'Down') {\n CodeMirror.e_stop(e);\n } else if (keyName == 'Ctrl-U') {\n // Ctrl-U clears input.\n CodeMirror.e_stop(e);\n close('');\n }\n }\n switch (command.searchArgs.querySrc) {\n case 'prompt':\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.isPlaying) {\n var query = macroModeState.replaySearchQueries.shift();\n handleQuery(query, true /** ignoreCase */, false /** smartCase */);\n } else {\n showPrompt(cm, {\n onClose: onPromptClose,\n prefix: promptPrefix,\n desc: searchPromptDesc,\n onKeyUp: onPromptKeyUp,\n onKeyDown: onPromptKeyDown\n });\n }\n break;\n case 'wordUnderCursor':\n var word = expandWordUnderCursor(cm, false /** inclusive */,\n true /** forward */, false /** bigWord */,\n true /** noSymbol */);\n var isKeyword = true;\n if (!word) {\n word = expandWordUnderCursor(cm, false /** inclusive */,\n true /** forward */, false /** bigWord */,\n false /** noSymbol */);\n isKeyword = false;\n }\n if (!word) {\n return;\n }\n var query = cm.getLine(word.start.line).substring(word.start.ch,\n word.end.ch);\n if (isKeyword && wholeWordOnly) {\n query = '\\\\b' + query + '\\\\b';\n } else {\n query = escapeRegex(query);\n }\n\n // cachedCursor is used to save the old position of the cursor\n // when * or # causes vim to seek for the nearest word and shift\n // the cursor before entering the motion.\n vimGlobalState.jumpList.cachedCursor = cm.getCursor();\n cm.setCursor(word.start);\n\n handleQuery(query, true /** ignoreCase */, false /** smartCase */);\n break;\n }\n },\n processEx: function(cm, vim, command) {\n function onPromptClose(input) {\n // Give the prompt some time to close so that if processCommand shows\n // an error, the elements don't overlap.\n vimGlobalState.exCommandHistoryController.pushInput(input);\n vimGlobalState.exCommandHistoryController.reset();\n exCommandDispatcher.processCommand(cm, input);\n }\n function onPromptKeyDown(e, input, close) {\n var keyName = CodeMirror.keyName(e), up, offset;\n if (keyName == 'Esc' || keyName == 'Ctrl-C' || keyName == 'Ctrl-[' ||\n (keyName == 'Backspace' && input == '')) {\n vimGlobalState.exCommandHistoryController.pushInput(input);\n vimGlobalState.exCommandHistoryController.reset();\n CodeMirror.e_stop(e);\n clearInputState(cm);\n close();\n cm.focus();\n }\n if (keyName == 'Up' || keyName == 'Down') {\n CodeMirror.e_stop(e);\n up = keyName == 'Up' ? true : false;\n offset = e.target ? e.target.selectionEnd : 0;\n input = vimGlobalState.exCommandHistoryController.nextMatch(input, up) || '';\n close(input);\n if (offset && e.target) e.target.selectionEnd = e.target.selectionStart = Math.min(offset, e.target.value.length);\n } else if (keyName == 'Ctrl-U') {\n // Ctrl-U clears input.\n CodeMirror.e_stop(e);\n close('');\n } else {\n if ( keyName != 'Left' && keyName != 'Right' && keyName != 'Ctrl' && keyName != 'Alt' && keyName != 'Shift')\n vimGlobalState.exCommandHistoryController.reset();\n }\n }\n if (command.type == 'keyToEx') {\n // Handle user defined Ex to Ex mappings\n exCommandDispatcher.processCommand(cm, command.exArgs.input);\n } else {\n if (vim.visualMode) {\n showPrompt(cm, { onClose: onPromptClose, prefix: ':', value: '\\'<,\\'>',\n onKeyDown: onPromptKeyDown, selectValueOnOpen: false});\n } else {\n showPrompt(cm, { onClose: onPromptClose, prefix: ':',\n onKeyDown: onPromptKeyDown});\n }\n }\n },\n evalInput: function(cm, vim) {\n // If the motion command is set, execute both the operator and motion.\n // Otherwise return.\n var inputState = vim.inputState;\n var motion = inputState.motion;\n var motionArgs = inputState.motionArgs || {};\n var operator = inputState.operator;\n var operatorArgs = inputState.operatorArgs || {};\n var registerName = inputState.registerName;\n var sel = vim.sel;\n // TODO: Make sure cm and vim selections are identical outside visual mode.\n var origHead = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.head): cm.getCursor('head'));\n var origAnchor = copyCursor(vim.visualMode ? clipCursorToContent(cm, sel.anchor) : cm.getCursor('anchor'));\n var oldHead = copyCursor(origHead);\n var oldAnchor = copyCursor(origAnchor);\n var newHead, newAnchor;\n var repeat;\n if (operator) {\n this.recordLastEdit(vim, inputState);\n }\n if (inputState.repeatOverride !== undefined) {\n // If repeatOverride is specified, that takes precedence over the\n // input state's repeat. Used by Ex mode and can be user defined.\n repeat = inputState.repeatOverride;\n } else {\n repeat = inputState.getRepeat();\n }\n if (repeat > 0 && motionArgs.explicitRepeat) {\n motionArgs.repeatIsExplicit = true;\n } else if (motionArgs.noRepeat ||\n (!motionArgs.explicitRepeat && repeat === 0)) {\n repeat = 1;\n motionArgs.repeatIsExplicit = false;\n }\n if (inputState.selectedCharacter) {\n // If there is a character input, stick it in all of the arg arrays.\n motionArgs.selectedCharacter = operatorArgs.selectedCharacter =\n inputState.selectedCharacter;\n }\n motionArgs.repeat = repeat;\n clearInputState(cm);\n if (motion) {\n var motionResult = motions[motion](cm, origHead, motionArgs, vim);\n vim.lastMotion = motions[motion];\n if (!motionResult) {\n return;\n }\n if (motionArgs.toJumplist) {\n var jumpList = vimGlobalState.jumpList;\n // if the current motion is # or *, use cachedCursor\n var cachedCursor = jumpList.cachedCursor;\n if (cachedCursor) {\n recordJumpPosition(cm, cachedCursor, motionResult);\n delete jumpList.cachedCursor;\n } else {\n recordJumpPosition(cm, origHead, motionResult);\n }\n }\n if (motionResult instanceof Array) {\n newAnchor = motionResult[0];\n newHead = motionResult[1];\n } else {\n newHead = motionResult;\n }\n // TODO: Handle null returns from motion commands better.\n if (!newHead) {\n newHead = copyCursor(origHead);\n }\n if (vim.visualMode) {\n if (!(vim.visualBlock && newHead.ch === Infinity)) {\n newHead = clipCursorToContent(cm, newHead);\n }\n if (newAnchor) {\n newAnchor = clipCursorToContent(cm, newAnchor);\n }\n newAnchor = newAnchor || oldAnchor;\n sel.anchor = newAnchor;\n sel.head = newHead;\n updateCmSelection(cm);\n updateMark(cm, vim, '<',\n cursorIsBefore(newAnchor, newHead) ? newAnchor\n : newHead);\n updateMark(cm, vim, '>',\n cursorIsBefore(newAnchor, newHead) ? newHead\n : newAnchor);\n } else if (!operator) {\n newHead = clipCursorToContent(cm, newHead);\n cm.setCursor(newHead.line, newHead.ch);\n }\n }\n if (operator) {\n if (operatorArgs.lastSel) {\n // Replaying a visual mode operation\n newAnchor = oldAnchor;\n var lastSel = operatorArgs.lastSel;\n var lineOffset = Math.abs(lastSel.head.line - lastSel.anchor.line);\n var chOffset = Math.abs(lastSel.head.ch - lastSel.anchor.ch);\n if (lastSel.visualLine) {\n // Linewise Visual mode: The same number of lines.\n newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);\n } else if (lastSel.visualBlock) {\n // Blockwise Visual mode: The same number of lines and columns.\n newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch + chOffset);\n } else if (lastSel.head.line == lastSel.anchor.line) {\n // Normal Visual mode within one line: The same number of characters.\n newHead = Pos(oldAnchor.line, oldAnchor.ch + chOffset);\n } else {\n // Normal Visual mode with several lines: The same number of lines, in the\n // last line the same number of characters as in the last line the last time.\n newHead = Pos(oldAnchor.line + lineOffset, oldAnchor.ch);\n }\n vim.visualMode = true;\n vim.visualLine = lastSel.visualLine;\n vim.visualBlock = lastSel.visualBlock;\n sel = vim.sel = {\n anchor: newAnchor,\n head: newHead\n };\n updateCmSelection(cm);\n } else if (vim.visualMode) {\n operatorArgs.lastSel = {\n anchor: copyCursor(sel.anchor),\n head: copyCursor(sel.head),\n visualBlock: vim.visualBlock,\n visualLine: vim.visualLine\n };\n }\n var curStart, curEnd, linewise, mode;\n var cmSel;\n if (vim.visualMode) {\n // Init visual op\n curStart = cursorMin(sel.head, sel.anchor);\n curEnd = cursorMax(sel.head, sel.anchor);\n linewise = vim.visualLine || operatorArgs.linewise;\n mode = vim.visualBlock ? 'block' :\n linewise ? 'line' :\n 'char';\n cmSel = makeCmSelection(cm, {\n anchor: curStart,\n head: curEnd\n }, mode);\n if (linewise) {\n var ranges = cmSel.ranges;\n if (mode == 'block') {\n // Linewise operators in visual block mode extend to end of line\n for (var i = 0; i < ranges.length; i++) {\n ranges[i].head.ch = lineLength(cm, ranges[i].head.line);\n }\n } else if (mode == 'line') {\n ranges[0].head = Pos(ranges[0].head.line + 1, 0);\n }\n }\n } else {\n // Init motion op\n curStart = copyCursor(newAnchor || oldAnchor);\n curEnd = copyCursor(newHead || oldHead);\n if (cursorIsBefore(curEnd, curStart)) {\n var tmp = curStart;\n curStart = curEnd;\n curEnd = tmp;\n }\n linewise = motionArgs.linewise || operatorArgs.linewise;\n if (linewise) {\n // Expand selection to entire line.\n expandSelectionToLine(cm, curStart, curEnd);\n } else if (motionArgs.forward) {\n // Clip to trailing newlines only if the motion goes forward.\n clipToLine(cm, curStart, curEnd);\n }\n mode = 'char';\n var exclusive = !motionArgs.inclusive || linewise;\n cmSel = makeCmSelection(cm, {\n anchor: curStart,\n head: curEnd\n }, mode, exclusive);\n }\n cm.setSelections(cmSel.ranges, cmSel.primary);\n vim.lastMotion = null;\n operatorArgs.repeat = repeat; // For indent in visual mode.\n operatorArgs.registerName = registerName;\n // Keep track of linewise as it affects how paste and change behave.\n operatorArgs.linewise = linewise;\n var operatorMoveTo = operators[operator](\n cm, operatorArgs, cmSel.ranges, oldAnchor, newHead);\n if (vim.visualMode) {\n exitVisualMode(cm, operatorMoveTo != null);\n }\n if (operatorMoveTo) {\n cm.setCursor(operatorMoveTo);\n }\n }\n },\n recordLastEdit: function(vim, inputState, actionCommand) {\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.isPlaying) { return; }\n vim.lastEditInputState = inputState;\n vim.lastEditActionCommand = actionCommand;\n macroModeState.lastInsertModeChanges.changes = [];\n macroModeState.lastInsertModeChanges.expectCursorActivityForChange = false;\n macroModeState.lastInsertModeChanges.visualBlock = vim.visualBlock ? vim.sel.head.line - vim.sel.anchor.line : 0;\n }\n };\n\n /**\n * typedef {Object{line:number,ch:number}} Cursor An object containing the\n * position of the cursor.\n */\n // All of the functions below return Cursor objects.\n var motions = {\n moveToTopLine: function(cm, _head, motionArgs) {\n var line = getUserVisibleLines(cm).top + motionArgs.repeat -1;\n return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n },\n moveToMiddleLine: function(cm) {\n var range = getUserVisibleLines(cm);\n var line = Math.floor((range.top + range.bottom) * 0.5);\n return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n },\n moveToBottomLine: function(cm, _head, motionArgs) {\n var line = getUserVisibleLines(cm).bottom - motionArgs.repeat +1;\n return Pos(line, findFirstNonWhiteSpaceCharacter(cm.getLine(line)));\n },\n expandToLine: function(_cm, head, motionArgs) {\n // Expands forward to end of line, and then to next line if repeat is\n // >1. Does not handle backward motion!\n var cur = head;\n return Pos(cur.line + motionArgs.repeat - 1, Infinity);\n },\n findNext: function(cm, _head, motionArgs) {\n var state = getSearchState(cm);\n var query = state.getQuery();\n if (!query) {\n return;\n }\n var prev = !motionArgs.forward;\n // If search is initiated with ? instead of /, negate direction.\n prev = (state.isReversed()) ? !prev : prev;\n highlightSearchMatches(cm, query);\n return findNext(cm, prev/** prev */, query, motionArgs.repeat);\n },\n goToMark: function(cm, _head, motionArgs, vim) {\n var pos = getMarkPos(cm, vim, motionArgs.selectedCharacter);\n if (pos) {\n return motionArgs.linewise ? { line: pos.line, ch: findFirstNonWhiteSpaceCharacter(cm.getLine(pos.line)) } : pos;\n }\n return null;\n },\n moveToOtherHighlightedEnd: function(cm, _head, motionArgs, vim) {\n if (vim.visualBlock && motionArgs.sameLine) {\n var sel = vim.sel;\n return [\n clipCursorToContent(cm, Pos(sel.anchor.line, sel.head.ch)),\n clipCursorToContent(cm, Pos(sel.head.line, sel.anchor.ch))\n ];\n } else {\n return ([vim.sel.head, vim.sel.anchor]);\n }\n },\n jumpToMark: function(cm, head, motionArgs, vim) {\n var best = head;\n for (var i = 0; i < motionArgs.repeat; i++) {\n var cursor = best;\n for (var key in vim.marks) {\n if (!isLowerCase(key)) {\n continue;\n }\n var mark = vim.marks[key].find();\n var isWrongDirection = (motionArgs.forward) ?\n cursorIsBefore(mark, cursor) : cursorIsBefore(cursor, mark);\n\n if (isWrongDirection) {\n continue;\n }\n if (motionArgs.linewise && (mark.line == cursor.line)) {\n continue;\n }\n\n var equal = cursorEqual(cursor, best);\n var between = (motionArgs.forward) ?\n cursorIsBetween(cursor, mark, best) :\n cursorIsBetween(best, mark, cursor);\n\n if (equal || between) {\n best = mark;\n }\n }\n }\n\n if (motionArgs.linewise) {\n // Vim places the cursor on the first non-whitespace character of\n // the line if there is one, else it places the cursor at the end\n // of the line, regardless of whether a mark was found.\n best = Pos(best.line, findFirstNonWhiteSpaceCharacter(cm.getLine(best.line)));\n }\n return best;\n },\n moveByCharacters: function(_cm, head, motionArgs) {\n var cur = head;\n var repeat = motionArgs.repeat;\n var ch = motionArgs.forward ? cur.ch + repeat : cur.ch - repeat;\n return Pos(cur.line, ch);\n },\n moveByLines: function(cm, head, motionArgs, vim) {\n var cur = head;\n var endCh = cur.ch;\n // Depending what our last motion was, we may want to do different\n // things. If our last motion was moving vertically, we want to\n // preserve the HPos from our last horizontal move. If our last motion\n // was going to the end of a line, moving vertically we should go to\n // the end of the line, etc.\n switch (vim.lastMotion) {\n case this.moveByLines:\n case this.moveByDisplayLines:\n case this.moveByScroll:\n case this.moveToColumn:\n case this.moveToEol:\n endCh = vim.lastHPos;\n break;\n default:\n vim.lastHPos = endCh;\n }\n var repeat = motionArgs.repeat+(motionArgs.repeatOffset||0);\n var line = motionArgs.forward ? cur.line + repeat : cur.line - repeat;\n var first = cm.firstLine();\n var last = cm.lastLine();\n var posV = cm.findPosV(cur, (motionArgs.forward ? repeat : -repeat), 'line', vim.lastHSPos);\n var hasMarkedText = motionArgs.forward ? posV.line > line : posV.line < line;\n if (hasMarkedText) {\n line = posV.line;\n endCh = posV.ch;\n }\n // Vim go to line begin or line end when cursor at first/last line and\n // move to previous/next line is triggered.\n if (line < first && cur.line == first){\n return this.moveToStartOfLine(cm, head, motionArgs, vim);\n }else if (line > last && cur.line == last){\n return this.moveToEol(cm, head, motionArgs, vim, true);\n }\n if (motionArgs.toFirstChar){\n endCh=findFirstNonWhiteSpaceCharacter(cm.getLine(line));\n vim.lastHPos = endCh;\n }\n vim.lastHSPos = cm.charCoords(Pos(line, endCh),'div').left;\n return Pos(line, endCh);\n },\n moveByDisplayLines: function(cm, head, motionArgs, vim) {\n var cur = head;\n switch (vim.lastMotion) {\n case this.moveByDisplayLines:\n case this.moveByScroll:\n case this.moveByLines:\n case this.moveToColumn:\n case this.moveToEol:\n break;\n default:\n vim.lastHSPos = cm.charCoords(cur,'div').left;\n }\n var repeat = motionArgs.repeat;\n var res=cm.findPosV(cur,(motionArgs.forward ? repeat : -repeat),'line',vim.lastHSPos);\n if (res.hitSide) {\n if (motionArgs.forward) {\n var lastCharCoords = cm.charCoords(res, 'div');\n var goalCoords = { top: lastCharCoords.top + 8, left: vim.lastHSPos };\n var res = cm.coordsChar(goalCoords, 'div');\n } else {\n var resCoords = cm.charCoords(Pos(cm.firstLine(), 0), 'div');\n resCoords.left = vim.lastHSPos;\n res = cm.coordsChar(resCoords, 'div');\n }\n }\n vim.lastHPos = res.ch;\n return res;\n },\n moveByPage: function(cm, head, motionArgs) {\n // CodeMirror only exposes functions that move the cursor page down, so\n // doing this bad hack to move the cursor and move it back. evalInput\n // will move the cursor to where it should be in the end.\n var curStart = head;\n var repeat = motionArgs.repeat;\n return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page');\n },\n moveByParagraph: function(cm, head, motionArgs) {\n var dir = motionArgs.forward ? 1 : -1;\n return findParagraph(cm, head, motionArgs.repeat, dir);\n },\n moveBySentence: function(cm, head, motionArgs) {\n var dir = motionArgs.forward ? 1 : -1;\n return findSentence(cm, head, motionArgs.repeat, dir);\n },\n moveByScroll: function(cm, head, motionArgs, vim) {\n var scrollbox = cm.getScrollInfo();\n var curEnd = null;\n var repeat = motionArgs.repeat;\n if (!repeat) {\n repeat = scrollbox.clientHeight / (2 * cm.defaultTextHeight());\n }\n var orig = cm.charCoords(head, 'local');\n motionArgs.repeat = repeat;\n var curEnd = motions.moveByDisplayLines(cm, head, motionArgs, vim);\n if (!curEnd) {\n return null;\n }\n var dest = cm.charCoords(curEnd, 'local');\n cm.scrollTo(null, scrollbox.top + dest.top - orig.top);\n return curEnd;\n },\n moveByWords: function(cm, head, motionArgs) {\n return moveToWord(cm, head, motionArgs.repeat, !!motionArgs.forward,\n !!motionArgs.wordEnd, !!motionArgs.bigWord);\n },\n moveTillCharacter: function(cm, _head, motionArgs) {\n var repeat = motionArgs.repeat;\n var curEnd = moveToCharacter(cm, repeat, motionArgs.forward,\n motionArgs.selectedCharacter);\n var increment = motionArgs.forward ? -1 : 1;\n recordLastCharacterSearch(increment, motionArgs);\n if (!curEnd) return null;\n curEnd.ch += increment;\n return curEnd;\n },\n moveToCharacter: function(cm, head, motionArgs) {\n var repeat = motionArgs.repeat;\n recordLastCharacterSearch(0, motionArgs);\n return moveToCharacter(cm, repeat, motionArgs.forward,\n motionArgs.selectedCharacter) || head;\n },\n moveToSymbol: function(cm, head, motionArgs) {\n var repeat = motionArgs.repeat;\n return findSymbol(cm, repeat, motionArgs.forward,\n motionArgs.selectedCharacter) || head;\n },\n moveToColumn: function(cm, head, motionArgs, vim) {\n var repeat = motionArgs.repeat;\n // repeat is equivalent to which column we want to move to!\n vim.lastHPos = repeat - 1;\n vim.lastHSPos = cm.charCoords(head,'div').left;\n return moveToColumn(cm, repeat);\n },\n moveToEol: function(cm, head, motionArgs, vim, keepHPos) {\n var cur = head;\n var retval= Pos(cur.line + motionArgs.repeat - 1, Infinity);\n var end=cm.clipPos(retval);\n end.ch--;\n if (!keepHPos) {\n vim.lastHPos = Infinity;\n vim.lastHSPos = cm.charCoords(end,'div').left;\n }\n return retval;\n },\n moveToFirstNonWhiteSpaceCharacter: function(cm, head) {\n // Go to the start of the line where the text begins, or the end for\n // whitespace-only lines\n var cursor = head;\n return Pos(cursor.line,\n findFirstNonWhiteSpaceCharacter(cm.getLine(cursor.line)));\n },\n moveToMatchedSymbol: function(cm, head) {\n var cursor = head;\n var line = cursor.line;\n var ch = cursor.ch;\n var lineText = cm.getLine(line);\n var symbol;\n for (; ch < lineText.length; ch++) {\n symbol = lineText.charAt(ch);\n if (symbol && isMatchableSymbol(symbol)) {\n var style = cm.getTokenTypeAt(Pos(line, ch + 1));\n if (style !== \"string\" && style !== \"comment\") {\n break;\n }\n }\n }\n if (ch < lineText.length) {\n // Only include angle brackets in analysis if they are being matched.\n var re = (ch === '<' || ch === '>') ? /[(){}[\\]<>]/ : /[(){}[\\]]/;\n var matched = cm.findMatchingBracket(Pos(line, ch), {bracketRegex: re});\n return matched.to;\n } else {\n return cursor;\n }\n },\n moveToStartOfLine: function(_cm, head) {\n return Pos(head.line, 0);\n },\n moveToLineOrEdgeOfDocument: function(cm, _head, motionArgs) {\n var lineNum = motionArgs.forward ? cm.lastLine() : cm.firstLine();\n if (motionArgs.repeatIsExplicit) {\n lineNum = motionArgs.repeat - cm.getOption('firstLineNumber');\n }\n return Pos(lineNum,\n findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));\n },\n textObjectManipulation: function(cm, head, motionArgs, vim) {\n // TODO: lots of possible exceptions that can be thrown here. Try da(\n // outside of a () block.\n var mirroredPairs = {'(': ')', ')': '(',\n '{': '}', '}': '{',\n '[': ']', ']': '[',\n '<': '>', '>': '<'};\n var selfPaired = {'\\'': true, '\"': true, '`': true};\n\n var character = motionArgs.selectedCharacter;\n // 'b' refers to '()' block.\n // 'B' refers to '{}' block.\n if (character == 'b') {\n character = '(';\n } else if (character == 'B') {\n character = '{';\n }\n\n // Inclusive is the difference between a and i\n // TODO: Instead of using the additional text object map to perform text\n // object operations, merge the map into the defaultKeyMap and use\n // motionArgs to define behavior. Define separate entries for 'aw',\n // 'iw', 'a[', 'i[', etc.\n var inclusive = !motionArgs.textObjectInner;\n\n var tmp;\n if (mirroredPairs[character]) {\n tmp = selectCompanionObject(cm, head, character, inclusive);\n } else if (selfPaired[character]) {\n tmp = findBeginningAndEnd(cm, head, character, inclusive);\n } else if (character === 'W') {\n tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,\n true /** bigWord */);\n } else if (character === 'w') {\n tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,\n false /** bigWord */);\n } else if (character === 'p') {\n tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive);\n motionArgs.linewise = true;\n if (vim.visualMode) {\n if (!vim.visualLine) { vim.visualLine = true; }\n } else {\n var operatorArgs = vim.inputState.operatorArgs;\n if (operatorArgs) { operatorArgs.linewise = true; }\n tmp.end.line--;\n }\n } else if (character === 't') {\n tmp = expandTagUnderCursor(cm, head, inclusive);\n } else {\n // No text object defined for this, don't move.\n return null;\n }\n\n if (!cm.state.vim.visualMode) {\n return [tmp.start, tmp.end];\n } else {\n return expandSelection(cm, tmp.start, tmp.end);\n }\n },\n\n repeatLastCharacterSearch: function(cm, head, motionArgs) {\n var lastSearch = vimGlobalState.lastCharacterSearch;\n var repeat = motionArgs.repeat;\n var forward = motionArgs.forward === lastSearch.forward;\n var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);\n cm.moveH(-increment, 'char');\n motionArgs.inclusive = forward ? true : false;\n var curEnd = moveToCharacter(cm, repeat, forward, lastSearch.selectedCharacter);\n if (!curEnd) {\n cm.moveH(increment, 'char');\n return head;\n }\n curEnd.ch += increment;\n return curEnd;\n }\n };\n\n function defineMotion(name, fn) {\n motions[name] = fn;\n }\n\n function fillArray(val, times) {\n var arr = [];\n for (var i = 0; i < times; i++) {\n arr.push(val);\n }\n return arr;\n }\n /**\n * An operator acts on a text selection. It receives the list of selections\n * as input. The corresponding CodeMirror selection is guaranteed to\n * match the input selection.\n */\n var operators = {\n change: function(cm, args, ranges) {\n var finalHead, text;\n var vim = cm.state.vim;\n var anchor = ranges[0].anchor,\n head = ranges[0].head;\n if (!vim.visualMode) {\n text = cm.getRange(anchor, head);\n var lastState = vim.lastEditInputState || {};\n if (lastState.motion == \"moveByWords\" && !isWhiteSpaceString(text)) {\n // Exclude trailing whitespace if the range is not all whitespace.\n var match = (/\\s+$/).exec(text);\n if (match && lastState.motionArgs && lastState.motionArgs.forward) {\n head = offsetCursor(head, 0, - match[0].length);\n text = text.slice(0, - match[0].length);\n }\n }\n var prevLineEnd = new Pos(anchor.line - 1, Number.MAX_VALUE);\n var wasLastLine = cm.firstLine() == cm.lastLine();\n if (head.line > cm.lastLine() && args.linewise && !wasLastLine) {\n cm.replaceRange('', prevLineEnd, head);\n } else {\n cm.replaceRange('', anchor, head);\n }\n if (args.linewise) {\n // Push the next line back down, if there is a next line.\n if (!wasLastLine) {\n cm.setCursor(prevLineEnd);\n CodeMirror.commands.newlineAndIndent(cm);\n }\n // make sure cursor ends up at the end of the line.\n anchor.ch = Number.MAX_VALUE;\n }\n finalHead = anchor;\n } else if (args.fullLine) {\n head.ch = Number.MAX_VALUE;\n head.line--;\n cm.setSelection(anchor, head)\n text = cm.getSelection();\n cm.replaceSelection(\"\");\n finalHead = anchor;\n } else {\n text = cm.getSelection();\n var replacement = fillArray('', ranges.length);\n cm.replaceSelections(replacement);\n finalHead = cursorMin(ranges[0].head, ranges[0].anchor);\n }\n vimGlobalState.registerController.pushText(\n args.registerName, 'change', text,\n args.linewise, ranges.length > 1);\n actions.enterInsertMode(cm, {head: finalHead}, cm.state.vim);\n },\n // delete is a javascript keyword.\n 'delete': function(cm, args, ranges) {\n var finalHead, text;\n var vim = cm.state.vim;\n if (!vim.visualBlock) {\n var anchor = ranges[0].anchor,\n head = ranges[0].head;\n if (args.linewise &&\n head.line != cm.firstLine() &&\n anchor.line == cm.lastLine() &&\n anchor.line == head.line - 1) {\n // Special case for dd on last line (and first line).\n if (anchor.line == cm.firstLine()) {\n anchor.ch = 0;\n } else {\n anchor = Pos(anchor.line - 1, lineLength(cm, anchor.line - 1));\n }\n }\n text = cm.getRange(anchor, head);\n cm.replaceRange('', anchor, head);\n finalHead = anchor;\n if (args.linewise) {\n finalHead = motions.moveToFirstNonWhiteSpaceCharacter(cm, anchor);\n }\n } else {\n text = cm.getSelection();\n var replacement = fillArray('', ranges.length);\n cm.replaceSelections(replacement);\n finalHead = ranges[0].anchor;\n }\n vimGlobalState.registerController.pushText(\n args.registerName, 'delete', text,\n args.linewise, vim.visualBlock);\n return clipCursorToContent(cm, finalHead);\n },\n indent: function(cm, args, ranges) {\n var vim = cm.state.vim;\n var startLine = ranges[0].anchor.line;\n var endLine = vim.visualBlock ?\n ranges[ranges.length - 1].anchor.line :\n ranges[0].head.line;\n // In visual mode, n> shifts the selection right n times, instead of\n // shifting n lines right once.\n var repeat = (vim.visualMode) ? args.repeat : 1;\n if (args.linewise) {\n // The only way to delete a newline is to delete until the start of\n // the next line, so in linewise mode evalInput will include the next\n // line. We don't want this in indent, so we go back a line.\n endLine--;\n }\n for (var i = startLine; i <= endLine; i++) {\n for (var j = 0; j < repeat; j++) {\n cm.indentLine(i, args.indentRight);\n }\n }\n return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);\n },\n indentAuto: function(cm, _args, ranges) {\n cm.execCommand(\"indentAuto\");\n return motions.moveToFirstNonWhiteSpaceCharacter(cm, ranges[0].anchor);\n },\n changeCase: function(cm, args, ranges, oldAnchor, newHead) {\n var selections = cm.getSelections();\n var swapped = [];\n var toLower = args.toLower;\n for (var j = 0; j < selections.length; j++) {\n var toSwap = selections[j];\n var text = '';\n if (toLower === true) {\n text = toSwap.toLowerCase();\n } else if (toLower === false) {\n text = toSwap.toUpperCase();\n } else {\n for (var i = 0; i < toSwap.length; i++) {\n var character = toSwap.charAt(i);\n text += isUpperCase(character) ? character.toLowerCase() :\n character.toUpperCase();\n }\n }\n swapped.push(text);\n }\n cm.replaceSelections(swapped);\n if (args.shouldMoveCursor){\n return newHead;\n } else if (!cm.state.vim.visualMode && args.linewise && ranges[0].anchor.line + 1 == ranges[0].head.line) {\n return motions.moveToFirstNonWhiteSpaceCharacter(cm, oldAnchor);\n } else if (args.linewise){\n return oldAnchor;\n } else {\n return cursorMin(ranges[0].anchor, ranges[0].head);\n }\n },\n yank: function(cm, args, ranges, oldAnchor) {\n var vim = cm.state.vim;\n var text = cm.getSelection();\n var endPos = vim.visualMode\n ? cursorMin(vim.sel.anchor, vim.sel.head, ranges[0].head, ranges[0].anchor)\n : oldAnchor;\n vimGlobalState.registerController.pushText(\n args.registerName, 'yank',\n text, args.linewise, vim.visualBlock);\n return endPos;\n }\n };\n\n function defineOperator(name, fn) {\n operators[name] = fn;\n }\n\n var actions = {\n jumpListWalk: function(cm, actionArgs, vim) {\n if (vim.visualMode) {\n return;\n }\n var repeat = actionArgs.repeat;\n var forward = actionArgs.forward;\n var jumpList = vimGlobalState.jumpList;\n\n var mark = jumpList.move(cm, forward ? repeat : -repeat);\n var markPos = mark ? mark.find() : undefined;\n markPos = markPos ? markPos : cm.getCursor();\n cm.setCursor(markPos);\n },\n scroll: function(cm, actionArgs, vim) {\n if (vim.visualMode) {\n return;\n }\n var repeat = actionArgs.repeat || 1;\n var lineHeight = cm.defaultTextHeight();\n var top = cm.getScrollInfo().top;\n var delta = lineHeight * repeat;\n var newPos = actionArgs.forward ? top + delta : top - delta;\n var cursor = copyCursor(cm.getCursor());\n var cursorCoords = cm.charCoords(cursor, 'local');\n if (actionArgs.forward) {\n if (newPos > cursorCoords.top) {\n cursor.line += (newPos - cursorCoords.top) / lineHeight;\n cursor.line = Math.ceil(cursor.line);\n cm.setCursor(cursor);\n cursorCoords = cm.charCoords(cursor, 'local');\n cm.scrollTo(null, cursorCoords.top);\n } else {\n // Cursor stays within bounds. Just reposition the scroll window.\n cm.scrollTo(null, newPos);\n }\n } else {\n var newBottom = newPos + cm.getScrollInfo().clientHeight;\n if (newBottom < cursorCoords.bottom) {\n cursor.line -= (cursorCoords.bottom - newBottom) / lineHeight;\n cursor.line = Math.floor(cursor.line);\n cm.setCursor(cursor);\n cursorCoords = cm.charCoords(cursor, 'local');\n cm.scrollTo(\n null, cursorCoords.bottom - cm.getScrollInfo().clientHeight);\n } else {\n // Cursor stays within bounds. Just reposition the scroll window.\n cm.scrollTo(null, newPos);\n }\n }\n },\n scrollToCursor: function(cm, actionArgs) {\n var lineNum = cm.getCursor().line;\n var charCoords = cm.charCoords(Pos(lineNum, 0), 'local');\n var height = cm.getScrollInfo().clientHeight;\n var y = charCoords.top;\n var lineHeight = charCoords.bottom - y;\n switch (actionArgs.position) {\n case 'center': y = y - (height / 2) + lineHeight;\n break;\n case 'bottom': y = y - height + lineHeight;\n break;\n }\n cm.scrollTo(null, y);\n },\n replayMacro: function(cm, actionArgs, vim) {\n var registerName = actionArgs.selectedCharacter;\n var repeat = actionArgs.repeat;\n var macroModeState = vimGlobalState.macroModeState;\n if (registerName == '@') {\n registerName = macroModeState.latestRegister;\n } else {\n macroModeState.latestRegister = registerName;\n }\n while(repeat--){\n executeMacroRegister(cm, vim, macroModeState, registerName);\n }\n },\n enterMacroRecordMode: function(cm, actionArgs) {\n var macroModeState = vimGlobalState.macroModeState;\n var registerName = actionArgs.selectedCharacter;\n if (vimGlobalState.registerController.isValidRegister(registerName)) {\n macroModeState.enterMacroRecordMode(cm, registerName);\n }\n },\n toggleOverwrite: function(cm) {\n if (!cm.state.overwrite) {\n cm.toggleOverwrite(true);\n cm.setOption('keyMap', 'vim-replace');\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"replace\"});\n } else {\n cm.toggleOverwrite(false);\n cm.setOption('keyMap', 'vim-insert');\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"insert\"});\n }\n },\n enterInsertMode: function(cm, actionArgs, vim) {\n if (cm.getOption('readOnly')) { return; }\n vim.insertMode = true;\n vim.insertModeRepeat = actionArgs && actionArgs.repeat || 1;\n var insertAt = (actionArgs) ? actionArgs.insertAt : null;\n var sel = vim.sel;\n var head = actionArgs.head || cm.getCursor('head');\n var height = cm.listSelections().length;\n if (insertAt == 'eol') {\n head = Pos(head.line, lineLength(cm, head.line));\n } else if (insertAt == 'bol') {\n head = Pos(head.line, 0);\n } else if (insertAt == 'charAfter') {\n head = offsetCursor(head, 0, 1);\n } else if (insertAt == 'firstNonBlank') {\n head = motions.moveToFirstNonWhiteSpaceCharacter(cm, head);\n } else if (insertAt == 'startOfSelectedArea') {\n if (!vim.visualMode)\n return;\n if (!vim.visualBlock) {\n if (sel.head.line < sel.anchor.line) {\n head = sel.head;\n } else {\n head = Pos(sel.anchor.line, 0);\n }\n } else {\n head = Pos(\n Math.min(sel.head.line, sel.anchor.line),\n Math.min(sel.head.ch, sel.anchor.ch));\n height = Math.abs(sel.head.line - sel.anchor.line) + 1;\n }\n } else if (insertAt == 'endOfSelectedArea') {\n if (!vim.visualMode)\n return;\n if (!vim.visualBlock) {\n if (sel.head.line >= sel.anchor.line) {\n head = offsetCursor(sel.head, 0, 1);\n } else {\n head = Pos(sel.anchor.line, 0);\n }\n } else {\n head = Pos(\n Math.min(sel.head.line, sel.anchor.line),\n Math.max(sel.head.ch + 1, sel.anchor.ch));\n height = Math.abs(sel.head.line - sel.anchor.line) + 1;\n }\n } else if (insertAt == 'inplace') {\n if (vim.visualMode){\n return;\n }\n } else if (insertAt == 'lastEdit') {\n head = getLastEditPos(cm) || head;\n }\n cm.setOption('disableInput', false);\n if (actionArgs && actionArgs.replace) {\n // Handle Replace-mode as a special case of insert mode.\n cm.toggleOverwrite(true);\n cm.setOption('keyMap', 'vim-replace');\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"replace\"});\n } else {\n cm.toggleOverwrite(false);\n cm.setOption('keyMap', 'vim-insert');\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"insert\"});\n }\n if (!vimGlobalState.macroModeState.isPlaying) {\n // Only record if not replaying.\n cm.on('change', onChange);\n CodeMirror.on(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);\n }\n if (vim.visualMode) {\n exitVisualMode(cm);\n }\n selectForInsert(cm, head, height);\n },\n toggleVisualMode: function(cm, actionArgs, vim) {\n var repeat = actionArgs.repeat;\n var anchor = cm.getCursor();\n var head;\n // TODO: The repeat should actually select number of characters/lines\n // equal to the repeat times the size of the previous visual\n // operation.\n if (!vim.visualMode) {\n // Entering visual mode\n vim.visualMode = true;\n vim.visualLine = !!actionArgs.linewise;\n vim.visualBlock = !!actionArgs.blockwise;\n head = clipCursorToContent(\n cm, Pos(anchor.line, anchor.ch + repeat - 1));\n vim.sel = {\n anchor: anchor,\n head: head\n };\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: vim.visualLine ? \"linewise\" : vim.visualBlock ? \"blockwise\" : \"\"});\n updateCmSelection(cm);\n updateMark(cm, vim, '<', cursorMin(anchor, head));\n updateMark(cm, vim, '>', cursorMax(anchor, head));\n } else if (vim.visualLine ^ actionArgs.linewise ||\n vim.visualBlock ^ actionArgs.blockwise) {\n // Toggling between modes\n vim.visualLine = !!actionArgs.linewise;\n vim.visualBlock = !!actionArgs.blockwise;\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\", subMode: vim.visualLine ? \"linewise\" : vim.visualBlock ? \"blockwise\" : \"\"});\n updateCmSelection(cm);\n } else {\n exitVisualMode(cm);\n }\n },\n reselectLastSelection: function(cm, _actionArgs, vim) {\n var lastSelection = vim.lastSelection;\n if (vim.visualMode) {\n updateLastSelection(cm, vim);\n }\n if (lastSelection) {\n var anchor = lastSelection.anchorMark.find();\n var head = lastSelection.headMark.find();\n if (!anchor || !head) {\n // If the marks have been destroyed due to edits, do nothing.\n return;\n }\n vim.sel = {\n anchor: anchor,\n head: head\n };\n vim.visualMode = true;\n vim.visualLine = lastSelection.visualLine;\n vim.visualBlock = lastSelection.visualBlock;\n updateCmSelection(cm);\n updateMark(cm, vim, '<', cursorMin(anchor, head));\n updateMark(cm, vim, '>', cursorMax(anchor, head));\n CodeMirror.signal(cm, 'vim-mode-change', {\n mode: 'visual',\n subMode: vim.visualLine ? 'linewise' :\n vim.visualBlock ? 'blockwise' : ''});\n }\n },\n joinLines: function(cm, actionArgs, vim) {\n var curStart, curEnd;\n if (vim.visualMode) {\n curStart = cm.getCursor('anchor');\n curEnd = cm.getCursor('head');\n if (cursorIsBefore(curEnd, curStart)) {\n var tmp = curEnd;\n curEnd = curStart;\n curStart = tmp;\n }\n curEnd.ch = lineLength(cm, curEnd.line) - 1;\n } else {\n // Repeat is the number of lines to join. Minimum 2 lines.\n var repeat = Math.max(actionArgs.repeat, 2);\n curStart = cm.getCursor();\n curEnd = clipCursorToContent(cm, Pos(curStart.line + repeat - 1,\n Infinity));\n }\n var finalCh = 0;\n for (var i = curStart.line; i < curEnd.line; i++) {\n finalCh = lineLength(cm, curStart.line);\n var tmp = Pos(curStart.line + 1,\n lineLength(cm, curStart.line + 1));\n var text = cm.getRange(curStart, tmp);\n text = actionArgs.keepSpaces\n ? text.replace(/\\n\\r?/g, '')\n : text.replace(/\\n\\s*/g, ' ');\n cm.replaceRange(text, curStart, tmp);\n }\n var curFinalPos = Pos(curStart.line, finalCh);\n if (vim.visualMode) {\n exitVisualMode(cm, false);\n }\n cm.setCursor(curFinalPos);\n },\n newLineAndEnterInsertMode: function(cm, actionArgs, vim) {\n vim.insertMode = true;\n var insertAt = copyCursor(cm.getCursor());\n if (insertAt.line === cm.firstLine() && !actionArgs.after) {\n // Special case for inserting newline before start of document.\n cm.replaceRange('\\n', Pos(cm.firstLine(), 0));\n cm.setCursor(cm.firstLine(), 0);\n } else {\n insertAt.line = (actionArgs.after) ? insertAt.line :\n insertAt.line - 1;\n insertAt.ch = lineLength(cm, insertAt.line);\n cm.setCursor(insertAt);\n var newlineFn = CodeMirror.commands.newlineAndIndentContinueComment ||\n CodeMirror.commands.newlineAndIndent;\n newlineFn(cm);\n }\n this.enterInsertMode(cm, { repeat: actionArgs.repeat }, vim);\n },\n paste: function(cm, actionArgs, vim) {\n var cur = copyCursor(cm.getCursor());\n var register = vimGlobalState.registerController.getRegister(\n actionArgs.registerName);\n var text = register.toString();\n if (!text) {\n return;\n }\n if (actionArgs.matchIndent) {\n var tabSize = cm.getOption(\"tabSize\");\n // length that considers tabs and tabSize\n var whitespaceLength = function(str) {\n var tabs = (str.split(\"\\t\").length - 1);\n var spaces = (str.split(\" \").length - 1);\n return tabs * tabSize + spaces * 1;\n };\n var currentLine = cm.getLine(cm.getCursor().line);\n var indent = whitespaceLength(currentLine.match(/^\\s*/)[0]);\n // chomp last newline b/c don't want it to match /^\\s*/gm\n var chompedText = text.replace(/\\n$/, '');\n var wasChomped = text !== chompedText;\n var firstIndent = whitespaceLength(text.match(/^\\s*/)[0]);\n var text = chompedText.replace(/^\\s*/gm, function(wspace) {\n var newIndent = indent + (whitespaceLength(wspace) - firstIndent);\n if (newIndent < 0) {\n return \"\";\n }\n else if (cm.getOption(\"indentWithTabs\")) {\n var quotient = Math.floor(newIndent / tabSize);\n return Array(quotient + 1).join('\\t');\n }\n else {\n return Array(newIndent + 1).join(' ');\n }\n });\n text += wasChomped ? \"\\n\" : \"\";\n }\n if (actionArgs.repeat > 1) {\n var text = Array(actionArgs.repeat + 1).join(text);\n }\n var linewise = register.linewise;\n var blockwise = register.blockwise;\n if (blockwise) {\n text = text.split('\\n');\n if (linewise) {\n text.pop();\n }\n for (var i = 0; i < text.length; i++) {\n text[i] = (text[i] == '') ? ' ' : text[i];\n }\n cur.ch += actionArgs.after ? 1 : 0;\n cur.ch = Math.min(lineLength(cm, cur.line), cur.ch);\n } else if (linewise) {\n if(vim.visualMode) {\n text = vim.visualLine ? text.slice(0, -1) : '\\n' + text.slice(0, text.length - 1) + '\\n';\n } else if (actionArgs.after) {\n // Move the newline at the end to the start instead, and paste just\n // before the newline character of the line we are on right now.\n text = '\\n' + text.slice(0, text.length - 1);\n cur.ch = lineLength(cm, cur.line);\n } else {\n cur.ch = 0;\n }\n } else {\n cur.ch += actionArgs.after ? 1 : 0;\n }\n var curPosFinal;\n var idx;\n if (vim.visualMode) {\n // save the pasted text for reselection if the need arises\n vim.lastPastedText = text;\n var lastSelectionCurEnd;\n var selectedArea = getSelectedAreaRange(cm, vim);\n var selectionStart = selectedArea[0];\n var selectionEnd = selectedArea[1];\n var selectedText = cm.getSelection();\n var selections = cm.listSelections();\n var emptyStrings = new Array(selections.length).join('1').split('1');\n // save the curEnd marker before it get cleared due to cm.replaceRange.\n if (vim.lastSelection) {\n lastSelectionCurEnd = vim.lastSelection.headMark.find();\n }\n // push the previously selected text to unnamed register\n vimGlobalState.registerController.unnamedRegister.setText(selectedText);\n if (blockwise) {\n // first delete the selected text\n cm.replaceSelections(emptyStrings);\n // Set new selections as per the block length of the yanked text\n selectionEnd = Pos(selectionStart.line + text.length-1, selectionStart.ch);\n cm.setCursor(selectionStart);\n selectBlock(cm, selectionEnd);\n cm.replaceSelections(text);\n curPosFinal = selectionStart;\n } else if (vim.visualBlock) {\n cm.replaceSelections(emptyStrings);\n cm.setCursor(selectionStart);\n cm.replaceRange(text, selectionStart, selectionStart);\n curPosFinal = selectionStart;\n } else {\n cm.replaceRange(text, selectionStart, selectionEnd);\n curPosFinal = cm.posFromIndex(cm.indexFromPos(selectionStart) + text.length - 1);\n }\n // restore the the curEnd marker\n if(lastSelectionCurEnd) {\n vim.lastSelection.headMark = cm.setBookmark(lastSelectionCurEnd);\n }\n if (linewise) {\n curPosFinal.ch=0;\n }\n } else {\n if (blockwise) {\n cm.setCursor(cur);\n for (var i = 0; i < text.length; i++) {\n var line = cur.line+i;\n if (line > cm.lastLine()) {\n cm.replaceRange('\\n', Pos(line, 0));\n }\n var lastCh = lineLength(cm, line);\n if (lastCh < cur.ch) {\n extendLineToColumn(cm, line, cur.ch);\n }\n }\n cm.setCursor(cur);\n selectBlock(cm, Pos(cur.line + text.length-1, cur.ch));\n cm.replaceSelections(text);\n curPosFinal = cur;\n } else {\n cm.replaceRange(text, cur);\n // Now fine tune the cursor to where we want it.\n if (linewise && actionArgs.after) {\n curPosFinal = Pos(\n cur.line + 1,\n findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line + 1)));\n } else if (linewise && !actionArgs.after) {\n curPosFinal = Pos(\n cur.line,\n findFirstNonWhiteSpaceCharacter(cm.getLine(cur.line)));\n } else if (!linewise && actionArgs.after) {\n idx = cm.indexFromPos(cur);\n curPosFinal = cm.posFromIndex(idx + text.length - 1);\n } else {\n idx = cm.indexFromPos(cur);\n curPosFinal = cm.posFromIndex(idx + text.length);\n }\n }\n }\n if (vim.visualMode) {\n exitVisualMode(cm, false);\n }\n cm.setCursor(curPosFinal);\n },\n undo: function(cm, actionArgs) {\n cm.operation(function() {\n repeatFn(cm, CodeMirror.commands.undo, actionArgs.repeat)();\n cm.setCursor(cm.getCursor('anchor'));\n });\n },\n redo: function(cm, actionArgs) {\n repeatFn(cm, CodeMirror.commands.redo, actionArgs.repeat)();\n },\n setRegister: function(_cm, actionArgs, vim) {\n vim.inputState.registerName = actionArgs.selectedCharacter;\n },\n setMark: function(cm, actionArgs, vim) {\n var markName = actionArgs.selectedCharacter;\n updateMark(cm, vim, markName, cm.getCursor());\n },\n replace: function(cm, actionArgs, vim) {\n var replaceWith = actionArgs.selectedCharacter;\n var curStart = cm.getCursor();\n var replaceTo;\n var curEnd;\n var selections = cm.listSelections();\n if (vim.visualMode) {\n curStart = cm.getCursor('start');\n curEnd = cm.getCursor('end');\n } else {\n var line = cm.getLine(curStart.line);\n replaceTo = curStart.ch + actionArgs.repeat;\n if (replaceTo > line.length) {\n replaceTo=line.length;\n }\n curEnd = Pos(curStart.line, replaceTo);\n }\n if (replaceWith=='\\n') {\n if (!vim.visualMode) cm.replaceRange('', curStart, curEnd);\n // special case, where vim help says to replace by just one line-break\n (CodeMirror.commands.newlineAndIndentContinueComment || CodeMirror.commands.newlineAndIndent)(cm);\n } else {\n var replaceWithStr = cm.getRange(curStart, curEnd);\n //replace all characters in range by selected, but keep linebreaks\n replaceWithStr = replaceWithStr.replace(/[^\\n]/g, replaceWith);\n if (vim.visualBlock) {\n // Tabs are split in visua block before replacing\n var spaces = new Array(cm.getOption(\"tabSize\")+1).join(' ');\n replaceWithStr = cm.getSelection();\n replaceWithStr = replaceWithStr.replace(/\\t/g, spaces).replace(/[^\\n]/g, replaceWith).split('\\n');\n cm.replaceSelections(replaceWithStr);\n } else {\n cm.replaceRange(replaceWithStr, curStart, curEnd);\n }\n if (vim.visualMode) {\n curStart = cursorIsBefore(selections[0].anchor, selections[0].head) ?\n selections[0].anchor : selections[0].head;\n cm.setCursor(curStart);\n exitVisualMode(cm, false);\n } else {\n cm.setCursor(offsetCursor(curEnd, 0, -1));\n }\n }\n },\n incrementNumberToken: function(cm, actionArgs) {\n var cur = cm.getCursor();\n var lineStr = cm.getLine(cur.line);\n var re = /(-?)(?:(0x)([\\da-f]+)|(0b|0|)(\\d+))/gi;\n var match;\n var start;\n var end;\n var numberStr;\n while ((match = re.exec(lineStr)) !== null) {\n start = match.index;\n end = start + match[0].length;\n if (cur.ch < end)break;\n }\n if (!actionArgs.backtrack && (end <= cur.ch))return;\n if (match) {\n var baseStr = match[2] || match[4]\n var digits = match[3] || match[5]\n var increment = actionArgs.increase ? 1 : -1;\n var base = {'0b': 2, '0': 8, '': 10, '0x': 16}[baseStr.toLowerCase()];\n var number = parseInt(match[1] + digits, base) + (increment * actionArgs.repeat);\n numberStr = number.toString(base);\n var zeroPadding = baseStr ? new Array(digits.length - numberStr.length + 1 + match[1].length).join('0') : ''\n if (numberStr.charAt(0) === '-') {\n numberStr = '-' + baseStr + zeroPadding + numberStr.substr(1);\n } else {\n numberStr = baseStr + zeroPadding + numberStr;\n }\n var from = Pos(cur.line, start);\n var to = Pos(cur.line, end);\n cm.replaceRange(numberStr, from, to);\n } else {\n return;\n }\n cm.setCursor(Pos(cur.line, start + numberStr.length - 1));\n },\n repeatLastEdit: function(cm, actionArgs, vim) {\n var lastEditInputState = vim.lastEditInputState;\n if (!lastEditInputState) { return; }\n var repeat = actionArgs.repeat;\n if (repeat && actionArgs.repeatIsExplicit) {\n vim.lastEditInputState.repeatOverride = repeat;\n } else {\n repeat = vim.lastEditInputState.repeatOverride || repeat;\n }\n repeatLastEdit(cm, vim, repeat, false /** repeatForInsert */);\n },\n indent: function(cm, actionArgs) {\n cm.indentLine(cm.getCursor().line, actionArgs.indentRight);\n },\n exitInsertMode: exitInsertMode\n };\n\n function defineAction(name, fn) {\n actions[name] = fn;\n }\n\n /*\n * Below are miscellaneous utility functions used by vim.js\n */\n\n /**\n * Clips cursor to ensure that line is within the buffer's range\n * If includeLineBreak is true, then allow cur.ch == lineLength.\n */\n function clipCursorToContent(cm, cur) {\n var vim = cm.state.vim;\n var includeLineBreak = vim.insertMode || vim.visualMode;\n var line = Math.min(Math.max(cm.firstLine(), cur.line), cm.lastLine() );\n var maxCh = lineLength(cm, line) - 1 + !!includeLineBreak;\n var ch = Math.min(Math.max(0, cur.ch), maxCh);\n return Pos(line, ch);\n }\n function copyArgs(args) {\n var ret = {};\n for (var prop in args) {\n if (args.hasOwnProperty(prop)) {\n ret[prop] = args[prop];\n }\n }\n return ret;\n }\n function offsetCursor(cur, offsetLine, offsetCh) {\n if (typeof offsetLine === 'object') {\n offsetCh = offsetLine.ch;\n offsetLine = offsetLine.line;\n }\n return Pos(cur.line + offsetLine, cur.ch + offsetCh);\n }\n function commandMatches(keys, keyMap, context, inputState) {\n // Partial matches are not applied. They inform the key handler\n // that the current key sequence is a subsequence of a valid key\n // sequence, so that the key buffer is not cleared.\n var match, partial = [], full = [];\n for (var i = 0; i < keyMap.length; i++) {\n var command = keyMap[i];\n if (context == 'insert' && command.context != 'insert' ||\n command.context && command.context != context ||\n inputState.operator && command.type == 'action' ||\n !(match = commandMatch(keys, command.keys))) { continue; }\n if (match == 'partial') { partial.push(command); }\n if (match == 'full') { full.push(command); }\n }\n return {\n partial: partial.length && partial,\n full: full.length && full\n };\n }\n function commandMatch(pressed, mapped) {\n if (mapped.slice(-11) == '<character>') {\n // Last character matches anything.\n var prefixLen = mapped.length - 11;\n var pressedPrefix = pressed.slice(0, prefixLen);\n var mappedPrefix = mapped.slice(0, prefixLen);\n return pressedPrefix == mappedPrefix && pressed.length > prefixLen ? 'full' :\n mappedPrefix.indexOf(pressedPrefix) == 0 ? 'partial' : false;\n } else {\n return pressed == mapped ? 'full' :\n mapped.indexOf(pressed) == 0 ? 'partial' : false;\n }\n }\n function lastChar(keys) {\n var match = /^.*(<[^>]+>)$/.exec(keys);\n var selectedCharacter = match ? match[1] : keys.slice(-1);\n if (selectedCharacter.length > 1){\n switch(selectedCharacter){\n case '<CR>':\n selectedCharacter='\\n';\n break;\n case '<Space>':\n selectedCharacter=' ';\n break;\n default:\n selectedCharacter='';\n break;\n }\n }\n return selectedCharacter;\n }\n function repeatFn(cm, fn, repeat) {\n return function() {\n for (var i = 0; i < repeat; i++) {\n fn(cm);\n }\n };\n }\n function copyCursor(cur) {\n return Pos(cur.line, cur.ch);\n }\n function cursorEqual(cur1, cur2) {\n return cur1.ch == cur2.ch && cur1.line == cur2.line;\n }\n function cursorIsBefore(cur1, cur2) {\n if (cur1.line < cur2.line) {\n return true;\n }\n if (cur1.line == cur2.line && cur1.ch < cur2.ch) {\n return true;\n }\n return false;\n }\n function cursorMin(cur1, cur2) {\n if (arguments.length > 2) {\n cur2 = cursorMin.apply(undefined, Array.prototype.slice.call(arguments, 1));\n }\n return cursorIsBefore(cur1, cur2) ? cur1 : cur2;\n }\n function cursorMax(cur1, cur2) {\n if (arguments.length > 2) {\n cur2 = cursorMax.apply(undefined, Array.prototype.slice.call(arguments, 1));\n }\n return cursorIsBefore(cur1, cur2) ? cur2 : cur1;\n }\n function cursorIsBetween(cur1, cur2, cur3) {\n // returns true if cur2 is between cur1 and cur3.\n var cur1before2 = cursorIsBefore(cur1, cur2);\n var cur2before3 = cursorIsBefore(cur2, cur3);\n return cur1before2 && cur2before3;\n }\n function lineLength(cm, lineNum) {\n return cm.getLine(lineNum).length;\n }\n function trim(s) {\n if (s.trim) {\n return s.trim();\n }\n return s.replace(/^\\s+|\\s+$/g, '');\n }\n function escapeRegex(s) {\n return s.replace(/([.?*+$\\[\\]\\/\\\\(){}|\\-])/g, '\\\\$1');\n }\n function extendLineToColumn(cm, lineNum, column) {\n var endCh = lineLength(cm, lineNum);\n var spaces = new Array(column-endCh+1).join(' ');\n cm.setCursor(Pos(lineNum, endCh));\n cm.replaceRange(spaces, cm.getCursor());\n }\n // This functions selects a rectangular block\n // of text with selectionEnd as any of its corner\n // Height of block:\n // Difference in selectionEnd.line and first/last selection.line\n // Width of the block:\n // Distance between selectionEnd.ch and any(first considered here) selection.ch\n function selectBlock(cm, selectionEnd) {\n var selections = [], ranges = cm.listSelections();\n var head = copyCursor(cm.clipPos(selectionEnd));\n var isClipped = !cursorEqual(selectionEnd, head);\n var curHead = cm.getCursor('head');\n var primIndex = getIndex(ranges, curHead);\n var wasClipped = cursorEqual(ranges[primIndex].head, ranges[primIndex].anchor);\n var max = ranges.length - 1;\n var index = max - primIndex > primIndex ? max : 0;\n var base = ranges[index].anchor;\n\n var firstLine = Math.min(base.line, head.line);\n var lastLine = Math.max(base.line, head.line);\n var baseCh = base.ch, headCh = head.ch;\n\n var dir = ranges[index].head.ch - baseCh;\n var newDir = headCh - baseCh;\n if (dir > 0 && newDir <= 0) {\n baseCh++;\n if (!isClipped) { headCh--; }\n } else if (dir < 0 && newDir >= 0) {\n baseCh--;\n if (!wasClipped) { headCh++; }\n } else if (dir < 0 && newDir == -1) {\n baseCh--;\n headCh++;\n }\n for (var line = firstLine; line <= lastLine; line++) {\n var range = {anchor: new Pos(line, baseCh), head: new Pos(line, headCh)};\n selections.push(range);\n }\n cm.setSelections(selections);\n selectionEnd.ch = headCh;\n base.ch = baseCh;\n return base;\n }\n function selectForInsert(cm, head, height) {\n var sel = [];\n for (var i = 0; i < height; i++) {\n var lineHead = offsetCursor(head, i, 0);\n sel.push({anchor: lineHead, head: lineHead});\n }\n cm.setSelections(sel, 0);\n }\n // getIndex returns the index of the cursor in the selections.\n function getIndex(ranges, cursor, end) {\n for (var i = 0; i < ranges.length; i++) {\n var atAnchor = end != 'head' && cursorEqual(ranges[i].anchor, cursor);\n var atHead = end != 'anchor' && cursorEqual(ranges[i].head, cursor);\n if (atAnchor || atHead) {\n return i;\n }\n }\n return -1;\n }\n function getSelectedAreaRange(cm, vim) {\n var lastSelection = vim.lastSelection;\n var getCurrentSelectedAreaRange = function() {\n var selections = cm.listSelections();\n var start = selections[0];\n var end = selections[selections.length-1];\n var selectionStart = cursorIsBefore(start.anchor, start.head) ? start.anchor : start.head;\n var selectionEnd = cursorIsBefore(end.anchor, end.head) ? end.head : end.anchor;\n return [selectionStart, selectionEnd];\n };\n var getLastSelectedAreaRange = function() {\n var selectionStart = cm.getCursor();\n var selectionEnd = cm.getCursor();\n var block = lastSelection.visualBlock;\n if (block) {\n var width = block.width;\n var height = block.height;\n selectionEnd = Pos(selectionStart.line + height, selectionStart.ch + width);\n var selections = [];\n // selectBlock creates a 'proper' rectangular block.\n // We do not want that in all cases, so we manually set selections.\n for (var i = selectionStart.line; i < selectionEnd.line; i++) {\n var anchor = Pos(i, selectionStart.ch);\n var head = Pos(i, selectionEnd.ch);\n var range = {anchor: anchor, head: head};\n selections.push(range);\n }\n cm.setSelections(selections);\n } else {\n var start = lastSelection.anchorMark.find();\n var end = lastSelection.headMark.find();\n var line = end.line - start.line;\n var ch = end.ch - start.ch;\n selectionEnd = {line: selectionEnd.line + line, ch: line ? selectionEnd.ch : ch + selectionEnd.ch};\n if (lastSelection.visualLine) {\n selectionStart = Pos(selectionStart.line, 0);\n selectionEnd = Pos(selectionEnd.line, lineLength(cm, selectionEnd.line));\n }\n cm.setSelection(selectionStart, selectionEnd);\n }\n return [selectionStart, selectionEnd];\n };\n if (!vim.visualMode) {\n // In case of replaying the action.\n return getLastSelectedAreaRange();\n } else {\n return getCurrentSelectedAreaRange();\n }\n }\n // Updates the previous selection with the current selection's values. This\n // should only be called in visual mode.\n function updateLastSelection(cm, vim) {\n var anchor = vim.sel.anchor;\n var head = vim.sel.head;\n // To accommodate the effect of lastPastedText in the last selection\n if (vim.lastPastedText) {\n head = cm.posFromIndex(cm.indexFromPos(anchor) + vim.lastPastedText.length);\n vim.lastPastedText = null;\n }\n vim.lastSelection = {'anchorMark': cm.setBookmark(anchor),\n 'headMark': cm.setBookmark(head),\n 'anchor': copyCursor(anchor),\n 'head': copyCursor(head),\n 'visualMode': vim.visualMode,\n 'visualLine': vim.visualLine,\n 'visualBlock': vim.visualBlock};\n }\n function expandSelection(cm, start, end) {\n var sel = cm.state.vim.sel;\n var head = sel.head;\n var anchor = sel.anchor;\n var tmp;\n if (cursorIsBefore(end, start)) {\n tmp = end;\n end = start;\n start = tmp;\n }\n if (cursorIsBefore(head, anchor)) {\n head = cursorMin(start, head);\n anchor = cursorMax(anchor, end);\n } else {\n anchor = cursorMin(start, anchor);\n head = cursorMax(head, end);\n head = offsetCursor(head, 0, -1);\n if (head.ch == -1 && head.line != cm.firstLine()) {\n head = Pos(head.line - 1, lineLength(cm, head.line - 1));\n }\n }\n return [anchor, head];\n }\n /**\n * Updates the CodeMirror selection to match the provided vim selection.\n * If no arguments are given, it uses the current vim selection state.\n */\n function updateCmSelection(cm, sel, mode) {\n var vim = cm.state.vim;\n sel = sel || vim.sel;\n var mode = mode ||\n vim.visualLine ? 'line' : vim.visualBlock ? 'block' : 'char';\n var cmSel = makeCmSelection(cm, sel, mode);\n cm.setSelections(cmSel.ranges, cmSel.primary);\n updateFakeCursor(cm);\n }\n function makeCmSelection(cm, sel, mode, exclusive) {\n var head = copyCursor(sel.head);\n var anchor = copyCursor(sel.anchor);\n if (mode == 'char') {\n var headOffset = !exclusive && !cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;\n var anchorOffset = cursorIsBefore(sel.head, sel.anchor) ? 1 : 0;\n head = offsetCursor(sel.head, 0, headOffset);\n anchor = offsetCursor(sel.anchor, 0, anchorOffset);\n return {\n ranges: [{anchor: anchor, head: head}],\n primary: 0\n };\n } else if (mode == 'line') {\n if (!cursorIsBefore(sel.head, sel.anchor)) {\n anchor.ch = 0;\n\n var lastLine = cm.lastLine();\n if (head.line > lastLine) {\n head.line = lastLine;\n }\n head.ch = lineLength(cm, head.line);\n } else {\n head.ch = 0;\n anchor.ch = lineLength(cm, anchor.line);\n }\n return {\n ranges: [{anchor: anchor, head: head}],\n primary: 0\n };\n } else if (mode == 'block') {\n var top = Math.min(anchor.line, head.line),\n left = Math.min(anchor.ch, head.ch),\n bottom = Math.max(anchor.line, head.line),\n right = Math.max(anchor.ch, head.ch) + 1;\n var height = bottom - top + 1;\n var primary = head.line == top ? 0 : height - 1;\n var ranges = [];\n for (var i = 0; i < height; i++) {\n ranges.push({\n anchor: Pos(top + i, left),\n head: Pos(top + i, right)\n });\n }\n return {\n ranges: ranges,\n primary: primary\n };\n }\n }\n function getHead(cm) {\n var cur = cm.getCursor('head');\n if (cm.getSelection().length == 1) {\n // Small corner case when only 1 character is selected. The \"real\"\n // head is the left of head and anchor.\n cur = cursorMin(cur, cm.getCursor('anchor'));\n }\n return cur;\n }\n\n /**\n * If moveHead is set to false, the CodeMirror selection will not be\n * touched. The caller assumes the responsibility of putting the cursor\n * in the right place.\n */\n function exitVisualMode(cm, moveHead) {\n var vim = cm.state.vim;\n if (moveHead !== false) {\n cm.setCursor(clipCursorToContent(cm, vim.sel.head));\n }\n updateLastSelection(cm, vim);\n vim.visualMode = false;\n vim.visualLine = false;\n vim.visualBlock = false;\n if (!vim.insertMode) CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n clearFakeCursor(vim);\n }\n\n // Remove any trailing newlines from the selection. For\n // example, with the caret at the start of the last word on the line,\n // 'dw' should word, but not the newline, while 'w' should advance the\n // caret to the first character of the next line.\n function clipToLine(cm, curStart, curEnd) {\n var selection = cm.getRange(curStart, curEnd);\n // Only clip if the selection ends with trailing newline + whitespace\n if (/\\n\\s*$/.test(selection)) {\n var lines = selection.split('\\n');\n // We know this is all whitespace.\n lines.pop();\n\n // Cases:\n // 1. Last word is an empty line - do not clip the trailing '\\n'\n // 2. Last word is not an empty line - clip the trailing '\\n'\n var line;\n // Find the line containing the last word, and clip all whitespace up\n // to it.\n for (var line = lines.pop(); lines.length > 0 && line && isWhiteSpaceString(line); line = lines.pop()) {\n curEnd.line--;\n curEnd.ch = 0;\n }\n // If the last word is not an empty line, clip an additional newline\n if (line) {\n curEnd.line--;\n curEnd.ch = lineLength(cm, curEnd.line);\n } else {\n curEnd.ch = 0;\n }\n }\n }\n\n // Expand the selection to line ends.\n function expandSelectionToLine(_cm, curStart, curEnd) {\n curStart.ch = 0;\n curEnd.ch = 0;\n curEnd.line++;\n }\n\n function findFirstNonWhiteSpaceCharacter(text) {\n if (!text) {\n return 0;\n }\n var firstNonWS = text.search(/\\S/);\n return firstNonWS == -1 ? text.length : firstNonWS;\n }\n\n function expandWordUnderCursor(cm, inclusive, _forward, bigWord, noSymbol) {\n var cur = getHead(cm);\n var line = cm.getLine(cur.line);\n var idx = cur.ch;\n\n // Seek to first word or non-whitespace character, depending on if\n // noSymbol is true.\n var test = noSymbol ? wordCharTest[0] : bigWordCharTest [0];\n while (!test(line.charAt(idx))) {\n idx++;\n if (idx >= line.length) { return null; }\n }\n\n if (bigWord) {\n test = bigWordCharTest[0];\n } else {\n test = wordCharTest[0];\n if (!test(line.charAt(idx))) {\n test = wordCharTest[1];\n }\n }\n\n var end = idx, start = idx;\n while (test(line.charAt(end)) && end < line.length) { end++; }\n while (test(line.charAt(start)) && start >= 0) { start--; }\n start++;\n\n if (inclusive) {\n // If present, include all whitespace after word.\n // Otherwise, include all whitespace before word, except indentation.\n var wordEnd = end;\n while (/\\s/.test(line.charAt(end)) && end < line.length) { end++; }\n if (wordEnd == end) {\n var wordStart = start;\n while (/\\s/.test(line.charAt(start - 1)) && start > 0) { start--; }\n if (!start) { start = wordStart; }\n }\n }\n return { start: Pos(cur.line, start), end: Pos(cur.line, end) };\n }\n\n /**\n * Depends on the following:\n *\n * - editor mode should be htmlmixedmode / xml\n * - mode/xml/xml.js should be loaded\n * - addon/fold/xml-fold.js should be loaded\n *\n * If any of the above requirements are not true, this function noops.\n *\n * This is _NOT_ a 100% accurate implementation of vim tag text objects.\n * The following caveats apply (based off cursory testing, I'm sure there\n * are other discrepancies):\n *\n * - Does not work inside comments:\n * ```\n * <!-- <div>broken</div> -->\n * ```\n * - Does not work when tags have different cases:\n * ```\n * <div>broken</DIV>\n * ```\n * - Does not work when cursor is inside a broken tag:\n * ```\n * <div><brok><en></div>\n * ```\n */\n function expandTagUnderCursor(cm, head, inclusive) {\n var cur = head;\n if (!CodeMirror.findMatchingTag || !CodeMirror.findEnclosingTag) {\n return { start: cur, end: cur };\n }\n\n var tags = CodeMirror.findMatchingTag(cm, head) || CodeMirror.findEnclosingTag(cm, head);\n if (!tags || !tags.open || !tags.close) {\n return { start: cur, end: cur };\n }\n\n if (inclusive) {\n return { start: tags.open.from, end: tags.close.to };\n }\n return { start: tags.open.to, end: tags.close.from };\n }\n\n function recordJumpPosition(cm, oldCur, newCur) {\n if (!cursorEqual(oldCur, newCur)) {\n vimGlobalState.jumpList.add(cm, oldCur, newCur);\n }\n }\n\n function recordLastCharacterSearch(increment, args) {\n vimGlobalState.lastCharacterSearch.increment = increment;\n vimGlobalState.lastCharacterSearch.forward = args.forward;\n vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter;\n }\n\n var symbolToMode = {\n '(': 'bracket', ')': 'bracket', '{': 'bracket', '}': 'bracket',\n '[': 'section', ']': 'section',\n '*': 'comment', '/': 'comment',\n 'm': 'method', 'M': 'method',\n '#': 'preprocess'\n };\n var findSymbolModes = {\n bracket: {\n isComplete: function(state) {\n if (state.nextCh === state.symb) {\n state.depth++;\n if (state.depth >= 1)return true;\n } else if (state.nextCh === state.reverseSymb) {\n state.depth--;\n }\n return false;\n }\n },\n section: {\n init: function(state) {\n state.curMoveThrough = true;\n state.symb = (state.forward ? ']' : '[') === state.symb ? '{' : '}';\n },\n isComplete: function(state) {\n return state.index === 0 && state.nextCh === state.symb;\n }\n },\n comment: {\n isComplete: function(state) {\n var found = state.lastCh === '*' && state.nextCh === '/';\n state.lastCh = state.nextCh;\n return found;\n }\n },\n // TODO: The original Vim implementation only operates on level 1 and 2.\n // The current implementation doesn't check for code block level and\n // therefore it operates on any levels.\n method: {\n init: function(state) {\n state.symb = (state.symb === 'm' ? '{' : '}');\n state.reverseSymb = state.symb === '{' ? '}' : '{';\n },\n isComplete: function(state) {\n if (state.nextCh === state.symb)return true;\n return false;\n }\n },\n preprocess: {\n init: function(state) {\n state.index = 0;\n },\n isComplete: function(state) {\n if (state.nextCh === '#') {\n var token = state.lineText.match(/#(\\w+)/)[1];\n if (token === 'endif') {\n if (state.forward && state.depth === 0) {\n return true;\n }\n state.depth++;\n } else if (token === 'if') {\n if (!state.forward && state.depth === 0) {\n return true;\n }\n state.depth--;\n }\n if (token === 'else' && state.depth === 0)return true;\n }\n return false;\n }\n }\n };\n function findSymbol(cm, repeat, forward, symb) {\n var cur = copyCursor(cm.getCursor());\n var increment = forward ? 1 : -1;\n var endLine = forward ? cm.lineCount() : -1;\n var curCh = cur.ch;\n var line = cur.line;\n var lineText = cm.getLine(line);\n var state = {\n lineText: lineText,\n nextCh: lineText.charAt(curCh),\n lastCh: null,\n index: curCh,\n symb: symb,\n reverseSymb: (forward ? { ')': '(', '}': '{' } : { '(': ')', '{': '}' })[symb],\n forward: forward,\n depth: 0,\n curMoveThrough: false\n };\n var mode = symbolToMode[symb];\n if (!mode)return cur;\n var init = findSymbolModes[mode].init;\n var isComplete = findSymbolModes[mode].isComplete;\n if (init) { init(state); }\n while (line !== endLine && repeat) {\n state.index += increment;\n state.nextCh = state.lineText.charAt(state.index);\n if (!state.nextCh) {\n line += increment;\n state.lineText = cm.getLine(line) || '';\n if (increment > 0) {\n state.index = 0;\n } else {\n var lineLen = state.lineText.length;\n state.index = (lineLen > 0) ? (lineLen-1) : 0;\n }\n state.nextCh = state.lineText.charAt(state.index);\n }\n if (isComplete(state)) {\n cur.line = line;\n cur.ch = state.index;\n repeat--;\n }\n }\n if (state.nextCh || state.curMoveThrough) {\n return Pos(line, state.index);\n }\n return cur;\n }\n\n /*\n * Returns the boundaries of the next word. If the cursor in the middle of\n * the word, then returns the boundaries of the current word, starting at\n * the cursor. If the cursor is at the start/end of a word, and we are going\n * forward/backward, respectively, find the boundaries of the next word.\n *\n * @param {CodeMirror} cm CodeMirror object.\n * @param {Cursor} cur The cursor position.\n * @param {boolean} forward True to search forward. False to search\n * backward.\n * @param {boolean} bigWord True if punctuation count as part of the word.\n * False if only [a-zA-Z0-9] characters count as part of the word.\n * @param {boolean} emptyLineIsWord True if empty lines should be treated\n * as words.\n * @return {Object{from:number, to:number, line: number}} The boundaries of\n * the word, or null if there are no more words.\n */\n function findWord(cm, cur, forward, bigWord, emptyLineIsWord) {\n var lineNum = cur.line;\n var pos = cur.ch;\n var line = cm.getLine(lineNum);\n var dir = forward ? 1 : -1;\n var charTests = bigWord ? bigWordCharTest: wordCharTest;\n\n if (emptyLineIsWord && line == '') {\n lineNum += dir;\n line = cm.getLine(lineNum);\n if (!isLine(cm, lineNum)) {\n return null;\n }\n pos = (forward) ? 0 : line.length;\n }\n\n while (true) {\n if (emptyLineIsWord && line == '') {\n return { from: 0, to: 0, line: lineNum };\n }\n var stop = (dir > 0) ? line.length : -1;\n var wordStart = stop, wordEnd = stop;\n // Find bounds of next word.\n while (pos != stop) {\n var foundWord = false;\n for (var i = 0; i < charTests.length && !foundWord; ++i) {\n if (charTests[i](line.charAt(pos))) {\n wordStart = pos;\n // Advance to end of word.\n while (pos != stop && charTests[i](line.charAt(pos))) {\n pos += dir;\n }\n wordEnd = pos;\n foundWord = wordStart != wordEnd;\n if (wordStart == cur.ch && lineNum == cur.line &&\n wordEnd == wordStart + dir) {\n // We started at the end of a word. Find the next one.\n continue;\n } else {\n return {\n from: Math.min(wordStart, wordEnd + 1),\n to: Math.max(wordStart, wordEnd),\n line: lineNum };\n }\n }\n }\n if (!foundWord) {\n pos += dir;\n }\n }\n // Advance to next/prev line.\n lineNum += dir;\n if (!isLine(cm, lineNum)) {\n return null;\n }\n line = cm.getLine(lineNum);\n pos = (dir > 0) ? 0 : line.length;\n }\n }\n\n /**\n * @param {CodeMirror} cm CodeMirror object.\n * @param {Pos} cur The position to start from.\n * @param {int} repeat Number of words to move past.\n * @param {boolean} forward True to search forward. False to search\n * backward.\n * @param {boolean} wordEnd True to move to end of word. False to move to\n * beginning of word.\n * @param {boolean} bigWord True if punctuation count as part of the word.\n * False if only alphabet characters count as part of the word.\n * @return {Cursor} The position the cursor should move to.\n */\n function moveToWord(cm, cur, repeat, forward, wordEnd, bigWord) {\n var curStart = copyCursor(cur);\n var words = [];\n if (forward && !wordEnd || !forward && wordEnd) {\n repeat++;\n }\n // For 'e', empty lines are not considered words, go figure.\n var emptyLineIsWord = !(forward && wordEnd);\n for (var i = 0; i < repeat; i++) {\n var word = findWord(cm, cur, forward, bigWord, emptyLineIsWord);\n if (!word) {\n var eodCh = lineLength(cm, cm.lastLine());\n words.push(forward\n ? {line: cm.lastLine(), from: eodCh, to: eodCh}\n : {line: 0, from: 0, to: 0});\n break;\n }\n words.push(word);\n cur = Pos(word.line, forward ? (word.to - 1) : word.from);\n }\n var shortCircuit = words.length != repeat;\n var firstWord = words[0];\n var lastWord = words.pop();\n if (forward && !wordEnd) {\n // w\n if (!shortCircuit && (firstWord.from != curStart.ch || firstWord.line != curStart.line)) {\n // We did not start in the middle of a word. Discard the extra word at the end.\n lastWord = words.pop();\n }\n return Pos(lastWord.line, lastWord.from);\n } else if (forward && wordEnd) {\n return Pos(lastWord.line, lastWord.to - 1);\n } else if (!forward && wordEnd) {\n // ge\n if (!shortCircuit && (firstWord.to != curStart.ch || firstWord.line != curStart.line)) {\n // We did not start in the middle of a word. Discard the extra word at the end.\n lastWord = words.pop();\n }\n return Pos(lastWord.line, lastWord.to);\n } else {\n // b\n return Pos(lastWord.line, lastWord.from);\n }\n }\n\n function moveToCharacter(cm, repeat, forward, character) {\n var cur = cm.getCursor();\n var start = cur.ch;\n var idx;\n for (var i = 0; i < repeat; i ++) {\n var line = cm.getLine(cur.line);\n idx = charIdxInLine(start, line, character, forward, true);\n if (idx == -1) {\n return null;\n }\n start = idx;\n }\n return Pos(cm.getCursor().line, idx);\n }\n\n function moveToColumn(cm, repeat) {\n // repeat is always >= 1, so repeat - 1 always corresponds\n // to the column we want to go to.\n var line = cm.getCursor().line;\n return clipCursorToContent(cm, Pos(line, repeat - 1));\n }\n\n function updateMark(cm, vim, markName, pos) {\n if (!inArray(markName, validMarks)) {\n return;\n }\n if (vim.marks[markName]) {\n vim.marks[markName].clear();\n }\n vim.marks[markName] = cm.setBookmark(pos);\n }\n\n function charIdxInLine(start, line, character, forward, includeChar) {\n // Search for char in line.\n // motion_options: {forward, includeChar}\n // If includeChar = true, include it too.\n // If forward = true, search forward, else search backwards.\n // If char is not found on this line, do nothing\n var idx;\n if (forward) {\n idx = line.indexOf(character, start + 1);\n if (idx != -1 && !includeChar) {\n idx -= 1;\n }\n } else {\n idx = line.lastIndexOf(character, start - 1);\n if (idx != -1 && !includeChar) {\n idx += 1;\n }\n }\n return idx;\n }\n\n function findParagraph(cm, head, repeat, dir, inclusive) {\n var line = head.line;\n var min = cm.firstLine();\n var max = cm.lastLine();\n var start, end, i = line;\n function isEmpty(i) { return !cm.getLine(i); }\n function isBoundary(i, dir, any) {\n if (any) { return isEmpty(i) != isEmpty(i + dir); }\n return !isEmpty(i) && isEmpty(i + dir);\n }\n if (dir) {\n while (min <= i && i <= max && repeat > 0) {\n if (isBoundary(i, dir)) { repeat--; }\n i += dir;\n }\n return new Pos(i, 0);\n }\n\n var vim = cm.state.vim;\n if (vim.visualLine && isBoundary(line, 1, true)) {\n var anchor = vim.sel.anchor;\n if (isBoundary(anchor.line, -1, true)) {\n if (!inclusive || anchor.line != line) {\n line += 1;\n }\n }\n }\n var startState = isEmpty(line);\n for (i = line; i <= max && repeat; i++) {\n if (isBoundary(i, 1, true)) {\n if (!inclusive || isEmpty(i) != startState) {\n repeat--;\n }\n }\n }\n end = new Pos(i, 0);\n // select boundary before paragraph for the last one\n if (i > max && !startState) { startState = true; }\n else { inclusive = false; }\n for (i = line; i > min; i--) {\n if (!inclusive || isEmpty(i) == startState || i == line) {\n if (isBoundary(i, -1, true)) { break; }\n }\n }\n start = new Pos(i, 0);\n return { start: start, end: end };\n }\n\n function findSentence(cm, cur, repeat, dir) {\n\n /*\n Takes an index object\n {\n line: the line string,\n ln: line number,\n pos: index in line,\n dir: direction of traversal (-1 or 1)\n }\n and modifies the line, ln, and pos members to represent the\n next valid position or sets them to null if there are\n no more valid positions.\n */\n function nextChar(cm, idx) {\n if (idx.pos + idx.dir < 0 || idx.pos + idx.dir >= idx.line.length) {\n idx.ln += idx.dir;\n if (!isLine(cm, idx.ln)) {\n idx.line = null;\n idx.ln = null;\n idx.pos = null;\n return;\n }\n idx.line = cm.getLine(idx.ln);\n idx.pos = (idx.dir > 0) ? 0 : idx.line.length - 1;\n }\n else {\n idx.pos += idx.dir;\n }\n }\n\n /*\n Performs one iteration of traversal in forward direction\n Returns an index object of the new location\n */\n function forward(cm, ln, pos, dir) {\n var line = cm.getLine(ln);\n var stop = (line === \"\");\n\n var curr = {\n line: line,\n ln: ln,\n pos: pos,\n dir: dir,\n }\n\n var last_valid = {\n ln: curr.ln,\n pos: curr.pos,\n }\n\n var skip_empty_lines = (curr.line === \"\");\n\n // Move one step to skip character we start on\n nextChar(cm, curr);\n\n while (curr.line !== null) {\n last_valid.ln = curr.ln;\n last_valid.pos = curr.pos;\n\n if (curr.line === \"\" && !skip_empty_lines) {\n return { ln: curr.ln, pos: curr.pos, };\n }\n else if (stop && curr.line !== \"\" && !isWhiteSpaceString(curr.line[curr.pos])) {\n return { ln: curr.ln, pos: curr.pos, };\n }\n else if (isEndOfSentenceSymbol(curr.line[curr.pos])\n && !stop\n && (curr.pos === curr.line.length - 1\n || isWhiteSpaceString(curr.line[curr.pos + 1]))) {\n stop = true;\n }\n\n nextChar(cm, curr);\n }\n\n /*\n Set the position to the last non whitespace character on the last\n valid line in the case that we reach the end of the document.\n */\n var line = cm.getLine(last_valid.ln);\n last_valid.pos = 0;\n for(var i = line.length - 1; i >= 0; --i) {\n if (!isWhiteSpaceString(line[i])) {\n last_valid.pos = i;\n break;\n }\n }\n\n return last_valid;\n\n }\n\n /*\n Performs one iteration of traversal in reverse direction\n Returns an index object of the new location\n */\n function reverse(cm, ln, pos, dir) {\n var line = cm.getLine(ln);\n\n var curr = {\n line: line,\n ln: ln,\n pos: pos,\n dir: dir,\n }\n\n var last_valid = {\n ln: curr.ln,\n pos: null,\n };\n\n var skip_empty_lines = (curr.line === \"\");\n\n // Move one step to skip character we start on\n nextChar(cm, curr);\n\n while (curr.line !== null) {\n\n if (curr.line === \"\" && !skip_empty_lines) {\n if (last_valid.pos !== null) {\n return last_valid;\n }\n else {\n return { ln: curr.ln, pos: curr.pos };\n }\n }\n else if (isEndOfSentenceSymbol(curr.line[curr.pos])\n && last_valid.pos !== null\n && !(curr.ln === last_valid.ln && curr.pos + 1 === last_valid.pos)) {\n return last_valid;\n }\n else if (curr.line !== \"\" && !isWhiteSpaceString(curr.line[curr.pos])) {\n skip_empty_lines = false;\n last_valid = { ln: curr.ln, pos: curr.pos }\n }\n\n nextChar(cm, curr);\n }\n\n /*\n Set the position to the first non whitespace character on the last\n valid line in the case that we reach the beginning of the document.\n */\n var line = cm.getLine(last_valid.ln);\n last_valid.pos = 0;\n for(var i = 0; i < line.length; ++i) {\n if (!isWhiteSpaceString(line[i])) {\n last_valid.pos = i;\n break;\n }\n }\n return last_valid;\n }\n\n var curr_index = {\n ln: cur.line,\n pos: cur.ch,\n };\n\n while (repeat > 0) {\n if (dir < 0) {\n curr_index = reverse(cm, curr_index.ln, curr_index.pos, dir);\n }\n else {\n curr_index = forward(cm, curr_index.ln, curr_index.pos, dir);\n }\n repeat--;\n }\n\n return Pos(curr_index.ln, curr_index.pos);\n }\n\n // TODO: perhaps this finagling of start and end positions belongs\n // in codemirror/replaceRange?\n function selectCompanionObject(cm, head, symb, inclusive) {\n var cur = head, start, end;\n\n var bracketRegexp = ({\n '(': /[()]/, ')': /[()]/,\n '[': /[[\\]]/, ']': /[[\\]]/,\n '{': /[{}]/, '}': /[{}]/,\n '<': /[<>]/, '>': /[<>]/})[symb];\n var openSym = ({\n '(': '(', ')': '(',\n '[': '[', ']': '[',\n '{': '{', '}': '{',\n '<': '<', '>': '<'})[symb];\n var curChar = cm.getLine(cur.line).charAt(cur.ch);\n // Due to the behavior of scanForBracket, we need to add an offset if the\n // cursor is on a matching open bracket.\n var offset = curChar === openSym ? 1 : 0;\n\n start = cm.scanForBracket(Pos(cur.line, cur.ch + offset), -1, undefined, {'bracketRegex': bracketRegexp});\n end = cm.scanForBracket(Pos(cur.line, cur.ch + offset), 1, undefined, {'bracketRegex': bracketRegexp});\n\n if (!start || !end) {\n return { start: cur, end: cur };\n }\n\n start = start.pos;\n end = end.pos;\n\n if ((start.line == end.line && start.ch > end.ch)\n || (start.line > end.line)) {\n var tmp = start;\n start = end;\n end = tmp;\n }\n\n if (inclusive) {\n end.ch += 1;\n } else {\n start.ch += 1;\n }\n\n return { start: start, end: end };\n }\n\n // Takes in a symbol and a cursor and tries to simulate text objects that\n // have identical opening and closing symbols\n // TODO support across multiple lines\n function findBeginningAndEnd(cm, head, symb, inclusive) {\n var cur = copyCursor(head);\n var line = cm.getLine(cur.line);\n var chars = line.split('');\n var start, end, i, len;\n var firstIndex = chars.indexOf(symb);\n\n // the decision tree is to always look backwards for the beginning first,\n // but if the cursor is in front of the first instance of the symb,\n // then move the cursor forward\n if (cur.ch < firstIndex) {\n cur.ch = firstIndex;\n // Why is this line even here???\n // cm.setCursor(cur.line, firstIndex+1);\n }\n // otherwise if the cursor is currently on the closing symbol\n else if (firstIndex < cur.ch && chars[cur.ch] == symb) {\n end = cur.ch; // assign end to the current cursor\n --cur.ch; // make sure to look backwards\n }\n\n // if we're currently on the symbol, we've got a start\n if (chars[cur.ch] == symb && !end) {\n start = cur.ch + 1; // assign start to ahead of the cursor\n } else {\n // go backwards to find the start\n for (i = cur.ch; i > -1 && !start; i--) {\n if (chars[i] == symb) {\n start = i + 1;\n }\n }\n }\n\n // look forwards for the end symbol\n if (start && !end) {\n for (i = start, len = chars.length; i < len && !end; i++) {\n if (chars[i] == symb) {\n end = i;\n }\n }\n }\n\n // nothing found\n if (!start || !end) {\n return { start: cur, end: cur };\n }\n\n // include the symbols\n if (inclusive) {\n --start; ++end;\n }\n\n return {\n start: Pos(cur.line, start),\n end: Pos(cur.line, end)\n };\n }\n\n // Search functions\n defineOption('pcre', true, 'boolean');\n function SearchState() {}\n SearchState.prototype = {\n getQuery: function() {\n return vimGlobalState.query;\n },\n setQuery: function(query) {\n vimGlobalState.query = query;\n },\n getOverlay: function() {\n return this.searchOverlay;\n },\n setOverlay: function(overlay) {\n this.searchOverlay = overlay;\n },\n isReversed: function() {\n return vimGlobalState.isReversed;\n },\n setReversed: function(reversed) {\n vimGlobalState.isReversed = reversed;\n },\n getScrollbarAnnotate: function() {\n return this.annotate;\n },\n setScrollbarAnnotate: function(annotate) {\n this.annotate = annotate;\n }\n };\n function getSearchState(cm) {\n var vim = cm.state.vim;\n return vim.searchState_ || (vim.searchState_ = new SearchState());\n }\n function dialog(cm, template, shortText, onClose, options) {\n if (cm.openDialog) {\n cm.openDialog(template, onClose, { bottom: true, value: options.value,\n onKeyDown: options.onKeyDown, onKeyUp: options.onKeyUp,\n selectValueOnOpen: false});\n }\n else {\n onClose(prompt(shortText, ''));\n }\n }\n function splitBySlash(argString) {\n return splitBySeparator(argString, '/');\n }\n\n function findUnescapedSlashes(argString) {\n return findUnescapedSeparators(argString, '/');\n }\n\n function splitBySeparator(argString, separator) {\n var slashes = findUnescapedSeparators(argString, separator) || [];\n if (!slashes.length) return [];\n var tokens = [];\n // in case of strings like foo/bar\n if (slashes[0] !== 0) return;\n for (var i = 0; i < slashes.length; i++) {\n if (typeof slashes[i] == 'number')\n tokens.push(argString.substring(slashes[i] + 1, slashes[i+1]));\n }\n return tokens;\n }\n\n function findUnescapedSeparators(str, separator) {\n if (!separator)\n separator = '/';\n\n var escapeNextChar = false;\n var slashes = [];\n for (var i = 0; i < str.length; i++) {\n var c = str.charAt(i);\n if (!escapeNextChar && c == separator) {\n slashes.push(i);\n }\n escapeNextChar = !escapeNextChar && (c == '\\\\');\n }\n return slashes;\n }\n\n // Translates a search string from ex (vim) syntax into javascript form.\n function translateRegex(str) {\n // When these match, add a '\\' if unescaped or remove one if escaped.\n var specials = '|(){';\n // Remove, but never add, a '\\' for these.\n var unescape = '}';\n var escapeNextChar = false;\n var out = [];\n for (var i = -1; i < str.length; i++) {\n var c = str.charAt(i) || '';\n var n = str.charAt(i+1) || '';\n var specialComesNext = (n && specials.indexOf(n) != -1);\n if (escapeNextChar) {\n if (c !== '\\\\' || !specialComesNext) {\n out.push(c);\n }\n escapeNextChar = false;\n } else {\n if (c === '\\\\') {\n escapeNextChar = true;\n // Treat the unescape list as special for removing, but not adding '\\'.\n if (n && unescape.indexOf(n) != -1) {\n specialComesNext = true;\n }\n // Not passing this test means removing a '\\'.\n if (!specialComesNext || n === '\\\\') {\n out.push(c);\n }\n } else {\n out.push(c);\n if (specialComesNext && n !== '\\\\') {\n out.push('\\\\');\n }\n }\n }\n }\n return out.join('');\n }\n\n // Translates the replace part of a search and replace from ex (vim) syntax into\n // javascript form. Similar to translateRegex, but additionally fixes back references\n // (translates '\\[0..9]' to '$[0..9]') and follows different rules for escaping '$'.\n var charUnescapes = {'\\\\n': '\\n', '\\\\r': '\\r', '\\\\t': '\\t'};\n function translateRegexReplace(str) {\n var escapeNextChar = false;\n var out = [];\n for (var i = -1; i < str.length; i++) {\n var c = str.charAt(i) || '';\n var n = str.charAt(i+1) || '';\n if (charUnescapes[c + n]) {\n out.push(charUnescapes[c+n]);\n i++;\n } else if (escapeNextChar) {\n // At any point in the loop, escapeNextChar is true if the previous\n // character was a '\\' and was not escaped.\n out.push(c);\n escapeNextChar = false;\n } else {\n if (c === '\\\\') {\n escapeNextChar = true;\n if ((isNumber(n) || n === '$')) {\n out.push('$');\n } else if (n !== '/' && n !== '\\\\') {\n out.push('\\\\');\n }\n } else {\n if (c === '$') {\n out.push('$');\n }\n out.push(c);\n if (n === '/') {\n out.push('\\\\');\n }\n }\n }\n }\n return out.join('');\n }\n\n // Unescape \\ and / in the replace part, for PCRE mode.\n var unescapes = {'\\\\/': '/', '\\\\\\\\': '\\\\', '\\\\n': '\\n', '\\\\r': '\\r', '\\\\t': '\\t', '\\\\&':'&'};\n function unescapeRegexReplace(str) {\n var stream = new CodeMirror.StringStream(str);\n var output = [];\n while (!stream.eol()) {\n // Search for \\.\n while (stream.peek() && stream.peek() != '\\\\') {\n output.push(stream.next());\n }\n var matched = false;\n for (var matcher in unescapes) {\n if (stream.match(matcher, true)) {\n matched = true;\n output.push(unescapes[matcher]);\n break;\n }\n }\n if (!matched) {\n // Don't change anything\n output.push(stream.next());\n }\n }\n return output.join('');\n }\n\n /**\n * Extract the regular expression from the query and return a Regexp object.\n * Returns null if the query is blank.\n * If ignoreCase is passed in, the Regexp object will have the 'i' flag set.\n * If smartCase is passed in, and the query contains upper case letters,\n * then ignoreCase is overridden, and the 'i' flag will not be set.\n * If the query contains the /i in the flag part of the regular expression,\n * then both ignoreCase and smartCase are ignored, and 'i' will be passed\n * through to the Regex object.\n */\n function parseQuery(query, ignoreCase, smartCase) {\n // First update the last search register\n var lastSearchRegister = vimGlobalState.registerController.getRegister('/');\n lastSearchRegister.setText(query);\n // Check if the query is already a regex.\n if (query instanceof RegExp) { return query; }\n // First try to extract regex + flags from the input. If no flags found,\n // extract just the regex. IE does not accept flags directly defined in\n // the regex string in the form /regex/flags\n var slashes = findUnescapedSlashes(query);\n var regexPart;\n var forceIgnoreCase;\n if (!slashes.length) {\n // Query looks like 'regexp'\n regexPart = query;\n } else {\n // Query looks like 'regexp/...'\n regexPart = query.substring(0, slashes[0]);\n var flagsPart = query.substring(slashes[0]);\n forceIgnoreCase = (flagsPart.indexOf('i') != -1);\n }\n if (!regexPart) {\n return null;\n }\n if (!getOption('pcre')) {\n regexPart = translateRegex(regexPart);\n }\n if (smartCase) {\n ignoreCase = (/^[^A-Z]*$/).test(regexPart);\n }\n var regexp = new RegExp(regexPart,\n (ignoreCase || forceIgnoreCase) ? 'i' : undefined);\n return regexp;\n }\n function showConfirm(cm, text) {\n if (cm.openNotification) {\n cm.openNotification('<span style=\"color: red\">' + text + '</span>',\n {bottom: true, duration: 5000});\n } else {\n alert(text);\n }\n }\n function makePrompt(prefix, desc) {\n var raw = '<span style=\"font-family: monospace; white-space: pre\">' +\n (prefix || \"\") + '<input type=\"text\" autocorrect=\"off\" ' +\n 'autocapitalize=\"off\" spellcheck=\"false\"></span>';\n if (desc)\n raw += ' <span style=\"color: #888\">' + desc + '</span>';\n return raw;\n }\n var searchPromptDesc = '(Javascript regexp)';\n function showPrompt(cm, options) {\n var shortText = (options.prefix || '') + ' ' + (options.desc || '');\n var prompt = makePrompt(options.prefix, options.desc);\n dialog(cm, prompt, shortText, options.onClose, options);\n }\n function regexEqual(r1, r2) {\n if (r1 instanceof RegExp && r2 instanceof RegExp) {\n var props = ['global', 'multiline', 'ignoreCase', 'source'];\n for (var i = 0; i < props.length; i++) {\n var prop = props[i];\n if (r1[prop] !== r2[prop]) {\n return false;\n }\n }\n return true;\n }\n return false;\n }\n // Returns true if the query is valid.\n function updateSearchQuery(cm, rawQuery, ignoreCase, smartCase) {\n if (!rawQuery) {\n return;\n }\n var state = getSearchState(cm);\n var query = parseQuery(rawQuery, !!ignoreCase, !!smartCase);\n if (!query) {\n return;\n }\n highlightSearchMatches(cm, query);\n if (regexEqual(query, state.getQuery())) {\n return query;\n }\n state.setQuery(query);\n return query;\n }\n function searchOverlay(query) {\n if (query.source.charAt(0) == '^') {\n var matchSol = true;\n }\n return {\n token: function(stream) {\n if (matchSol && !stream.sol()) {\n stream.skipToEnd();\n return;\n }\n var match = stream.match(query, false);\n if (match) {\n if (match[0].length == 0) {\n // Matched empty string, skip to next.\n stream.next();\n return 'searching';\n }\n if (!stream.sol()) {\n // Backtrack 1 to match \\b\n stream.backUp(1);\n if (!query.exec(stream.next() + match[0])) {\n stream.next();\n return null;\n }\n }\n stream.match(query);\n return 'searching';\n }\n while (!stream.eol()) {\n stream.next();\n if (stream.match(query, false)) break;\n }\n },\n query: query\n };\n }\n var highlightTimeout = 0;\n function highlightSearchMatches(cm, query) {\n clearTimeout(highlightTimeout);\n highlightTimeout = setTimeout(function() {\n var searchState = getSearchState(cm);\n var overlay = searchState.getOverlay();\n if (!overlay || query != overlay.query) {\n if (overlay) {\n cm.removeOverlay(overlay);\n }\n overlay = searchOverlay(query);\n cm.addOverlay(overlay);\n if (cm.showMatchesOnScrollbar) {\n if (searchState.getScrollbarAnnotate()) {\n searchState.getScrollbarAnnotate().clear();\n }\n searchState.setScrollbarAnnotate(cm.showMatchesOnScrollbar(query));\n }\n searchState.setOverlay(overlay);\n }\n }, 50);\n }\n function findNext(cm, prev, query, repeat) {\n if (repeat === undefined) { repeat = 1; }\n return cm.operation(function() {\n var pos = cm.getCursor();\n var cursor = cm.getSearchCursor(query, pos);\n for (var i = 0; i < repeat; i++) {\n var found = cursor.find(prev);\n if (i == 0 && found && cursorEqual(cursor.from(), pos)) { found = cursor.find(prev); }\n if (!found) {\n // SearchCursor may have returned null because it hit EOF, wrap\n // around and try again.\n cursor = cm.getSearchCursor(query,\n (prev) ? Pos(cm.lastLine()) : Pos(cm.firstLine(), 0) );\n if (!cursor.find(prev)) {\n return;\n }\n }\n }\n return cursor.from();\n });\n }\n function clearSearchHighlight(cm) {\n var state = getSearchState(cm);\n cm.removeOverlay(getSearchState(cm).getOverlay());\n state.setOverlay(null);\n if (state.getScrollbarAnnotate()) {\n state.getScrollbarAnnotate().clear();\n state.setScrollbarAnnotate(null);\n }\n }\n /**\n * Check if pos is in the specified range, INCLUSIVE.\n * Range can be specified with 1 or 2 arguments.\n * If the first range argument is an array, treat it as an array of line\n * numbers. Match pos against any of the lines.\n * If the first range argument is a number,\n * if there is only 1 range argument, check if pos has the same line\n * number\n * if there are 2 range arguments, then check if pos is in between the two\n * range arguments.\n */\n function isInRange(pos, start, end) {\n if (typeof pos != 'number') {\n // Assume it is a cursor position. Get the line number.\n pos = pos.line;\n }\n if (start instanceof Array) {\n return inArray(pos, start);\n } else {\n if (end) {\n return (pos >= start && pos <= end);\n } else {\n return pos == start;\n }\n }\n }\n function getUserVisibleLines(cm) {\n var scrollInfo = cm.getScrollInfo();\n var occludeToleranceTop = 6;\n var occludeToleranceBottom = 10;\n var from = cm.coordsChar({left:0, top: occludeToleranceTop + scrollInfo.top}, 'local');\n var bottomY = scrollInfo.clientHeight - occludeToleranceBottom + scrollInfo.top;\n var to = cm.coordsChar({left:0, top: bottomY}, 'local');\n return {top: from.line, bottom: to.line};\n }\n\n function getMarkPos(cm, vim, markName) {\n if (markName == '\\'' || markName == '`') {\n return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0);\n } else if (markName == '.') {\n return getLastEditPos(cm);\n }\n\n var mark = vim.marks[markName];\n return mark && mark.find();\n }\n\n function getLastEditPos(cm) {\n var done = cm.doc.history.done;\n for (var i = done.length; i--;) {\n if (done[i].changes) {\n return copyCursor(done[i].changes[0].to);\n }\n }\n }\n\n var ExCommandDispatcher = function() {\n this.buildCommandMap_();\n };\n ExCommandDispatcher.prototype = {\n processCommand: function(cm, input, opt_params) {\n var that = this;\n cm.operation(function () {\n cm.curOp.isVimOp = true;\n that._processCommand(cm, input, opt_params);\n });\n },\n _processCommand: function(cm, input, opt_params) {\n var vim = cm.state.vim;\n var commandHistoryRegister = vimGlobalState.registerController.getRegister(':');\n var previousCommand = commandHistoryRegister.toString();\n if (vim.visualMode) {\n exitVisualMode(cm);\n }\n var inputStream = new CodeMirror.StringStream(input);\n // update \": with the latest command whether valid or invalid\n commandHistoryRegister.setText(input);\n var params = opt_params || {};\n params.input = input;\n try {\n this.parseInput_(cm, inputStream, params);\n } catch(e) {\n showConfirm(cm, e);\n throw e;\n }\n var command;\n var commandName;\n if (!params.commandName) {\n // If only a line range is defined, move to the line.\n if (params.line !== undefined) {\n commandName = 'move';\n }\n } else {\n command = this.matchCommand_(params.commandName);\n if (command) {\n commandName = command.name;\n if (command.excludeFromCommandHistory) {\n commandHistoryRegister.setText(previousCommand);\n }\n this.parseCommandArgs_(inputStream, params, command);\n if (command.type == 'exToKey') {\n // Handle Ex to Key mapping.\n for (var i = 0; i < command.toKeys.length; i++) {\n CodeMirror.Vim.handleKey(cm, command.toKeys[i], 'mapping');\n }\n return;\n } else if (command.type == 'exToEx') {\n // Handle Ex to Ex mapping.\n this.processCommand(cm, command.toInput);\n return;\n }\n }\n }\n if (!commandName) {\n showConfirm(cm, 'Not an editor command \":' + input + '\"');\n return;\n }\n try {\n exCommands[commandName](cm, params);\n // Possibly asynchronous commands (e.g. substitute, which might have a\n // user confirmation), are responsible for calling the callback when\n // done. All others have it taken care of for them here.\n if ((!command || !command.possiblyAsync) && params.callback) {\n params.callback();\n }\n } catch(e) {\n showConfirm(cm, e);\n throw e;\n }\n },\n parseInput_: function(cm, inputStream, result) {\n inputStream.eatWhile(':');\n // Parse range.\n if (inputStream.eat('%')) {\n result.line = cm.firstLine();\n result.lineEnd = cm.lastLine();\n } else {\n result.line = this.parseLineSpec_(cm, inputStream);\n if (result.line !== undefined && inputStream.eat(',')) {\n result.lineEnd = this.parseLineSpec_(cm, inputStream);\n }\n }\n\n // Parse command name.\n var commandMatch = inputStream.match(/^(\\w+|!!|@@|[!#&*<=>@~])/);\n if (commandMatch) {\n result.commandName = commandMatch[1];\n } else {\n result.commandName = inputStream.match(/.*/)[0];\n }\n\n return result;\n },\n parseLineSpec_: function(cm, inputStream) {\n var numberMatch = inputStream.match(/^(\\d+)/);\n if (numberMatch) {\n // Absolute line number plus offset (N+M or N-M) is probably a typo,\n // not something the user actually wanted. (NB: vim does allow this.)\n return parseInt(numberMatch[1], 10) - 1;\n }\n switch (inputStream.next()) {\n case '.':\n return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);\n case '$':\n return this.parseLineSpecOffset_(inputStream, cm.lastLine());\n case '\\'':\n var markName = inputStream.next();\n var markPos = getMarkPos(cm, cm.state.vim, markName);\n if (!markPos) throw new Error('Mark not set');\n return this.parseLineSpecOffset_(inputStream, markPos.line);\n case '-':\n case '+':\n inputStream.backUp(1);\n // Offset is relative to current line if not otherwise specified.\n return this.parseLineSpecOffset_(inputStream, cm.getCursor().line);\n default:\n inputStream.backUp(1);\n return undefined;\n }\n },\n parseLineSpecOffset_: function(inputStream, line) {\n var offsetMatch = inputStream.match(/^([+-])?(\\d+)/);\n if (offsetMatch) {\n var offset = parseInt(offsetMatch[2], 10);\n if (offsetMatch[1] == \"-\") {\n line -= offset;\n } else {\n line += offset;\n }\n }\n return line;\n },\n parseCommandArgs_: function(inputStream, params, command) {\n if (inputStream.eol()) {\n return;\n }\n params.argString = inputStream.match(/.*/)[0];\n // Parse command-line arguments\n var delim = command.argDelimiter || /\\s+/;\n var args = trim(params.argString).split(delim);\n if (args.length && args[0]) {\n params.args = args;\n }\n },\n matchCommand_: function(commandName) {\n // Return the command in the command map that matches the shortest\n // prefix of the passed in command name. The match is guaranteed to be\n // unambiguous if the defaultExCommandMap's shortNames are set up\n // correctly. (see @code{defaultExCommandMap}).\n for (var i = commandName.length; i > 0; i--) {\n var prefix = commandName.substring(0, i);\n if (this.commandMap_[prefix]) {\n var command = this.commandMap_[prefix];\n if (command.name.indexOf(commandName) === 0) {\n return command;\n }\n }\n }\n return null;\n },\n buildCommandMap_: function() {\n this.commandMap_ = {};\n for (var i = 0; i < defaultExCommandMap.length; i++) {\n var command = defaultExCommandMap[i];\n var key = command.shortName || command.name;\n this.commandMap_[key] = command;\n }\n },\n map: function(lhs, rhs, ctx) {\n if (lhs != ':' && lhs.charAt(0) == ':') {\n if (ctx) { throw Error('Mode not supported for ex mappings'); }\n var commandName = lhs.substring(1);\n if (rhs != ':' && rhs.charAt(0) == ':') {\n // Ex to Ex mapping\n this.commandMap_[commandName] = {\n name: commandName,\n type: 'exToEx',\n toInput: rhs.substring(1),\n user: true\n };\n } else {\n // Ex to key mapping\n this.commandMap_[commandName] = {\n name: commandName,\n type: 'exToKey',\n toKeys: rhs,\n user: true\n };\n }\n } else {\n if (rhs != ':' && rhs.charAt(0) == ':') {\n // Key to Ex mapping.\n var mapping = {\n keys: lhs,\n type: 'keyToEx',\n exArgs: { input: rhs.substring(1) }\n };\n if (ctx) { mapping.context = ctx; }\n defaultKeymap.unshift(mapping);\n } else {\n // Key to key mapping\n var mapping = {\n keys: lhs,\n type: 'keyToKey',\n toKeys: rhs\n };\n if (ctx) { mapping.context = ctx; }\n defaultKeymap.unshift(mapping);\n }\n }\n },\n unmap: function(lhs, ctx) {\n if (lhs != ':' && lhs.charAt(0) == ':') {\n // Ex to Ex or Ex to key mapping\n if (ctx) { throw Error('Mode not supported for ex mappings'); }\n var commandName = lhs.substring(1);\n if (this.commandMap_[commandName] && this.commandMap_[commandName].user) {\n delete this.commandMap_[commandName];\n return;\n }\n } else {\n // Key to Ex or key to key mapping\n var keys = lhs;\n for (var i = 0; i < defaultKeymap.length; i++) {\n if (keys == defaultKeymap[i].keys\n && defaultKeymap[i].context === ctx) {\n defaultKeymap.splice(i, 1);\n return;\n }\n }\n }\n throw Error('No such mapping.');\n }\n };\n\n var exCommands = {\n colorscheme: function(cm, params) {\n if (!params.args || params.args.length < 1) {\n showConfirm(cm, cm.getOption('theme'));\n return;\n }\n cm.setOption('theme', params.args[0]);\n },\n map: function(cm, params, ctx) {\n var mapArgs = params.args;\n if (!mapArgs || mapArgs.length < 2) {\n if (cm) {\n showConfirm(cm, 'Invalid mapping: ' + params.input);\n }\n return;\n }\n exCommandDispatcher.map(mapArgs[0], mapArgs[1], ctx);\n },\n imap: function(cm, params) { this.map(cm, params, 'insert'); },\n nmap: function(cm, params) { this.map(cm, params, 'normal'); },\n vmap: function(cm, params) { this.map(cm, params, 'visual'); },\n unmap: function(cm, params, ctx) {\n var mapArgs = params.args;\n if (!mapArgs || mapArgs.length < 1) {\n if (cm) {\n showConfirm(cm, 'No such mapping: ' + params.input);\n }\n return;\n }\n exCommandDispatcher.unmap(mapArgs[0], ctx);\n },\n move: function(cm, params) {\n commandDispatcher.processCommand(cm, cm.state.vim, {\n type: 'motion',\n motion: 'moveToLineOrEdgeOfDocument',\n motionArgs: { forward: false, explicitRepeat: true,\n linewise: true },\n repeatOverride: params.line+1});\n },\n set: function(cm, params) {\n var setArgs = params.args;\n // Options passed through to the setOption/getOption calls. May be passed in by the\n // local/global versions of the set command\n var setCfg = params.setCfg || {};\n if (!setArgs || setArgs.length < 1) {\n if (cm) {\n showConfirm(cm, 'Invalid mapping: ' + params.input);\n }\n return;\n }\n var expr = setArgs[0].split('=');\n var optionName = expr[0];\n var value = expr[1];\n var forceGet = false;\n\n if (optionName.charAt(optionName.length - 1) == '?') {\n // If post-fixed with ?, then the set is actually a get.\n if (value) { throw Error('Trailing characters: ' + params.argString); }\n optionName = optionName.substring(0, optionName.length - 1);\n forceGet = true;\n }\n if (value === undefined && optionName.substring(0, 2) == 'no') {\n // To set boolean options to false, the option name is prefixed with\n // 'no'.\n optionName = optionName.substring(2);\n value = false;\n }\n\n var optionIsBoolean = options[optionName] && options[optionName].type == 'boolean';\n if (optionIsBoolean && value == undefined) {\n // Calling set with a boolean option sets it to true.\n value = true;\n }\n // If no value is provided, then we assume this is a get.\n if (!optionIsBoolean && value === undefined || forceGet) {\n var oldValue = getOption(optionName, cm, setCfg);\n if (oldValue instanceof Error) {\n showConfirm(cm, oldValue.message);\n } else if (oldValue === true || oldValue === false) {\n showConfirm(cm, ' ' + (oldValue ? '' : 'no') + optionName);\n } else {\n showConfirm(cm, ' ' + optionName + '=' + oldValue);\n }\n } else {\n var setOptionReturn = setOption(optionName, value, cm, setCfg);\n if (setOptionReturn instanceof Error) {\n showConfirm(cm, setOptionReturn.message);\n }\n }\n },\n setlocal: function (cm, params) {\n // setCfg is passed through to setOption\n params.setCfg = {scope: 'local'};\n this.set(cm, params);\n },\n setglobal: function (cm, params) {\n // setCfg is passed through to setOption\n params.setCfg = {scope: 'global'};\n this.set(cm, params);\n },\n registers: function(cm, params) {\n var regArgs = params.args;\n var registers = vimGlobalState.registerController.registers;\n var regInfo = '----------Registers----------<br><br>';\n if (!regArgs) {\n for (var registerName in registers) {\n var text = registers[registerName].toString();\n if (text.length) {\n regInfo += '\"' + registerName + ' ' + text + '<br>';\n }\n }\n } else {\n var registerName;\n regArgs = regArgs.join('');\n for (var i = 0; i < regArgs.length; i++) {\n registerName = regArgs.charAt(i);\n if (!vimGlobalState.registerController.isValidRegister(registerName)) {\n continue;\n }\n var register = registers[registerName] || new Register();\n regInfo += '\"' + registerName + ' ' + register.toString() + '<br>';\n }\n }\n showConfirm(cm, regInfo);\n },\n sort: function(cm, params) {\n var reverse, ignoreCase, unique, number, pattern;\n function parseArgs() {\n if (params.argString) {\n var args = new CodeMirror.StringStream(params.argString);\n if (args.eat('!')) { reverse = true; }\n if (args.eol()) { return; }\n if (!args.eatSpace()) { return 'Invalid arguments'; }\n var opts = args.match(/([dinuox]+)?\\s*(\\/.+\\/)?\\s*/);\n if (!opts && !args.eol()) { return 'Invalid arguments'; }\n if (opts[1]) {\n ignoreCase = opts[1].indexOf('i') != -1;\n unique = opts[1].indexOf('u') != -1;\n var decimal = opts[1].indexOf('d') != -1 || opts[1].indexOf('n') != -1 && 1;\n var hex = opts[1].indexOf('x') != -1 && 1;\n var octal = opts[1].indexOf('o') != -1 && 1;\n if (decimal + hex + octal > 1) { return 'Invalid arguments'; }\n number = decimal && 'decimal' || hex && 'hex' || octal && 'octal';\n }\n if (opts[2]) {\n pattern = new RegExp(opts[2].substr(1, opts[2].length - 2), ignoreCase ? 'i' : '');\n }\n }\n }\n var err = parseArgs();\n if (err) {\n showConfirm(cm, err + ': ' + params.argString);\n return;\n }\n var lineStart = params.line || cm.firstLine();\n var lineEnd = params.lineEnd || params.line || cm.lastLine();\n if (lineStart == lineEnd) { return; }\n var curStart = Pos(lineStart, 0);\n var curEnd = Pos(lineEnd, lineLength(cm, lineEnd));\n var text = cm.getRange(curStart, curEnd).split('\\n');\n var numberRegex = pattern ? pattern :\n (number == 'decimal') ? /(-?)([\\d]+)/ :\n (number == 'hex') ? /(-?)(?:0x)?([0-9a-f]+)/i :\n (number == 'octal') ? /([0-7]+)/ : null;\n var radix = (number == 'decimal') ? 10 : (number == 'hex') ? 16 : (number == 'octal') ? 8 : null;\n var numPart = [], textPart = [];\n if (number || pattern) {\n for (var i = 0; i < text.length; i++) {\n var matchPart = pattern ? text[i].match(pattern) : null;\n if (matchPart && matchPart[0] != '') {\n numPart.push(matchPart);\n } else if (!pattern && numberRegex.exec(text[i])) {\n numPart.push(text[i]);\n } else {\n textPart.push(text[i]);\n }\n }\n } else {\n textPart = text;\n }\n function compareFn(a, b) {\n if (reverse) { var tmp; tmp = a; a = b; b = tmp; }\n if (ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); }\n var anum = number && numberRegex.exec(a);\n var bnum = number && numberRegex.exec(b);\n if (!anum) { return a < b ? -1 : 1; }\n anum = parseInt((anum[1] + anum[2]).toLowerCase(), radix);\n bnum = parseInt((bnum[1] + bnum[2]).toLowerCase(), radix);\n return anum - bnum;\n }\n function comparePatternFn(a, b) {\n if (reverse) { var tmp; tmp = a; a = b; b = tmp; }\n if (ignoreCase) { a[0] = a[0].toLowerCase(); b[0] = b[0].toLowerCase(); }\n return (a[0] < b[0]) ? -1 : 1;\n }\n numPart.sort(pattern ? comparePatternFn : compareFn);\n if (pattern) {\n for (var i = 0; i < numPart.length; i++) {\n numPart[i] = numPart[i].input;\n }\n } else if (!number) { textPart.sort(compareFn); }\n text = (!reverse) ? textPart.concat(numPart) : numPart.concat(textPart);\n if (unique) { // Remove duplicate lines\n var textOld = text;\n var lastLine;\n text = [];\n for (var i = 0; i < textOld.length; i++) {\n if (textOld[i] != lastLine) {\n text.push(textOld[i]);\n }\n lastLine = textOld[i];\n }\n }\n cm.replaceRange(text.join('\\n'), curStart, curEnd);\n },\n global: function(cm, params) {\n // a global command is of the form\n // :[range]g/pattern/[cmd]\n // argString holds the string /pattern/[cmd]\n var argString = params.argString;\n if (!argString) {\n showConfirm(cm, 'Regular Expression missing from global');\n return;\n }\n // range is specified here\n var lineStart = (params.line !== undefined) ? params.line : cm.firstLine();\n var lineEnd = params.lineEnd || params.line || cm.lastLine();\n // get the tokens from argString\n var tokens = splitBySlash(argString);\n var regexPart = argString, cmd;\n if (tokens.length) {\n regexPart = tokens[0];\n cmd = tokens.slice(1, tokens.length).join('/');\n }\n if (regexPart) {\n // If regex part is empty, then use the previous query. Otherwise\n // use the regex part as the new query.\n try {\n updateSearchQuery(cm, regexPart, true /** ignoreCase */,\n true /** smartCase */);\n } catch (e) {\n showConfirm(cm, 'Invalid regex: ' + regexPart);\n return;\n }\n }\n // now that we have the regexPart, search for regex matches in the\n // specified range of lines\n var query = getSearchState(cm).getQuery();\n var matchedLines = [], content = '';\n for (var i = lineStart; i <= lineEnd; i++) {\n var matched = query.test(cm.getLine(i));\n if (matched) {\n matchedLines.push(i+1);\n content+= cm.getLine(i) + '<br>';\n }\n }\n // if there is no [cmd], just display the list of matched lines\n if (!cmd) {\n showConfirm(cm, content);\n return;\n }\n var index = 0;\n var nextCommand = function() {\n if (index < matchedLines.length) {\n var command = matchedLines[index] + cmd;\n exCommandDispatcher.processCommand(cm, command, {\n callback: nextCommand\n });\n }\n index++;\n };\n nextCommand();\n },\n substitute: function(cm, params) {\n if (!cm.getSearchCursor) {\n throw new Error('Search feature not available. Requires searchcursor.js or ' +\n 'any other getSearchCursor implementation.');\n }\n var argString = params.argString;\n var tokens = argString ? splitBySeparator(argString, argString[0]) : [];\n var regexPart, replacePart = '', trailing, flagsPart, count;\n var confirm = false; // Whether to confirm each replace.\n var global = false; // True to replace all instances on a line, false to replace only 1.\n if (tokens.length) {\n regexPart = tokens[0];\n if (getOption('pcre') && regexPart !== '') {\n regexPart = new RegExp(regexPart).source; //normalize not escaped characters\n }\n replacePart = tokens[1];\n if (regexPart && regexPart[regexPart.length - 1] === '$') {\n regexPart = regexPart.slice(0, regexPart.length - 1) + '\\\\n';\n replacePart = replacePart ? replacePart + '\\n' : '\\n';\n }\n if (replacePart !== undefined) {\n if (getOption('pcre')) {\n replacePart = unescapeRegexReplace(replacePart.replace(/([^\\\\])&/g,\"$1$$&\"));\n } else {\n replacePart = translateRegexReplace(replacePart);\n }\n vimGlobalState.lastSubstituteReplacePart = replacePart;\n }\n trailing = tokens[2] ? tokens[2].split(' ') : [];\n } else {\n // either the argString is empty or its of the form ' hello/world'\n // actually splitBySlash returns a list of tokens\n // only if the string starts with a '/'\n if (argString && argString.length) {\n showConfirm(cm, 'Substitutions should be of the form ' +\n ':s/pattern/replace/');\n return;\n }\n }\n // After the 3rd slash, we can have flags followed by a space followed\n // by count.\n if (trailing) {\n flagsPart = trailing[0];\n count = parseInt(trailing[1]);\n if (flagsPart) {\n if (flagsPart.indexOf('c') != -1) {\n confirm = true;\n flagsPart.replace('c', '');\n }\n if (flagsPart.indexOf('g') != -1) {\n global = true;\n flagsPart.replace('g', '');\n }\n if (getOption('pcre')) {\n regexPart = regexPart + '/' + flagsPart;\n } else {\n regexPart = regexPart.replace(/\\//g, \"\\\\/\") + '/' + flagsPart;\n }\n }\n }\n if (regexPart) {\n // If regex part is empty, then use the previous query. Otherwise use\n // the regex part as the new query.\n try {\n updateSearchQuery(cm, regexPart, true /** ignoreCase */,\n true /** smartCase */);\n } catch (e) {\n showConfirm(cm, 'Invalid regex: ' + regexPart);\n return;\n }\n }\n replacePart = replacePart || vimGlobalState.lastSubstituteReplacePart;\n if (replacePart === undefined) {\n showConfirm(cm, 'No previous substitute regular expression');\n return;\n }\n var state = getSearchState(cm);\n var query = state.getQuery();\n var lineStart = (params.line !== undefined) ? params.line : cm.getCursor().line;\n var lineEnd = params.lineEnd || lineStart;\n if (lineStart == cm.firstLine() && lineEnd == cm.lastLine()) {\n lineEnd = Infinity;\n }\n if (count) {\n lineStart = lineEnd;\n lineEnd = lineStart + count - 1;\n }\n var startPos = clipCursorToContent(cm, Pos(lineStart, 0));\n var cursor = cm.getSearchCursor(query, startPos);\n doReplace(cm, confirm, global, lineStart, lineEnd, cursor, query, replacePart, params.callback);\n },\n redo: CodeMirror.commands.redo,\n undo: CodeMirror.commands.undo,\n write: function(cm) {\n if (CodeMirror.commands.save) {\n // If a save command is defined, call it.\n CodeMirror.commands.save(cm);\n } else if (cm.save) {\n // Saves to text area if no save command is defined and cm.save() is available.\n cm.save();\n }\n },\n nohlsearch: function(cm) {\n clearSearchHighlight(cm);\n },\n yank: function (cm) {\n var cur = copyCursor(cm.getCursor());\n var line = cur.line;\n var lineText = cm.getLine(line);\n vimGlobalState.registerController.pushText(\n '0', 'yank', lineText, true, true);\n },\n delmarks: function(cm, params) {\n if (!params.argString || !trim(params.argString)) {\n showConfirm(cm, 'Argument required');\n return;\n }\n\n var state = cm.state.vim;\n var stream = new CodeMirror.StringStream(trim(params.argString));\n while (!stream.eol()) {\n stream.eatSpace();\n\n // Record the streams position at the beginning of the loop for use\n // in error messages.\n var count = stream.pos;\n\n if (!stream.match(/[a-zA-Z]/, false)) {\n showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n return;\n }\n\n var sym = stream.next();\n // Check if this symbol is part of a range\n if (stream.match('-', true)) {\n // This symbol is part of a range.\n\n // The range must terminate at an alphabetic character.\n if (!stream.match(/[a-zA-Z]/, false)) {\n showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n return;\n }\n\n var startMark = sym;\n var finishMark = stream.next();\n // The range must terminate at an alphabetic character which\n // shares the same case as the start of the range.\n if (isLowerCase(startMark) && isLowerCase(finishMark) ||\n isUpperCase(startMark) && isUpperCase(finishMark)) {\n var start = startMark.charCodeAt(0);\n var finish = finishMark.charCodeAt(0);\n if (start >= finish) {\n showConfirm(cm, 'Invalid argument: ' + params.argString.substring(count));\n return;\n }\n\n // Because marks are always ASCII values, and we have\n // determined that they are the same case, we can use\n // their char codes to iterate through the defined range.\n for (var j = 0; j <= finish - start; j++) {\n var mark = String.fromCharCode(start + j);\n delete state.marks[mark];\n }\n } else {\n showConfirm(cm, 'Invalid argument: ' + startMark + '-');\n return;\n }\n } else {\n // This symbol is a valid mark, and is not part of a range.\n delete state.marks[sym];\n }\n }\n }\n };\n\n var exCommandDispatcher = new ExCommandDispatcher();\n\n /**\n * @param {CodeMirror} cm CodeMirror instance we are in.\n * @param {boolean} confirm Whether to confirm each replace.\n * @param {Cursor} lineStart Line to start replacing from.\n * @param {Cursor} lineEnd Line to stop replacing at.\n * @param {RegExp} query Query for performing matches with.\n * @param {string} replaceWith Text to replace matches with. May contain $1,\n * $2, etc for replacing captured groups using Javascript replace.\n * @param {function()} callback A callback for when the replace is done.\n */\n function doReplace(cm, confirm, global, lineStart, lineEnd, searchCursor, query,\n replaceWith, callback) {\n // Set up all the functions.\n cm.state.vim.exMode = true;\n var done = false;\n var lastPos = searchCursor.from();\n function replaceAll() {\n cm.operation(function() {\n while (!done) {\n replace();\n next();\n }\n stop();\n });\n }\n function replace() {\n var text = cm.getRange(searchCursor.from(), searchCursor.to());\n var newText = text.replace(query, replaceWith);\n searchCursor.replace(newText);\n }\n function next() {\n // The below only loops to skip over multiple occurrences on the same\n // line when 'global' is not true.\n while(searchCursor.findNext() &&\n isInRange(searchCursor.from(), lineStart, lineEnd)) {\n if (!global && lastPos && searchCursor.from().line == lastPos.line) {\n continue;\n }\n cm.scrollIntoView(searchCursor.from(), 30);\n cm.setSelection(searchCursor.from(), searchCursor.to());\n lastPos = searchCursor.from();\n done = false;\n return;\n }\n done = true;\n }\n function stop(close) {\n if (close) { close(); }\n cm.focus();\n if (lastPos) {\n cm.setCursor(lastPos);\n var vim = cm.state.vim;\n vim.exMode = false;\n vim.lastHPos = vim.lastHSPos = lastPos.ch;\n }\n if (callback) { callback(); }\n }\n function onPromptKeyDown(e, _value, close) {\n // Swallow all keys.\n CodeMirror.e_stop(e);\n var keyName = CodeMirror.keyName(e);\n switch (keyName) {\n case 'Y':\n replace(); next(); break;\n case 'N':\n next(); break;\n case 'A':\n // replaceAll contains a call to close of its own. We don't want it\n // to fire too early or multiple times.\n var savedCallback = callback;\n callback = undefined;\n cm.operation(replaceAll);\n callback = savedCallback;\n break;\n case 'L':\n replace();\n // fall through and exit.\n case 'Q':\n case 'Esc':\n case 'Ctrl-C':\n case 'Ctrl-[':\n stop(close);\n break;\n }\n if (done) { stop(close); }\n return true;\n }\n\n // Actually do replace.\n next();\n if (done) {\n showConfirm(cm, 'No matches for ' + query.source);\n return;\n }\n if (!confirm) {\n replaceAll();\n if (callback) { callback(); }\n return;\n }\n showPrompt(cm, {\n prefix: 'replace with <strong>' + replaceWith + '</strong> (y/n/a/q/l)',\n onKeyDown: onPromptKeyDown\n });\n }\n\n CodeMirror.keyMap.vim = {\n attach: attachVimMap,\n detach: detachVimMap,\n call: cmKey\n };\n\n function exitInsertMode(cm) {\n var vim = cm.state.vim;\n var macroModeState = vimGlobalState.macroModeState;\n var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.');\n var isPlaying = macroModeState.isPlaying;\n var lastChange = macroModeState.lastInsertModeChanges;\n if (!isPlaying) {\n cm.off('change', onChange);\n CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown);\n }\n if (!isPlaying && vim.insertModeRepeat > 1) {\n // Perform insert mode repeat for commands like 3,a and 3,o.\n repeatLastEdit(cm, vim, vim.insertModeRepeat - 1,\n true /** repeatForInsert */);\n vim.lastEditInputState.repeatOverride = vim.insertModeRepeat;\n }\n delete vim.insertModeRepeat;\n vim.insertMode = false;\n cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1);\n cm.setOption('keyMap', 'vim');\n cm.setOption('disableInput', true);\n cm.toggleOverwrite(false); // exit replace mode if we were in it.\n // update the \". register before exiting insert mode\n insertModeChangeRegister.setText(lastChange.changes.join(''));\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"normal\"});\n if (macroModeState.isRecording) {\n logInsertModeChange(macroModeState);\n }\n }\n\n function _mapCommand(command) {\n defaultKeymap.unshift(command);\n }\n\n function mapCommand(keys, type, name, args, extra) {\n var command = {keys: keys, type: type};\n command[type] = name;\n command[type + \"Args\"] = args;\n for (var key in extra)\n command[key] = extra[key];\n _mapCommand(command);\n }\n\n // The timeout in milliseconds for the two-character ESC keymap should be\n // adjusted according to your typing speed to prevent false positives.\n defineOption('insertModeEscKeysTimeout', 200, 'number');\n\n CodeMirror.keyMap['vim-insert'] = {\n // TODO: override navigation keys so that Esc will cancel automatic\n // indentation from o, O, i_<CR>\n fallthrough: ['default'],\n attach: attachVimMap,\n detach: detachVimMap,\n call: cmKey\n };\n\n CodeMirror.keyMap['vim-replace'] = {\n 'Backspace': 'goCharLeft',\n fallthrough: ['vim-insert'],\n attach: attachVimMap,\n detach: detachVimMap,\n call: cmKey\n };\n\n function executeMacroRegister(cm, vim, macroModeState, registerName) {\n var register = vimGlobalState.registerController.getRegister(registerName);\n if (registerName == ':') {\n // Read-only register containing last Ex command.\n if (register.keyBuffer[0]) {\n exCommandDispatcher.processCommand(cm, register.keyBuffer[0]);\n }\n macroModeState.isPlaying = false;\n return;\n }\n var keyBuffer = register.keyBuffer;\n var imc = 0;\n macroModeState.isPlaying = true;\n macroModeState.replaySearchQueries = register.searchQueries.slice(0);\n for (var i = 0; i < keyBuffer.length; i++) {\n var text = keyBuffer[i];\n var match, key;\n while (text) {\n // Pull off one command key, which is either a single character\n // or a special sequence wrapped in '<' and '>', e.g. '<Space>'.\n match = (/<\\w+-.+?>|<\\w+>|./).exec(text);\n key = match[0];\n text = text.substring(match.index + key.length);\n CodeMirror.Vim.handleKey(cm, key, 'macro');\n if (vim.insertMode) {\n var changes = register.insertModeChanges[imc++].changes;\n vimGlobalState.macroModeState.lastInsertModeChanges.changes =\n changes;\n repeatInsertModeChanges(cm, changes, 1);\n exitInsertMode(cm);\n }\n }\n }\n macroModeState.isPlaying = false;\n }\n\n function logKey(macroModeState, key) {\n if (macroModeState.isPlaying) { return; }\n var registerName = macroModeState.latestRegister;\n var register = vimGlobalState.registerController.getRegister(registerName);\n if (register) {\n register.pushText(key);\n }\n }\n\n function logInsertModeChange(macroModeState) {\n if (macroModeState.isPlaying) { return; }\n var registerName = macroModeState.latestRegister;\n var register = vimGlobalState.registerController.getRegister(registerName);\n if (register && register.pushInsertModeChanges) {\n register.pushInsertModeChanges(macroModeState.lastInsertModeChanges);\n }\n }\n\n function logSearchQuery(macroModeState, query) {\n if (macroModeState.isPlaying) { return; }\n var registerName = macroModeState.latestRegister;\n var register = vimGlobalState.registerController.getRegister(registerName);\n if (register && register.pushSearchQuery) {\n register.pushSearchQuery(query);\n }\n }\n\n /**\n * Listens for changes made in insert mode.\n * Should only be active in insert mode.\n */\n function onChange(cm, changeObj) {\n var macroModeState = vimGlobalState.macroModeState;\n var lastChange = macroModeState.lastInsertModeChanges;\n if (!macroModeState.isPlaying) {\n while(changeObj) {\n lastChange.expectCursorActivityForChange = true;\n if (lastChange.ignoreCount > 1) {\n lastChange.ignoreCount--;\n } else if (changeObj.origin == '+input' || changeObj.origin == 'paste'\n || changeObj.origin === undefined /* only in testing */) {\n var selectionCount = cm.listSelections().length;\n if (selectionCount > 1)\n lastChange.ignoreCount = selectionCount;\n var text = changeObj.text.join('\\n');\n if (lastChange.maybeReset) {\n lastChange.changes = [];\n lastChange.maybeReset = false;\n }\n if (text) {\n if (cm.state.overwrite && !/\\n/.test(text)) {\n lastChange.changes.push([text]);\n } else {\n lastChange.changes.push(text);\n }\n }\n }\n // Change objects may be chained with next.\n changeObj = changeObj.next;\n }\n }\n }\n\n /**\n * Listens for any kind of cursor activity on CodeMirror.\n */\n function onCursorActivity(cm) {\n var vim = cm.state.vim;\n if (vim.insertMode) {\n // Tracking cursor activity in insert mode (for macro support).\n var macroModeState = vimGlobalState.macroModeState;\n if (macroModeState.isPlaying) { return; }\n var lastChange = macroModeState.lastInsertModeChanges;\n if (lastChange.expectCursorActivityForChange) {\n lastChange.expectCursorActivityForChange = false;\n } else {\n // Cursor moved outside the context of an edit. Reset the change.\n lastChange.maybeReset = true;\n }\n } else if (!cm.curOp.isVimOp) {\n handleExternalSelection(cm, vim);\n }\n if (vim.visualMode) {\n updateFakeCursor(cm);\n }\n }\n /**\n * Keeps track of a fake cursor to support visual mode cursor behavior.\n */\n function updateFakeCursor(cm) {\n var className = 'cm-animate-fat-cursor';\n var vim = cm.state.vim;\n var from = clipCursorToContent(cm, copyCursor(vim.sel.head));\n var to = offsetCursor(from, 0, 1);\n clearFakeCursor(vim);\n // In visual mode, the cursor may be positioned over EOL.\n if (from.ch == cm.getLine(from.line).length) {\n var widget = document.createElement(\"span\");\n widget.textContent = \"\\u00a0\";\n widget.className = className;\n vim.fakeCursorBookmark = cm.setBookmark(from, {widget: widget});\n } else {\n vim.fakeCursor = cm.markText(from, to, {className: className});\n }\n }\n function clearFakeCursor(vim) {\n if (vim.fakeCursor) {\n vim.fakeCursor.clear();\n vim.fakeCursor = null;\n }\n if (vim.fakeCursorBookmark) {\n vim.fakeCursorBookmark.clear();\n vim.fakeCursorBookmark = null;\n }\n }\n function handleExternalSelection(cm, vim) {\n var anchor = cm.getCursor('anchor');\n var head = cm.getCursor('head');\n // Enter or exit visual mode to match mouse selection.\n if (vim.visualMode && !cm.somethingSelected()) {\n exitVisualMode(cm, false);\n } else if (!vim.visualMode && !vim.insertMode && cm.somethingSelected()) {\n vim.visualMode = true;\n vim.visualLine = false;\n CodeMirror.signal(cm, \"vim-mode-change\", {mode: \"visual\"});\n }\n if (vim.visualMode) {\n // Bind CodeMirror selection model to vim selection model.\n // Mouse selections are considered visual characterwise.\n var headOffset = !cursorIsBefore(head, anchor) ? -1 : 0;\n var anchorOffset = cursorIsBefore(head, anchor) ? -1 : 0;\n head = offsetCursor(head, 0, headOffset);\n anchor = offsetCursor(anchor, 0, anchorOffset);\n vim.sel = {\n anchor: anchor,\n head: head\n };\n updateMark(cm, vim, '<', cursorMin(head, anchor));\n updateMark(cm, vim, '>', cursorMax(head, anchor));\n } else if (!vim.insertMode) {\n // Reset lastHPos if selection was modified by something outside of vim mode e.g. by mouse.\n vim.lastHPos = cm.getCursor().ch;\n }\n }\n\n /** Wrapper for special keys pressed in insert mode */\n function InsertModeKey(keyName) {\n this.keyName = keyName;\n }\n\n /**\n * Handles raw key down events from the text area.\n * - Should only be active in insert mode.\n * - For recording deletes in insert mode.\n */\n function onKeyEventTargetKeyDown(e) {\n var macroModeState = vimGlobalState.macroModeState;\n var lastChange = macroModeState.lastInsertModeChanges;\n var keyName = CodeMirror.keyName(e);\n if (!keyName) { return; }\n function onKeyFound() {\n if (lastChange.maybeReset) {\n lastChange.changes = [];\n lastChange.maybeReset = false;\n }\n lastChange.changes.push(new InsertModeKey(keyName));\n return true;\n }\n if (keyName.indexOf('Delete') != -1 || keyName.indexOf('Backspace') != -1) {\n CodeMirror.lookupKey(keyName, 'vim-insert', onKeyFound);\n }\n }\n\n /**\n * Repeats the last edit, which includes exactly 1 command and at most 1\n * insert. Operator and motion commands are read from lastEditInputState,\n * while action commands are read from lastEditActionCommand.\n *\n * If repeatForInsert is true, then the function was called by\n * exitInsertMode to repeat the insert mode changes the user just made. The\n * corresponding enterInsertMode call was made with a count.\n */\n function repeatLastEdit(cm, vim, repeat, repeatForInsert) {\n var macroModeState = vimGlobalState.macroModeState;\n macroModeState.isPlaying = true;\n var isAction = !!vim.lastEditActionCommand;\n var cachedInputState = vim.inputState;\n function repeatCommand() {\n if (isAction) {\n commandDispatcher.processAction(cm, vim, vim.lastEditActionCommand);\n } else {\n commandDispatcher.evalInput(cm, vim);\n }\n }\n function repeatInsert(repeat) {\n if (macroModeState.lastInsertModeChanges.changes.length > 0) {\n // For some reason, repeat cw in desktop VIM does not repeat\n // insert mode changes. Will conform to that behavior.\n repeat = !vim.lastEditActionCommand ? 1 : repeat;\n var changeObject = macroModeState.lastInsertModeChanges;\n repeatInsertModeChanges(cm, changeObject.changes, repeat);\n }\n }\n vim.inputState = vim.lastEditInputState;\n if (isAction && vim.lastEditActionCommand.interlaceInsertRepeat) {\n // o and O repeat have to be interlaced with insert repeats so that the\n // insertions appear on separate lines instead of the last line.\n for (var i = 0; i < repeat; i++) {\n repeatCommand();\n repeatInsert(1);\n }\n } else {\n if (!repeatForInsert) {\n // Hack to get the cursor to end up at the right place. If I is\n // repeated in insert mode repeat, cursor will be 1 insert\n // change set left of where it should be.\n repeatCommand();\n }\n repeatInsert(repeat);\n }\n vim.inputState = cachedInputState;\n if (vim.insertMode && !repeatForInsert) {\n // Don't exit insert mode twice. If repeatForInsert is set, then we\n // were called by an exitInsertMode call lower on the stack.\n exitInsertMode(cm);\n }\n macroModeState.isPlaying = false;\n }\n\n function repeatInsertModeChanges(cm, changes, repeat) {\n function keyHandler(binding) {\n if (typeof binding == 'string') {\n CodeMirror.commands[binding](cm);\n } else {\n binding(cm);\n }\n return true;\n }\n var head = cm.getCursor('head');\n var visualBlock = vimGlobalState.macroModeState.lastInsertModeChanges.visualBlock;\n if (visualBlock) {\n // Set up block selection again for repeating the changes.\n selectForInsert(cm, head, visualBlock + 1);\n repeat = cm.listSelections().length;\n cm.setCursor(head);\n }\n for (var i = 0; i < repeat; i++) {\n if (visualBlock) {\n cm.setCursor(offsetCursor(head, i, 0));\n }\n for (var j = 0; j < changes.length; j++) {\n var change = changes[j];\n if (change instanceof InsertModeKey) {\n CodeMirror.lookupKey(change.keyName, 'vim-insert', keyHandler);\n } else if (typeof change == \"string\") {\n var cur = cm.getCursor();\n cm.replaceRange(change, cur, cur);\n } else {\n var start = cm.getCursor();\n var end = offsetCursor(start, 0, change[0].length);\n cm.replaceRange(change[0], start, end);\n }\n }\n }\n if (visualBlock) {\n cm.setCursor(offsetCursor(head, 0, 1));\n }\n }\n\n resetVimGlobalState();\n return vimApi;\n };\n // Initialize Vim and make it available as an API.\n CodeMirror.Vim = Vim();\n});\n"]}