Skip to content

Commit d1d7333

Browse files
Merge remote-tracking branch 'origin/main' into main-overleaf
2 parents 29f7a87 + d0797ab commit d1d7333

File tree

6 files changed

+39
-16
lines changed

6 files changed

+39
-16
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## 6.5.6 (2024-02-07)
2+
3+
### Bug fixes
4+
5+
Make `highlightSelectionMatches` include whitespace in the selection in its matches.
6+
7+
Fix a bug that caused `SearchCursor` to return invalid ranges when matching astral chars that the the normalizer normalized to single-code-unit chars.
8+
9+
## 6.5.5 (2023-11-27)
10+
11+
### Bug fixes
12+
13+
Fix a bug that caused codes like `\n` to be unescaped in strings inserted via replace placeholders like `$&`.
14+
15+
Use the keybinding Mod-Alt-g for `gotoLine` to the search keymap, to make it usable for people whose keyboard layout uses Alt/Option-g to type some character.
16+
117
## 6.5.4 (2023-09-20)
218

319
### Bug fixes

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@codemirror/search",
3-
"version": "6.5.4",
3+
"version": "6.5.6",
44
"description": "Search functionality for the CodeMirror code editor",
55
"scripts": {
66
"test": "cm-runtests",

src/cursor.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class SearchCursor implements Iterator<{from: number, to: number}>{
7676
let norm = this.normalize(str)
7777
for (let i = 0, pos = start;; i++) {
7878
let code = norm.charCodeAt(i)
79-
let match = this.match(code, pos)
79+
let match = this.match(code, pos, this.bufferPos + this.bufferStart)
8080
if (i == norm.length - 1) {
8181
if (match) {
8282
this.value = match
@@ -89,13 +89,13 @@ export class SearchCursor implements Iterator<{from: number, to: number}>{
8989
}
9090
}
9191

92-
private match(code: number, pos: number) {
92+
private match(code: number, pos: number, end: number) {
9393
let match: null | {from: number, to: number} = null
9494
for (let i = 0; i < this.matches.length; i += 2) {
9595
let index = this.matches[i], keep = false
9696
if (this.query.charCodeAt(index) == code) {
9797
if (index == this.query.length - 1) {
98-
match = {from: this.matches[i + 1], to: pos + 1}
98+
match = {from: this.matches[i + 1], to: end}
9999
} else {
100100
this.matches[i]++
101101
keep = true
@@ -108,7 +108,7 @@ export class SearchCursor implements Iterator<{from: number, to: number}>{
108108
}
109109
if (this.query.charCodeAt(0) == code) {
110110
if (this.query.length == 1)
111-
match = {from: pos, to: pos + 1}
111+
match = {from: pos, to: end}
112112
else
113113
this.matches.push(1, pos)
114114
}

src/search.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,11 @@ export class StringQuery extends QueryType<SearchResult> {
215215

216216
nextMatch(state: EditorState, curFrom: number, curTo: number) {
217217
let cursor = stringCursor(this.spec, state, curTo, state.doc.length).nextOverlapping()
218-
if (cursor.done) cursor = stringCursor(this.spec, state, 0, curFrom).nextOverlapping()
219-
return cursor.done ? null : cursor.value
218+
if (cursor.done) {
219+
let end = Math.min(state.doc.length, curFrom + this.spec.unquoted.length)
220+
cursor = stringCursor(this.spec, state, 0, end).nextOverlapping()
221+
}
222+
return cursor.done || cursor.value.from == curFrom && cursor.value.to == curTo ? null : cursor.value
220223
}
221224

222225
// Searching in reverse is, rather than implementing an inverted search
@@ -233,8 +236,10 @@ export class StringQuery extends QueryType<SearchResult> {
233236
}
234237

235238
prevMatch(state: EditorState, curFrom: number, curTo: number) {
236-
return this.prevMatchInRange(state, 0, curFrom) ||
237-
this.prevMatchInRange(state, curTo, state.doc.length)
239+
let found = this.prevMatchInRange(state, 0, curFrom)
240+
if (!found)
241+
found = this.prevMatchInRange(state, Math.max(0, curTo - this.spec.unquoted.length), state.doc.length)
242+
return found && (found.from != curFrom || found.to != curTo) ? found : null
238243
}
239244

240245
getReplacement(_result: SearchResult) { return this.spec.unquote(this.spec.replace) }
@@ -590,17 +595,15 @@ export const closeSearchPanel: Command = view => {
590595
/// - Mod-f: [`openSearchPanel`](#search.openSearchPanel)
591596
/// - F3, Mod-g: [`findNext`](#search.findNext)
592597
/// - Shift-F3, Shift-Mod-g: [`findPrevious`](#search.findPrevious)
593-
/// - Alt-g: [`gotoLine`](#search.gotoLine)
598+
/// - Mod-Alt-g: [`gotoLine`](#search.gotoLine)
594599
/// - Mod-d: [`selectNextOccurrence`](#search.selectNextOccurrence)
595600
export const searchKeymap: readonly KeyBinding[] = [
596601
{key: "Mod-f", run: openSearchPanel, scope: "editor search-panel"},
597602
{key: "F3", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true},
598603
{key: "Mod-g", run: findNext, shift: findPrevious, scope: "editor search-panel", preventDefault: true},
599604
{key: "Escape", run: closeSearchPanel, scope: "editor search-panel"},
600605
{key: "Mod-Shift-l", run: selectSelectionMatches},
601-
// This keybinding causes issues with entering @ on certain keyboard layouts
602-
// https://github.com/overleaf/internal/issues/12119
603-
// {key: "Alt-g", run: gotoLine},
606+
{key: "Mod-Alt-g", run: gotoLine},
604607
{key: "Mod-d", run: selectNextOccurrence, preventDefault: true},
605608
]
606609

src/selection-match.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ const matchHighlighter = ViewPlugin.fromClass(class {
8787
if (conf.wholeWords) {
8888
query = state.sliceDoc(range.from, range.to) // TODO: allow and include leading/trailing space?
8989
check = state.charCategorizer(range.head)
90-
if (!(insideWordBoundaries(check, state, range.from, range.to)
91-
&& insideWord(check, state, range.from, range.to))) return Decoration.none
90+
if (!(insideWordBoundaries(check, state, range.from, range.to) &&
91+
insideWord(check, state, range.from, range.to))) return Decoration.none
9292
} else {
93-
query = state.sliceDoc(range.from, range.to).trim()
93+
query = state.sliceDoc(range.from, range.to)
9494
if (!query) return Decoration.none
9595
}
9696
}

test/test-cursor.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ describe("SearchCursor", () => {
6464
it("will not match partial normalized content", () => {
6565
testMatches(new SearchCursor(Text.of(["´"]), " "), [])
6666
})
67+
68+
it("produces the correct range for astral chars that get normalized to non-astral", () => {
69+
testMatches(new SearchCursor(Text.of(["𝜎"]), "𝜎"), [[0, 2]])
70+
})
6771
})
6872

6973
describe("RegExpCursor", () => {

0 commit comments

Comments
 (0)