use vim to run watchBuild
This commit is contained in:
parent
845812f3b3
commit
898bf1585f
3 changed files with 104 additions and 90 deletions
|
@ -5,7 +5,7 @@
|
|||
"main": "lib/index.js",
|
||||
"publisher": "chemzqm",
|
||||
"engines": {
|
||||
"coc": "^0.0.35"
|
||||
"coc": "^0.0.65"
|
||||
},
|
||||
"keywords": [
|
||||
"coc.nvim",
|
||||
|
@ -446,7 +446,7 @@
|
|||
"@types/fast-diff": "^1.2.0",
|
||||
"@types/find-up": "^2.1.1",
|
||||
"@types/node": "^11.13.0",
|
||||
"coc.nvim": "0.0.62",
|
||||
"coc.nvim": "^0.0.65",
|
||||
"rimraf": "^2.6.3",
|
||||
"tslint": "^5.15.0"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ChildProcess, spawn } from 'child_process'
|
||||
import { disposeAll, StatusBarItem, workspace } from 'coc.nvim'
|
||||
import { disposeAll, StatusBarItem, workspace, TaskOptions } from 'coc.nvim'
|
||||
import { Command, CommandManager } from 'coc.nvim/lib/commands'
|
||||
import findUp from 'find-up'
|
||||
import fs from 'fs'
|
||||
|
@ -9,6 +9,7 @@ import { Disposable, Location } from 'vscode-languageserver-protocol'
|
|||
import Uri from 'vscode-uri'
|
||||
import which from 'which'
|
||||
import { resolveRoot } from '../utils/fs'
|
||||
import Task from 'coc.nvim/lib/model/task'
|
||||
|
||||
const TSC = './node_modules/.bin/tsc'
|
||||
const countRegex = /Found\s+(\d+)\s+error/
|
||||
|
@ -27,20 +28,64 @@ enum TscStatus {
|
|||
ERROR,
|
||||
}
|
||||
|
||||
class WatchCommand implements Command {
|
||||
public readonly id: string = 'tsserver.watchBuild'
|
||||
export default class WatchProject implements Disposable {
|
||||
private disposables: Disposable[] = []
|
||||
public static readonly id: string = 'tsserver.watchBuild'
|
||||
public static readonly startTexts: string[] = ['Starting compilation in watch mode', 'Starting incremental compilation']
|
||||
private statusItem: StatusBarItem
|
||||
private isRunning = false
|
||||
private process: ChildProcess
|
||||
private task: Task
|
||||
private options: TaskOptions
|
||||
|
||||
constructor() {
|
||||
public constructor(
|
||||
commandManager: CommandManager
|
||||
) {
|
||||
this.statusItem = workspace.createStatusBarItem(1, { progress: true })
|
||||
let task = this.task = workspace.createTask('TSC')
|
||||
this.options = this.getOptions()
|
||||
this.disposables.push(commandManager.registerCommand(WatchProject.id, async () => {
|
||||
await this.start(this.options)
|
||||
}))
|
||||
task.onExit(code => {
|
||||
if (code != 0) {
|
||||
workspace.showMessage(`TSC exit with code ${code}`, 'warning')
|
||||
}
|
||||
this.onStop()
|
||||
})
|
||||
task.onStdout(lines => {
|
||||
for (let line of lines) {
|
||||
this.onLine(line)
|
||||
}
|
||||
})
|
||||
task.onStderr(lines => {
|
||||
workspace.showMessage(`TSC error: ` + lines.join('\n'), 'error')
|
||||
})
|
||||
this.disposables.push(Disposable.create(() => {
|
||||
task.dispose()
|
||||
}))
|
||||
this.check().catch(_e => {
|
||||
// noop
|
||||
})
|
||||
}
|
||||
|
||||
private async check(): Promise<void> {
|
||||
let running = await this.task.running
|
||||
if (running) {
|
||||
this.statusItem.isProgress = false
|
||||
this.statusItem.text = '?'
|
||||
this.statusItem.show()
|
||||
} else {
|
||||
this.onStop()
|
||||
}
|
||||
}
|
||||
|
||||
private async start(options: TaskOptions): Promise<void> {
|
||||
await this.task.start(options)
|
||||
}
|
||||
|
||||
private onStop(): void {
|
||||
let { nvim } = workspace
|
||||
this.isRunning = false
|
||||
nvim.setVar('Tsc_running', 0, true)
|
||||
this.statusItem.hide()
|
||||
}
|
||||
|
||||
|
@ -51,60 +96,43 @@ class WatchCommand implements Command {
|
|||
workspace.nvim.call('setqflist', [[], 'r'], true)
|
||||
}
|
||||
|
||||
private async start(cmd: string, args: string[], cwd: string): Promise<void> {
|
||||
if (this.isRunning) {
|
||||
this.process.kill()
|
||||
await wait(200)
|
||||
private onLine(line: string): void {
|
||||
if (countRegex.test(line)) {
|
||||
let ms = line.match(countRegex)
|
||||
this.statusItem.text = ms[1] == '0' ? '✓' : '✗'
|
||||
this.statusItem.isProgress = false
|
||||
} else if (WatchProject.startTexts.findIndex(s => line.indexOf(s) !== -1) != -1) {
|
||||
this.onStart()
|
||||
} else {
|
||||
let ms = line.match(errorRegex)
|
||||
if (!ms) return
|
||||
let fullpath = path.join(this.options.cwd, ms[1])
|
||||
let uri = Uri.file(fullpath).toString()
|
||||
let doc = workspace.getDocument(uri)
|
||||
let bufnr = doc ? doc.bufnr : null
|
||||
let item = {
|
||||
filename: fullpath,
|
||||
lnum: Number(ms[2]),
|
||||
col: Number(ms[3]),
|
||||
text: `[tsc ${ms[5]}] ${ms[6]}`,
|
||||
type: /error/i.test(ms[4]) ? 'E' : 'W'
|
||||
} as any
|
||||
if (bufnr) item.bufnr = bufnr
|
||||
workspace.nvim.call('setqflist', [[item], 'a'])
|
||||
}
|
||||
this.isRunning = true
|
||||
workspace.nvim.setVar('Tsc_running', 1, true)
|
||||
this.process = spawn(cmd, args, { cwd })
|
||||
this.process.on('error', e => {
|
||||
workspace.showMessage(e.message, 'error')
|
||||
})
|
||||
const rl = readline.createInterface(this.process.stdout)
|
||||
this.process.on('exit', () => {
|
||||
this.onStop()
|
||||
rl.close()
|
||||
})
|
||||
this.process.stderr.on('data', chunk => {
|
||||
workspace.showMessage(chunk.toString('utf8'), 'error')
|
||||
})
|
||||
const startTexts = ['Starting compilation in watch mode', 'Starting incremental compilation']
|
||||
rl.on('line', line => {
|
||||
if (countRegex.test(line)) {
|
||||
let ms = line.match(countRegex)
|
||||
this.statusItem.text = ms[1] == '0' ? '✓' : '✗'
|
||||
this.statusItem.isProgress = false
|
||||
} else if (startTexts.findIndex(s => line.indexOf(s) !== -1) != -1) {
|
||||
this.onStart()
|
||||
} else {
|
||||
let ms = line.match(errorRegex)
|
||||
if (!ms) return
|
||||
let fullpath = path.join(cwd, ms[1])
|
||||
let uri = Uri.file(fullpath).toString()
|
||||
let doc = workspace.getDocument(uri)
|
||||
let bufnr = doc ? doc.bufnr : null
|
||||
let item = {
|
||||
filename: fullpath,
|
||||
lnum: Number(ms[2]),
|
||||
col: Number(ms[3]),
|
||||
text: `[tsc ${ms[5]}] ${ms[6]}`,
|
||||
type: /error/i.test(ms[4]) ? 'E' : 'W'
|
||||
} as any
|
||||
if (bufnr) item.bufnr = bufnr
|
||||
workspace.nvim.call('setqflist', [[item], 'a'])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public async execute(): Promise<void> {
|
||||
public getOptions(): TaskOptions {
|
||||
let docs = workspace.documents
|
||||
let idx = docs.findIndex(doc => doc.uri.indexOf(TSC) !== -1)
|
||||
if (idx !== -1) return
|
||||
let document = await workspace.document
|
||||
let fsPath = Uri.parse(document.uri).fsPath
|
||||
let cwd = path.dirname(fsPath)
|
||||
let doc = workspace.getDocument(workspace.bufnr)
|
||||
let cwd: string
|
||||
if (doc && doc.schema == 'file') {
|
||||
cwd = path.dirname(Uri.parse(doc.uri).fsPath)
|
||||
} else {
|
||||
cwd = workspace.cwd
|
||||
}
|
||||
let res = findUp.sync(['node_modules'], { cwd })
|
||||
let cmd: string
|
||||
let root: string
|
||||
|
@ -130,26 +158,11 @@ class WatchCommand implements Command {
|
|||
return
|
||||
}
|
||||
let configPath = path.relative(root, path.join(configRoot, 'tsconfig.json'))
|
||||
this.start(cmd, ['-p', configPath, '--watch', 'true', '--pretty', 'false'], root)
|
||||
}
|
||||
}
|
||||
|
||||
export default class WatchProject implements Disposable {
|
||||
private disposables: Disposable[] = []
|
||||
|
||||
public constructor(
|
||||
commandManager: CommandManager
|
||||
) {
|
||||
let cmd = new WatchCommand()
|
||||
commandManager.register(cmd)
|
||||
let { nvim } = workspace
|
||||
nvim.getVar('Tsc_running').then(running => {
|
||||
if (running) {
|
||||
cmd.execute().catch(e => {
|
||||
workspace.showMessage('TSC:' + e.message, 'error')
|
||||
})
|
||||
}
|
||||
})
|
||||
return {
|
||||
cmd,
|
||||
args: ['-p', configPath, '--watch', 'true', '--pretty', 'false'],
|
||||
cwd: root
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
|
|
29
yarn.lock
29
yarn.lock
|
@ -85,6 +85,11 @@ balanced-match@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
binary-search@1.3.5:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.5.tgz#479ad009589e0273cf54e5d74ab1546c489078ce"
|
||||
integrity sha512-RHFP0AdU6KAB0CCZsRMU2CJTk2EpL8GLURT+4gilpjr1f/7M91FgUMnXuQLmf3OKLet34gjuNFwO7e4agdX5pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
|
@ -125,22 +130,23 @@ chalk@^2.3.0:
|
|||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
coc.nvim@0.0.62:
|
||||
version "0.0.62"
|
||||
resolved "https://registry.yarnpkg.com/coc.nvim/-/coc.nvim-0.0.62.tgz#49557e9bc95ce3627df66914b787be982374d986"
|
||||
integrity sha512-DlaLXlRELXwu39DkXvZ+kfZdKImLiq9mRkFOnzzwMD/xftN/Ytj2UlEndMr9gl2hmM5Z6VzZC1wvn6JYU9Zj7A==
|
||||
coc.nvim@^0.0.65:
|
||||
version "0.0.65"
|
||||
resolved "https://registry.yarnpkg.com/coc.nvim/-/coc.nvim-0.0.65.tgz#6c802a30beb63b02a71f2bdd07db50542c77a46f"
|
||||
integrity sha512-CPvc4g0PJMlo/0A8kXvIAOWGqaDJKOpe6OvMhY4SJhWZRL03AExjByiLLGcBD+tOONBJNyDpPBnfMUqkOD0Vmg==
|
||||
dependencies:
|
||||
"@chemzqm/neovim" "4.4.1"
|
||||
binary-search "1.3.5"
|
||||
debounce "^1.2.0"
|
||||
fast-diff "^1.2.0"
|
||||
fb-watchman "^2.0.0"
|
||||
find-up "^3.0.0"
|
||||
glob "^7.1.3"
|
||||
isuri "^2.0.3"
|
||||
jsonc-parser "^2.0.3"
|
||||
log4js "^4.0.2"
|
||||
jsonc-parser "^2.1.0"
|
||||
log4js "^4.1.0"
|
||||
minimatch "^3.0.4"
|
||||
semver "^5.6.0"
|
||||
semver "^6.0.0"
|
||||
tslib "^1.9.3"
|
||||
uuid "^3.3.2"
|
||||
vscode-languageserver-protocol "^3.15.0-next.1"
|
||||
|
@ -339,7 +345,7 @@ js-yaml@^3.13.0:
|
|||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
jsonc-parser@^2.0.3:
|
||||
jsonc-parser@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.1.0.tgz#eb0d0c7a3c33048524ce3574c57c7278fb2f1bf3"
|
||||
integrity sha512-n9GrT8rrr2fhvBbANa1g+xFmgGK5X91KFeDwlKQ3+SJfmH5+tKv/M/kahx/TXOMflfWHKGKqKyfHQaLKTNzJ6w==
|
||||
|
@ -364,7 +370,7 @@ lodash@^4.17.10, lodash@^4.17.11:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
||||
|
||||
log4js@^4.0.2:
|
||||
log4js@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/log4js/-/log4js-4.1.0.tgz#57983c6a443546a8c8607e9cb045d2a117c27644"
|
||||
integrity sha512-eDa+zZPeVEeK6QGJAePyXM6pg4P3n3TO5rX9iZMVY48JshsTyLJZLIL5HipI1kQ2qLsSyOpUqNND/C5H4WhhiA==
|
||||
|
@ -484,11 +490,6 @@ semver@^5.3.0:
|
|||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
|
||||
integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==
|
||||
|
||||
semver@^5.6.0:
|
||||
version "5.6.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
|
||||
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
|
||||
|
||||
semver@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.0.0.tgz#05e359ee571e5ad7ed641a6eec1e547ba52dea65"
|
||||
|
|
Loading…
Reference in a new issue