mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Only rebuild changed line indentation decorations (#16092)
GitOrigin-RevId: 13855598e2cfc06d2ea2357d1c71875993a106a9
This commit is contained in:
parent
8cb76ce40b
commit
c4b05f7a73
1 changed files with 67 additions and 6 deletions
|
@ -78,12 +78,14 @@ export const lineWrappingIndentation = (visual: boolean) => {
|
|||
update(update: ViewUpdate) {
|
||||
const maxIndent = view.state.field(field)
|
||||
|
||||
if (
|
||||
maxIndent !== previousMaxIndent ||
|
||||
update.geometryChanged ||
|
||||
update.viewportChanged
|
||||
) {
|
||||
if (maxIndent !== previousMaxIndent) {
|
||||
value.decorations = buildDecorations(view, maxIndent)
|
||||
} else if (update.geometryChanged || update.viewportChanged) {
|
||||
value.decorations = updateDecorations(
|
||||
value.decorations,
|
||||
update,
|
||||
maxIndent
|
||||
)
|
||||
}
|
||||
|
||||
previousMaxIndent = maxIndent
|
||||
|
@ -111,7 +113,6 @@ export const buildDecorations = (view: EditorView, maxIndent: number) => {
|
|||
let from = 0
|
||||
|
||||
for (const line of doc.iterLines()) {
|
||||
// const indent = line.match(/^(\s*)/)[1].length
|
||||
const indent = calculateIndent(line, tabSize, maxIndent)
|
||||
|
||||
if (indent) {
|
||||
|
@ -124,6 +125,66 @@ export const buildDecorations = (view: EditorView, maxIndent: number) => {
|
|||
return Decoration.set(decorations)
|
||||
}
|
||||
|
||||
export const updateDecorations = (
|
||||
decorations: DecorationSet,
|
||||
update: ViewUpdate,
|
||||
maxIndent: number
|
||||
) => {
|
||||
const add: Range<Decoration>[] = []
|
||||
|
||||
const { doc, tabSize } = update.state
|
||||
|
||||
const changedLinesFrom = new Set()
|
||||
|
||||
let filterFrom = doc.length
|
||||
let filterTo = 0
|
||||
|
||||
update.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
|
||||
// remove changed lines
|
||||
const fromALineNumber = doc.lineAt(fromA).number
|
||||
const toALineNumber = doc.lineAt(toA).number
|
||||
|
||||
for (
|
||||
let lineNumber = fromALineNumber;
|
||||
lineNumber <= toALineNumber;
|
||||
lineNumber++
|
||||
) {
|
||||
const line = doc.line(lineNumber)
|
||||
changedLinesFrom.add(line.from)
|
||||
filterFrom = Math.min(line.from, filterFrom)
|
||||
filterTo = Math.max(line.from, filterTo)
|
||||
}
|
||||
|
||||
// add changed lines
|
||||
const fromBLineNumber = doc.lineAt(fromB).number
|
||||
const toBLineNumber = doc.lineAt(toB).number
|
||||
|
||||
for (
|
||||
let lineNumber = fromBLineNumber;
|
||||
lineNumber <= toBLineNumber;
|
||||
lineNumber++
|
||||
) {
|
||||
const line = doc.line(lineNumber)
|
||||
const indent = calculateIndent(line.text, tabSize, maxIndent)
|
||||
|
||||
if (indent) {
|
||||
add.push(lineIndentDecoration(indent).range(line.from))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return decorations
|
||||
.update({
|
||||
filter(from) {
|
||||
return !changedLinesFrom.has(from)
|
||||
},
|
||||
filterFrom,
|
||||
filterTo,
|
||||
})
|
||||
.map(update.changes)
|
||||
.update({ add })
|
||||
}
|
||||
|
||||
const lineIndentDecoration = (indent: number) =>
|
||||
Decoration.line({
|
||||
attributes: {
|
||||
|
|
Loading…
Reference in a new issue