Skip to content

Commit 5bdc7fd

Browse files
committed
Merge branch 'main' into worksofliam/issue361
Signed-off-by: worksofliam <mrliamallan@live.co.uk>
2 parents 5d51d0a + 8d95287 commit 5bdc7fd

29 files changed

+736
-116
lines changed

extension/client/package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension/client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"vscode-languageclient": "^7.0.0"
1313
},
1414
"devDependencies": {
15-
"@halcyontech/vscode-ibmi-types": "^2.11.0",
15+
"@halcyontech/vscode-ibmi-types": "^2.15.3",
1616
"@types/vscode": "^1.63.0",
1717
"@vscode/test-electron": "^2.1.2"
1818
}

extension/client/src/base.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
import { CodeForIBMi } from "@halcyontech/vscode-ibmi-types";
2-
import Instance from "@halcyontech/vscode-ibmi-types/api/Instance";
3-
import { Extension, extensions } from "vscode";
2+
import Instance from "@halcyontech/vscode-ibmi-types/Instance";
3+
import { ConfigurationChangeEvent, Extension, extensions, workspace } from "vscode";
44

55
let baseExtension: Extension<CodeForIBMi>|undefined;
66

7+
export async function checkAndWait() {
8+
baseExtension = extensions.getExtension(`halcyontechltd.code-for-ibmi`);
9+
10+
if (baseExtension) {
11+
if (!baseExtension.isActive) {
12+
await baseExtension.activate();
13+
}
14+
}
15+
16+
return getInstance();
17+
}
18+
719
/**
820
* This should be used on your extension activation.
921
*/
@@ -21,4 +33,14 @@ export function loadBase(): CodeForIBMi|undefined {
2133
export function getInstance(): Instance|undefined {
2234
const base = loadBase();
2335
return (base ? base.instance : undefined);
36+
}
37+
38+
// Stolen directly from vscode-ibmi
39+
export function onCodeForIBMiConfigurationChange<T>(props: string | string[], todo: (value: ConfigurationChangeEvent) => void) {
40+
const keys = (Array.isArray(props) ? props : Array.of(props)).map(key => `code-for-ibmi.${key}`);
41+
return workspace.onDidChangeConfiguration(async event => {
42+
if (keys.some(key => event.affectsConfiguration(key))) {
43+
todo(event);
44+
}
45+
})
2446
}

extension/client/src/commands.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { commands, ExtensionContext, window } from "vscode";
2+
import { clearTableCache } from "./requests";
3+
import { LanguageClient } from "vscode-languageclient/node";
4+
5+
export function registerCommands(context: ExtensionContext, client: LanguageClient) {
6+
context.subscriptions.push(
7+
commands.registerCommand(`vscode-rpgle.server.reloadCache`, () => {
8+
clearTableCache(client);
9+
})
10+
)
11+
}

extension/client/src/extension.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* ------------------------------------------------------------------------------------------ */
55

66
import * as path from 'path';
7-
import { workspace, ExtensionContext, Uri, commands, RelativePattern } from 'vscode';
7+
import { workspace, ExtensionContext } from 'vscode';
88

99
import * as Linter from "./linter";
1010
import * as columnAssist from "./language/columnAssist";
@@ -18,8 +18,11 @@ import {
1818
} from 'vscode-languageclient/node';
1919

2020
import { projectFilesGlob } from './configuration';
21-
import buildRequestHandlers from './requests';
21+
import { clearTableCache, buildRequestHandlers } from './requests';
2222
import { getServerImplementationProvider, getServerSymbolProvider } from './language/serverReferences';
23+
import { checkAndWait, loadBase, onCodeForIBMiConfigurationChange } from './base';
24+
import { registerCommands } from './commands';
25+
import { setLanguageSettings } from './language/config';
2326

2427
let client: LanguageClient;
2528

@@ -43,6 +46,8 @@ export function activate(context: ExtensionContext) {
4346
}
4447
};
4548

49+
loadBase();
50+
4651
// Options to control the language client
4752
const clientOptions: LanguageClientOptions = {
4853
// Register the server for plain text documents
@@ -66,8 +71,25 @@ export function activate(context: ExtensionContext) {
6671
clientOptions
6772
);
6873

69-
client.onReady().then(() => {
74+
client.onReady().then(async () => {
7075
buildRequestHandlers(client);
76+
77+
const instance = await checkAndWait();
78+
79+
// We need to clear table caches when the connection changes
80+
if (instance) {
81+
// When the connection is established
82+
instance.subscribe(context, "connected", "vscode-rpgle", () => {
83+
clearTableCache(client);
84+
});
85+
86+
// When the library list changes
87+
context.subscriptions.push(
88+
onCodeForIBMiConfigurationChange("connectionSettings", async () => {
89+
clearTableCache(client);
90+
}),
91+
);
92+
}
7193
});
7294

7395
// Start the client. This will also launch the server
@@ -76,11 +98,14 @@ export function activate(context: ExtensionContext) {
7698
Linter.initialise(context);
7799
columnAssist.registerColumnAssist(context);
78100

101+
registerCommands(context, client);
102+
79103
context.subscriptions.push(getServerSymbolProvider());
80104
context.subscriptions.push(getServerImplementationProvider());
81-
105+
context.subscriptions.push(setLanguageSettings());
82106
// context.subscriptions.push(...initBuilder(client));
83107

108+
84109
console.log(`started`);
85110
}
86111

extension/client/src/language/columnAssist.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
import { commands, DecorationOptions, ExtensionContext, Range, ThemeColor, window } from 'vscode';
2+
import { commands, DecorationOptions, ExtensionContext, Range, Selection, TextDocument, ThemeColor, window } from 'vscode';
33
import * as Configuration from "../configuration";
44
import { loadBase } from '../base';
55

@@ -42,6 +42,15 @@ const getAreasForLine = (line: string, index: number) => {
4242
}
4343
}
4444

45+
function documentIsFree(document: TextDocument) {
46+
if (document.languageId === `rpgle`) {
47+
const line = document.getText(new Range(0, 0, 0, 6)).toUpperCase();
48+
return line === `**FREE`;
49+
}
50+
51+
return false;
52+
}
53+
4554
export function registerColumnAssist(context: ExtensionContext) {
4655
context.subscriptions.push(
4756
commands.registerCommand(`vscode-rpgle.assist.launchUI`, async () => {
@@ -50,7 +59,7 @@ export function registerColumnAssist(context: ExtensionContext) {
5059
const document = editor.document;
5160

5261
if (document.languageId === `rpgle`) {
53-
if (document.getText(new Range(0, 0, 0, 6)).toUpperCase() !== `**FREE`) {
62+
if (!documentIsFree(document)) {
5463
const lineNumber = editor.selection.start.line;
5564
const positionIndex = editor.selection.start.character;
5665

@@ -81,6 +90,13 @@ export function registerColumnAssist(context: ExtensionContext) {
8190
}
8291
}),
8392

93+
commands.registerCommand(`vscode-rpgle.assist.moveLeft`, () => {
94+
moveFromPosition(`left`);
95+
}),
96+
commands.registerCommand(`vscode-rpgle.assist.moveRight`, () => {
97+
moveFromPosition(`right`);
98+
}),
99+
84100
window.onDidChangeTextEditorSelection(e => {
85101
const editor = e.textEditor;
86102
if (rulerEnabled) {
@@ -92,13 +108,43 @@ export function registerColumnAssist(context: ExtensionContext) {
92108
)
93109
}
94110

111+
function moveFromPosition(direction: "left"|"right", editor = window.activeTextEditor) {
112+
if (editor && editor.document.languageId === `rpgle` && !documentIsFree(editor.document)) {
113+
const document = editor.document;
114+
const lineNumber = editor.selection.start.line;
115+
const positionIndex = editor.selection.start.character;
116+
117+
const positionsData = getAreasForLine(
118+
document.getText(new Range(lineNumber, 0, lineNumber, 100)),
119+
positionIndex
120+
);
121+
122+
if (positionsData) {
123+
let newIndex: number|undefined;
124+
if (direction === `left`) {
125+
newIndex = positionsData.active - 1;
126+
} else
127+
if (direction === `right`) {
128+
newIndex = positionsData.active + 1;
129+
}
130+
131+
if (newIndex !== undefined && newIndex >= 0 && newIndex < positionsData.specification.length) {
132+
const box = positionsData.specification[newIndex];
133+
if (box) {
134+
editor.selection = new Selection(lineNumber, box.start, lineNumber, box.start);
135+
}
136+
}
137+
}
138+
}
139+
}
140+
95141
function updateRuler(editor = window.activeTextEditor) {
96142
let clear = true;
97143

98144
if (editor) {
99145
const document = editor.document;
100146
if (document.languageId === `rpgle`) {
101-
if (document.getText(new Range(0, 0, 0, 6)).toUpperCase() !== `**FREE`) {
147+
if (!documentIsFree(document)) {
102148
const lineNumber = editor.selection.start.line;
103149
const positionIndex = editor.selection.start.character;
104150

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { languages } from "vscode";
2+
3+
export function setLanguageSettings() {
4+
return languages.setLanguageConfiguration(`rpgle`, {
5+
wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
6+
});
7+
}

extension/client/src/language/serverReferences.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { commands, Definition, DocumentSymbol, languages, Location, ProgressLocation, Range, SymbolInformation, SymbolKind, TextDocument, Uri, window, workspace } from "vscode";
22
import { getInstance } from "../base";
33
import IBMi from "@halcyontech/vscode-ibmi-types/api/IBMi";
4-
import { ConnectionConfiguration } from "@halcyontech/vscode-ibmi-types/api/Configuration";
5-
import { IBMiMember } from "@halcyontech/vscode-ibmi-types";
4+
import { ConnectionConfig, IBMiMember } from "@halcyontech/vscode-ibmi-types";
65

76
export function getServerSymbolProvider() {
87
let latestFetch: ExportInfo[]|undefined;
@@ -68,11 +67,11 @@ export function getServerImplementationProvider() {
6867
return languages.registerImplementationProvider({language: `rpgle`, scheme: `member`}, {
6968
async provideImplementation(document, position, token): Promise<Definition|undefined> {
7069
const instance = getInstance();
70+
const connection = instance?.getConnection();
7171

72-
if (instance && instance.getConnection()) {
72+
if (connection) {
7373
const word = document.getText(document.getWordRangeAtPosition(position));
74-
const connection = instance.getConnection();
75-
const config = connection.config! //TODO in vscode-ibmi 3.0.0 - change to getConfig()
74+
const config = connection.getConfig() //TODO in vscode-ibmi 3.0.0 - change to getConfig()
7675

7776
const uriPath = document.uri.path;
7877
const member = connection.parserMemberPath(uriPath);
@@ -117,7 +116,7 @@ async function getSymbolFromDocument(docUri: Uri, name: string): Promise<Documen
117116
return;
118117
}
119118

120-
function getLibraryList(config: ConnectionConfiguration.Parameters, member?: IBMiMember): string[] {
119+
function getLibraryList(config: ConnectionConfig, member?: IBMiMember): string[] {
121120
let libraryList = [config.currentLibrary, ...config.libraryList];
122121

123122
if (member) {

0 commit comments

Comments
 (0)