Merge pull request #2226 from LivelyKernel/isearch-regexp-support

isearch regexp support
This commit is contained in:
Harutyun Amirjanyan 2014-11-06 10:15:53 +04:00
commit 989d0ac3fb
3 changed files with 80 additions and 4 deletions

View file

@ -162,6 +162,28 @@ exports.iSearchCommands = [{
exec: function(iSearch) { iSearch.$editor.execCommand('recenterTopBottom'); },
readOnly: true,
isIncrementalSearchCommand: true
}, {
name: 'selectAllMatches',
bindKey: 'Ctrl-space',
exec: function(iSearch) {
var ed = iSearch.$editor,
hl = ed.session.$isearchHighlight,
ranges = hl && hl.cache ? hl.cache
.reduce(function(ranges, ea) {
return ranges.concat(ea ? ea : []); }, []) : [];
iSearch.deactivate(false);
ranges.forEach(ed.selection.addRange.bind(ed.selection));
},
readOnly: true,
isIncrementalSearchCommand: true
}, {
name: 'searchAsRegExp',
bindKey: 'Alt-r',
exec: function(iSearch) {
iSearch.convertNeedleToRegExp();
},
readOnly: true,
isIncrementalSearchCommand: true
}];
function IncrementalSearchKeyboardHandler(iSearch) {

View file

@ -64,6 +64,34 @@ function IncrementalSearch() {
oop.inherits(IncrementalSearch, Search);
// regexp handling
function isRegExp(obj) {
return obj instanceof RegExp;
}
function regExpToObject(re) {
var string = String(re),
start = string.indexOf('/'),
flagStart = string.lastIndexOf('/');
return {
expression: string.slice(start+1, flagStart),
flags: string.slice(flagStart+1)
}
}
function stringToRegExp(string, flags) {
try {
return new RegExp(string, flags);
} catch (e) { return string; }
}
function objectToRegExp(obj) {
return stringToRegExp(obj.expression, obj.flags);
}
// iSearch class
;(function() {
this.activate = function(ed, backwards) {
@ -140,7 +168,9 @@ oop.inherits(IncrementalSearch, Search);
// try to find the next occurence and enable highlighting marker
options.start = this.$currentPos;
var session = this.$editor.session,
found = this.find(session);
found = this.find(session),
shouldSelect = this.$editor.emacsMark ?
!!this.$editor.emacsMark() : !this.$editor.selection.isEmpty();
if (found) {
if (options.backwards) found = Range.fromPoints(found.end, found.start);
this.$editor.moveCursorToPosition(found.end);
@ -156,13 +186,21 @@ oop.inherits(IncrementalSearch, Search);
this.addString = function(s) {
return this.highlightAndFindWithNeedle(false, function(needle) {
return needle + s;
if (!isRegExp(needle))
return needle + s;
var reObj = regExpToObject(needle);
reObj.expression += s;
return objectToRegExp(reObj);
});
}
this.removeChar = function(c) {
return this.highlightAndFindWithNeedle(false, function(needle) {
return needle.length > 0 ? needle.substring(0, needle.length-1) : needle;
if (!isRegExp(needle))
return needle.substring(0, needle.length-1);
var reObj = regExpToObject(needle);
reObj.expression = reObj.expression.substring(0, reObj.expression.length-1);
return objectToRegExp(reObj);
});
}
@ -189,6 +227,18 @@ oop.inherits(IncrementalSearch, Search);
this.addString(text);
}
this.convertNeedleToRegExp = function() {
return this.highlightAndFindWithNeedle(false, function(needle) {
return isRegExp(needle) ? needle : stringToRegExp(needle, 'ig');
});
}
this.convertNeedleToString = function() {
return this.highlightAndFindWithNeedle(false, function(needle) {
return isRegExp(needle) ? regExpToObject(needle).expression : needle;
});
}
this.statusMessage = function(found) {
var options = this.$options, msg = '';
msg += options.backwards ? 'reverse-' : '';

View file

@ -35,10 +35,12 @@ if (typeof process !== "undefined") {
define(function(require, exports, module) {
"use strict";
var emacs = require('./keyboard/emacs');
var EditSession = require("./edit_session").EditSession;
var Editor = require("./editor").Editor;
var MockRenderer = require("./test/mockrenderer").MockRenderer;
var Range = require("./range").Range;
var MultiSelect = require("./multi_select").MultiSelect;
var assert = require("./test/assertions");
var IncrementalSearch = require("./incremental_search").IncrementalSearch;
@ -69,6 +71,7 @@ module.exports = {
setUp: function() {
var session = new EditSession(["abc123", "xyz124"]);
editor = new Editor(new MockRenderer(), session);
new MultiSelect(editor);
iSearch = new IncrementalSearch();
},
@ -195,7 +198,8 @@ module.exports = {
editor.keyBinding.addKeyboardHandler(emacs.handler);
emacs.handler.commands.setMark.exec(editor);
iSearch.activate(editor);
iSearch.addString('1'); iSearch.addString('2');;
iSearch.addString('1'); iSearch.addString('2');
testRanges("Range: [0/0] -> [0/5]", [editor.getSelectionRange()], "sel range");
}