mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-08-31 05:47:22 +00:00
Status bar items and glslangValidator download
glslangValidator download done in client side both client and server create status bar items to notify of progress etc
This commit is contained in:
parent
46215f8a91
commit
36fd728533
3 changed files with 189 additions and 55 deletions
|
@ -1,40 +1,72 @@
|
|||
import * as path from 'path'
|
||||
import * as vscode from 'vscode'
|
||||
import * as vscodeLang from 'vscode-languageclient'
|
||||
import { promptDownload, testExecutable } from './glslangValidator'
|
||||
|
||||
export const glslConfigParam = 'mcglsl.glslangValidatorPath'
|
||||
|
||||
export let outputChannel: vscode.OutputChannel
|
||||
|
||||
let statusBarItem: vscode.StatusBarItem
|
||||
|
||||
let globalContext: vscode.ExtensionContext
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
const outputChannel = vscode.window.createOutputChannel('vscode-mc-shader')
|
||||
outputChannel = vscode.window.createOutputChannel('vscode-mc-shader')
|
||||
globalContext = context
|
||||
|
||||
const clientOpts: vscodeLang.LanguageClientOptions = {
|
||||
documentSelector: [{scheme: 'file', language: 'glsl'}],
|
||||
outputChannel: outputChannel,
|
||||
outputChannelName: 'vscode-mc-shader',
|
||||
synchronize: {
|
||||
configurationSection: 'mcglsl',
|
||||
fileEvents: vscode.workspace.createFileSystemWatcher('**/*.{fsh,gsh,vsh,glsl}')
|
||||
},
|
||||
{
|
||||
if (!testExecutable(vscode.workspace.getConfiguration().get(glslConfigParam))) {
|
||||
await promptDownload()
|
||||
} else {
|
||||
outputChannel.appendLine('glslangValidator found!')
|
||||
}
|
||||
}
|
||||
|
||||
const serverOpts: vscodeLang.ServerOptions = {
|
||||
command: context.asAbsolutePath(path.join('server', 'target', 'debug', 'vscode-mc-shader')),
|
||||
|
||||
}
|
||||
|
||||
outputChannel.appendLine('starting language server...')
|
||||
|
||||
const langServer = new vscodeLang.LanguageClient('vscode-mc-shader', serverOpts, clientOpts)
|
||||
|
||||
context.subscriptions.push(langServer.start())
|
||||
|
||||
await langServer.onReady()
|
||||
{
|
||||
|
||||
langServer.onNotification('sampleText', (...nums: number[]) => {
|
||||
outputChannel.appendLine(`got notif: ${nums.join(' ')}`)
|
||||
})
|
||||
const clientOpts: vscodeLang.LanguageClientOptions = {
|
||||
documentSelector: [{scheme: 'file', language: 'glsl'}],
|
||||
outputChannel: outputChannel,
|
||||
outputChannelName: 'vscode-mc-shader',
|
||||
synchronize: {
|
||||
configurationSection: 'mcglsl',
|
||||
fileEvents: vscode.workspace.createFileSystemWatcher('**/*.{fsh,gsh,vsh,glsl}')
|
||||
},
|
||||
}
|
||||
|
||||
langServer.onNotification('update-config', (dir: string) => {
|
||||
vscode.workspace.getConfiguration().update('mcglsl.glslangValidatorPath', dir, vscode.ConfigurationTarget.Global)
|
||||
})
|
||||
const serverOpts: vscodeLang.ServerOptions = {
|
||||
command: context.asAbsolutePath(path.join('server', 'target', 'debug', 'vscode-mc-shader')),
|
||||
}
|
||||
|
||||
outputChannel.appendLine('language server started!')
|
||||
outputChannel.appendLine('starting language server...')
|
||||
|
||||
const langServer = new vscodeLang.LanguageClient('vscode-mc-shader', serverOpts, clientOpts)
|
||||
|
||||
context.subscriptions.push(langServer.start())
|
||||
|
||||
await langServer.onReady()
|
||||
|
||||
langServer.onNotification('updateConfig', (dir: string) => {
|
||||
vscode.workspace.getConfiguration().update(glslConfigParam, dir, vscode.ConfigurationTarget.Global)
|
||||
})
|
||||
|
||||
langServer.onNotification('status', updateStatus)
|
||||
|
||||
langServer.onNotification('clearStatus', clearStatus)
|
||||
|
||||
outputChannel.appendLine('language server started!')
|
||||
}
|
||||
}
|
||||
|
||||
export function updateStatus(icon: string, text: string) {
|
||||
if(statusBarItem != null) statusBarItem.dispose()
|
||||
statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left)
|
||||
statusBarItem.text = icon + " [Minecraft Shaders] " + text
|
||||
statusBarItem.show()
|
||||
globalContext.subscriptions.push(statusBarItem)
|
||||
}
|
||||
|
||||
export function clearStatus() {
|
||||
if(statusBarItem != null) statusBarItem.dispose()
|
||||
}
|
89
client/src/glslangValidator.ts
Normal file
89
client/src/glslangValidator.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import * as unzip from 'adm-zip'
|
||||
import { execSync } from 'child_process'
|
||||
import { writeFileSync } from 'fs'
|
||||
import fetch from 'node-fetch'
|
||||
import { platform } from 'os'
|
||||
import * as vscode from 'vscode'
|
||||
import { clearStatus, glslConfigParam, outputChannel, updateStatus } from './extension'
|
||||
|
||||
const url = {
|
||||
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
|
||||
'linux': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip',
|
||||
'darwin': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-osx-Release.zip'
|
||||
}
|
||||
|
||||
const config = vscode.workspace.getConfiguration()
|
||||
|
||||
export async function promptDownload() {
|
||||
const chosen = await vscode.window.showErrorMessage(
|
||||
`[mc-glsl] glslangValidator not found at: '${config.get(glslConfigParam)}'.`,
|
||||
{title: 'Download'},
|
||||
{title: 'Cancel'}
|
||||
)
|
||||
|
||||
if (!chosen || chosen.title !== 'Download') return
|
||||
|
||||
await installExecutable()
|
||||
}
|
||||
|
||||
async function installExecutable() {
|
||||
try {
|
||||
updateStatus('$(cloud-download)', 'Downloading glslangValidator')
|
||||
|
||||
const glslangBin = '/glslangValidator' + (platform() === 'win32' ? '.exe' : '')
|
||||
const glslangPath = config.get('mcglsl.shaderpacksPath') + glslangBin
|
||||
|
||||
const response = await fetch(url[platform()])
|
||||
outputChannel.appendLine('glslangValidator download response status: ' + response.status )
|
||||
|
||||
const zip = new unzip(await response.buffer())
|
||||
|
||||
const bin = zip.readFile('bin' + glslangBin)
|
||||
outputChannel.appendLine('buffer length ' + bin.length)
|
||||
writeFileSync(glslangPath, bin, {encoding: null, mode: 0o755})
|
||||
|
||||
// Make sure download was successful
|
||||
if (!testExecutable(glslangPath)) {
|
||||
vscode.window.showErrorMessage(`Unexpected error occurred checking for binary at ${glslangPath}. Please try again`)
|
||||
clearStatus()
|
||||
throw new Error('failed to install glslangValidator')
|
||||
}
|
||||
|
||||
// All done!
|
||||
outputChannel.appendLine(`successfully downloaded glslangValidator to ${glslangPath}`)
|
||||
vscode.window.showInformationMessage(
|
||||
`glslangValidator has been downloaded to ${glslangPath}. Your config should be updated automatically.`
|
||||
)
|
||||
config.update('mcglsl.glslangValidatorPath', glslangPath, vscode.ConfigurationTarget.Global)
|
||||
clearStatus()
|
||||
} catch (e) {
|
||||
outputChannel.appendLine(`failed downloading glslangValidator ${e}`)
|
||||
vscode.window.showErrorMessage(`Failed to install glslangValidator: ${e}`)
|
||||
clearStatus()
|
||||
throw e
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function testExecutable(glslangPath?: string): boolean {
|
||||
glslangPath = glslangPath || config.get(glslConfigParam)
|
||||
let stdout = ''
|
||||
try {
|
||||
stdout = execSync(glslangPath, {
|
||||
stdio: 'pipe',
|
||||
}).toString()
|
||||
} catch (e) {
|
||||
stdout = (e.stdout.toString() as string)
|
||||
}
|
||||
|
||||
outputChannel.appendLine('glslangValidator first line stdout: "' + stdout.split('\n')[0] + '"')
|
||||
const success = stdout.startsWith('Usage')
|
||||
|
||||
if (success) {
|
||||
outputChannel.appendLine(`glslangValidator found at ${glslangPath}`)
|
||||
} else {
|
||||
outputChannel.appendLine(`glslangValidator not found at ${glslangPath}`)
|
||||
}
|
||||
|
||||
return success
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue