-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfind.js
118 lines (117 loc) · 3.32 KB
/
find.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function find(editor, {
target,
replacement = false,
fromRow = 0,
fromCol = 0,
caseSensitive = false,
regExp = false,
direction = 1
}, repeat = true) {
const normalizeChar = caseSensitive ? ch => { return ch; } : ch => { return ((typeof ch) === 'string') ? ch.toLowerCase() : ch; };
if ((fromRow === 0) && (fromCol === 0)) {
repeat = false;
}
if (direction === 1) {
const expression = regExp && new RegExp(target.join(''), caseSensitive ? '' : 'i');
for (let row = fromRow; (row < editor.chars.length); row++) {
const editorChars = editor.chars[row];
if (regExp) {
const s = editorChars.slice(fromCol).join('');
const indexOf = s.search(expression);
if (indexOf >= 0) {
return replaceAndOrMove(editorChars, row, indexOf);
}
} else {
// TODO pick up with replacement logic here
for (let col = fromCol; (col < editorChars.length); col++) {
let j;
for (j = 0; (j < target.length); j++) {
if (normalizeChar(editorChars[col + j]) !== normalizeChar(target[j])) {
break;
}
}
if (j === target.length) {
return replaceAndOrMove(editorChars, row, col);
}
}
}
fromCol = 0;
}
if (repeat) {
return find(editor, {
target,
replacement,
fromRow: 0,
fromCol: 0,
caseSensitive,
regExp,
direction
}, false);
}
} else {
const expression = regExp && new RegExp(target.join(''), 'g' + (caseSensitive ? '' : 'i'));
for (let row = fromRow; (row >= 0); row--) {
const editorChars = editor.chars[row];
if (fromCol === false) {
fromCol = editorChars.length - 1;
}
if (regExp) {
const s = editorChars.slice(0, fromCol).join('');
const matches = s.matchAll(expression);
const [match] = matches;
if (match) {
const indexOf = match.index;
return replaceAndOrMove(editorChars, row, indexOf);
}
} else {
for (let col = fromCol; (col >= 0); col--) {
let j;
for (j = 0; (j < target.length); j++) {
if (col - j < 0) {
break;
}
if (normalizeChar(editorChars[col - j]) !== normalizeChar(target[target.length - j - 1])) {
break;
}
}
if (j === target.length) {
return replaceAndOrMove(editorChars, row, col - target.length + 1);
}
}
}
fromCol = false;
}
if (repeat) {
return find(editor, {
target,
replacement,
fromRow: editor.chars.length - 1,
fromCol: editor.chars[editor.chars.length - 1].length - 1,
caseSensitive,
regExp,
direction
}, false);
}
}
return false;
function replaceAndOrMove(chars, row, col) {
if (replacement) {
editor.undos.push({
action: 'find',
row,
col,
target,
replacement,
direction
});
}
if (replacement !== false) {
chars.splice(col, target.length, ...replacement);
}
let newCol = (direction === 1) ? ((replacement === false) ? col : col + replacement.length)
: col;
editor.moveTo(row, newCol);
return true;
}
}
export default find;