mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-08-04 00:49:17 +00:00
Added support for ../ includes
This commit is contained in:
parent
243eb671bc
commit
2421aeb32c
6 changed files with 48 additions and 47 deletions
|
@ -1,11 +1,11 @@
|
|||
# Minecraft GLSL Shaders
|
||||
## vscode-mc-shader
|
||||
|
||||
[](https://ci.netsoc.co/Strum355/vscode-mc-shader)
|
||||
<!-- [](https://ci.netsoc.co/Strum355/vscode-mc-shader)
|
||||
[](https://github.com/Strum355/vscode-mc-shader/issues)
|
||||
[](https://github.com/Strum355/vscode-mc-shader)
|
||||
[](https://codeclimate.com/github/Strum355/vscode-mc-shader/maintainability)
|
||||
[](https://waffle.io/Strum355/vscode-mc-shader)
|
||||
[](https://waffle.io/Strum355/vscode-mc-shader) -->
|
||||
|
||||
VSCode-MC-Shader is a [Visual Studio Code](https://code.visualstudio.com/) extension for developing Minecraft GLSL Shaders for [Optifine](http://optifine.net). It currently provides linting and syntax highlighting (by stef-levesque/vscode-shader dependency).
|
||||
|
||||
|
@ -31,7 +31,7 @@ Got a feature request? Chuck it into an Issue!
|
|||
- Visual Studio Code (v1.17.0 or higher - minimum requirement untested)
|
||||
- The [Shader languages support for VS Code](https://marketplace.visualstudio.com/items?itemName=slevesque.shader) extension. This should automatically install when you install this extension.
|
||||
- That the shader(s) you're editing are in the `shaderpacks` folder in `.minecraft`.
|
||||
- The [OpenGL / OpenGL ES Reference Compiler](https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang/Install/) (for convenience, put it in your PATH, this is the assumed location if not specified). If, for some reason, you're using MacOS, there are no pre-compiled binaries of this.
|
||||
- The [OpenGL / OpenGL ES Reference Compiler](https://github.com/KhronosGroup/glslang) (for convenience, put it in your PATH, this is the assumed location if not specified). If, for some reason, you're using MacOS, there are no pre-compiled binaries of this.
|
||||
- [MacOS] Not MacOS. Not that you're making MC Shaders on/for MacOS anyways...right?
|
||||
|
||||
## Extension Settings
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "vscode-mc-shader",
|
||||
"displayName": "Minecraft GLSL Shaders",
|
||||
"description": "A Visual Studio Code extension for linting/etc Minecraft GLSL Shaders",
|
||||
"version": "0.9.0",
|
||||
"version": "0.8.1",
|
||||
"publisher": "Strum355",
|
||||
"author": "Noah Santschi-Cooney (Strum355)",
|
||||
"license": "MIT",
|
||||
|
|
|
@ -33,10 +33,7 @@ export namespace Comment {
|
|||
|
||||
function empty(i: number, line: string, twice: boolean): string {
|
||||
line = line.substr(0, i) + ' ' + line.substr(i + 1)
|
||||
if (twice) {
|
||||
i++
|
||||
line = line.substr(0, i) + ' ' + line.substr(i + 1)
|
||||
}
|
||||
if (twice) line = line.substr(0, i + 1) + ' ' + line.substr(i + 3)
|
||||
return line
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import { execSync } from 'child_process'
|
|||
import { serverLog } from './logging'
|
||||
import { dirname } from 'path'
|
||||
import { DidChangeConfigurationParams } from 'vscode-languageserver/lib/main'
|
||||
import { win } from './linter';
|
||||
|
||||
const url = {
|
||||
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
|
||||
|
@ -87,16 +88,16 @@ async function downloadGlslang() {
|
|||
createReadStream(conf.shaderpacksPath + '/glslangValidator.zip')
|
||||
.pipe(unzip.Parse())
|
||||
.on('entry', entry => {
|
||||
if (entry.path === 'bin/glslangValidator') {
|
||||
entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator'))
|
||||
if (entry.path === 'bin/glslangValidator' + win ? '.exe' : '') {
|
||||
entry.pipe(createWriteStream(conf.shaderpacksPath + '/glslangValidator' + win ? '.exe' : ''))
|
||||
return
|
||||
}
|
||||
entry.autodrain()
|
||||
})
|
||||
.on('close', () => {
|
||||
chmodSync(conf.shaderpacksPath + '/glslangValidator', 0o775)
|
||||
chmodSync(conf.shaderpacksPath + '/glslangValidator' + win ? '.exe' : '', 0o775)
|
||||
unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip')
|
||||
connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator')
|
||||
connection.sendNotification('update-config', conf.shaderpacksPath + '/glslangValidator' + win ? '.exe' : '')
|
||||
connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator. Your config should be updated automatically.')
|
||||
glslangReady = true
|
||||
})
|
||||
|
|
|
@ -15,7 +15,7 @@ const reVersion = /#version [\d]{3}/
|
|||
const reInclude = /^(?:\s)*?(?:#include) "(.+)"\r?/
|
||||
const reIncludeExt = /#extension GL_GOOGLE_include_directive ?: ?require/
|
||||
const include = '#extension GL_GOOGLE_include_directive : require'
|
||||
const win = platform() === 'win32'
|
||||
export const win = platform() === 'win32'
|
||||
|
||||
const filters = [
|
||||
/stdin/,
|
||||
|
@ -111,11 +111,11 @@ function includeDirective(lines: string[], docURI: string): boolean {
|
|||
break
|
||||
}
|
||||
|
||||
if (i === lines.length - 1) {
|
||||
/* if (i === lines.length - 1) {
|
||||
linterLog.warn(() => `no version found for ${docURI}. inserting at top`)
|
||||
lines.splice(0, 0, include)
|
||||
break
|
||||
}
|
||||
} */
|
||||
}
|
||||
return hasDirective
|
||||
}
|
||||
|
@ -123,11 +123,10 @@ function includeDirective(lines: string[], docURI: string): boolean {
|
|||
const buildIncludeGraph = (inc: IncludeObj) => includeGraph.setParent(inc.path, inc.parent, inc.lineNum)
|
||||
|
||||
function processIncludes(lines: string[], incStack: string[], allIncludes: Set<IncludeObj>, diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
|
||||
// todo figure out why incStack[0] here
|
||||
const includes = getIncludes(incStack[0], lines)
|
||||
const parent = incStack[incStack.length - 1]
|
||||
const includes = getIncludes(parent, lines)
|
||||
includes.forEach(i => allIncludes.add(i))
|
||||
|
||||
const parent = incStack[incStack.length - 1]
|
||||
includeGraph.nodes.get(parent).children.forEach((node, uri) => {
|
||||
if (!includes.has(uri)) {
|
||||
includeGraph.nodes.get(parent).children.delete(uri)
|
||||
|
@ -154,14 +153,14 @@ function getIncludes(uri: string, lines: string[]) {
|
|||
total: -1,
|
||||
comment: Comment.State.No,
|
||||
parStack: [uri],
|
||||
count: [0],
|
||||
count: [-1],
|
||||
}
|
||||
|
||||
return new Map(lines.reduce<IncludeObj[]>((out, line, i) => processLine(out, line, lines, i, lineInfo), []).map(inc => [inc.path, inc] as [string, IncludeObj]))
|
||||
return lines.reduce<Map<string, IncludeObj>>((out, line, i) => processLine(out, line, lines, i, lineInfo), new Map())
|
||||
}
|
||||
|
||||
// TODO can surely be reworked
|
||||
function processLine(includes: IncludeObj[], line: string, lines: string[], i: number, linesInfo: LinesProcessingInfo): IncludeObj[] {
|
||||
function processLine(includes: Map<string, IncludeObj>, line: string, lines: string[], i: number, linesInfo: LinesProcessingInfo): Map<string, IncludeObj> {
|
||||
const updated = Comment.update(line, linesInfo.comment)
|
||||
linesInfo.comment = updated[0]
|
||||
|
||||
|
@ -177,7 +176,6 @@ function processLine(includes: IncludeObj[], line: string, lines: string[], i: n
|
|||
|
||||
if (line.startsWith('#line')) {
|
||||
const inc = line.slice(line.indexOf('"') + 1, line.lastIndexOf('"'))
|
||||
|
||||
if (inc === linesInfo.parStack[linesInfo.parStack.length - 2]) {
|
||||
linesInfo.count.pop()
|
||||
linesInfo.parStack.pop()
|
||||
|
@ -191,13 +189,16 @@ function processLine(includes: IncludeObj[], line: string, lines: string[], i: n
|
|||
const match = line.match(reInclude)
|
||||
|
||||
if (match) {
|
||||
includes.push({
|
||||
path: formatURI(absPath(linesInfo.parStack[linesInfo.parStack.length - 1], match[1])),
|
||||
lineNum: linesInfo.count[linesInfo.count.length - 1],
|
||||
lineNumTopLevel: linesInfo.total,
|
||||
parent: formatURI(linesInfo.parStack[linesInfo.parStack.length - 1]),
|
||||
match
|
||||
})
|
||||
includes.set(
|
||||
formatURI(absPath(linesInfo.parStack[linesInfo.parStack.length - 1], match[1])),
|
||||
{
|
||||
path: formatURI(absPath(linesInfo.parStack[linesInfo.parStack.length - 1], match[1])),
|
||||
lineNum: linesInfo.count[linesInfo.count.length - 1],
|
||||
lineNumTopLevel: linesInfo.total,
|
||||
parent: formatURI(linesInfo.parStack[linesInfo.parStack.length - 1]),
|
||||
match
|
||||
}
|
||||
)
|
||||
}
|
||||
return includes
|
||||
}
|
||||
|
@ -210,7 +211,7 @@ function ifInvalidFile(inc: IncludeObj, lines: string[], incStack: string[], dia
|
|||
const file = incStack[incStack.length - 1]
|
||||
const diag: Diagnostic = {
|
||||
severity: DiagnosticSeverity.Error,
|
||||
range: calcRange(inc.lineNum, file),
|
||||
range: calcRange(inc.lineNum - ((!hasDirective && includeGraph.get(file).parents.size === 0) ? 1 : 0), file),
|
||||
message: msg,
|
||||
source: 'mc-glsl'
|
||||
}
|
||||
|
@ -227,9 +228,13 @@ function ifInvalidFile(inc: IncludeObj, lines: string[], incStack: string[], dia
|
|||
}
|
||||
|
||||
function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
|
||||
let stats: Stats
|
||||
try {
|
||||
stats = statSync(inc.path)
|
||||
const stats = statSync(inc.path)
|
||||
if (!stats.isFile()) {
|
||||
const err = new Error()
|
||||
err['code'] = 'ENOENT'
|
||||
throw err
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.code === 'ENOENT') {
|
||||
ifInvalidFile(inc, lines, incStack, diagnostics, hasDirective)
|
||||
|
@ -238,11 +243,6 @@ function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diag
|
|||
throw e
|
||||
}
|
||||
|
||||
if (!stats.isFile()) {
|
||||
ifInvalidFile(inc, lines, incStack, diagnostics, hasDirective)
|
||||
return
|
||||
}
|
||||
|
||||
const dataLines = readFileSync(inc.path).toString().split('\n')
|
||||
|
||||
// if the includes parent is the top level (aka where the include directive is placed)
|
||||
|
@ -293,9 +293,8 @@ function processErrors(out: string, docURI: string, diagnostics: Map<string, Dia
|
|||
|
||||
const diag: Diagnostic = {
|
||||
severity: error.type,
|
||||
// had to do - 2 here instead of - 1, windows only perhaps?
|
||||
range: calcRange(error.line - ((!hasDirective && includeGraph.get(fileName).parents.size === 0) ? 2 : 1), fileName),
|
||||
message: `Line ${error.line} ${replaceWords(error.msg)}`,
|
||||
message: `Line ${error.line + 1} ${replaceWords(error.msg)}`,
|
||||
source: 'mc-glsl'
|
||||
}
|
||||
|
||||
|
@ -311,8 +310,8 @@ function propogateDiagnostic(error: ErrorMatch, diagnostics: Map<string, Diagnos
|
|||
includeGraph.get(parentURI || error.file).parents.forEach((pair, parURI) => {
|
||||
const diag: Diagnostic = {
|
||||
severity: error.type,
|
||||
range: calcRange(pair.first - (pair.second.parents.size > 0 ? 0 : (2 - (hasDirective ? 1 : 0))), parURI),
|
||||
message: `Line ${error.line} ${trimPath(error.file)} ${replaceWords(error.msg)}`,
|
||||
range: calcRange(pair.first - ((!hasDirective && pair.second.parents.size === 0) ? 1 : 0), parURI),
|
||||
message: `Line ${error.line + 1} ${trimPath(error.file)} ${replaceWords(error.msg)}`,
|
||||
source: 'mc-glsl'
|
||||
}
|
||||
|
||||
|
@ -338,6 +337,8 @@ const filterMatches = (output: string) => output
|
|||
.filter(match => match && match.length === 5)
|
||||
|
||||
function calcRange(lineNum: number, uri: string): Range {
|
||||
linterLog.debug(() => `calculating range for ${trimPath(uri)} at L${lineNum}`)
|
||||
|
||||
const lines = getDocumentContents(uri).split('\n')
|
||||
const line = lines[lineNum]
|
||||
const startOfLine = line.length - line.trimLeft().length
|
||||
|
@ -353,9 +354,11 @@ function absPath(currFile: string, includeFile: string): string {
|
|||
}
|
||||
|
||||
// TODO add explanation comment
|
||||
if (includeFile.charAt(0) === '/') {
|
||||
if (includeFile.charAt(0) === '/' || (includeFile.charAt(0) === '.' && includeFile.charAt(1) === '.')) {
|
||||
const shaderPath = trimPath(currFile).split('/').slice(0, 3).join('/')
|
||||
return path.join(conf.shaderpacksPath, shaderPath, includeFile)
|
||||
}
|
||||
} /* else if (includeFile.charAt(0) === '.' && includeFile.charAt(1) === '.') {
|
||||
|
||||
} */
|
||||
return path.join(path.dirname(currFile), includeFile)
|
||||
}
|
|
@ -45,14 +45,14 @@ export function onEvent(document: vsclangproto.TextDocument) {
|
|||
|
||||
const uri = formatURI(document.uri)
|
||||
if (includeGraph.get(uri).parents.size > 0) {
|
||||
lintBubbleDown(uri, document)
|
||||
lintBubbleDown(uri)
|
||||
return
|
||||
}
|
||||
|
||||
// i think we still need to keep this in case we havent found the root of this files include tree
|
||||
const lines = document.getText().split('\n')
|
||||
const hasVersion = lines.filter(l => reVersion.test(l)).length > 0
|
||||
if (!ext.has(extname(document.uri)) || !hasVersion) return
|
||||
if (!hasVersion) return
|
||||
|
||||
try {
|
||||
preprocess(document.getText().split('\n'), uri)
|
||||
|
@ -61,10 +61,10 @@ export function onEvent(document: vsclangproto.TextDocument) {
|
|||
}
|
||||
}
|
||||
|
||||
function lintBubbleDown(uri: string, document: vsclangproto.TextDocument) {
|
||||
function lintBubbleDown(uri: string) {
|
||||
includeGraph.get(uri).parents.forEach((parent, parentURI) => {
|
||||
if (parent.second.parents.size > 0) {
|
||||
lintBubbleDown(parentURI, document)
|
||||
lintBubbleDown(parentURI)
|
||||
} else {
|
||||
const lines = getDocumentContents(parentURI).split('\n')
|
||||
// feel like we could perhaps do better? Hope no one puts #version at the top of their includes..
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue