mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-07-24 11:44:44 +00:00
Preparing for release with more logging and more safety checks
This commit is contained in:
parent
9660263dad
commit
41cce2121c
8 changed files with 50 additions and 37 deletions
|
@ -12,9 +12,9 @@ VSCode-MC-Shader is a [Visual Studio Code](https://code.visualstudio.com/) exten
|
|||
|
||||
## Features
|
||||
|
||||
- Linting (unpolished)
|
||||
- Linting
|
||||
- Syntax highlighting (by extension dependency)
|
||||
- Support for `#includes` directives
|
||||
- Support for `#include` directives
|
||||
- Auto-complete prompts (incomplete)
|
||||
|
||||
## Planned
|
||||
|
@ -37,7 +37,6 @@ Got a feature request? Chuck it into an Issue!
|
|||
| 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` |
|
||||
| `mcglsl.shaderpacksPath` | string | The path to the shaderpacks folder in your Minecraft installation folder. | None |
|
||||
|
||||
## Contributing
|
||||
|
|
11
package.json
11
package.json
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"name": "vscode-mc-shader",
|
||||
"displayName": "vscode-mc-shader",
|
||||
"displayName": "Minecraft GLSL Shader",
|
||||
"description": "A Visual Studio Code extension for linting/etc Minecraft GLSL Shaders",
|
||||
"version": "0.0.1",
|
||||
"publisher": "Noah Santschi-Cooney (Strum355)",
|
||||
"version": "0.9.0",
|
||||
"publisher": "Strum355",
|
||||
"author": "Noah Santschi-Cooney (Strum355)",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
@ -50,11 +50,6 @@
|
|||
"default": "glslangValidator",
|
||||
"description": "The path to the glslangValidator executable. Default value assumes its in your PATH."
|
||||
},
|
||||
"mcglsl.lintOnType": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Whether or not to lint while typing. May decrease performance."
|
||||
},
|
||||
"mcglsl.shaderpacksPath": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { connection, documents, onEvent } from './server'
|
||||
import fetch from 'node-fetch'
|
||||
import { platform } from 'os'
|
||||
import { createWriteStream, chmodSync, createReadStream, unlinkSync } from 'fs'
|
||||
import { createWriteStream, chmodSync, createReadStream, unlinkSync, read } from 'fs'
|
||||
import * as unzip from 'unzip'
|
||||
import { postError } from './utils'
|
||||
import { execSync } from 'child_process'
|
||||
import { serverLog } from './logging'
|
||||
import { dirname } from 'path'
|
||||
|
||||
const url = {
|
||||
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
|
||||
|
@ -12,6 +14,8 @@ const url = {
|
|||
'darwin': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-osx-Release.zip'
|
||||
}
|
||||
|
||||
export let glslangReady = false
|
||||
|
||||
export interface Config {
|
||||
readonly shaderpacksPath: string
|
||||
readonly glslangPath: string
|
||||
|
@ -21,17 +25,28 @@ export let conf: Config = {shaderpacksPath: '', glslangPath: ''}
|
|||
|
||||
export const onConfigChange = async (change) => {
|
||||
const temp = change.settings.mcglsl as Config
|
||||
if (temp.shaderpacksPath === conf.shaderpacksPath && temp.glslangPath === conf.glslangPath) return
|
||||
conf = {shaderpacksPath: temp['shaderpacksPath'].replace(/\\/g, '/'), glslangPath: temp['glslangValidatorPath'].replace(/\\/g, '/')}
|
||||
serverLog.debug(() => 'new config: ' + JSON.stringify(temp))
|
||||
serverLog.debug(() => 'old config: ' + JSON.stringify(conf))
|
||||
|
||||
if (conf.shaderpacksPath === '' || conf.shaderpacksPath.replace(dirname(conf.shaderpacksPath), '') !== '/shaderpacks') {
|
||||
serverLog.error(() => 'shaderpack path not set or doesn\'t end in \'shaderpacks\'', null)
|
||||
connection.window.showErrorMessage('mcglsl.shaderpacksPath is not set or doesn\'t end in \'shaderpacks\'. Please set it in your settings.')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (!execSync(conf.glslangPath).toString().startsWith('Usage')) {
|
||||
documents.all().forEach(onEvent)
|
||||
glslangReady = true
|
||||
} else {
|
||||
promptDownloadGlslang()
|
||||
}
|
||||
} catch (e) {
|
||||
if ((e.stdout.toString() as string).startsWith('Usage')) {
|
||||
documents.all().forEach(onEvent)
|
||||
glslangReady = true
|
||||
} else {
|
||||
promptDownloadGlslang()
|
||||
}
|
||||
|
@ -47,11 +62,6 @@ async function promptDownloadGlslang() {
|
|||
|
||||
if (!chosen || chosen.title !== 'Download') return
|
||||
|
||||
if (conf.shaderpacksPath === '') {
|
||||
connection.window.showErrorMessage('Please set mcglsl.shaderpacksPath as this is where glslangValidator will be saved to.')
|
||||
return
|
||||
}
|
||||
|
||||
downloadGlslang()
|
||||
}
|
||||
|
||||
|
@ -76,7 +86,8 @@ async function downloadGlslang() {
|
|||
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')
|
||||
connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator. Your config should be updated automatically.')
|
||||
glslangReady = true
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
// can you imagine that some people out there would import a whole library just for this?
|
||||
export type Pair<T, S> = {
|
||||
first: T,
|
||||
second: S
|
||||
}
|
||||
|
||||
type Node = {
|
||||
parents: Map<string, Pair<number, Node>>
|
||||
children: Map<string, Node>
|
||||
|
@ -10,6 +16,11 @@ export class Graph {
|
|||
return this.nodes.has(uri) ? this.nodes.get(uri).parents.size > 0 : false
|
||||
}
|
||||
|
||||
public get(uri: string): Node {
|
||||
if (!this.nodes.has(uri)) this.nodes.set(uri, {parents: new Map(), children: new Map()})
|
||||
return this.nodes.get(uri)
|
||||
}
|
||||
|
||||
public setParent(uri: string, parent: string, lineNum: number) {
|
||||
const par: Node = this.nodes.has(parent) ? this.nodes.get(parent) : {parents: new Map(), children: new Map()}
|
||||
if (this.nodes.has(uri)) {
|
||||
|
@ -17,21 +28,14 @@ export class Graph {
|
|||
node.parents.set(parent, {first: lineNum, second: par})
|
||||
par.children.set(uri, node)
|
||||
} else {
|
||||
const node: Node = {parents: new Map([par].map(p => [parent, {first: lineNum, second: p}]) as [string, Pair<number, Node>][]), children: new Map()}
|
||||
const node: Node = {
|
||||
parents: new Map([par].map(p => [parent, {first: lineNum, second: p}]) as [string, Pair<number, Node>][]),
|
||||
children: new Map()
|
||||
}
|
||||
|
||||
par.children.set(uri, node)
|
||||
this.nodes.set(uri, node)
|
||||
}
|
||||
this.nodes.set(parent, par)
|
||||
}
|
||||
|
||||
public get(uri: string): Node {
|
||||
if (!this.nodes.has(uri)) this.nodes.set(uri, {parents: new Map(), children: new Map()})
|
||||
return this.nodes.get(uri)
|
||||
}
|
||||
}
|
||||
|
||||
// can you imagine that some people out there would import a whole library just for this?
|
||||
export type Pair<T, S> = {
|
||||
first: T,
|
||||
second: S
|
||||
}
|
|
@ -136,7 +136,7 @@ function processIncludes(lines: string[], incStack: string[], allIncludes: Set<I
|
|||
}
|
||||
}
|
||||
|
||||
export function getIncludes(uri: string, lines: string[]) {
|
||||
function getIncludes(uri: string, lines: string[]) {
|
||||
// the numbers start at -1 because we increment them as soon as we enter the loop so that we
|
||||
// dont have to put an incrememnt at each return
|
||||
const lineInfo: LinesProcessingInfo = {
|
||||
|
@ -312,7 +312,7 @@ function propogateDiagnostic(error: ErrorMatch, diagnostics: Map<string, Diagnos
|
|||
})
|
||||
}
|
||||
|
||||
export const replaceWords = (msg: string) => Array.from(tokens.entries()).reduce((acc, [key, value]) => acc.replace(key, value), msg)
|
||||
const replaceWords = (msg: string) => Array.from(tokens.entries()).reduce((acc, [key, value]) => acc.replace(key, value), msg)
|
||||
|
||||
const errorType = (error: string) => error === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning
|
||||
|
||||
|
@ -333,7 +333,7 @@ function calcRange(lineNum: number, uri: string): Range {
|
|||
return Range.create(lineNum, startOfLine, lineNum, endOfLine)
|
||||
}
|
||||
|
||||
export function absPath(currFile: string, includeFile: string): string {
|
||||
function absPath(currFile: string, includeFile: string): string {
|
||||
if (!currFile.startsWith(conf.shaderpacksPath) || conf.shaderpacksPath === '') {
|
||||
connection.window.showErrorMessage(`Shaderpacks path may not be correct. Current file is in '${currFile}' but the path is set to '${conf.shaderpacksPath}'`)
|
||||
return ''
|
||||
|
|
|
@ -4,3 +4,4 @@ CategoryServiceFactory.setDefaultConfiguration(new CategoryConfiguration(LogLeve
|
|||
|
||||
export const linterLog = new Category('linter')
|
||||
export const completionLog = new Category('completion')
|
||||
export const serverLog = new Category('server')
|
|
@ -2,14 +2,14 @@ import * as vsclang from 'vscode-languageserver'
|
|||
import * as vsclangproto from 'vscode-languageserver-protocol'
|
||||
import { completions } from './completionProvider'
|
||||
import { preprocess, ext, includeGraph } from './linter'
|
||||
import { extname } from 'path'
|
||||
import { extname, dirname } from 'path'
|
||||
|
||||
const reVersion = /#version [\d]{3}/
|
||||
|
||||
export let connection: vsclang.IConnection
|
||||
connection = vsclang.createConnection(new vsclang.IPCMessageReader(process), new vsclang.IPCMessageWriter(process))
|
||||
|
||||
import { onConfigChange } from './config'
|
||||
import { onConfigChange, conf, glslangReady } from './config'
|
||||
import { formatURI, postError, getDocumentContents } from './utils'
|
||||
|
||||
export const documents = new vsclang.TextDocuments()
|
||||
|
@ -39,6 +39,8 @@ documents.onDidClose((event) => connection.sendDiagnostics({uri: event.document.
|
|||
//documents.onDidChangeContent(onEvent)
|
||||
|
||||
export function onEvent(document: vsclangproto.TextDocument) {
|
||||
if (conf.shaderpacksPath.replace(dirname(conf.shaderpacksPath), '') !== '/shaderpacks' || !glslangReady) return
|
||||
|
||||
const uri = formatURI(document.uri)
|
||||
if (includeGraph.get(uri).parents.size > 0) {
|
||||
lintBubbleDown(uri, document)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { connection, documents } from './server'
|
||||
import { readFileSync } from 'fs'
|
||||
import { conf } from './config'
|
||||
import { serverLog } from './logging'
|
||||
|
||||
export function postError(e: Error) {
|
||||
connection.window.showErrorMessage(e.message)
|
||||
console.log(e)
|
||||
serverLog.error(e.message, new Error())
|
||||
}
|
||||
|
||||
export const formatURI = (uri: string) => uri.replace(/^file:\/\//, '').replace(/^(?:\/)c%3A/, 'C:').replace(/\\/g, '/')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue