1
0
Fork 0
mirror of synced 2024-06-26 02:31:09 -04:00
ultimate-vim/sources_non_forked/coc.nvim/src/model/progress.ts
2022-07-20 13:20:15 +08:00

70 lines
2.4 KiB
TypeScript

'use strict'
import { Neovim } from '@chemzqm/neovim'
import Notification, { NotificationPreferences } from './notification'
import { CancellationToken, CancellationTokenSource, Event, Emitter } from 'vscode-languageserver-protocol'
import events from '../events'
const logger = require('../util/logger')('model-progress')
export interface Progress {
report(value: { message?: string; increment?: number }): void
}
export interface ProgressOptions<R> {
title?: string
cancellable?: boolean
task: (progress: Progress, token: CancellationToken) => Thenable<R>
}
export default class ProgressNotification<R> extends Notification {
private tokenSource: CancellationTokenSource
private readonly _onDidFinish = new Emitter<R>()
public readonly onDidFinish: Event<R> = this._onDidFinish.event
constructor(nvim: Neovim, private option: ProgressOptions<R>) {
super(nvim, {
kind: 'progress',
title: option.title,
buttons: option.cancellable ? [{ index: 1, text: 'Cancel' }] : undefined
}, false)
this.disposables.push(this._onDidFinish)
events.on('BufWinLeave', bufnr => {
if (bufnr == this.bufnr) {
if (this.tokenSource) this.tokenSource.cancel()
this._onDidFinish.fire(undefined)
this.dispose()
}
}, null, this.disposables)
}
public async show(preferences: Partial<NotificationPreferences>): Promise<void> {
let { task } = this.option
let tokenSource = this.tokenSource = new CancellationTokenSource()
this.disposables.push(tokenSource)
let total = 0
if (this.config.buttons || !preferences.disabled) {
await super.show(preferences)
} else {
logger.warn(`progress window disabled by "notification.disabledProgressSources"`)
}
task({
report: p => {
if (!this.winid) return
let { nvim } = this
if (p.increment) {
total += p.increment
nvim.call('coc#window#set_var', [this.winid, 'percent', `${total}%`], true)
}
if (p.message) nvim.call('coc#window#set_var', [this.winid, 'message', p.message.replace(/\r?\n/g, ' ')], true)
}
}, tokenSource.token).then(res => {
if (this._disposed) return
this._onDidFinish.fire(res)
this.dispose()
}, err => {
this.nvim.echoError(err)
if (this._disposed) return
this._onDidFinish.fire(undefined)
this.dispose()
})
}
}