/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to codeigniter/js/ace/keybinding-vim.js

  • Committer: galaxyAbstractor
  • Date: 2013-04-10 15:49:32 UTC
  • mto: (19.1.5 lenasys)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: galaxyabstractor@gmail.com-20130410154932-4vizlzk0ar5gykvi
* Added an simple admin panel to the codeviewer-cmssy stuff
* Redesigned a bit like the mockups - still stuff to come
* Implemented the codeviewer + admin panel again using the Framework CodeIgniter instead 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Distributed under the BSD license:
 
3
 *
 
4
 * Copyright (c) 2010, Ajax.org B.V.
 
5
 * All rights reserved.
 
6
 * 
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions are met:
 
9
 *     * Redistributions of source code must retain the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer.
 
11
 *     * Redistributions in binary form must reproduce the above copyright
 
12
 *       notice, this list of conditions and the following disclaimer in the
 
13
 *       documentation and/or other materials provided with the distribution.
 
14
 *     * Neither the name of Ajax.org B.V. nor the
 
15
 *       names of its contributors may be used to endorse or promote products
 
16
 *       derived from this software without specific prior written permission.
 
17
 * 
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 *
 
29
 * ***** END LICENSE BLOCK ***** */
 
30
 
 
31
define('ace/keyboard/vim', ['require', 'exports', 'module' , 'ace/keyboard/vim/commands', 'ace/keyboard/vim/maps/util', 'ace/lib/useragent'], function(require, exports, module) {
 
32
 
 
33
 
 
34
var cmds = require("./vim/commands");
 
35
var coreCommands = cmds.coreCommands;
 
36
var util = require("./vim/maps/util");
 
37
var useragent = require("../lib/useragent");
 
38
 
 
39
var startCommands = {
 
40
    "i": {
 
41
        command: coreCommands.start
 
42
    },
 
43
    "I": {
 
44
        command: coreCommands.startBeginning
 
45
    },
 
46
    "a": {
 
47
        command: coreCommands.append
 
48
    },
 
49
    "A": {
 
50
        command: coreCommands.appendEnd
 
51
    },
 
52
    "ctrl-f": {
 
53
        command: "gotopagedown"
 
54
    },
 
55
    "ctrl-b": {
 
56
        command: "gotopageup"
 
57
    }
 
58
};
 
59
 
 
60
exports.handler = {
 
61
    handleMacRepeat: function(data, hashId, key) {
 
62
        if (hashId == -1) {
 
63
            data.inputChar = key;
 
64
            data.lastEvent = "input";
 
65
        } else if (data.inputChar && data.$lastHash == hashId && data.$lastKey == key) {
 
66
            if (data.lastEvent == "input") {
 
67
                data.lastEvent = "input1";
 
68
            } else if (data.lastEvent == "input1") {
 
69
                return true;
 
70
            }
 
71
        } else {
 
72
            data.$lastHash = hashId;
 
73
            data.$lastKey = key;
 
74
            data.lastEvent = "keypress";
 
75
        }
 
76
    },
 
77
 
 
78
    handleKeyboard: function(data, hashId, key, keyCode, e) {
 
79
        if (hashId != 0 && (key == "" || key == "\x00"))
 
80
            return null;
 
81
 
 
82
        if (hashId == 1)
 
83
            key = "ctrl-" + key;
 
84
        
 
85
        if ((key == "esc" && hashId == 0) || key == "ctrl-[") {
 
86
            return {command: coreCommands.stop};
 
87
        } else if (data.state == "start") {
 
88
            if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) {
 
89
                hashId = -1;
 
90
                key = data.inputChar;
 
91
            }
 
92
            
 
93
            if (hashId == -1 || hashId == 1 || hashId == 0 && key.length > 1) {
 
94
                if (cmds.inputBuffer.idle && startCommands[key])
 
95
                    return startCommands[key];
 
96
                return {
 
97
                    command: {
 
98
                        exec: function(editor) { 
 
99
                            return cmds.inputBuffer.push(editor, key);
 
100
                        }
 
101
                    }
 
102
                };
 
103
            } // if no modifier || shift: wait for input.
 
104
            else if (key.length == 1 && (hashId == 0 || hashId == 4)) {
 
105
                return {command: "null", passEvent: true};
 
106
            } else if (key == "esc" && hashId == 0) {
 
107
                return {command: coreCommands.stop};
 
108
            }
 
109
        } else {
 
110
            if (key == "ctrl-w") {
 
111
                return {command: "removewordleft"};
 
112
            }
 
113
        }
 
114
    },
 
115
 
 
116
    attach: function(editor) {
 
117
        editor.on("click", exports.onCursorMove);
 
118
        if (util.currentMode !== "insert")
 
119
            cmds.coreCommands.stop.exec(editor);
 
120
        editor.$vimModeHandler = this;
 
121
    },
 
122
 
 
123
    detach: function(editor) {
 
124
        editor.removeListener("click", exports.onCursorMove);
 
125
        util.noMode(editor);
 
126
        util.currentMode = "normal";
 
127
    },
 
128
 
 
129
    actions: cmds.actions,
 
130
    getStatusText: function() {
 
131
        if (util.currentMode == "insert")
 
132
            return "INSERT";
 
133
        if (util.onVisualMode)
 
134
            return (util.onVisualLineMode ? "VISUAL LINE " : "VISUAL ") + cmds.inputBuffer.status;
 
135
        return cmds.inputBuffer.status;
 
136
    }
 
137
};
 
138
 
 
139
 
 
140
exports.onCursorMove = function(e) {
 
141
    cmds.onCursorMove(e.editor, e);
 
142
    exports.onCursorMove.scheduled = false;
 
143
};
 
144
 
 
145
});
 
146
 
 
147
define('ace/keyboard/vim/commands', ['require', 'exports', 'module' , 'ace/keyboard/vim/maps/util', 'ace/keyboard/vim/maps/motions', 'ace/keyboard/vim/maps/operators', 'ace/keyboard/vim/maps/aliases', 'ace/keyboard/vim/registers'], function(require, exports, module) {
 
148
 
 
149
"never use strict";
 
150
 
 
151
var util = require("./maps/util");
 
152
var motions = require("./maps/motions");
 
153
var operators = require("./maps/operators");
 
154
var alias = require("./maps/aliases");
 
155
var registers = require("./registers");
 
156
 
 
157
var NUMBER = 1;
 
158
var OPERATOR = 2;
 
159
var MOTION = 3;
 
160
var ACTION = 4;
 
161
var HMARGIN = 8; // Minimum amount of line separation between margins;
 
162
 
 
163
var repeat = function repeat(fn, count, args) {
 
164
    while (0 < count--)
 
165
        fn.apply(this, args);
 
166
};
 
167
 
 
168
var ensureScrollMargin = function(editor) {
 
169
    var renderer = editor.renderer;
 
170
    var pos = renderer.$cursorLayer.getPixelPosition();
 
171
 
 
172
    var top = pos.top;
 
173
 
 
174
    var margin = HMARGIN * renderer.layerConfig.lineHeight;
 
175
    if (2 * margin > renderer.$size.scrollerHeight)
 
176
        margin = renderer.$size.scrollerHeight / 2;
 
177
 
 
178
    if (renderer.scrollTop > top - margin) {
 
179
        renderer.session.setScrollTop(top - margin);
 
180
    }
 
181
 
 
182
    if (renderer.scrollTop + renderer.$size.scrollerHeight < top + margin + renderer.lineHeight) {
 
183
        renderer.session.setScrollTop(top + margin + renderer.lineHeight - renderer.$size.scrollerHeight);
 
184
    }
 
185
};
 
186
 
 
187
var actions = exports.actions = {
 
188
    "z": {
 
189
        param: true,
 
190
        fn: function(editor, range, count, param) {
 
191
            switch (param) {
 
192
                case "z":
 
193
                    editor.renderer.alignCursor(null, 0.5);
 
194
                    break;
 
195
                case "t":
 
196
                    editor.renderer.alignCursor(null, 0);
 
197
                    break;
 
198
                case "b":
 
199
                    editor.renderer.alignCursor(null, 1);
 
200
                    break;
 
201
            }
 
202
        }
 
203
    },
 
204
    "r": {
 
205
        param: true,
 
206
        fn: function(editor, range, count, param) {
 
207
            if (param && param.length) {
 
208
                repeat(function() { editor.insert(param); }, count || 1);
 
209
                editor.navigateLeft();
 
210
            }
 
211
        }
 
212
    },
 
213
    "R": {
 
214
        fn: function(editor, range, count, param) {
 
215
            util.insertMode(editor);
 
216
            editor.setOverwrite(true);
 
217
        }
 
218
    },
 
219
    "~": {
 
220
        fn: function(editor, range, count) {
 
221
            repeat(function() {
 
222
                var range = editor.selection.getRange();
 
223
                if (range.isEmpty())
 
224
                    range.end.column++;
 
225
                var text = editor.session.getTextRange(range);
 
226
                var toggled = text.toUpperCase();
 
227
                if (toggled == text)
 
228
                    editor.navigateRight();
 
229
                else
 
230
                    editor.session.replace(range, toggled);
 
231
            }, count || 1);
 
232
        }
 
233
    },
 
234
    "*": {
 
235
        fn: function(editor, range, count, param) {
 
236
            editor.selection.selectWord();
 
237
            editor.findNext();
 
238
            ensureScrollMargin(editor);
 
239
            var r = editor.selection.getRange();
 
240
            editor.selection.setSelectionRange(r, true);
 
241
        }
 
242
    },
 
243
    "#": {
 
244
        fn: function(editor, range, count, param) {
 
245
            editor.selection.selectWord();
 
246
            editor.findPrevious();
 
247
            ensureScrollMargin(editor);
 
248
            var r = editor.selection.getRange();
 
249
            editor.selection.setSelectionRange(r, true);
 
250
        }
 
251
    },
 
252
    "m": {
 
253
        param: true,
 
254
        fn: function(editor, range, count, param) {
 
255
            var s =  editor.session;
 
256
            var markers = s.vimMarkers || (s.vimMarkers = {});
 
257
            var c = editor.getCursorPosition();
 
258
            if (!markers[param]) {
 
259
                markers[param] = editor.session.doc.createAnchor(c);
 
260
            }
 
261
            markers[param].setPosition(c.row, c.column, true);
 
262
        }
 
263
    },
 
264
    "n": {
 
265
        fn: function(editor, range, count, param) {
 
266
            var options = editor.getLastSearchOptions();
 
267
            options.backwards = false;
 
268
 
 
269
            editor.selection.moveCursorRight();
 
270
            editor.selection.clearSelection();
 
271
            editor.findNext(options);
 
272
 
 
273
            ensureScrollMargin(editor);
 
274
            var r = editor.selection.getRange();
 
275
            r.end.row = r.start.row;
 
276
            r.end.column = r.start.column;
 
277
            editor.selection.setSelectionRange(r, true);
 
278
        }
 
279
    },
 
280
    "N": {
 
281
        fn: function(editor, range, count, param) {
 
282
            var options = editor.getLastSearchOptions();
 
283
            options.backwards = true;
 
284
 
 
285
            editor.findPrevious(options);
 
286
            ensureScrollMargin(editor);
 
287
            var r = editor.selection.getRange();
 
288
            r.end.row = r.start.row;
 
289
            r.end.column = r.start.column;
 
290
            editor.selection.setSelectionRange(r, true);
 
291
        }
 
292
    },
 
293
    "v": {
 
294
        fn: function(editor, range, count, param) {
 
295
            editor.selection.selectRight();
 
296
            util.visualMode(editor, false);
 
297
        },
 
298
        acceptsMotion: true
 
299
    },
 
300
    "V": {
 
301
        fn: function(editor, range, count, param) {
 
302
            var row = editor.getCursorPosition().row;
 
303
            editor.selection.clearSelection();
 
304
            editor.selection.moveCursorTo(row, 0);
 
305
            editor.selection.selectLineEnd();
 
306
            editor.selection.visualLineStart = row;
 
307
 
 
308
            util.visualMode(editor, true);
 
309
        },
 
310
        acceptsMotion: true
 
311
    },
 
312
    "Y": {
 
313
        fn: function(editor, range, count, param) {
 
314
            util.copyLine(editor);
 
315
        }
 
316
    },
 
317
    "p": {
 
318
        fn: function(editor, range, count, param) {
 
319
            var defaultReg = registers._default;
 
320
 
 
321
            editor.setOverwrite(false);
 
322
            if (defaultReg.isLine) {
 
323
                var pos = editor.getCursorPosition();
 
324
                var lines = defaultReg.text.split("\n");
 
325
                editor.session.getDocument().insertLines(pos.row + 1, lines);
 
326
                editor.moveCursorTo(pos.row + 1, 0);
 
327
            }
 
328
            else {
 
329
                editor.navigateRight();
 
330
                editor.insert(defaultReg.text);
 
331
                editor.navigateLeft();
 
332
            }
 
333
            editor.setOverwrite(true);
 
334
            editor.selection.clearSelection();
 
335
        }
 
336
    },
 
337
    "P": {
 
338
        fn: function(editor, range, count, param) {
 
339
            var defaultReg = registers._default;
 
340
            editor.setOverwrite(false);
 
341
 
 
342
            if (defaultReg.isLine) {
 
343
                var pos = editor.getCursorPosition();
 
344
                var lines = defaultReg.text.split("\n");
 
345
                editor.session.getDocument().insertLines(pos.row, lines);
 
346
                editor.moveCursorTo(pos.row, 0);
 
347
            }
 
348
            else {
 
349
                editor.insert(defaultReg.text);
 
350
            }
 
351
            editor.setOverwrite(true);
 
352
            editor.selection.clearSelection();
 
353
        }
 
354
    },
 
355
    "J": {
 
356
        fn: function(editor, range, count, param) {
 
357
            var session = editor.session;
 
358
            range = editor.getSelectionRange();
 
359
            var pos = {row: range.start.row, column: range.start.column};
 
360
            count = count || range.end.row - range.start.row;
 
361
            var maxRow = Math.min(pos.row + (count || 1), session.getLength() - 1);
 
362
 
 
363
            range.start.column = session.getLine(pos.row).length;
 
364
            range.end.column = session.getLine(maxRow).length;
 
365
            range.end.row = maxRow;
 
366
 
 
367
            var text = "";
 
368
            for (var i = pos.row; i < maxRow; i++) {
 
369
                var nextLine = session.getLine(i + 1);
 
370
                text += " " + /^\s*(.*)$/.exec(nextLine)[1] || "";
 
371
            }
 
372
 
 
373
            session.replace(range, text);
 
374
            editor.moveCursorTo(pos.row, pos.column);
 
375
        }
 
376
    },
 
377
    "u": {
 
378
        fn: function(editor, range, count, param) {
 
379
            count = parseInt(count || 1, 10);
 
380
            for (var i = 0; i < count; i++) {
 
381
                editor.undo();
 
382
            }
 
383
            editor.selection.clearSelection();
 
384
        }
 
385
    },
 
386
    "ctrl-r": {
 
387
        fn: function(editor, range, count, param) {
 
388
            count = parseInt(count || 1, 10);
 
389
            for (var i = 0; i < count; i++) {
 
390
                editor.redo();
 
391
            }
 
392
            editor.selection.clearSelection();
 
393
        }
 
394
    },
 
395
    ":": {
 
396
        fn: function(editor, range, count, param) {
 
397
        }
 
398
    },
 
399
    "/": {
 
400
        fn: function(editor, range, count, param) {
 
401
        }
 
402
    },
 
403
    "?": {
 
404
        fn: function(editor, range, count, param) {
 
405
        }
 
406
    },
 
407
    ".": {
 
408
        fn: function(editor, range, count, param) {
 
409
            util.onInsertReplaySequence = inputBuffer.lastInsertCommands;
 
410
            var previous = inputBuffer.previous;
 
411
            if (previous) // If there is a previous action
 
412
                inputBuffer.exec(editor, previous.action, previous.param);
 
413
        }
 
414
    },
 
415
    "ctrl-x": {
 
416
        fn: function(editor, range, count, param) {
 
417
            editor.modifyNumber(-(count || 1));
 
418
        }
 
419
    },
 
420
    "ctrl-a": {
 
421
        fn: function(editor, range, count, param) {
 
422
            editor.modifyNumber(count || 1);
 
423
        }
 
424
    }
 
425
};
 
426
 
 
427
var inputBuffer = exports.inputBuffer = {
 
428
    accepting: [NUMBER, OPERATOR, MOTION, ACTION],
 
429
    currentCmd: null,
 
430
    currentCount: "",
 
431
    status: "",
 
432
    operator: null,
 
433
    motion: null,
 
434
 
 
435
    lastInsertCommands: [],
 
436
 
 
437
    push: function(editor, ch, keyId) {
 
438
        var isKeyHandled = true;
 
439
        this.idle = false;
 
440
        var wObj = this.waitingForParam;
 
441
        if (wObj) {
 
442
            this.exec(editor, wObj, ch);
 
443
        }
 
444
        else if (!(ch === "0" && !this.currentCount.length) &&
 
445
            (ch.match(/^\d+$/) && this.isAccepting(NUMBER))) {
 
446
            this.currentCount += ch;
 
447
            this.currentCmd = NUMBER;
 
448
            this.accepting = [NUMBER, OPERATOR, MOTION, ACTION];
 
449
        }
 
450
        else if (!this.operator && this.isAccepting(OPERATOR) && operators[ch]) {
 
451
            this.operator = {
 
452
                ch: ch,
 
453
                count: this.getCount()
 
454
            };
 
455
            this.currentCmd = OPERATOR;
 
456
            this.accepting = [NUMBER, MOTION, ACTION];
 
457
            this.exec(editor, { operator: this.operator });
 
458
        }
 
459
        else if (motions[ch] && this.isAccepting(MOTION)) {
 
460
            this.currentCmd = MOTION;
 
461
 
 
462
            var ctx = {
 
463
                operator: this.operator,
 
464
                motion: {
 
465
                    ch: ch,
 
466
                    count: this.getCount()
 
467
                }
 
468
            };
 
469
 
 
470
            if (motions[ch].param)
 
471
                this.waitForParam(ctx);
 
472
            else
 
473
                this.exec(editor, ctx);
 
474
        }
 
475
        else if (alias[ch] && this.isAccepting(MOTION)) {
 
476
            alias[ch].operator.count = this.getCount();
 
477
            this.exec(editor, alias[ch]);
 
478
        }
 
479
        else if (actions[ch] && this.isAccepting(ACTION)) {
 
480
            var actionObj = {
 
481
                action: {
 
482
                    fn: actions[ch].fn,
 
483
                    count: this.getCount()
 
484
                }
 
485
            };
 
486
 
 
487
            if (actions[ch].param) {
 
488
                this.waitForParam(actionObj);
 
489
            }
 
490
            else {
 
491
                this.exec(editor, actionObj);
 
492
            }
 
493
 
 
494
            if (actions[ch].acceptsMotion)
 
495
                this.idle = false;
 
496
        }
 
497
        else if (this.operator) {
 
498
            this.exec(editor, { operator: this.operator }, ch);
 
499
        }
 
500
        else {
 
501
            isKeyHandled = ch.length == 1;
 
502
            this.reset();
 
503
        }
 
504
        
 
505
        if (this.waitingForParam || this.motion || this.operator) {
 
506
            this.status += ch;
 
507
        } else if (this.currentCount) {
 
508
            this.status = this.currentCount;
 
509
        } else if (this.status) {
 
510
            this.status = "";
 
511
        } else {
 
512
            return isKeyHandled;
 
513
        }
 
514
        editor._emit("changeStatus");
 
515
        return isKeyHandled;
 
516
    },
 
517
 
 
518
    waitForParam: function(cmd) {
 
519
        this.waitingForParam = cmd;
 
520
    },
 
521
 
 
522
    getCount: function() {
 
523
        var count = this.currentCount;
 
524
        this.currentCount = "";
 
525
        return count && parseInt(count, 10);
 
526
    },
 
527
 
 
528
    exec: function(editor, action, param) {
 
529
        var m = action.motion;
 
530
        var o = action.operator;
 
531
        var a = action.action;
 
532
 
 
533
        if (!param)
 
534
            param = action.param;
 
535
 
 
536
        if (o) {
 
537
            this.previous = {
 
538
                action: action,
 
539
                param: param
 
540
            };
 
541
        }
 
542
 
 
543
        if (o && !editor.selection.isEmpty()) {
 
544
            if (operators[o.ch].selFn) {
 
545
                operators[o.ch].selFn(editor, editor.getSelectionRange(), o.count, param);
 
546
                this.reset();
 
547
            }
 
548
            return;
 
549
        }
 
550
        else if (!m && !a && o && param) {
 
551
            operators[o.ch].fn(editor, null, o.count, param);
 
552
            this.reset();
 
553
        }
 
554
        else if (m) {
 
555
            var run = function(fn) {
 
556
                if (fn && typeof fn === "function") { // There should always be a motion
 
557
                    if (m.count && !motionObj.handlesCount)
 
558
                        repeat(fn, m.count, [editor, null, m.count, param]);
 
559
                    else
 
560
                        fn(editor, null, m.count, param);
 
561
                }
 
562
            };
 
563
 
 
564
            var motionObj = motions[m.ch];
 
565
            var selectable = motionObj.sel;
 
566
 
 
567
            if (!o) {
 
568
                if ((util.onVisualMode || util.onVisualLineMode) && selectable)
 
569
                    run(motionObj.sel);
 
570
                else
 
571
                    run(motionObj.nav);
 
572
            }
 
573
            else if (selectable) {
 
574
                repeat(function() {
 
575
                    run(motionObj.sel);
 
576
                    operators[o.ch].fn(editor, editor.getSelectionRange(), o.count, param);
 
577
                }, o.count || 1);
 
578
            }
 
579
            this.reset();
 
580
        }
 
581
        else if (a) {
 
582
            a.fn(editor, editor.getSelectionRange(), a.count, param);
 
583
            this.reset();
 
584
        }
 
585
        handleCursorMove(editor);
 
586
    },
 
587
 
 
588
    isAccepting: function(type) {
 
589
        return this.accepting.indexOf(type) !== -1;
 
590
    },
 
591
 
 
592
    reset: function() {
 
593
        this.operator = null;
 
594
        this.motion = null;
 
595
        this.currentCount = "";
 
596
        this.status = "";
 
597
        this.accepting = [NUMBER, OPERATOR, MOTION, ACTION];
 
598
        this.idle = true;
 
599
        this.waitingForParam = null;
 
600
    }
 
601
};
 
602
 
 
603
function setPreviousCommand(fn) {
 
604
    inputBuffer.previous = { action: { action: { fn: fn } } };
 
605
}
 
606
 
 
607
exports.coreCommands = {
 
608
    start: {
 
609
        exec: function start(editor) {
 
610
            util.insertMode(editor);
 
611
            setPreviousCommand(start);
 
612
        }
 
613
    },
 
614
    startBeginning: {
 
615
        exec: function startBeginning(editor) {
 
616
            editor.navigateLineStart();
 
617
            util.insertMode(editor);
 
618
            setPreviousCommand(startBeginning);
 
619
        }
 
620
    },
 
621
    stop: {
 
622
        exec: function stop(editor) {
 
623
            inputBuffer.reset();
 
624
            util.onVisualMode = false;
 
625
            util.onVisualLineMode = false;
 
626
            inputBuffer.lastInsertCommands = util.normalMode(editor);
 
627
        }
 
628
    },
 
629
    append: {
 
630
        exec: function append(editor) {
 
631
            var pos = editor.getCursorPosition();
 
632
            var lineLen = editor.session.getLine(pos.row).length;
 
633
            if (lineLen)
 
634
                editor.navigateRight();
 
635
            util.insertMode(editor);
 
636
            setPreviousCommand(append);
 
637
        }
 
638
    },
 
639
    appendEnd: {
 
640
        exec: function appendEnd(editor) {
 
641
            editor.navigateLineEnd();
 
642
            util.insertMode(editor);
 
643
            setPreviousCommand(appendEnd);
 
644
        }
 
645
    }
 
646
};
 
647
 
 
648
var handleCursorMove = exports.onCursorMove = function(editor, e) {
 
649
    if (util.currentMode === 'insert' || handleCursorMove.running)
 
650
        return;
 
651
    else if(!editor.selection.isEmpty()) {
 
652
        handleCursorMove.running = true;
 
653
        if (util.onVisualLineMode) {
 
654
            var originRow = editor.selection.visualLineStart;
 
655
            var cursorRow = editor.getCursorPosition().row;
 
656
            if(originRow <= cursorRow) {
 
657
                var endLine = editor.session.getLine(cursorRow);
 
658
                editor.selection.clearSelection();
 
659
                editor.selection.moveCursorTo(originRow, 0);
 
660
                editor.selection.selectTo(cursorRow, endLine.length);
 
661
            } else {
 
662
                var endLine = editor.session.getLine(originRow);
 
663
                editor.selection.clearSelection();
 
664
                editor.selection.moveCursorTo(originRow, endLine.length);
 
665
                editor.selection.selectTo(cursorRow, 0);
 
666
            }
 
667
        }
 
668
        handleCursorMove.running = false;
 
669
        return;
 
670
    }
 
671
    else {
 
672
        if (e && (util.onVisualLineMode || util.onVisualMode)) {
 
673
            editor.selection.clearSelection();
 
674
            util.normalMode(editor);
 
675
        }
 
676
 
 
677
        handleCursorMove.running = true;
 
678
        var pos = editor.getCursorPosition();
 
679
        var lineLen = editor.session.getLine(pos.row).length;
 
680
 
 
681
        if (lineLen && pos.column === lineLen)
 
682
            editor.navigateLeft();
 
683
        handleCursorMove.running = false;
 
684
    }
 
685
};
 
686
});
 
687
define('ace/keyboard/vim/maps/util', ['require', 'exports', 'module' , 'ace/keyboard/vim/registers', 'ace/lib/dom'], function(require, exports, module) {
 
688
var registers = require("../registers");
 
689
 
 
690
var dom = require("../../../lib/dom");
 
691
dom.importCssString('.insert-mode .ace_cursor{\
 
692
    border-left: 2px solid #333333;\
 
693
}\
 
694
.ace_dark.insert-mode .ace_cursor{\
 
695
    border-left: 2px solid #eeeeee;\
 
696
}\
 
697
.normal-mode .ace_cursor{\
 
698
    border: 0!important;\
 
699
    background-color: red;\
 
700
    opacity: 0.5;\
 
701
}', 'vimMode');
 
702
 
 
703
module.exports = {
 
704
    onVisualMode: false,
 
705
    onVisualLineMode: false,
 
706
    currentMode: 'normal',
 
707
    noMode: function(editor) {
 
708
        editor.unsetStyle('insert-mode');
 
709
        editor.unsetStyle('normal-mode');
 
710
        if (editor.commands.recording)
 
711
            editor.commands.toggleRecording(editor);
 
712
        editor.setOverwrite(false);
 
713
    },
 
714
    insertMode: function(editor) {
 
715
        this.currentMode = 'insert';
 
716
        editor.setStyle('insert-mode');
 
717
        editor.unsetStyle('normal-mode');
 
718
 
 
719
        editor.setOverwrite(false);
 
720
        editor.keyBinding.$data.buffer = "";
 
721
        editor.keyBinding.$data.state = "insertMode";
 
722
        this.onVisualMode = false;
 
723
        this.onVisualLineMode = false;
 
724
        if(this.onInsertReplaySequence) {
 
725
            editor.commands.macro = this.onInsertReplaySequence;
 
726
            editor.commands.replay(editor);
 
727
            this.onInsertReplaySequence = null;
 
728
            this.normalMode(editor);
 
729
        } else {
 
730
            editor._emit("changeStatus");
 
731
            if(!editor.commands.recording)
 
732
                editor.commands.toggleRecording(editor);
 
733
        }
 
734
    },
 
735
    normalMode: function(editor) {
 
736
        this.currentMode = 'normal';
 
737
 
 
738
        editor.unsetStyle('insert-mode');
 
739
        editor.setStyle('normal-mode');
 
740
        editor.clearSelection();
 
741
 
 
742
        var pos;
 
743
        if (!editor.getOverwrite()) {
 
744
            pos = editor.getCursorPosition();
 
745
            if (pos.column > 0)
 
746
                editor.navigateLeft();
 
747
        }
 
748
 
 
749
        editor.setOverwrite(true);
 
750
        editor.keyBinding.$data.buffer = "";
 
751
        editor.keyBinding.$data.state = "start";
 
752
        this.onVisualMode = false;
 
753
        this.onVisualLineMode = false;
 
754
        editor._emit("changeStatus");
 
755
        if (editor.commands.recording) {
 
756
            editor.commands.toggleRecording(editor);
 
757
            return editor.commands.macro;
 
758
        }
 
759
        else {
 
760
            return [];
 
761
        }
 
762
    },
 
763
    visualMode: function(editor, lineMode) {
 
764
        if (
 
765
            (this.onVisualLineMode && lineMode)
 
766
            || (this.onVisualMode && !lineMode)
 
767
        ) {
 
768
            this.normalMode(editor);
 
769
            return;
 
770
        }
 
771
 
 
772
        editor.setStyle('insert-mode');
 
773
        editor.unsetStyle('normal-mode');
 
774
 
 
775
        editor._emit("changeStatus");
 
776
        if (lineMode) {
 
777
            this.onVisualLineMode = true;
 
778
        } else {
 
779
            this.onVisualMode = true;
 
780
            this.onVisualLineMode = false;
 
781
        }
 
782
    },
 
783
    getRightNthChar: function(editor, cursor, ch, n) {
 
784
        var line = editor.getSession().getLine(cursor.row);
 
785
        var matches = line.substr(cursor.column + 1).split(ch);
 
786
 
 
787
        return n < matches.length ? matches.slice(0, n).join(ch).length : null;
 
788
    },
 
789
    getLeftNthChar: function(editor, cursor, ch, n) {
 
790
        var line = editor.getSession().getLine(cursor.row);
 
791
        var matches = line.substr(0, cursor.column).split(ch);
 
792
 
 
793
        return n < matches.length ? matches.slice(-1 * n).join(ch).length : null;
 
794
    },
 
795
    toRealChar: function(ch) {
 
796
        if (ch.length === 1)
 
797
            return ch;
 
798
 
 
799
        if (/^shift-./.test(ch))
 
800
            return ch[ch.length - 1].toUpperCase();
 
801
        else
 
802
            return "";
 
803
    },
 
804
    copyLine: function(editor) {
 
805
        var pos = editor.getCursorPosition();
 
806
        editor.selection.clearSelection();
 
807
        editor.moveCursorTo(pos.row, pos.column);
 
808
        editor.selection.selectLine();
 
809
        registers._default.isLine = true;
 
810
        registers._default.text = editor.getCopyText().replace(/\n$/, "");
 
811
        editor.selection.clearSelection();
 
812
        editor.moveCursorTo(pos.row, pos.column);
 
813
    }
 
814
};
 
815
});
 
816
 
 
817
define('ace/keyboard/vim/registers', ['require', 'exports', 'module' ], function(require, exports, module) {
 
818
 
 
819
"never use strict";
 
820
 
 
821
module.exports = {
 
822
    _default: {
 
823
        text: "",
 
824
        isLine: false
 
825
    }
 
826
};
 
827
 
 
828
});
 
829
 
 
830
 
 
831
define('ace/keyboard/vim/maps/motions', ['require', 'exports', 'module' , 'ace/keyboard/vim/maps/util', 'ace/search', 'ace/range'], function(require, exports, module) {
 
832
 
 
833
 
 
834
var util = require("./util");
 
835
 
 
836
var keepScrollPosition = function(editor, fn) {
 
837
    var scrollTopRow = editor.renderer.getScrollTopRow();
 
838
    var initialRow = editor.getCursorPosition().row;
 
839
    var diff = initialRow - scrollTopRow;
 
840
    fn && fn.call(editor);
 
841
    editor.renderer.scrollToRow(editor.getCursorPosition().row - diff);
 
842
};
 
843
 
 
844
function Motion(m) {
 
845
    if (typeof m == "function") {
 
846
        var getPos = m;
 
847
        m = this;
 
848
    } else {
 
849
        var getPos = m.getPos;
 
850
    }
 
851
    m.nav = function(editor, range, count, param) {
 
852
        var a = getPos(editor, range, count, param, false);
 
853
        if (!a)
 
854
            return;
 
855
        editor.clearSelection();
 
856
        editor.moveCursorTo(a.row, a.column);
 
857
    };
 
858
    m.sel = function(editor, range, count, param) {
 
859
        var a = getPos(editor, range, count, param, true);
 
860
        if (!a)
 
861
            return;
 
862
        editor.selection.selectTo(a.row, a.column);
 
863
    };
 
864
    return m;
 
865
}
 
866
 
 
867
var nonWordRe = /[\s.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
 
868
var wordSeparatorRe = /[.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
 
869
var whiteRe = /\s/;
 
870
var StringStream = function(editor, cursor) {
 
871
    var sel = editor.selection;
 
872
    this.range = sel.getRange();
 
873
    cursor = cursor || sel.selectionLead;
 
874
    this.row = cursor.row;
 
875
    this.col = cursor.column;
 
876
    var line = editor.session.getLine(this.row);
 
877
    var maxRow = editor.session.getLength();
 
878
    this.ch = line[this.col] || '\n';
 
879
    this.skippedLines = 0;
 
880
 
 
881
    this.next = function() {
 
882
        this.ch = line[++this.col] || this.handleNewLine(1);
 
883
        return this.ch;
 
884
    };
 
885
    this.prev = function() {
 
886
        this.ch = line[--this.col] || this.handleNewLine(-1);
 
887
        return this.ch;
 
888
    };
 
889
    this.peek = function(dir) {
 
890
        var ch = line[this.col + dir];
 
891
        if (ch)
 
892
            return ch;
 
893
        if (dir == -1)
 
894
            return '\n';
 
895
        if (this.col == line.length - 1)
 
896
            return '\n';
 
897
        return editor.session.getLine(this.row + 1)[0] || '\n';
 
898
    };
 
899
 
 
900
    this.handleNewLine = function(dir) {
 
901
        if (dir == 1){
 
902
            if (this.col == line.length)
 
903
                return '\n';
 
904
            if (this.row == maxRow - 1)
 
905
                return '';
 
906
            this.col = 0;
 
907
            this.row ++;
 
908
            line = editor.session.getLine(this.row);
 
909
            this.skippedLines++;
 
910
            return line[0] || '\n';
 
911
        }
 
912
        if (dir == -1) {
 
913
            if (this.row === 0)
 
914
                return '';
 
915
            this.row --;
 
916
            line = editor.session.getLine(this.row);
 
917
            this.col = line.length;
 
918
            this.skippedLines--;
 
919
            return '\n';
 
920
        }
 
921
    };
 
922
    this.debug = function() {
 
923
        console.log(line.substring(0, this.col)+'|'+this.ch+'\''+this.col+'\''+line.substr(this.col+1));
 
924
    };
 
925
};
 
926
 
 
927
var Search = require("../../../search").Search;
 
928
var search = new Search();
 
929
 
 
930
function find(editor, needle, dir) {
 
931
    search.$options.needle = needle;
 
932
    search.$options.backwards = dir == -1;
 
933
    return search.find(editor.session);
 
934
}
 
935
 
 
936
var Range = require("../../../range").Range;
 
937
 
 
938
module.exports = {
 
939
    "w": new Motion(function(editor) {
 
940
        var str = new StringStream(editor);
 
941
 
 
942
        if (str.ch && wordSeparatorRe.test(str.ch)) {
 
943
            while (str.ch && wordSeparatorRe.test(str.ch))
 
944
                str.next();
 
945
        } else {
 
946
            while (str.ch && !nonWordRe.test(str.ch))
 
947
                str.next();
 
948
        }
 
949
        while (str.ch && whiteRe.test(str.ch) && str.skippedLines < 2)
 
950
            str.next();
 
951
 
 
952
        str.skippedLines == 2 && str.prev();
 
953
        return {column: str.col, row: str.row};
 
954
    }),
 
955
    "W": new Motion(function(editor) {
 
956
        var str = new StringStream(editor);
 
957
        while(str.ch && !(whiteRe.test(str.ch) && !whiteRe.test(str.peek(1))) && str.skippedLines < 2)
 
958
            str.next();
 
959
        if (str.skippedLines == 2)
 
960
            str.prev();
 
961
        else
 
962
            str.next();
 
963
 
 
964
        return {column: str.col, row: str.row};
 
965
    }),
 
966
    "b": new Motion(function(editor) {
 
967
        var str = new StringStream(editor);
 
968
 
 
969
        str.prev();
 
970
        while (str.ch && whiteRe.test(str.ch) && str.skippedLines > -2)
 
971
            str.prev();
 
972
 
 
973
        if (str.ch && wordSeparatorRe.test(str.ch)) {
 
974
            while (str.ch && wordSeparatorRe.test(str.ch))
 
975
                str.prev();
 
976
        } else {
 
977
            while (str.ch && !nonWordRe.test(str.ch))
 
978
                str.prev();
 
979
        }
 
980
        str.ch && str.next();
 
981
        return {column: str.col, row: str.row};
 
982
    }),
 
983
    "B": new Motion(function(editor) {
 
984
        var str = new StringStream(editor);
 
985
        str.prev();
 
986
        while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(-1))) && str.skippedLines > -2)
 
987
            str.prev();
 
988
 
 
989
        if (str.skippedLines == -2)
 
990
            str.next();
 
991
 
 
992
        return {column: str.col, row: str.row};
 
993
    }),
 
994
    "e": new Motion(function(editor) {
 
995
        var str = new StringStream(editor);
 
996
 
 
997
        str.next();
 
998
        while (str.ch && whiteRe.test(str.ch))
 
999
            str.next();
 
1000
 
 
1001
        if (str.ch && wordSeparatorRe.test(str.ch)) {
 
1002
            while (str.ch && wordSeparatorRe.test(str.ch))
 
1003
                str.next();
 
1004
        } else {
 
1005
            while (str.ch && !nonWordRe.test(str.ch))
 
1006
                str.next();
 
1007
        }
 
1008
        str.ch && str.prev();
 
1009
        return {column: str.col, row: str.row};
 
1010
    }),
 
1011
    "E": new Motion(function(editor) {
 
1012
        var str = new StringStream(editor);
 
1013
        str.next();
 
1014
        while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(1))))
 
1015
            str.next();
 
1016
 
 
1017
        return {column: str.col, row: str.row};
 
1018
    }),
 
1019
 
 
1020
    "l": {
 
1021
        nav: function(editor) {
 
1022
            var pos = editor.getCursorPosition();
 
1023
            var col = pos.column;
 
1024
            var lineLen = editor.session.getLine(pos.row).length;
 
1025
            if (lineLen && col !== lineLen)
 
1026
                editor.navigateRight();
 
1027
        },
 
1028
        sel: function(editor) {
 
1029
            var pos = editor.getCursorPosition();
 
1030
            var col = pos.column;
 
1031
            var lineLen = editor.session.getLine(pos.row).length;
 
1032
            if (lineLen && col !== lineLen) //In selection mode you can select the newline
 
1033
                editor.selection.selectRight();
 
1034
        }
 
1035
    },
 
1036
    "h": {
 
1037
        nav: function(editor) {
 
1038
            var pos = editor.getCursorPosition();
 
1039
            if (pos.column > 0)
 
1040
                editor.navigateLeft();
 
1041
        },
 
1042
        sel: function(editor) {
 
1043
            var pos = editor.getCursorPosition();
 
1044
            if (pos.column > 0)
 
1045
                editor.selection.selectLeft();
 
1046
        }
 
1047
    },
 
1048
    "H": {
 
1049
        nav: function(editor) {
 
1050
            var row = editor.renderer.getScrollTopRow();
 
1051
            editor.moveCursorTo(row);
 
1052
        },
 
1053
        sel: function(editor) {
 
1054
            var row = editor.renderer.getScrollTopRow();
 
1055
            editor.selection.selectTo(row);
 
1056
        }
 
1057
    },
 
1058
    "M": {
 
1059
        nav: function(editor) {
 
1060
            var topRow = editor.renderer.getScrollTopRow();
 
1061
            var bottomRow = editor.renderer.getScrollBottomRow();
 
1062
            var row = topRow + ((bottomRow - topRow) / 2);
 
1063
            editor.moveCursorTo(row);
 
1064
        },
 
1065
        sel: function(editor) {
 
1066
            var topRow = editor.renderer.getScrollTopRow();
 
1067
            var bottomRow = editor.renderer.getScrollBottomRow();
 
1068
            var row = topRow + ((bottomRow - topRow) / 2);
 
1069
            editor.selection.selectTo(row);
 
1070
        }
 
1071
    },
 
1072
    "L": {
 
1073
        nav: function(editor) {
 
1074
            var row = editor.renderer.getScrollBottomRow();
 
1075
            editor.moveCursorTo(row);
 
1076
        },
 
1077
        sel: function(editor) {
 
1078
            var row = editor.renderer.getScrollBottomRow();
 
1079
            editor.selection.selectTo(row);
 
1080
        }
 
1081
    },
 
1082
    "k": {
 
1083
        nav: function(editor) {
 
1084
            editor.navigateUp();
 
1085
        },
 
1086
        sel: function(editor) {
 
1087
            editor.selection.selectUp();
 
1088
        }
 
1089
    },
 
1090
    "j": {
 
1091
        nav: function(editor) {
 
1092
            editor.navigateDown();
 
1093
        },
 
1094
        sel: function(editor) {
 
1095
            editor.selection.selectDown();
 
1096
        }
 
1097
    },
 
1098
 
 
1099
    "i": {
 
1100
        param: true,
 
1101
        sel: function(editor, range, count, param) {
 
1102
            switch (param) {
 
1103
                case "w":
 
1104
                    editor.selection.selectWord();
 
1105
                    break;
 
1106
                case "W":
 
1107
                    editor.selection.selectAWord();
 
1108
                    break;
 
1109
                case "(":
 
1110
                case "{":
 
1111
                case "[":
 
1112
                    var cursor = editor.getCursorPosition();
 
1113
                    var end = editor.session.$findClosingBracket(param, cursor, /paren/);
 
1114
                    if (!end)
 
1115
                        return;
 
1116
                    var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
 
1117
                    if (!start)
 
1118
                        return;
 
1119
                    start.column ++;
 
1120
                    editor.selection.setSelectionRange(Range.fromPoints(start, end));
 
1121
                    break;
 
1122
                case "'":
 
1123
                case '"':
 
1124
                case "/":
 
1125
                    var end = find(editor, param, 1);
 
1126
                    if (!end)
 
1127
                        return;
 
1128
                    var start = find(editor, param, -1);
 
1129
                    if (!start)
 
1130
                        return;
 
1131
                    editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start));
 
1132
                    break;
 
1133
            }
 
1134
        }
 
1135
    },
 
1136
    "a": {
 
1137
        param: true,
 
1138
        sel: function(editor, range, count, param) {
 
1139
            switch (param) {
 
1140
                case "w":
 
1141
                    editor.selection.selectAWord();
 
1142
                    break;
 
1143
                case "W":
 
1144
                    editor.selection.selectAWord();
 
1145
                    break;
 
1146
                case "(":
 
1147
                case "{":
 
1148
                case "[":
 
1149
                    var cursor = editor.getCursorPosition();
 
1150
                    var end = editor.session.$findClosingBracket(param, cursor, /paren/);
 
1151
                    if (!end)
 
1152
                        return;
 
1153
                    var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/);
 
1154
                    if (!start)
 
1155
                        return;
 
1156
                    end.column ++;
 
1157
                    editor.selection.setSelectionRange(Range.fromPoints(start, end));
 
1158
                    break;
 
1159
                case "'":
 
1160
                case "\"":
 
1161
                case "/":
 
1162
                    var end = find(editor, param, 1);
 
1163
                    if (!end)
 
1164
                        return;
 
1165
                    var start = find(editor, param, -1);
 
1166
                    if (!start)
 
1167
                        return;
 
1168
                    end.column ++;
 
1169
                    editor.selection.setSelectionRange(Range.fromPoints(start.start, end.end));
 
1170
                    break;
 
1171
            }
 
1172
        }
 
1173
    },
 
1174
 
 
1175
    "f": new Motion({
 
1176
        param: true,
 
1177
        handlesCount: true,
 
1178
        getPos: function(editor, range, count, param, isSel) {
 
1179
            var cursor = editor.getCursorPosition();
 
1180
            var column = util.getRightNthChar(editor, cursor, param, count || 1);
 
1181
 
 
1182
            if (typeof column === "number") {
 
1183
                cursor.column += column + (isSel ? 2 : 1);
 
1184
                return cursor;
 
1185
            }
 
1186
        }
 
1187
    }),
 
1188
    "F": new Motion({
 
1189
        param: true,
 
1190
        handlesCount: true,
 
1191
        getPos: function(editor, range, count, param, isSel) {
 
1192
            var cursor = editor.getCursorPosition();
 
1193
            var column = util.getLeftNthChar(editor, cursor, param, count || 1);
 
1194
 
 
1195
            if (typeof column === "number") {
 
1196
                cursor.column -= column + 1;
 
1197
                return cursor;
 
1198
            }
 
1199
        }
 
1200
    }),
 
1201
    "t": new Motion({
 
1202
        param: true,
 
1203
        handlesCount: true,
 
1204
        getPos: function(editor, range, count, param, isSel) {
 
1205
            var cursor = editor.getCursorPosition();
 
1206
            var column = util.getRightNthChar(editor, cursor, param, count || 1);
 
1207
 
 
1208
            if (typeof column === "number") {
 
1209
                cursor.column += column + (isSel ? 1 : 0);
 
1210
                return cursor;
 
1211
            }
 
1212
        }
 
1213
    }),
 
1214
    "T": new Motion({
 
1215
        param: true,
 
1216
        handlesCount: true,
 
1217
        getPos: function(editor, range, count, param, isSel) {
 
1218
            var cursor = editor.getCursorPosition();
 
1219
            var column = util.getLeftNthChar(editor, cursor, param, count || 1);
 
1220
 
 
1221
            if (typeof column === "number") {
 
1222
                cursor.column -= column;
 
1223
                return cursor;
 
1224
            }
 
1225
        }
 
1226
    }),
 
1227
 
 
1228
    "^": {
 
1229
        nav: function(editor) {
 
1230
            editor.navigateLineStart();
 
1231
        },
 
1232
        sel: function(editor) {
 
1233
            editor.selection.selectLineStart();
 
1234
        }
 
1235
    },
 
1236
    "$": {
 
1237
        nav: function(editor) {
 
1238
            editor.navigateLineEnd();
 
1239
        },
 
1240
        sel: function(editor) {
 
1241
            editor.selection.selectLineEnd();
 
1242
        }
 
1243
    },
 
1244
    "0": new Motion(function(ed) {
 
1245
        return {row: ed.selection.lead.row, column: 0};
 
1246
    }),
 
1247
    "G": {
 
1248
        nav: function(editor, range, count, param) {
 
1249
            if (!count && count !== 0) { // Stupid JS
 
1250
                count = editor.session.getLength();
 
1251
            }
 
1252
            editor.gotoLine(count);
 
1253
        },
 
1254
        sel: function(editor, range, count, param) {
 
1255
            if (!count && count !== 0) { // Stupid JS
 
1256
                count = editor.session.getLength();
 
1257
            }
 
1258
            editor.selection.selectTo(count, 0);
 
1259
        }
 
1260
    },
 
1261
    "g": {
 
1262
        param: true,
 
1263
        nav: function(editor, range, count, param) {
 
1264
            switch(param) {
 
1265
                case "m":
 
1266
                    console.log("Middle line");
 
1267
                    break;
 
1268
                case "e":
 
1269
                    console.log("End of prev word");
 
1270
                    break;
 
1271
                case "g":
 
1272
                    editor.gotoLine(count || 0);
 
1273
                case "u":
 
1274
                    editor.gotoLine(count || 0);
 
1275
                case "U":
 
1276
                    editor.gotoLine(count || 0);
 
1277
            }
 
1278
        },
 
1279
        sel: function(editor, range, count, param) {
 
1280
            switch(param) {
 
1281
                case "m":
 
1282
                    console.log("Middle line");
 
1283
                    break;
 
1284
                case "e":
 
1285
                    console.log("End of prev word");
 
1286
                    break;
 
1287
                case "g":
 
1288
                    editor.selection.selectTo(count || 0, 0);
 
1289
            }
 
1290
        }
 
1291
    },
 
1292
    "o": {
 
1293
        nav: function(editor, range, count, param) {
 
1294
            count = count || 1;
 
1295
            var content = "";
 
1296
            while (0 < count--)
 
1297
                content += "\n";
 
1298
 
 
1299
            if (content.length) {
 
1300
                editor.navigateLineEnd()
 
1301
                editor.insert(content);
 
1302
                util.insertMode(editor);
 
1303
            }
 
1304
        }
 
1305
    },
 
1306
    "O": {
 
1307
        nav: function(editor, range, count, param) {
 
1308
            var row = editor.getCursorPosition().row;
 
1309
            count = count || 1;
 
1310
            var content = "";
 
1311
            while (0 < count--)
 
1312
                content += "\n";
 
1313
 
 
1314
            if (content.length) {
 
1315
                if(row > 0) {
 
1316
                    editor.navigateUp();
 
1317
                    editor.navigateLineEnd()
 
1318
                    editor.insert(content);
 
1319
                } else {
 
1320
                    editor.session.insert({row: 0, column: 0}, content);
 
1321
                    editor.navigateUp();
 
1322
                }
 
1323
                util.insertMode(editor);
 
1324
            }
 
1325
        }
 
1326
    },
 
1327
    "%": new Motion(function(editor){
 
1328
        var brRe = /[\[\]{}()]/g;
 
1329
        var cursor = editor.getCursorPosition();
 
1330
        var ch = editor.session.getLine(cursor.row)[cursor.column];
 
1331
        if (!brRe.test(ch)) {
 
1332
            var range = find(editor, brRe);
 
1333
            if (!range)
 
1334
                return;
 
1335
            cursor = range.start;
 
1336
        }
 
1337
        var match = editor.session.findMatchingBracket({
 
1338
            row: cursor.row,
 
1339
            column: cursor.column + 1
 
1340
        });
 
1341
 
 
1342
        return match;
 
1343
    }),
 
1344
    "{": new Motion(function(ed) {
 
1345
        var session = ed.session;
 
1346
        var row = session.selection.lead.row;
 
1347
        while(row > 0 && !/\S/.test(session.getLine(row)))
 
1348
            row--;
 
1349
        while(/\S/.test(session.getLine(row)))
 
1350
            row--;
 
1351
        return {column: 0, row: row};
 
1352
    }),
 
1353
    "}": new Motion(function(ed) {
 
1354
        var session = ed.session;
 
1355
        var l = session.getLength();
 
1356
        var row = session.selection.lead.row;
 
1357
        while(row < l && !/\S/.test(session.getLine(row)))
 
1358
            row++;
 
1359
        while(/\S/.test(session.getLine(row)))
 
1360
            row++;
 
1361
        return {column: 0, row: row};
 
1362
    }),
 
1363
    "ctrl-d": {
 
1364
        nav: function(editor, range, count, param) {
 
1365
            editor.selection.clearSelection();
 
1366
            keepScrollPosition(editor, editor.gotoPageDown);
 
1367
        },
 
1368
        sel: function(editor, range, count, param) {
 
1369
            keepScrollPosition(editor, editor.selectPageDown);
 
1370
        }
 
1371
    },
 
1372
    "ctrl-u": {
 
1373
        nav: function(editor, range, count, param) {
 
1374
            editor.selection.clearSelection();
 
1375
            keepScrollPosition(editor, editor.gotoPageUp);
 
1376
        },
 
1377
        sel: function(editor, range, count, param) {
 
1378
            keepScrollPosition(editor, editor.selectPageUp);
 
1379
        }
 
1380
    },
 
1381
    "`": new Motion({
 
1382
        param: true,
 
1383
        handlesCount: true,
 
1384
        getPos: function(editor, range, count, param, isSel) {
 
1385
            var s = editor.session;
 
1386
            var marker = s.vimMarkers && s.vimMarkers[param];
 
1387
            if (marker) {
 
1388
                return marker.getPosition();
 
1389
            }
 
1390
        }
 
1391
    }),
 
1392
    "'": new Motion({
 
1393
        param: true,
 
1394
        handlesCount: true,
 
1395
        getPos: function(editor, range, count, param, isSel) {
 
1396
            var s = editor.session;
 
1397
            var marker = s.vimMarkers && s.vimMarkers[param];
 
1398
            if (marker) {
 
1399
                var pos = marker.getPosition();
 
1400
                var line = editor.session.getLine(pos.row);                
 
1401
                pos.column = line.search(/\S/);
 
1402
                if (pos.column == -1)
 
1403
                    pos.column = line.length;
 
1404
                return pos;
 
1405
            }
 
1406
        }
 
1407
    }),
 
1408
};
 
1409
 
 
1410
module.exports.backspace = module.exports.left = module.exports.h;
 
1411
module.exports.right = module.exports.l;
 
1412
module.exports.up = module.exports.k;
 
1413
module.exports.down = module.exports.j;
 
1414
module.exports.pagedown = module.exports["ctrl-d"];
 
1415
module.exports.pageup = module.exports["ctrl-u"];
 
1416
 
 
1417
});
 
1418
 
 
1419
define('ace/keyboard/vim/maps/operators', ['require', 'exports', 'module' , 'ace/keyboard/vim/maps/util', 'ace/keyboard/vim/registers'], function(require, exports, module) {
 
1420
 
 
1421
"never use strict";
 
1422
 
 
1423
var util = require("./util");
 
1424
var registers = require("../registers");
 
1425
 
 
1426
module.exports = {
 
1427
    "d": {
 
1428
        selFn: function(editor, range, count, param) {
 
1429
            registers._default.text = editor.getCopyText();
 
1430
            registers._default.isLine = util.onVisualLineMode;
 
1431
            if(util.onVisualLineMode)
 
1432
                editor.removeLines();
 
1433
            else
 
1434
                editor.session.remove(range);
 
1435
            util.normalMode(editor);
 
1436
        },
 
1437
        fn: function(editor, range, count, param) {
 
1438
            count = count || 1;
 
1439
            switch (param) {
 
1440
                case "d":
 
1441
                    registers._default.text = "";
 
1442
                    registers._default.isLine = true;
 
1443
                    for (var i = 0; i < count; i++) {
 
1444
                        editor.selection.selectLine();
 
1445
                        registers._default.text += editor.getCopyText();
 
1446
                        var selRange = editor.getSelectionRange();
 
1447
                        if (!selRange.isMultiLine()) {
 
1448
                            lastLineReached = true
 
1449
                            var row = selRange.start.row - 1;
 
1450
                            var col = editor.session.getLine(row).length
 
1451
                            selRange.setStart(row, col);
 
1452
                            editor.session.remove(selRange);
 
1453
                            editor.selection.clearSelection();
 
1454
                            break;
 
1455
                        }
 
1456
                        editor.session.remove(selRange);
 
1457
                        editor.selection.clearSelection();
 
1458
                    }
 
1459
                    registers._default.text = registers._default.text.replace(/\n$/, "");
 
1460
                    break;
 
1461
                default:
 
1462
                    if (range) {
 
1463
                        editor.selection.setSelectionRange(range);
 
1464
                        registers._default.text = editor.getCopyText();
 
1465
                        registers._default.isLine = false;
 
1466
                        editor.session.remove(range);
 
1467
                        editor.selection.clearSelection();
 
1468
                    }
 
1469
            }
 
1470
        }
 
1471
    },
 
1472
    "c": {
 
1473
        selFn: function(editor, range, count, param) {
 
1474
            editor.session.remove(range);
 
1475
            util.insertMode(editor);
 
1476
        },
 
1477
        fn: function(editor, range, count, param) {
 
1478
            count = count || 1;
 
1479
            switch (param) {
 
1480
                case "c":
 
1481
                    for (var i = 0; i < count; i++) {
 
1482
                        editor.removeLines();
 
1483
                        util.insertMode(editor);
 
1484
                    }
 
1485
 
 
1486
                    break;
 
1487
                default:
 
1488
                    if (range) {
 
1489
                        editor.session.remove(range);
 
1490
                        util.insertMode(editor);
 
1491
                    }
 
1492
            }
 
1493
        }
 
1494
    },
 
1495
    "y": {
 
1496
        selFn: function(editor, range, count, param) {
 
1497
            registers._default.text = editor.getCopyText();
 
1498
            registers._default.isLine = util.onVisualLineMode;
 
1499
            editor.selection.clearSelection();
 
1500
            util.normalMode(editor);
 
1501
        },
 
1502
        fn: function(editor, range, count, param) {
 
1503
            count = count || 1;
 
1504
            switch (param) {
 
1505
                case "y":
 
1506
                    var pos = editor.getCursorPosition();
 
1507
                    editor.selection.selectLine();
 
1508
                    for (var i = 0; i < count - 1; i++) {
 
1509
                        editor.selection.moveCursorDown();
 
1510
                    }
 
1511
                    registers._default.text = editor.getCopyText().replace(/\n$/, "");
 
1512
                    editor.selection.clearSelection();
 
1513
                    registers._default.isLine = true;
 
1514
                    editor.moveCursorToPosition(pos);
 
1515
                    break;
 
1516
                default:
 
1517
                    if (range) {
 
1518
                        var pos = editor.getCursorPosition();
 
1519
                        editor.selection.setSelectionRange(range);
 
1520
                        registers._default.text = editor.getCopyText();
 
1521
                        registers._default.isLine = false;
 
1522
                        editor.selection.clearSelection();
 
1523
                        editor.moveCursorTo(pos.row, pos.column);
 
1524
                    }
 
1525
            }
 
1526
        }
 
1527
    },
 
1528
    ">": {
 
1529
        selFn: function(editor, range, count, param) {
 
1530
            count = count || 1;
 
1531
            for (var i = 0; i < count; i++) {
 
1532
                editor.indent();
 
1533
            }
 
1534
            util.normalMode(editor);
 
1535
        },
 
1536
        fn: function(editor, range, count, param) {
 
1537
            count = parseInt(count || 1, 10);
 
1538
            switch (param) {
 
1539
                case ">":
 
1540
                    var pos = editor.getCursorPosition();
 
1541
                    editor.selection.selectLine();
 
1542
                    for (var i = 0; i < count - 1; i++) {
 
1543
                        editor.selection.moveCursorDown();
 
1544
                    }
 
1545
                    editor.indent();
 
1546
                    editor.selection.clearSelection();
 
1547
                    editor.moveCursorToPosition(pos);
 
1548
                    editor.navigateLineEnd();
 
1549
                    editor.navigateLineStart();
 
1550
                    break;
 
1551
            }
 
1552
        }
 
1553
    },
 
1554
    "<": {
 
1555
        selFn: function(editor, range, count, param) {
 
1556
            count = count || 1;
 
1557
            for (var i = 0; i < count; i++) {
 
1558
                editor.blockOutdent();
 
1559
            }
 
1560
            util.normalMode(editor);
 
1561
        },
 
1562
        fn: function(editor, range, count, param) {
 
1563
            count = count || 1;
 
1564
            switch (param) {
 
1565
                case "<":
 
1566
                    var pos = editor.getCursorPosition();
 
1567
                    editor.selection.selectLine();
 
1568
                    for (var i = 0; i < count - 1; i++) {
 
1569
                        editor.selection.moveCursorDown();
 
1570
                    }
 
1571
                    editor.blockOutdent();
 
1572
                    editor.selection.clearSelection();
 
1573
                    editor.moveCursorToPosition(pos);
 
1574
                    editor.navigateLineEnd();
 
1575
                    editor.navigateLineStart();
 
1576
                    break;
 
1577
            }
 
1578
        }
 
1579
    }
 
1580
};
 
1581
});
 
1582
 
 
1583
"use strict"
 
1584
 
 
1585
define('ace/keyboard/vim/maps/aliases', ['require', 'exports', 'module' ], function(require, exports, module) {
 
1586
module.exports = {
 
1587
    "x": {
 
1588
        operator: {
 
1589
            ch: "d",
 
1590
            count: 1
 
1591
        },
 
1592
        motion: {
 
1593
            ch: "l",
 
1594
            count: 1
 
1595
        }
 
1596
    },
 
1597
    "X": {
 
1598
        operator: {
 
1599
            ch: "d",
 
1600
            count: 1
 
1601
        },
 
1602
        motion: {
 
1603
            ch: "h",
 
1604
            count: 1
 
1605
        }
 
1606
    },
 
1607
    "D": {
 
1608
        operator: {
 
1609
            ch: "d",
 
1610
            count: 1
 
1611
        },
 
1612
        motion: {
 
1613
            ch: "$",
 
1614
            count: 1
 
1615
        }
 
1616
    },
 
1617
    "C": {
 
1618
        operator: {
 
1619
            ch: "c",
 
1620
            count: 1
 
1621
        },
 
1622
        motion: {
 
1623
            ch: "$",
 
1624
            count: 1
 
1625
        }
 
1626
    },
 
1627
    "s": {
 
1628
        operator: {
 
1629
            ch: "c",
 
1630
            count: 1
 
1631
        },
 
1632
        motion: {
 
1633
            ch: "l",
 
1634
            count: 1
 
1635
        }
 
1636
    },
 
1637
    "S": {
 
1638
        operator: {
 
1639
            ch: "c",
 
1640
            count: 1
 
1641
        },
 
1642
        param: "c"
 
1643
    }
 
1644
};
 
1645
});
 
1646