Skip to content

Commit 22130a1

Browse files
committed
perf(document): check sha256 on vim9 CursorHold
Check last checked changedtick, avoid transfer buffer
1 parent 317e12e commit 22130a1

File tree

5 files changed

+32
-12
lines changed

5 files changed

+32
-12
lines changed

autoload/coc/vim9.vim

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
vim9script
22
scriptencoding utf-8
33

4+
# Check if lines synchronized as expected
5+
export def Check_sha256(bufnr: number, expected: string): bool
6+
if !exists('*sha256')
7+
return true
8+
endif
9+
return getbufline(bufnr, 1, '$')->join("\n")->sha256() ==# expected
10+
enddef
11+
412
# From `coc#highlight#set(`:
513
# type HighlightItem = [hlGroup, lnum, colStart, colEnd, combine?, start_incl?, end_incl?]
614
# From `src/core/highlights.ts`:

src/__tests__/vim.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ describe('Buffer API', () => {
429429
called = true
430430
}
431431
}, null, disposables)
432-
Object.assign(doc, { lines: [''] })
432+
Object.assign(doc, { lines: [''], _changedtick: doc.changedtick + 1 })
433433
await events.fire('CursorHold', [buffer.id, [1, 1]])
434434
expect(called).toBe(true)
435435
expect(doc.getLines()).toEqual(['1', '2'])

src/core/documents.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,15 @@ export default class Documents implements Disposable {
8181
this._bufnr = bufnr
8282
await Promise.all(bufnrs.map(bufnr => this.createDocument(bufnr)))
8383
if (isVim) {
84+
const checkedTick: Map<number, number> = new Map()
8485
events.on('CursorHold', async bufnr => {
8586
let doc = this.getDocument(bufnr)
86-
if (doc && doc.attached) await doc.checkLines()
87+
if (doc && doc.attached && checkedTick.get(bufnr) != doc.changedtick) {
88+
let sha256 = doc.getSha256()
89+
let same = await nvim.callVim('coc#vim9#Check_sha256', [bufnr, sha256])
90+
checkedTick.set(bufnr, doc.changedtick)
91+
if (!same) await doc.fetchLines()
92+
}
8793
}, null, this.disposables)
8894
}
8995
events.on('BufDetach', this.onBufDetach, this, this.disposables)

src/model/document.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createLogger } from '../logger'
88
import { BufferOption, DidChangeTextDocumentParams, HighlightItem, HighlightItemOption, TextDocumentContentChange } from '../types'
99
import { isVim } from '../util/constants'
1010
import { diffLines, getTextEdit } from '../util/diff'
11-
import { disposeAll, getConditionValue, wait, waitNextTick } from '../util/index'
11+
import { disposeAll, getConditionValue, sha256, wait, waitNextTick } from '../util/index'
1212
import { isUrl } from '../util/is'
1313
import { debounce, path } from '../util/node'
1414
import { equals, toObject } from '../util/object'
@@ -17,7 +17,7 @@ import { Disposable, Emitter, Event } from '../util/protocol'
1717
import { byteIndex, byteLength, byteSlice, characterIndex, toText } from '../util/string'
1818
import { applyEdits, filterSortEdits, getPositionFromEdits, getStartLine, mergeTextEdits, TextChangeItem, toTextChanges } from '../util/textedit'
1919
import { Chars } from './chars'
20-
import { firstDiffLine, LinesTextDocument } from './textdocument'
20+
import { LinesTextDocument } from './textdocument'
2121
const logger = createLogger('document')
2222

2323
export type LastChangeType = 'insert' | 'change' | 'delete'
@@ -627,15 +627,16 @@ export default class Document {
627627
this._forceSync()
628628
}
629629

630-
public async checkLines(): Promise<void> {
630+
public getSha256(): string {
631+
return sha256(this.lines.join('\n'))
632+
}
633+
634+
public async fetchLines(): Promise<void> {
631635
let lines = await this.nvim.call('getbufline', [this.bufnr, 1, '$']) as ReadonlyArray<string>
632-
let diff = firstDiffLine(this.lines, lines)
633-
if (diff) {
634-
this.lines = lines
635-
fireLinesChanged(this.bufnr)
636-
this.fireContentChanges()
637-
logger.error(`Buffer ${this.bufnr} not synchronized on line ${diff[0]}\nExpected:${diff[2]}\nCurrent:${diff[1]}`)
638-
}
636+
this.lines = lines
637+
fireLinesChanged(this.bufnr)
638+
this.fireContentChanges()
639+
logger.error(`Buffer ${this.bufnr} not synchronized on vim9, consider send bug report!`)
639640
}
640641
}
641642

src/util/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
'use strict'
22
import type { CancellationToken } from 'vscode-languageserver-protocol'
3+
import { crypto } from './node'
34

45
export interface Disposable {
56
dispose(): void
67
}
78

9+
export function sha256(data: string): string {
10+
return crypto.createHash('sha256').update(data).digest('hex')
11+
}
12+
813
export function getConditionValue<T>(value: T, testValue: T): T {
914
return global.__TEST__ ? testValue : value
1015
}

0 commit comments

Comments
 (0)