diff --git a/client/src/extension.ts b/client/src/extension.ts index b13d7dc4..f3d8bd35 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -90,6 +90,14 @@ export function activate(context: ExtensionContext) { return; }); + client.onRequest("getWorkingDirectory", async (): Promise => { + const instance = getBase(); + if (instance && instance.getConnection()) { + const config = instance.getConfig(); + return config.homeDirectory; + } + }) + client.onRequest("getFile", async (stringUri: string): Promise => { // Always assumes URI is valid. Use getUri first const uri = Uri.parse(stringUri); diff --git a/client/src/linter.ts b/client/src/linter.ts index e281e5a5..e0919b33 100644 --- a/client/src/linter.ts +++ b/client/src/linter.ts @@ -31,7 +31,7 @@ export function initialise(context: ExtensionContext) { console.log(`Creating Uri path: ${JSON.stringify(uri)}`); await workspace.fs.writeFile( - uri, + uri, Buffer.from(JSON.stringify(defaultConfig, null, 2), `utf8`) ); } @@ -46,7 +46,7 @@ export function initialise(context: ExtensionContext) { } else if (instance && instance.getConnection()) { /** @type {"member"|"streamfile"} */ let type = `member`; - let configPath: string|undefined; + let configPath: string | undefined; if (filter && filter.description) { // Bad way to get the library for the filter .. @@ -56,25 +56,32 @@ export function initialise(context: ExtensionContext) { } else if (editor) { //@ts-ignore type = editor.document.uri.scheme; - - console.log(`Uri remote path: ${JSON.stringify(editor.document.uri)}`); - const [_, baseLibrary, baseSourceFile, basename] = editor.document.uri.path.split(`/`); - const cleanString = [ - baseLibrary, - `VSCODE`, - `RPGLINT.JSON` - ].join(`/`); - - const memberUri = Uri.from({ - scheme: `member`, - path: cleanString - }); + console.log(`Uri remote path: ${JSON.stringify(editor.document.uri)}`); - if (memberUri) { - configPath = memberUri.path; - } else { - window.showErrorMessage(`No lint config path for this file. File must either be a member or a streamfile on the host IBM i.`); + switch (type) { + case `member`: + const [_, baseLibrary, baseSourceFile, basename] = editor.document.uri.path.split(`/`); + const cleanString = [ + baseLibrary, + `VSCODE`, + `RPGLINT.JSON` + ].join(`/`); + + const memberUri = Uri.from({ + scheme: `member`, + path: cleanString + }); + + configPath = memberUri.path; + break; + + case `streamfile`: + const config = instance.getConfig(); + if (config.homeDirectory) { + configPath = path.posix.join(config.homeDirectory, `.vscode`, `rpglint.json`) + } + break; } } else { window.showErrorMessage(`No active editor found.`); @@ -89,52 +96,60 @@ export function initialise(context: ExtensionContext) { const content = instance.getContent(); window.showErrorMessage(`RPGLE linter config doesn't exist for this file. Would you like to create a default at ${configPath}?`, `Yes`, `No`).then - (async (value) => { - if (value === `Yes`) { - const jsonString = JSON.stringify(defaultConfig, null, 2); - - switch (type) { - case `member`: - if (configPath) { - const memberPath = configPath.split(`/`); - - // Will not crash, even if it fails - await commands.executeCommand( - `code-for-ibmi.runCommand`, - { - 'command': `CRTSRCPF FILE(${memberPath[0]}/VSCODE) RCDLEN(112)` - } - ); - - // Will not crash, even if it fails - await commands.executeCommand( - `code-for-ibmi.runCommand`, - { - command: `ADDPFM FILE(${memberPath[0]}/VSCODE) MBR(RPGLINT) SRCTYPE(JSON)` + (async (value) => { + if (value === `Yes`) { + const jsonString = JSON.stringify(defaultConfig, null, 2); + + switch (type) { + case `member`: + if (configPath) { + const memberPath = configPath.split(`/`); + + // Will not crash, even if it fails + await commands.executeCommand( + `code-for-ibmi.runCommand`, + { + 'command': `CRTSRCPF FILE(${memberPath[0]}/VSCODE) RCDLEN(112)` + } + ); + + // Will not crash, even if it fails + await commands.executeCommand( + `code-for-ibmi.runCommand`, + { + command: `ADDPFM FILE(${memberPath[0]}/VSCODE) MBR(RPGLINT) SRCTYPE(JSON)` + } + ); + + try { + console.log(`Member path: ${[memberPath[0], `VSCODE`, `RPGLINT`].join(`/`)}`); + + await content.uploadMemberContent(null, memberPath[0], `VSCODE`, `RPGLINT`, jsonString); + await commands.executeCommand(`code-for-ibmi.openEditable`, configPath); + } catch (e) { + console.log(e); + window.showErrorMessage(`Failed to create and open new lint configuration file: ${configPath}`); + } } - ); + break; - try { - console.log(`Member path: ${[memberPath[0], `VSCODE`, `RPGLINT`].join(`/`)}`); + case `streamfile`: + console.log(`IFS path: ${configPath}`); - await content.uploadMemberContent(null, memberPath[0], `VSCODE`, `RPGLINT`, jsonString); - await commands.executeCommand(`code-for-ibmi.openEditable`, configPath); - } catch (e) { - console.log(e); - } + try { + await content.writeStreamfile(configPath, jsonString); + await commands.executeCommand(`code-for-ibmi.openEditable`, configPath); + } catch (e) { + console.log(e); + window.showErrorMessage(`Failed to create and open new lint configuration file: ${configPath}`); + } + break; } - break; - - case `streamfile`: - console.log(`IFS path: ${configPath}`); - - await content.writeStreamfile(configPath, jsonString); - await commands.executeCommand(`code-for-ibmi.openEditable`, configPath); - break; } - } - }); + }); } + } else { + window.showErrorMessage(`No lint config path for this file. File must either be a member or a streamfile on the host IBM i.`); } } else { window.showErrorMessage(`Not connected to a system.`); diff --git a/server/src/connection.ts b/server/src/connection.ts index 983f6f5a..7858d5fa 100644 --- a/server/src/connection.ts +++ b/server/src/connection.ts @@ -45,6 +45,10 @@ export async function getFileRequest(uri: string) { return; } +export function getWorkingDirectory(): Promise { + return connection.sendRequest("getWorkingDirectory"); +} + export function getObject(objectPath: string): Promise { return connection.sendRequest("getObject", objectPath); } diff --git a/server/src/providers/linter/index.ts b/server/src/providers/linter/index.ts index ea1ee5ff..02e7617b 100644 --- a/server/src/providers/linter/index.ts +++ b/server/src/providers/linter/index.ts @@ -10,7 +10,7 @@ import codeActionsProvider from './codeActions'; import documentFormattingProvider from './documentFormatting'; import * as Project from "../project"; -import { connection, getFileRequest, validateUri, watchedFilesChangeEvent } from '../../connection'; +import { connection, getFileRequest, getWorkingDirectory, validateUri, watchedFilesChangeEvent } from '../../connection'; export let jsonCache: { [uri: string]: string } = {}; @@ -56,7 +56,7 @@ export function initialise(connection: _Connection) { } }); - documents.onDidClose(async (e: TextDocumentChangeEvent) => { + documents.onDidOpen(async e => { const uri = e.document.uri; const possibleUri = await getLintConfigUri(uri); @@ -104,6 +104,18 @@ export async function getLintConfigUri(workingUri: string) { if (jsonCache[cleanString]) return cleanString; cleanString = await validateUri(cleanString); break; + + case `streamfile`: + const workingDir = await getWorkingDirectory(); + if (workingDir) { + cleanString = URI.from({ + scheme: `streamfile`, + path: path.posix.join(workingDir, `.vscode`, `rpglint.json`) + }).toString(); + + cleanString = await validateUri(cleanString, uri.scheme); + } + break; case `file`: cleanString = await validateUri(`rpglint.json`, uri.scheme);