Added postError function for short error notifications. Using existsSync to check if binary exists. Seperated onConfigChange into different functions. lineNum -2 for windows instead of -1 for linux, such a pain.

This commit is contained in:
Noah Santschi-Cooney 2018-07-20 22:05:59 +01:00
parent c8c7a29abb
commit 1cec184e04
4 changed files with 69 additions and 57 deletions

View file

@ -1,10 +1,9 @@
import { connection, documents, onEvent } from './server' import { connection, documents, onEvent } from './server'
import { exec, execSync } from 'child_process'
import { extname } from 'path'
import fetch from 'node-fetch' import fetch from 'node-fetch'
import { platform } from 'os' import { platform } from 'os'
import { createWriteStream, chmodSync, createReadStream, unlinkSync } from 'fs' import { createWriteStream, chmodSync, createReadStream, unlinkSync, existsSync } from 'fs'
import * as unzip from 'unzip' import * as unzip from 'unzip'
import { postError } from './utils'
const url = { const url = {
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip', 'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
@ -17,55 +16,61 @@ export interface Config {
readonly glslangPath: string readonly glslangPath: string
} }
export let conf: Partial<Config> = {} export let conf: Config = {shaderpacksPath: '', glslangPath: ''}
export const onConfigChange = async (change) => { export const onConfigChange = async (change) => {
const temp = change.settings.mcglsl as Config const temp = change.settings.mcglsl as Config
conf = {shaderpacksPath: temp['shaderpacksPath'], glslangPath: temp['glslangValidatorPath']} conf = {shaderpacksPath: temp['shaderpacksPath'], glslangPath: temp['glslangValidatorPath']}
try {
execSync(conf.glslangPath)
documents.all().forEach(document => onEvent)
} catch (e) {
if (e.status !== 1) {
const chosen = await connection.window.showErrorMessage(
`[mc-glsl] glslangValidator not found at: '${conf.glslangPath}' or returned non-0 code`,
{title: 'Download'},
{title: 'Cancel'}
)
if (!chosen || chosen.title !== 'Download') return if (existsSync(conf.glslangPath)) {
documents.all().forEach(onEvent)
if (conf.shaderpacksPath === '') { } else {
connection.window.showErrorMessage('Please set mcglsl.shaderpacksPath') promptDownloadGlslang()
return }
} }
const res = await fetch(url[platform()]) async function promptDownloadGlslang() {
const chosen = await connection.window.showErrorMessage(
try { `[mc-glsl] glslangValidator not found at: '${conf.glslangPath}'.`,
const zip = createWriteStream(conf.shaderpacksPath + '/glslangValidator.zip') {title: 'Download'},
res.body.pipe(zip) {title: 'Cancel'}
)
zip.on('finish', async () => {
createReadStream(conf.shaderpacksPath + '/glslangValidator.zip') if (!chosen || chosen.title !== 'Download') return
.pipe(unzip.Parse())
.on('entry', (entry) => { if (conf.shaderpacksPath === '') {
if (entry.path === 'bin/glslangValidator') { connection.window.showErrorMessage('Please set mcglsl.shaderpacksPath as this is where glslangValidator will be saved to.')
entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator')) return
return }
}
entry.autodrain() downloadGlslang()
}) }
.on('close', () => {
chmodSync(conf.shaderpacksPath + '/glslangValidator', 0o775) async function downloadGlslang() {
unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip') const res = await fetch(url[platform()])
connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator')
connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator') try {
}) const zip = createWriteStream(conf.shaderpacksPath + '/glslangValidator.zip')
}) res.body.pipe(zip)
} catch (e) {
connection.window.showErrorMessage(e.message) zip.on('finish', async () => {
} createReadStream(conf.shaderpacksPath + '/glslangValidator.zip')
} .pipe(unzip.Parse())
.on('entry', entry => {
if (entry.path === 'bin/glslangValidator') {
entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator'))
return
}
entry.autodrain()
})
.on('close', () => {
chmodSync(conf.shaderpacksPath + '/glslangValidator', 0o775)
unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip')
connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator')
connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator')
})
})
} catch (e) {
postError(e)
} }
} }

View file

@ -1,23 +1,27 @@
import { TextDocument, Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver' import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver'
import { connection, documents } from './server' import { connection, documents } from './server'
import { execSync } from 'child_process' import { execSync } from 'child_process'
import * as path from 'path' import * as path from 'path'
import { readFileSync, existsSync } from 'fs' import { readFileSync, existsSync } from 'fs'
import { conf } from './config' import { conf } from './config'
import { postError } from './utils'
import { platform } from 'os'
const reDiag = /^(ERROR|WARNING): ([^?<>:*|"]+?):(\d+): (?:'.*?' : )?(.+)$/ const reDiag = /^(ERROR|WARNING): ([^?<>:*|"]+?):(\d+): (?:'.*?' : )?(.+)[\r\n|\n]/
const reVersion = /#version [\d]{3}/ const reVersion = /#version [\d]{3}/
const reInclude = /^(?:\s)*?(?:#include) "((?:\/?[^?<>:*|"]+?)+?\.(?:[a-zA-Z]+?))"$/ const reInclude = /^(?:\s)*?(?:#include) "((?:\/?[^?<>:*|"]+?)+?\.(?:[a-zA-Z]+?))"$/
const reIncludeExt = /#extension GL_GOOGLE_include_directive ?: ?require/ const reIncludeExt = /#extension GL_GOOGLE_include_directive ?: ?require/
const include = '#extension GL_GOOGLE_include_directive : require' const include = '#extension GL_GOOGLE_include_directive : require'
const win = platform() === 'win32'
const filters = [ const filters = [
/stdin/,
/(No code generated)/, /(No code generated)/,
/(compilation terminated)/, /(compilation terminated)/,
/Could not process include directive for header name:/ /Could not process include directive for header name:/
] ]
const files = new Map<string, number>() const includeToParent = new Map<string, string[]>()
type IncludeObj = { type IncludeObj = {
lineNum: number, lineNum: number,
@ -98,7 +102,7 @@ export function preprocess(lines: string[], docURI: string) {
try { try {
lint(docURI, lines, includeMap, diagnostics) lint(docURI, lines, includeMap, diagnostics)
} catch (e) { } catch (e) {
console.log(e) postError(e)
} }
} }
@ -180,6 +184,7 @@ function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diag
// add #line indicating we are entering a new include block // add #line indicating we are entering a new include block
lines[inc.lineNumTopLevel] = `#line 0 "${inc.path}"` lines[inc.lineNumTopLevel] = `#line 0 "${inc.path}"`
// merge the lines of the file into the current document // merge the lines of the file into the current document
// TODO do we wanna use a DLL here?
lines.splice(inc.lineNumTopLevel + 1, 0, ...dataLines) lines.splice(inc.lineNumTopLevel + 1, 0, ...dataLines)
// add the closing #line indicating we're re-entering a block a level up // add the closing #line indicating we're re-entering a block a level up
lines.splice(inc.lineNumTopLevel + 1 + dataLines.length, 0, `#line ${inc.lineNum} "${inc.parent}"`) lines.splice(inc.lineNumTopLevel + 1 + dataLines.length, 0, `#line ${inc.lineNum} "${inc.parent}"`)
@ -205,7 +210,8 @@ function lint(uri: string, lines: string[], includes: Map<string, IncludeObj>, d
let diag: Diagnostic = { let diag: Diagnostic = {
severity: errorType(type), severity: errorType(type),
range: calcRange(parseInt(line) - 1, file.length - 1 ? file : uri), // had to do - 2 here instead of - 1, windows only perhaps?
range: calcRange(parseInt(line) - (win ? 2 : 1), file.length - 1 ? file : uri),
message: replaceWord(msg), message: replaceWord(msg),
source: 'mc-glsl' source: 'mc-glsl'
} }

View file

@ -2,17 +2,12 @@ import * as vsclang from 'vscode-languageserver'
import * as vsclangproto from 'vscode-languageserver-protocol' import * as vsclangproto from 'vscode-languageserver-protocol'
import { completions } from './completionProvider' import { completions } from './completionProvider'
import { preprocess, ext, formatURI } from './linter' import { preprocess, ext, formatURI } from './linter'
import { exec, execSync } from 'child_process'
import { extname } from 'path' import { extname } from 'path'
import fetch from 'node-fetch'
import { platform } from 'os'
import { createWriteStream, chmodSync, createReadStream, unlinkSync } from 'fs'
import * as unzip from 'unzip'
export let connection: vsclang.IConnection export let connection: vsclang.IConnection
connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process)) connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process))
import { Config, onConfigChange } from './config' import { onConfigChange } from './config'
export const documents = new vsclang.TextDocuments() export const documents = new vsclang.TextDocuments()
documents.listen(connection) documents.listen(connection)

6
server/src/utils.ts Normal file
View file

@ -0,0 +1,6 @@
import { connection } from './server'
export function postError(e: Error) {
connection.window.showErrorMessage(e.message)
console.log(e)
}