Skip to content
This repository has been archived by the owner on Sep 6, 2021. It is now read-only.

Commit

Permalink
Added new line and tab as replacement in case of regex search
Browse files Browse the repository at this point in the history
  • Loading branch information
ficristo committed Feb 13, 2016
1 parent 57e18b9 commit eaa8a6b
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/search/FindInFilesUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ define(function (require, exports, module) {
// Single-file scope: don't use any file filters
filter = null;
}

if (queryInfo.isRegexp) {
replaceText = FindUtils.parseString(replaceText);
}

searchAndShowResults(queryInfo, scope, filter, replaceText, candidateFilesPromise);
}
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/search/FindReplace.js
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ define(function (require, exports, module) {
// Delegate to Replace in Files.
FindInFilesUI.searchAndShowResults(state.queryInfo, editor.document.file, null, replaceText);
} else {
cm.replaceSelection(state.queryInfo.isRegexp ? FindUtils.parseDollars(replaceText, state.lastMatch) : replaceText);
cm.replaceSelection(state.queryInfo.isRegexp ? FindUtils.parseRegexp(replaceText, state.lastMatch) : replaceText);

updateResultSet(editor); // we updated the text, so result count & tickmarks must be refreshed

Expand Down
43 changes: 41 additions & 2 deletions src/search/FindUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,43 @@ define(function (require, exports, module) {
return replaceWith;
}

/**
* Parses a string and replace the \r, \n and \t sequences of characters
* with a character based on the regex meaning of these sequences.
* \n => Line Feed
* \r => Carriage Return
* \t => Tab
*
* @param {string} string - The string to parse.
* @return {string} The replaced text.
*/
function parseString(string) {
return string.replace(/\\(.)/g, function (match, ch) {
if (ch === "n") {
return "\n";
}
if (ch === "r") {
return "\r";
}
if (ch === "t") {
return "\t";
}
return ch;
});
}

/**
* Parses a string through parseDollars and parseString functions.
*
* @param {string} string - The string to parse.
* @param {Object} match - The match data from the regexp.
* @return {string} The replaced text.
*/
function parseRegexp(string, match) {
var str = parseDollars(string, match);
return parseString(str);
}

/**
* Does a set of replacements in a single document in memory.
* @param {!Document} doc The document to do the replacements in.
Expand All @@ -129,7 +166,7 @@ define(function (require, exports, module) {
doc.batchOperation(function () {
matchInfo.matches.reverse().forEach(function (match) {
if (match.isChecked) {
doc.replaceRange(isRegexp ? parseDollars(replaceText, match.result) : replaceText, match.start, match.end);
doc.replaceRange(isRegexp ? parseRegexp(replaceText, match.result) : replaceText, match.start, match.end);
}
});
});
Expand Down Expand Up @@ -161,7 +198,7 @@ define(function (require, exports, module) {
matchInfo.matches.forEach(function (match) {
if (match.isChecked) {
result.push(contents.slice(lastIndex, match.startOffset));
result.push(isRegexp ? parseDollars(replaceText, match.result) : replaceText);
result.push(isRegexp ? parseRegexp(replaceText, match.result) : replaceText);
lastIndex = match.endOffset;
}
});
Expand Down Expand Up @@ -523,6 +560,8 @@ define(function (require, exports, module) {
}

exports.parseDollars = parseDollars;
exports.parseString = parseString;
exports.parseRegexp = parseRegexp;
exports.hasCheckedMatches = hasCheckedMatches;
exports.performReplacements = performReplacements;
exports.labelForScope = labelForScope;
Expand Down
31 changes: 31 additions & 0 deletions test/spec/FindInFiles-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,37 @@ define(function (require, exports, module) {
});
});

it("should replace instances of a string in a project with escaped chars", function () {
openTestProjectCopy(defaultSourcePath);
doBasicTest({
queryInfo: {query: "bar"},
numMatches: 7,
replaceText: "\\r\\n\\t",
knownGoodFolder: "replace-escaped-chars"
});
});

it("should replace instances of a string in a project with escaped chars in regex mode", function () {
openTestProjectCopy(defaultSourcePath);
doBasicTest({
queryInfo: {query: "bar", isRegexp: true},
numMatches: 7,
replaceText: "\\\\r\\\\n\\\\t",
knownGoodFolder: "replace-escaped-chars"
});
});

it("should replace instances of a regexp in a project with unescaped chars in regex mode", function () {
openTestProjectCopy(defaultSourcePath, FileUtils.LINE_ENDINGS_LF);
doBasicTest({
queryInfo: {query: "\n", isRegexp: true},
numMatches: 51,
replaceText: "\\t\\r\\n",
knownGoodFolder: "replace-unescaped-chars",
lineEndings: FileUtils.LINE_ENDINGS_CRLF
});
});

it("should replace instances of a string in a project respecting CRLF line endings", function () {
openTestProjectCopy(defaultSourcePath, FileUtils.LINE_ENDINGS_CRLF);
doBasicTest({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
\r\n\t.txt file

This file should *not* show up in certain searches
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* foo.css */
body {
margin: 0;
}
h1, footer {
padding: 2px auto;
}
ul.foo {
list-style: none;
}
.\r\n\t {
font-size: large;
}
22 changes: 22 additions & 0 deletions test/spec/FindReplace-known-goods/replace-escaped-chars/foo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Foo</title>
<link rel="stylesheet" href="css/foo.css">
<script src="foo.js"></script>
</head>

<body>

<h1>Foo</h1>
<p>Intro to foo</p>
<ul class="foo">
<li>foo</li>
<li>\r\n\t</li>
<li>baz</li>
</ul>
<p class="\r\n\t">It's all about the \r\n\t</p>

</body>
</html>
13 changes: 13 additions & 0 deletions test/spec/FindReplace-known-goods/replace-escaped-chars/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* Test comment */
define(function (require, exports, module) {
var Foo = require("modules/Foo"),
\r\n\t = require("modules/\r\n\t"),
Baz = require("modules/Baz");

function callFoo() {

foo();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bar.txt file

This file should *not* show up in certain searches
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* foo.css */
body {
margin: 0;
}
h1, footer {
padding: 2px auto;
}
ul.foo {
list-style: none;
}
.bar {
font-size: large;
}
22 changes: 22 additions & 0 deletions test/spec/FindReplace-known-goods/replace-unescaped-chars/foo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Foo</title>
<link rel="stylesheet" href="css/foo.css">
<script src="foo.js"></script>
</head>

<body>

<h1>Foo</h1>
<p>Intro to foo</p>
<ul class="foo">
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
<p class="bar">It's all about the bar</p>

</body>
</html>
13 changes: 13 additions & 0 deletions test/spec/FindReplace-known-goods/replace-unescaped-chars/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* Test comment */
define(function (require, exports, module) {
var Foo = require("modules/Foo"),
Bar = require("modules/Bar"),
Baz = require("modules/Baz");

function callFoo() {

foo();

}

}
61 changes: 61 additions & 0 deletions test/spec/FindReplace-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,67 @@ define(function (require, exports, module) {
expect(/_modules\/Foo-Foo\$&/i.test(myEditor.getSelectedText())).toBe(true);
});
});

it("should replace a string with \\r\\n\\t chars", function () {
runs(function () {
twCommandManager.execute(Commands.CMD_REPLACE);
enterSearchText("Foo");
enterReplaceText("\\r\\n\\t");

var expectedMatch = {start: {line: LINE_FIRST_REQUIRE, ch: 8}, end: {line: LINE_FIRST_REQUIRE, ch: 11}};

expectSelection(expectedMatch);
expect(/Foo/.test(myEditor.getSelectedText())).toBe(true);

expect(tw$("#replace-yes").is(":enabled")).toBe(true);
tw$("#replace-yes").click();

myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: 8}, {line: LINE_FIRST_REQUIRE, ch: 14});
expect(myEditor.getSelectedText()).toEqual("\\r\\n\\t");
});
});

it("should replace a string with \\r\\n\\t chars in regex mode", function () {
runs(function () {
twCommandManager.execute(Commands.CMD_REPLACE);
toggleRegexp(true);
enterSearchText("Foo");
enterReplaceText("\\\\r\\\\n\\\\t");

var expectedMatch = {start: {line: LINE_FIRST_REQUIRE, ch: 8}, end: {line: LINE_FIRST_REQUIRE, ch: 11}};

expectSelection(expectedMatch);
expect(/Foo/.test(myEditor.getSelectedText())).toBe(true);

expect(tw$("#replace-yes").is(":enabled")).toBe(true);
tw$("#replace-yes").click();

myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: 8}, {line: LINE_FIRST_REQUIRE, ch: 14});
expect(myEditor.getSelectedText()).toEqual("\\r\\n\\t");
});
});

it("should replace a string with a new line and a tab in regex mode", function () {
runs(function () {
twCommandManager.execute(Commands.CMD_REPLACE);
toggleRegexp(true);
enterSearchText("Foo");
enterReplaceText("\\r\\n\\t");

var expectedMatch = {start: {line: LINE_FIRST_REQUIRE, ch: 8}, end: {line: LINE_FIRST_REQUIRE, ch: 11}};

expectSelection(expectedMatch);
expect(/Foo/.test(myEditor.getSelectedText())).toBe(true);

expect(tw$("#replace-yes").is(":enabled")).toBe(true);
tw$("#replace-yes").click();

myEditor.setSelection({line: LINE_FIRST_REQUIRE, ch: 4}, {line: LINE_FIRST_REQUIRE + 1, ch: 3});
// TODO: The test supposes \n line endings.
// Once this will change the code check below should be changed as well.
expect(myEditor.getSelectedText()).toEqual("var \n\t =");
});
});
});


Expand Down

0 comments on commit eaa8a6b

Please sign in to comment.