[incremental search] refining forward/backward behavior

This commit is contained in:
Robert Krahn 2013-03-10 09:25:40 -07:00
commit 1423893c3b
2 changed files with 80 additions and 57 deletions

View file

@ -31,7 +31,6 @@
define(function(require, exports, module) {
"use strict";
var lang = require("./lib/lang");
var oop = require("./lib/oop");
var Range = require("./range").Range;
var Search = require("./search").Search;
@ -65,46 +64,51 @@ oop.inherits(IncrementalSearch, Search);
var iSearch = this;
iSearch.activate = function(editor) {
iSearch.activate = function(editor, backwards) {
this.$editor = editor;
this.$startRange = this.$currentRange = editor.selection.toOrientedRange();
var pos = editor.getCursorPosition();
this.$startRange = this.$currentRange = Range.fromPoints(pos, pos);
// this.$startRange = this.$currentRange = editor.selection.toOrientedRange();
this.installKeyboardHandler(editor);
this.$options.needle = '';
this.$options.backwards = backwards;
}
this.deactivate = function() {
iSearch.deactivate = function(reset) {
this.cancelSearch(reset);
this.uninstallKeyboardHandler(this.$editor);
delete this.$editor;
}
iSearch.cancelSearch = function() {
var session = this.$editor.session,
sel = this.$editor.selection;
iSearch.cancelSearch = function(reset) {
var e = this.$editor;
this.$prevNeedle = this.$options.needle;
this.$options.needle = '';
session.highlight(null);
sel.setRange(this.$startRange);
e.session.highlight(null);
if (reset) e.selection.setRange(this.$startRange);
else e.selection.clearSelection();
return this.$currentRange = this.$startRange;
}
iSearch.highlightAndFindWithNeedle = function(dir, moveToNext, needleUpdateFunc) {
iSearch.highlightAndFindWithNeedle = function(moveToNext, needleUpdateFunc) {
if (!this.$editor) return null;
dir = dir || 'forward';
var session = this.$editor.session,
options = this.$options;
var options = this.$options;
if (needleUpdateFunc) options.needle = needleUpdateFunc(options.needle || '') || '';
if (options.needle.length === 0) {
return this.cancelSearch();
return this.cancelSearch(true);
}
if (dir === "forward") {
options.start = moveToNext ? this.$currentRange.end : this.$currentRange.start;
options.backwards = false;
} else {
options.start = moveToNext ? this.$currentRange.start : this.$currentRange.end;
options.backwards = true;
}
var range = this.find(session);
if (!range) range = this.$currentRange;
this.$editor.selection.setRange(range);
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
var session = this.$editor.session, range = this.$currentRange;
if (!options.backwards) {
options.start = moveToNext ? range.end : range.start;
} else {
options.start = moveToNext ? range.start : range.end;
}
range = this.find(session) || range;
// if (dir === "backward") range = Range.fromPoints(range.end, range.start);
this.$editor.selection.setRange(range, options.backwards);
this.$currentRange = range;
session.highlight(options.re);
@ -112,58 +116,77 @@ oop.inherits(IncrementalSearch, Search);
}
this.addChar = function(c) {
return this.highlightAndFindWithNeedle('forward', false, function(needle) {
return this.highlightAndFindWithNeedle(false, function(needle) {
return needle + c;
});
},
}
iSearch.removeChar = function(c) {
return this.highlightAndFindWithNeedle('forward', false, function(needle) {
return this.highlightAndFindWithNeedle(false, function(needle) {
return needle.length > 0 ? needle.substring(0, needle.length-1) : needle;
});
}
iSearch.forward = function() {
return this.highlightAndFindWithNeedle('forward', true);
iSearch.next = function(backwards) {
this.$options.backwards = backwards;
return this.highlightAndFindWithNeedle(true);
}
iSearch.backward = function() {
return this.highlightAndFindWithNeedle('backward', true);
}
this.installKeyboardHandler = function(editor) {
this.$origKeyboardHandlers = [].concat(editor.keyBinding.$handlers);
this.$origKeyboardHandlers.reverse().forEach(function(handler) {
editor.keyBinding.removeKeyboardHandler(handler);
});
iSearch.installKeyboardHandler = function(editor) {
// this.$origKeyboardHandlers = [].concat(editor.keyBinding.$handlers);
// this.$origKeyboardHandlers.reverse().forEach(function(handler) {
// editor.keyBinding.removeKeyboardHandler(handler);
// });
editor.keyBinding.addKeyboardHandler(this.$keyboardHandler);
}
this.uninstallKeyboardHandler = function(editor) {
iSearch.uninstallKeyboardHandler = function(editor) {
editor.keyBinding.removeKeyboardHandler(this.$keyboardHandler);
if (this.$origKeyboardHandlers) {
this.$origKeyboardHandlers.forEach(function(handler) {
editor.keyBinding.addKeyboardHandler(handler);
});
delete this.$origKeyboardHandlers;
}
// if (this.$origKeyboardHandlers) {
// this.$origKeyboardHandlers.forEach(function(handler) {
// editor.keyBinding.addKeyboardHandler(handler);
// });
// delete this.$origKeyboardHandlers;
// }
}
iSearch.message = function(msg) {
console.log(msg);
if (this.commandLine)
this.commandLine.setValue(msg, 1);
}
iSearch.handleKeyboard = function(data, hashId, key, keyCode) {
console.log("data: %s, hashId: %s, key: %s, keyCode: %s",
data, hashId, key, keyCode);
this.message("data: " + data + ", hashId: " + hashId + ", key: " + key + ", keyCode: " + keyCode);
var stop = {command: 'null'},
result = undefined;
console.log(this.$options.needle);
if (hashId === 0) {
if (key === 'backspace') this.removeChar();
else if (key.length === 1) this.addChar(key);
if (key === 'backspace') { this.removeChar(); result = stop; }
if (key === 'return') { this.deactivate(); this.message(''); return stop; }
if (key === 'esc') { this.deactivate(true); this.message(''); return stop; }
if (key.length === 1) { this.addChar(key); result = stop; }
}
if (hashId === 1) {
if (key === 's') this.forward();
if (key === 'r') this.backward();
if (key === 's' || key === 'r') {
if (this.$options.needle.length === 0)
this.$options.needle = this.$prevNeedle || '';
this.$options.backwards = key === 'r';
this.forward();
result = stop;
}
if (key === 'g') { this.deactivate(true); this.message(''); return stop; }
// let others handle but don't deactivate iSearch
// stop.passEvent = true;
// return stop;
}
console.log(this.$options.needle);
return {command: 'null'}
this.message('isearch: ' + this.$options.needle);
// this.deactivate();
return result;
}

View file

@ -105,20 +105,20 @@ module.exports = {
"test: forward / backward" : function() {
iSearch.activate(editor);
iSearch.addChar('1'); iSearch.addChar('2');
var range = iSearch.forward();
var range = iSearch.next();
testRanges("Range: [1/3] -> [1/5]", [range], "range");
range = iSearch.forward();
range = iSearch.next();
testRanges("Range: [1/3] -> [1/5]", [range], "range");
range = iSearch.backward();
range = iSearch.next(true); // backwards
testRanges("Range: [0/3] -> [0/5]", [range], "range");
},
"test: cancelSearch" : function() {
iSearch.activate(editor);
iSearch.addChar('1'); iSearch.addChar('2');
var range = iSearch.cancelSearch();
var range = iSearch.cancelSearch(true);
testRanges("Range: [0/0] -> [0/0]", [range], "range");
iSearch.addChar('1'); range = iSearch.addChar('2');