diff --git a/lib/ace/keyboard/vim/commands.js b/lib/ace/keyboard/vim/commands.js index 5e1a1912..3312f4a1 100644 --- a/lib/ace/keyboard/vim/commands.js +++ b/lib/ace/keyboard/vim/commands.js @@ -16,15 +16,11 @@ var operators = require("./maps/operators"); var alias = require("./maps/aliases"); var registers = require("./registers"); -var NUMBER = 1; +var NUMBER = 1; var OPERATOR = 2; -var MOTION = 3; -var ACTION = 4; - -//var NORMAL_MODE = 0; -//var INSERT_MODE = 1; -//var VISUAL_MODE = 2; -//getSelectionLead +var MOTION = 3; +var ACTION = 4; +var HMARGIN = 8; // Minimum amount of line separation between margins; exports.searchStore = { current: "", @@ -39,11 +35,34 @@ exports.searchStore = { }; var repeat = function repeat(fn, count, args) { - count = parseInt(count); + count = parseInt(count, 10); while (0 < count--) fn.apply(this, args); }; +var toggleCase = function toggleCase(ch) { + if (ch.toUpperCase() === ch) + return ch.toLowerCase(); + else + return ch.toUpperCase(); +}; + +var ensureScrollMargin = function(editor) { + setTimeout(function() { + var curPos = editor.getCursorPosition().row; + var topRow = editor.renderer.layerConfig.firstRow; + var linesToBottom = editor.renderer.layerConfig.lastRow - curPos; + var linesToTop = curPos - topRow; + + if (linesToBottom >= 0 && linesToBottom < HMARGIN) { + editor.scrollToRow(topRow + (HMARGIN - linesToBottom)); + } + else if (linesToTop >= 0 && linesToTop < HMARGIN) { + editor.scrollToRow(topRow - (HMARGIN - linesToTop)); + } + }, 20); // Delay introduced to ensure scroll after async find operation. +}; + var actions = { "z": { param: true, @@ -83,8 +102,9 @@ var actions = { fn: function(editor, range, count, param) { editor.selection.selectWord(); editor.findNext(); + ensureScrollMargin(editor); var cursor = editor.selection.getCursor(); - var range = editor.session.getWordRange(cursor.row, cursor.column); + range = editor.session.getWordRange(cursor.row, cursor.column); editor.selection.setSelectionRange(range, true); } }, @@ -92,23 +112,32 @@ var actions = { fn: function(editor, range, count, param) { editor.selection.selectWord(); editor.findPrevious(); + ensureScrollMargin(editor); var cursor = editor.selection.getCursor(); - var range = editor.session.getWordRange(cursor.row, cursor.column); + range = editor.session.getWordRange(cursor.row, cursor.column); editor.selection.setSelectionRange(range, true); } }, "n": { fn: function(editor, range, count, param) { - editor.findNext(editor.getLastSearchOptions()); + var options = editor.getLastSearchOptions(); + options.backwards = false; + + editor.findNext(options); + + ensureScrollMargin(editor); editor.selection.clearSelection(); - //editor.navigateWordLeft(); } }, "shift-n": { fn: function(editor, range, count, param) { - editor.findPrevious(editor.getLastSearchOptions()); + var options = editor.getLastSearchOptions(); + options.backwards = true; + + editor.navigateWordLeft(); + editor.findPrevious(options); + ensureScrollMargin(editor); editor.selection.clearSelection(); - //editor.navigateWordLeft(); } }, "v": { @@ -231,9 +260,10 @@ var actions = { }, ".": { fn: function(editor, range, count, param) { - var previous = inputBuffer.previous; util.onInsertReplaySequence = inputBuffer.lastInsertCommands; - inputBuffer.exec(editor, previous.action, previous.param); + var previous = inputBuffer.previous; + if (previous) // If there is a previous action + inputBuffer.exec(editor, previous.action, previous.param); } } }; @@ -336,7 +366,7 @@ var inputBuffer = exports.inputBuffer = { var o = action.operator; var a = action.action; - if(o) { + if (o) { this.previous = { action: action, param: param @@ -489,12 +519,4 @@ var handleCursorMove = exports.onCursorMove = function(editor) { handleCursorMove.running = false; } }; - -function toggleCase(ch) { - if(ch.toUpperCase() === ch) - return ch.toLowerCase(); - else - return ch.toUpperCase(); -} - -}); \ No newline at end of file +}); diff --git a/lib/ace/keyboard/vim/keyboard.js b/lib/ace/keyboard/vim/keyboard.js index a51a5e7a..08b02714 100644 --- a/lib/ace/keyboard/vim/keyboard.js +++ b/lib/ace/keyboard/vim/keyboard.js @@ -85,4 +85,4 @@ var states = exports.states = { }; exports.handler = new StateHandler(states); -}); \ No newline at end of file +}); diff --git a/lib/ace/keyboard/vim/maps/motions.js b/lib/ace/keyboard/vim/maps/motions.js index 89b77a18..1c9ec02a 100644 --- a/lib/ace/keyboard/vim/maps/motions.js +++ b/lib/ace/keyboard/vim/maps/motions.js @@ -1,4 +1,4 @@ -"never use strict" +"use strict" define(function(require, exports, module) { @@ -114,6 +114,30 @@ module.exports = { } } }, + "shift-f": { + param: true, + nav: function(editor, range, count, param) { + count = parseInt(count, 10) || 1; + var ed = editor; + var cursor = ed.getCursorPosition(); + var column = util.getLeftNthChar(editor, cursor, param, count); + + if (typeof column === "number") { + ed.selection.clearSelection(); // Why does it select in the first place? + ed.moveCursorTo(cursor.row, cursor.column - column + 1); + } + }, + sel: function(editor, range, count, param) { + count = parseInt(count, 10) || 1; + var ed = editor; + var cursor = ed.getCursorPosition(); + var column = util.getLeftNthChar(editor, cursor, param, count); + + if (typeof column === "number") { + ed.moveCursorTo(cursor.row, cursor.column - column + 1); + } + } + }, "t": { param: true, nav: function(editor, range, count, param) { diff --git a/lib/ace/keyboard/vim/maps/util.js b/lib/ace/keyboard/vim/maps/util.js index 60e120cf..ae280aac 100644 --- a/lib/ace/keyboard/vim/maps/util.js +++ b/lib/ace/keyboard/vim/maps/util.js @@ -88,9 +88,9 @@ module.exports = { }, getLeftNthChar: function(editor, cursor, char, n) { var line = editor.getSession().getLine(cursor.row); - var matches = line.substr(0, cursor.column + 1).split(char); + var matches = line.substr(0, cursor.column).split(char); - return n < matches.length ? matches.slice(-1 * n).join(char).length + 1: 0; + return n < matches.length ? matches.slice(-1 * n).join(char).length + 2 : 0; }, toRealChar: function(char) { if (char.length === 1)