Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move installer, runner and snippets into extension #19

Merged
merged 5 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
},
"dependencies": {
"vscode-languageclient": "5.1.1",
"xml2js": "^0.4.23"
"xml2js": "^0.6.2"
},
"devDependencies": {
"@halcyontech/vscode-ibmi-types": "^2.8.0",
"@types/node": "^18.11.5",
"@types/vscode": "^1.50.0",
"@types/xml2js": "^0.4.11",
"@vscode/test-electron": "^2.1.2",
"@halcyontech/vscode-ibmi-types": "^2.6.1"
"@vscode/test-electron": "^2.1.2"
}
}
77 changes: 77 additions & 0 deletions client/src/clRunner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { EndOfLine, ExtensionContext, Position, Range, Selection, TextDocument, commands, window } from "vscode";
import { getInstance } from './external/api/ibmi';

export function initialiseRunner(context: ExtensionContext) {
context.subscriptions.push(
commands.registerCommand(`vscode-clle.runSelected`, async () => {
const instance = getInstance();
const editor = window.activeTextEditor;

if (editor) {
const document = editor.document;

if (document && document.languageId === `cl`) {
const connection = instance.getConnection();

if (connection) {
const selectedCommand = getCommandString(editor.selection, document);

if (selectedCommand.range) {
editor.selection = new Selection(
new Position(selectedCommand.range.start, 0),
new Position(selectedCommand.range.end, document.lineAt(selectedCommand.range.end).range.end.character)
);
}

await commands.executeCommand(`code-for-ibmi.runAction`, editor.document.uri, undefined, {
command: selectedCommand.content,
environment: `ile`,
name: `CL command`,
});
}
}
}
})
)
}

function getCommandString(selection: Selection, document: TextDocument): {content: string, range?: {start: number, end: number}} {
if (selection.isEmpty) {
let line = selection.start.line;

// First let's find out if this command belong to another command
while((line-1) >= 0 && document.lineAt(line-1).text.trim().endsWith(`+`) && line-- > 0);

// Then fetch all the lines
const startLine = line;
let content = [document.lineAt(line).text.trim()];

// Then we fetch the next continuation lines
while (content[content.length - 1].endsWith(`+`)) {
line += 1;
content.push(document.lineAt(line).text.trim());
}

return {
content: removePlusJoins(content).join(` `),
range: {
start: startLine,
end: line
}
};
} else {
const lines = document.getText(new Range(selection.start, selection.end)).split(document.eol === EndOfLine.CRLF ? `\r\n` : `\n`);
return {
content: removePlusJoins(lines).join(` `)
};
}
}

function removePlusJoins(lines: string[]) {
for (let i = 0; i < lines.length; i++) {
lines[i] = lines[i].trim();
if (lines[i].endsWith(`+`)) lines[i] = lines[i].substring(0, lines[i].length - 1);
}

return lines;
}
7 changes: 5 additions & 2 deletions client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import {getHandler} from "./external";
import { loadBase } from './external/api/ibmi';
import { initialiseRunner } from './clRunner';

let client: LanguageClient;

Expand Down Expand Up @@ -53,7 +54,7 @@ export function activate(context: ExtensionContext) {
serverOptions,
clientOptions
);
5

// Start the client. This will also launch the server
client.start();

Expand All @@ -77,7 +78,9 @@ export function activate(context: ExtensionContext) {
return definition;
}
});
})
});

initialiseRunner(context);
}

export function deactivate(): Thenable<void> | undefined {
Expand Down
26 changes: 26 additions & 0 deletions client/src/external/handlers/vscodeIbmi/gencmdxml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const content = [
`pgm parm(&name &cmd)`,
` dcl &name *char 10`,
` dcl &cmd *char 20`,
` dcl &destinfo *char 64`,
` dcl &destfmt *char 8 value('DEST0200')`,
` dcl &rcvvar *char 1`,
` dcl &rcvfmt *char 8 value('CMDD0100')`,
` dcl &error *char 16 value(x'00000010')`,
` dcl &null2 *char 2 value(x'0000')`,
` dcl &null3 *char 3 value(x'000000')`,
` dcl &null10 *char 10 value(x'00000000000000000000')`,
` /*chgvar &cmd value('GENDDL *LIBL') */`,
` chgvar %bin(&destinfo 1 4) value(0) /* CCSID */`,
` chgvar %sst(&destinfo 5 2) value(&null2) /* country */`,
` chgvar %sst(&destinfo 7 3) value(&null3) /* language */`,
` chgvar %sst(&destinfo 10 3) value(&null3) /* reserved */`,
` chgvar %bin(&destinfo 13 4) value(0) /* path type */`,
` chgvar %bin(&destinfo 17 4) value(15) /* path name len */`,
` chgvar %sst(&destinfo 21 2) value('/') /* delimiter */`,
` chgvar %sst(&destinfo 23 10) value(&null10) /* reserved */`,
` chgvar %sst(&destinfo 33 32) value('/tmp/' *tcat &name)`,
` call qcdrcmdd (&cmd &destinfo &destfmt +`,
` &rcvvar &rcvfmt &error)`,
`endpgm`
];
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Handler from './handler';
import Handler from '../handler';
import * as xml2js from "xml2js";
import { getInstance } from '../api/ibmi';
import { getInstance } from '../../api/ibmi';
import Instance from '@halcyontech/vscode-ibmi-types/api/Instance';

import { content as gencmdxml } from './gencmdxml';

enum Status {
NotChecked,
Installed,
Expand Down Expand Up @@ -31,6 +33,26 @@ export default class vscodeIbmi extends Handler {
return false;
}

async install(): Promise<boolean> {
const instance = this.instance;
const connection = instance.getConnection()!;
const content = instance.getContent()!;
const config = instance.getConfig()!;

const tempLib = config.tempLibrary;

//It may exist already so we just ignore the error
await connection.runCommand({ command: `CRTSRCPF ${tempLib}/QTOOLS`, noLibList: true })

await content.uploadMemberContent(undefined, tempLib, `QTOOLS`, `GENCMDXML`, gencmdxml.join(`\n`));
const createResult = await connection.runCommand({
command: `CRTBNDCL PGM(${tempLib}/GENCMDXML) SRCFILE(${tempLib}/QTOOLS) DBGVIEW(*SOURCE) TEXT('vscode-ibmi xml generator for commands')`,
noLibList: true
});

return createResult.code === 0;
}

/**
* Returns DSPFFD outfile rows
*/
Expand Down Expand Up @@ -102,22 +124,28 @@ export default class vscodeIbmi extends Handler {
if (this.installed === Status.Installed) return true;
if (this.instance) {
const connection = this.instance.getConnection();
const content = this.instance.getContent();
const config = this.instance.getConfig();
const tempLib = config.tempLibrary;

const checkResult = await connection.runCommand({
command: `CHKOBJ OBJ(${tempLib}/GENCMDXML) OBJTYPE(*PGM)`,
noLibList: true
});
const exists = await content.checkObject({ type: `*PGM`, library: tempLib, name: `GENCMDXML`});

if (checkResult.code === 0) {
if (exists) {
this.installed = Status.Installed;
return true;
}

this.installed = Status.NotInstalled;
}

if (this.installed === Status.NotInstalled) {
const installed = await this.install();
if (installed) {
this.installed = Status.Installed;
return true;
}
}

return false;
}

Expand Down Expand Up @@ -145,11 +173,15 @@ export default class vscodeIbmi extends Handler {
if (callResult.code === 0) {
console.log(callResult);

const xml = await content.downloadStreamfile(`/tmp/${targetName}`);

const commandData = await xml2js.parseStringPromise(xml);

return commandData;
try {
const xml = (await content.downloadStreamfileRaw(`/tmp/${targetName}`)).toString();

const commandData = await xml2js.parseStringPromise(xml);

return commandData;
} catch (e) {
console.log(`Command likely doesn't exist: ${targetCommand}: ${e.message}`);
}
}

return undefined;
Expand Down
39 changes: 0 additions & 39 deletions client/src/test/completion.test.ts

This file was deleted.

Loading