diff --git a/lib/ace/commands/incremental_search_commands.js b/lib/ace/commands/incremental_search_commands.js index ebe979ca..8ef80303 100644 --- a/lib/ace/commands/incremental_search_commands.js +++ b/lib/ace/commands/incremental_search_commands.js @@ -94,14 +94,14 @@ exports.iSearchCommands = [{ }, { name: "extendSearchTerm", exec: function(iSearch, string) { - iSearch.addChar(string); + iSearch.addString(string); }, readOnly: true, isIncrementalSearchCommand: true }, { name: "extendSearchTermSpace", bindKey: "space", - exec: function(iSearch) { iSearch.addChar(' '); }, + exec: function(iSearch) { iSearch.addString(' '); }, readOnly: true, isIncrementalSearchCommand: true }, { @@ -134,6 +134,34 @@ exports.iSearchCommands = [{ }, readOnly: true, isIncrementalSearchCommand: true +}, { + name: "yankNextWord", + bindKey: "Ctrl-w", + exec: function(iSearch) { + var ed = iSearch.$editor, + range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorWordRight(); }), + string = ed.session.getTextRange(range); + iSearch.addString(string); + }, + readOnly: true, + isIncrementalSearchCommand: true +}, { + name: "yankNextChar", + bindKey: "Ctrl-Alt-y", + exec: function(iSearch) { + var ed = iSearch.$editor, + range = ed.selection.getRangeOfMovements(function(sel) { sel.moveCursorRight(); }), + string = ed.session.getTextRange(range); + iSearch.addString(string); + }, + readOnly: true, + isIncrementalSearchCommand: true +}, { + name: 'recenterTopBottom', + bindKey: 'Ctrl-l', + exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); }, + readOnly: true, + isIncrementalSearchCommand: true }]; function IncrementalSearchKeyboardHandler(iSearch) { @@ -163,6 +191,8 @@ oop.inherits(IncrementalSearchKeyboardHandler, HashHandler); var handleKeyboard$super = this.handleKeyboard; this.handleKeyboard = function(data, hashId, key, keyCode) { + if (((hashId === 1/*ctrl*/ || hashId === 8/*command*/) && key === 'v') + || (hashId === 1/*ctrl*/ && key === 'y')) return null; var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode); if (cmd.command) { return cmd; } if (hashId == -1) { diff --git a/lib/ace/incremental_search.js b/lib/ace/incremental_search.js index e6fa8928..88615006 100644 --- a/lib/ace/incremental_search.js +++ b/lib/ace/incremental_search.js @@ -72,6 +72,8 @@ oop.inherits(IncrementalSearch, Search); this.$options.needle = ''; this.$options.backwards = backwards; ed.keyBinding.addKeyboardHandler(this.$keyboardHandler); + // we need to completely intercept paste, just registering an event handler does not work + this.$originalEditorOnPaste = ed.onPaste; ed.onPaste = this.onPaste.bind(this); this.$mousedownHandler = ed.addEventListener('mousedown', this.onMouseDown.bind(this)); this.selectionFix(ed); this.statusMessage(true); @@ -79,11 +81,13 @@ oop.inherits(IncrementalSearch, Search); this.deactivate = function(reset) { this.cancelSearch(reset); - this.$editor.keyBinding.removeKeyboardHandler(this.$keyboardHandler); + var ed = this.$editor; + ed.keyBinding.removeKeyboardHandler(this.$keyboardHandler); if (this.$mousedownHandler) { - this.$editor.removeEventListener('mousedown', this.$mousedownHandler); + ed.removeEventListener('mousedown', this.$mousedownHandler); delete this.$mousedownHandler; } + ed.onPaste = this.$originalEditorOnPaste; this.message(''); } @@ -150,9 +154,9 @@ oop.inherits(IncrementalSearch, Search); return found; } - this.addChar = function(c) { + this.addString = function(s) { return this.highlightAndFindWithNeedle(false, function(needle) { - return needle + c; + return needle + s; }); } @@ -181,6 +185,10 @@ oop.inherits(IncrementalSearch, Search); return true; } + this.onPaste = function(text) { + this.addString(text); + } + this.statusMessage = function(found) { var options = this.$options, msg = ''; msg += options.backwards ? 'reverse-' : ''; diff --git a/lib/ace/incremental_search_test.js b/lib/ace/incremental_search_test.js index c351d8e2..262e09a7 100644 --- a/lib/ace/incremental_search_test.js +++ b/lib/ace/incremental_search_test.js @@ -95,17 +95,17 @@ module.exports = { "test: find simple text incrementally" : function() { iSearch.activate(editor); - var range = iSearch.addChar('1'), // "1" + var range = iSearch.addString('1'), // "1" highlightRanges = callHighlighterUpdate(editor.session); testRanges("Range: [0/3] -> [0/4]", [range], "range"); testRanges("Range: [0/3] -> [0/4],Range: [1/3] -> [1/4]", highlightRanges, "highlight"); - range = iSearch.addChar('2'); // "12" + range = iSearch.addString('2'); // "12" highlightRanges = callHighlighterUpdate(editor.session); testRanges("Range: [0/3] -> [0/5]", [range], "range"); testRanges("Range: [0/3] -> [0/5],Range: [1/3] -> [1/5]", highlightRanges, "highlight"); - range = iSearch.addChar('3'); // "123" + range = iSearch.addString('3'); // "123" highlightRanges = callHighlighterUpdate(editor.session); testRanges("Range: [0/3] -> [0/6]", [range], "range"); testRanges("Range: [0/3] -> [0/6]", highlightRanges, "highlight"); @@ -118,7 +118,7 @@ module.exports = { "test: forward / backward" : function() { iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2'); + iSearch.addString('1'); iSearch.addString('2'); var range = iSearch.next(); testRanges("Range: [1/3] -> [1/5]", [range], "range"); @@ -131,18 +131,18 @@ module.exports = { "test: cancelSearch" : function() { iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2'); + iSearch.addString('1'); iSearch.addString('2'); var range = iSearch.cancelSearch(true); testRanges("Range: [0/0] -> [0/0]", [range], "range"); - iSearch.addChar('1'); range = iSearch.addChar('2'); + iSearch.addString('1'); range = iSearch.addString('2'); testRanges("Range: [0/3] -> [0/5]", [range], "range"); }, "test: failing search keeps pos" : function() { iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2'); - var range = iSearch.addChar('x'); + iSearch.addString('1'); iSearch.addString('2'); + var range = iSearch.addString('x'); testRanges("", [range], "range"); assert.position(editor.getCursorPosition(), 0, 5); }, @@ -150,14 +150,14 @@ module.exports = { "test: backwards search" : function() { editor.moveCursorTo(1,0); iSearch.activate(editor, true); - iSearch.addChar('1'); var range = iSearch.addChar('2');; + iSearch.addString('1'); var range = iSearch.addString('2');; testRanges("Range: [0/5] -> [0/3]", [range], "range"); assert.position(editor.getCursorPosition(), 0, 3); }, "test: forwards then backwards, same result, reoriented range" : function() { iSearch.activate(editor); - iSearch.addChar('1'); var range = iSearch.addChar('2');; + iSearch.addString('1'); var range = iSearch.addString('2');; testRanges("Range: [0/3] -> [0/5]", [range], "range"); assert.position(editor.getCursorPosition(), 0, 5); @@ -168,7 +168,7 @@ module.exports = { "test: reuse prev search via option" : function() { iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2');; + iSearch.addString('1'); iSearch.addString('2');; assert.position(editor.getCursorPosition(), 0, 5); iSearch.deactivate(); @@ -179,14 +179,14 @@ module.exports = { "test: don't extend selection range if selection is empty" : function() { iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2');; + iSearch.addString('1'); iSearch.addString('2');; testRanges("Range: [0/5] -> [0/5]", [editor.getSelectionRange()], "sel range"); }, "test: extend selection range if selection exists" : function() { iSearch.activate(editor); editor.selection.selectTo(0, 1); - iSearch.addChar('1'); iSearch.addChar('2');; + iSearch.addString('1'); iSearch.addString('2');; testRanges("Range: [0/0] -> [0/5]", [editor.getSelectionRange()], "sel range"); }, @@ -195,7 +195,7 @@ module.exports = { editor.keyBinding.addKeyboardHandler(emacs.handler); emacs.handler.commands.setMark.exec(editor); iSearch.activate(editor); - iSearch.addChar('1'); iSearch.addChar('2');; + iSearch.addString('1'); iSearch.addString('2');; testRanges("Range: [0/0] -> [0/5]", [editor.getSelectionRange()], "sel range"); } diff --git a/lib/ace/keyboard/emacs.js b/lib/ace/keyboard/emacs.js index 7e855959..f1adb9ef 100644 --- a/lib/ace/keyboard/emacs.js +++ b/lib/ace/keyboard/emacs.js @@ -219,6 +219,10 @@ exports.handler.bindKey = function(key, command) { }; exports.handler.handleKeyboard = function(data, hashId, key, keyCode) { + // if keyCode == -1 a non-printable key was pressed, such as just + // control. Handling those is currently not supported in this handler + if (keyCode === -1) return undefined; + var editor = data.editor; // insertstring data.count times if (hashId == -1) { diff --git a/lib/ace/occur.js b/lib/ace/occur.js index 385bc76a..d3522ee3 100644 --- a/lib/ace/occur.js +++ b/lib/ace/occur.js @@ -112,12 +112,15 @@ oop.inherits(Occur, Search); occurSession.$occur = this; occurSession.$occurMatchingLines = found; editor.setSession(occurSession); + this.$useEmacsStyleLineStart = this.$originalSession.$useEmacsStyleLineStart; + occurSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart; this.highlight(occurSession, options.re); occurSession._emit('changeBackMarker'); } this.displayOriginalContent = function(editor) { editor.setSession(this.$originalSession); + this.$originalSession.$useEmacsStyleLineStart = this.$useEmacsStyleLineStart; } /** diff --git a/lib/ace/selection.js b/lib/ace/selection.js index 712021ad..403b1e76 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -889,6 +889,27 @@ var Selection = function(session) { return range; } + /** + * Saves the current cursor position and calls `func` that can change the cursor + * postion. The result is the range of the starting and eventual cursor position. + * Will reset the cursor position. + * @param {Function} The callback that should change the cursor position + * @returns {Range} + * + **/ + this.getRangeOfMovements = function(func) { + var start = this.getCursor(); + try { + func.call(null, this); + var end = this.getCursor(); + return Range.fromPoints(start,end); + } catch(e) { + return Range.fromPoints(start,start); + } finally { + this.moveCursorToPosition(start); + } + } + this.toJSON = function() { if (this.rangeCount) { var data = this.ranges.map(function(r) {