Moved config to own file and made it a class. Added lintOnType config option to package.json and readme.

This commit is contained in:
Noah Santschi-Cooney 2018-05-28 00:49:55 +01:00
parent 18e321ccc8
commit 2e88c004d2
No known key found for this signature in database
GPG key ID: 3B22282472C8AE48
4 changed files with 72 additions and 63 deletions

View file

@ -28,7 +28,10 @@ Got a feature request? Chuck it into an Issue!
## Extension Settings
- `mcglsl.glslangValidatorPath` : The path to the glslangValidator executable. If not provided, it assumes its in your `PATH`.
| Option Name | Data Type | Description | Default Value |
| ----------- | --------- | ----------- | ------------- |
| `mcglsl.glslangValidatorPath` | string | The path to the glslangValidator executable. | In your `PATH`.|
|`mcglsl.lintOnType` | bool | Whether or not to lint while typing. Can decrease performance. | `false` |
## Contributing

View file

@ -43,7 +43,12 @@
"mcglsl.glslangValidatorPath": {
"type": "string",
"default": "glslangValidator",
"description": "The path to the glslangValidator binary. By default it assumes its in your PATH"
"description": "The path to the glslangValidator executable. Default value assumes its in your PATH"
},
"mc.glsl.lintOnType": {
"type": "boolean",
"default": false,
"description": "Whether or not to lint while typing. Can decrease performance."
}
}
}

35
src/config.ts Normal file
View file

@ -0,0 +1,35 @@
import * as vscode from 'vscode'
import * as path from 'path'
import * as os from 'os'
// glslangPath: Path to glslangValidator (assumed in PATH by default)
// workDir: the directory in which all the files should be, ending in /shaders
// tmpdir: the directory into which the symlinks are stored, should be the OS's temp dir
// isWin: are we on Windows?
export class Config {
readonly glslangPath: string
readonly workDir: string
readonly tmpdir: string
readonly isWin: boolean
constructor() {
const c = vscode.workspace.getConfiguration('mcglsl')
console.log('[MC-GLSL] glslangValidatorPath set to', c.get('glslangValidatorPath'))
console.log('[MC-GLSL] temp directory root set to', path.join(os.tmpdir(), vscode.workspace.name!, 'shaders'))
this.glslangPath = c.get('glslangValidatorPath') as string
this.workDir = path.basename(vscode.workspace.rootPath!) === 'shaders' ?
vscode.workspace.rootPath! :
path.join(vscode.workspace.rootPath!, 'shaders')
this.tmpdir = path.join(os.tmpdir(), vscode.workspace.name!, 'shaders')
this.isWin = os.platform() === 'win32'
}
public onChange(e: vscode.ConfigurationChangeEvent) {
if (e.affectsConfiguration('mcglsl')) {
console.log('[MC-GLSL] config changed')
Object.assign(this, new Config())
}
}
}

View file

@ -1,21 +1,12 @@
'use strict'
import * as vscode from 'vscode'
import * as os from 'os'
import * as cp from 'child_process'
import * as fs from 'fs'
import * as shell from 'shelljs'
import * as path from 'path'
import '../global'
// glslangPath: Path to glslangValidator (assumed in PATH by default)
// tmpdir: the directory into which the symlinks are stored, should be the OS's temp dir
interface Config {
readonly glslangPath: string
readonly workDir: string
readonly tmpdir: string
readonly isWin: boolean
}
import { Config } from '../config'
// These are used for symlinking as glslangValidator only accepts files in these formats
const extensions: { [id: string]: string } = {
@ -31,30 +22,35 @@ const filters: RegExp[] = [
/(required extension not requested: GL_GOOGLE_include_directive)/,
/('#include' : must be followed by a header name)/,
/('#include' : unexpected include directive)/,
/('#include' : must be followed by a file designation)/,
/(No code generated)/,
/(compilation terminated)/,
/\/\w*.(vert|frag)$/
]
const syntaxError = /(syntax error)/
const outputMatch = /(WARNING:|ERROR:)\s\d+:(\d+): (\W.*)/
const include = /^(?: |\t)*(?:#include) "((?:\/[\S]+)+\.(?:glsl))"$/
const regSyntaxError = /(syntax error)/
const regOutputMatch = /(WARNING:|ERROR:)\s\d+:(\d+): (\W.*)/
const regInclude = /^(?: |\t)*(?:#include) "((?:\/[\S]+)+\.(?:glsl))"$/
export default class GLSLProvider implements vscode.CodeActionProvider {
private diagnosticCollection: vscode.DiagnosticCollection // where errors/warnings/hints are pushed to be displayed
private config: Config
private onTypeDisposable?: vscode.Disposable
constructor(subs: vscode.Disposable[], config?: Config) {
constructor(subs: vscode.Disposable[]) {
this.diagnosticCollection = vscode.languages.createDiagnosticCollection()
subs.push(this)
// For if i ever get testing to work
if (config !== null) {
this.config = this.initConfig()
this.config = new Config()
const c = vscode.workspace.getConfiguration('mcglsl')
if (c.get('lintOnType') as boolean) {
this.onTypeDisposable = vscode.workspace.onDidChangeTextDocument(this.docChange, this)
console.log('[MC-GLSL] linting while typing.')
} else {
this.config = config
if (this.onTypeDisposable) this.onTypeDisposable.dispose()
console.log('[MC-GLSL] not linting while typing.')
}
this.checkBinary()
@ -70,47 +66,17 @@ export default class GLSLProvider implements vscode.CodeActionProvider {
vscode.workspace.onDidOpenTextDocument(this.lint, this)
vscode.workspace.onDidSaveTextDocument(this.lint, this)
vscode.workspace.onDidChangeConfiguration(this.configChange, this)
vscode.workspace.onDidChangeConfiguration((e: vscode.ConfigurationChangeEvent) => {
this.config.onChange(e)
this.checkBinary()
}, this)
vscode.workspace.textDocuments.forEach(doc => this.lint(doc))
}
private initConfig(): Config {
const c = vscode.workspace.getConfiguration('mcglsl')
console.log('[MC-GLSL] glslangValidatorPath set to', c.get('glslangValidatorPath'))
console.log('[MC-GLSL] temp directory root set to', path.join(os.tmpdir(), vscode.workspace.name!, 'shaders'))
if (c.get('lintOnSave') as boolean) {
this.onTypeDisposable = vscode.workspace.onDidChangeTextDocument(this.docChange, this)
console.log('[MC-GLSL] linting on save')
} else if (this.onTypeDisposable) {
this.onTypeDisposable.dispose()
console.log('[MC-GLSL] not linting on save')
}
return {
glslangPath: c.get('glslangValidatorPath') as string,
workDir: vscode.workspace.rootPath!,
tmpdir: path.join(os.tmpdir(), vscode.workspace.name!, 'shaders'),
isWin: require('os').platform() === 'win32',
}
}
// Called when the config files are changed
private configChange(e: vscode.ConfigurationChangeEvent) {
if (e.affectsConfiguration('mcglsl')) {
console.log('[MC-GLSL] config changed')
this.config = this.initConfig()
this.checkBinary()
}
}
// Check if glslangValidator binary can be found
public checkBinary() {
const ret = shell.which(this.config.glslangPath)
if (ret == null) {
if (shell.which(this.config.glslangPath) == null) {
const msg = '[MC-GLSL] glslangValidator not found. Please check that you\'ve given the right path.'
console.log(msg)
vscode.window.showErrorMessage(msg)
@ -127,18 +93,17 @@ export default class GLSLProvider implements vscode.CodeActionProvider {
// Returns true if the string matches any of the regex
public matchesFilters = (s: string) => filters.some(reg => reg.test(s))
// Split output by line, remove empty lines, remove the first and 2 trailing lines,
// and then remove all lines that match any of the regex
// Split output by line, remove empty lines and then remove all lines that match any of the regex
private filterMessages = (res: string) => res
.split('\n')
.filter(s => s.length > 1 && !this.matchesFilters(s))
.map(s => s.match(outputMatch))
.map(s => s.match(regOutputMatch))
.filter(match => match && match.length > 3)
private filterPerLine(matches: RegExpMatchArray[], document: vscode.TextDocument) {
return matches.filter(match => {
let line = document.lineAt(parseInt(match![2]))
return !(syntaxError.test(match[0]) && line.text.leftTrim().startsWith('#include'))
return !(regSyntaxError.test(match[0]) && line.text.leftTrim().startsWith('#include'))
})
}
@ -163,12 +128,13 @@ export default class GLSLProvider implements vscode.CodeActionProvider {
const range = this.calcRange(document, lineNum)
if (diags.length > 0 && range.isEqual(diags[diags.length - 1].range) && syntaxError.test(message)) return
if (diags.length > 0 && range.isEqual(diags[diags.length - 1].range) && regSyntaxError.test(message)) return
diags.push(new vscode.Diagnostic(range, '[mc-glsl] ' + message, severity))
})
this.findIncludes(document).forEach(include => {
//path.join(this.config.workDir, match![1])
if (include.text.includes('../')) {
const trimmed = include.text.leftTrim()
const range = new vscode.Range(include.lineNumber, include.text.length - trimmed.length, include.lineNumber, (include.text.length - trimmed.length) + trimmed.length)
@ -183,7 +149,7 @@ export default class GLSLProvider implements vscode.CodeActionProvider {
const includes = this.findIncludes(document)
}
private findIncludes = (document: vscode.TextDocument) => this.filter(document, line => include.test(line.text))
private findIncludes = (document: vscode.TextDocument) => this.filter(document, line => regInclude.test(line.text))
private filter(document: vscode.TextDocument, f: (s: vscode.TextLine) => boolean): vscode.TextLine[] {
const out: vscode.TextLine[] = []
@ -199,8 +165,8 @@ export default class GLSLProvider implements vscode.CodeActionProvider {
return new vscode.Range(lineNum - 1, line.length - trimmed.length, lineNum - 1, line.length - 1)
}
private createSymlinks(linkname: string, document: vscode.TextDocument) {
if (fs.existsSync(linkname)) {
private async createSymlinks(linkname: string, document: vscode.TextDocument) {
if (await fs.exists(linkname)) {
return
}