Skip to content

Enabled multi-selection support for several commands #2620

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

Merged
merged 24 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5e220c9
Restrict multi-selection on commands
sebjulliand Apr 12, 2025
b19d5cf
Muli-selection support for generateBinderSource command
sebjulliand Apr 12, 2025
357742e
Muli-selection support for code-for-ibmi.browse/edit commands
sebjulliand Apr 12, 2025
5a36e20
Enabled multi selection for openIFSFile menu
sebjulliand Apr 12, 2025
8fdaf08
Enabled multi selection for maintainFilter command
sebjulliand Apr 12, 2025
00a1903
Fixed filter update when multiple filters are opened simultaneously
sebjulliand Apr 12, 2025
9930c58
multi selection actions (work in progress)
sebjulliand Apr 17, 2025
111aa60
Multi selection actions working
sebjulliand Apr 18, 2025
f6be325
Fixed names uppercasing
sebjulliand Apr 18, 2025
ab03174
Enhanced actions result panel for multi executions
sebjulliand Apr 19, 2025
82511f8
Enabled multi selection for search in source files
sebjulliand Apr 19, 2025
2f05e1a
Enabled multi selection for search and find in streamfiles
sebjulliand Apr 19, 2025
50d781e
Fixed warning
sebjulliand Apr 19, 2025
37f4714
Prompt once, execute many
sebjulliand Apr 19, 2025
11c3eae
Allow runAction on multiple IFS files
sebjulliand Apr 29, 2025
76b10ce
Make sure every action target belong to the same workspace
sebjulliand Apr 29, 2025
e805a28
Cleaner config object access
sebjulliand Apr 29, 2025
44eac22
Added getLocalActionsFiles method
sebjulliand May 2, 2025
ada4d2c
Enabled actions to run on multiple local files
sebjulliand May 2, 2025
9c9a667
Merge branch 'master' into multiActionSupport
sebjulliand May 2, 2025
798d625
Duplicated warning to check actions uri scheme
sebjulliand May 3, 2025
094a782
Fixed toPaseVariables exporting invalid pase variables
sebjulliand May 3, 2025
38ff4af
Added tests for each action schemes to test multiple executions
sebjulliand May 3, 2025
0b16e33
Fixed running action from editor UI
sebjulliand May 5, 2025
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
248 changes: 154 additions & 94 deletions package-lock.json

Large diffs are not rendered by default.

51 changes: 28 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2651,7 +2651,7 @@
},
{
"command": "code-for-ibmi.copyFilter",
"when": "view == objectBrowser && viewItem =~ /^filter.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^filter.*$/",
"group": "4_filters@2"
},
{
Expand All @@ -2661,27 +2661,27 @@
},
{
"command": "code-for-ibmi.moveFilterUp",
"when": "view == objectBrowser && viewItem =~ /^filter.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^filter.*$/",
"group": "inline"
},
{
"command": "code-for-ibmi.moveFilterDown",
"when": "view == objectBrowser && viewItem =~ /^filter.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^filter.*$/",
"group": "inline"
},
{
"command": "code-for-ibmi.moveFilterToTop",
"when": "view == objectBrowser && viewItem =~ /^filter.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^filter.*$/",
"group": "5_filters@1"
},
{
"command": "code-for-ibmi.moveFilterToBottom",
"when": "view == objectBrowser && viewItem =~ /^filter.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^filter.*$/",
"group": "5_filters@2"
},
{
"command": "code-for-ibmi.createMember",
"when": "view == objectBrowser && viewItem == SPF",
"when": "view == objectBrowser && !listMultiSelection && viewItem == SPF",
"group": "3_sourceFileStuff@1"
},
{
Expand Down Expand Up @@ -2721,7 +2721,7 @@
},
{
"submenu": "code-for-ibmi.debug.group",
"when": "view == objectBrowser && viewItem =~ /^object.(pgm|srvpgm).*/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^object.(pgm|srvpgm).*/",
"group": "2_debug@1"
},
{
Expand All @@ -2731,17 +2731,17 @@
},
{
"command": "code-for-ibmi.setCurrentLibrary",
"when": "!code-for-ibmi:libraryListDisabled && view == objectBrowser && viewItem =~ /library/",
"when": "!code-for-ibmi:libraryListDisabled && !listMultiSelection && view == objectBrowser && viewItem =~ /library/",
"group": "2_library@2"
},
{
"command": "code-for-ibmi.updateMemberText",
"when": "view == objectBrowser && viewItem == member",
"when": "view == objectBrowser && !listMultiSelection && viewItem == member",
"group": "2_memberStuff@1"
},
{
"command": "code-for-ibmi.copyMember",
"when": "view == objectBrowser && viewItem =~ /^member.*$/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^member.*$/",
"group": "2_memberStuff@2"
},
{
Expand All @@ -2751,7 +2751,7 @@
},
{
"command": "code-for-ibmi.renameMember",
"when": "view == objectBrowser && viewItem == member",
"when": "view == objectBrowser && !listMultiSelection && viewItem == member",
"group": "2_memberStuff@3"
},
{
Expand All @@ -2761,7 +2761,7 @@
},
{
"command": "code-for-ibmi.uploadAndReplaceMemberAsFile",
"when": "view == objectBrowser && viewItem == member",
"when": "view == objectBrowser && !listMultiSelection && viewItem == member",
"group": "3_memberTransfer@2"
},
{
Expand All @@ -2781,12 +2781,12 @@
},
{
"submenu": "code-for-ibmi.openIFSFile",
"when": "view == ifsBrowser && !listMultiSelection && viewItem == streamfile",
"when": "view == ifsBrowser && viewItem == streamfile",
"group": "0_open@1"
},
{
"command": "code-for-ibmi.runAction",
"when": "view == ifsBrowser && !listMultiSelection && viewItem == streamfile",
"when": "view == ifsBrowser && viewItem == streamfile",
"group": "1_workspace@1"
},
{
Expand Down Expand Up @@ -2821,12 +2821,12 @@
},
{
"command": "code-for-ibmi.searchIFS",
"when": "view == ifsBrowser && !listMultiSelection && viewItem =~ /^directory.*$/",
"when": "view == ifsBrowser && viewItem =~ /^directory.*$/",
"group": "3_ifsStuff@1"
},
{
"command": "code-for-ibmi.ifs.find",
"when": "view == ifsBrowser && !listMultiSelection && viewItem =~ /^(directory|shortcut).*$/",
"when": "view == ifsBrowser && viewItem =~ /^(directory|shortcut).*$/",
"group": "3_ifsStuff@2"
},
{
Expand Down Expand Up @@ -2916,12 +2916,12 @@
},
{
"command": "code-for-ibmi.changeObjectDesc",
"when": "view == objectBrowser && (viewItem =~ /^object/ || viewItem == SPF)",
"when": "view == objectBrowser && !listMultiSelection && (viewItem =~ /^object/ || viewItem == SPF)",
"group": "1_objActions@1"
},
{
"command": "code-for-ibmi.copyObject",
"when": "view == objectBrowser && (viewItem =~ /^object/ || viewItem == SPF)",
"when": "view == objectBrowser && !listMultiSelection && (viewItem =~ /^object/ || viewItem == SPF)",
"group": "1_objActions@2"
},
{
Expand All @@ -2931,17 +2931,17 @@
},
{
"command": "code-for-ibmi.renameObject",
"when": "view == objectBrowser && viewItem =~ /^object/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^object/",
"group": "1_objActions@3"
},
{
"command": "code-for-ibmi.moveObject",
"when": "view == objectBrowser && viewItem =~ /^object(?!.lib)/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /^object(?!.lib)/",
"group": "1_objActions@4"
},
{
"command": "code-for-ibmi.createSourceFile",
"when": "view == objectBrowser && viewItem =~ /library/",
"when": "view == objectBrowser && !listMultiSelection && viewItem =~ /library/",
"group": "1_LibActions@1"
},
{
Expand Down Expand Up @@ -2988,12 +2988,17 @@
"command": "code-for-ibmi.generateBinderSource",
"when": "view == objectBrowser && viewItem =~ /^object.(module|srvpgm).*/",
"group": "1_objActions@6"
}
}
],
"explorer/context": [
{
"submenu": "code-for-ibmi.compareWithLocal",
"group": "3_compare@40"
},
{
"command": "code-for-ibmi.runAction",
"when": "code-for-ibmi:connected && !explorerResourceIsFolder && code-for-ibmi:hasLocalActions",
"group": "1_localactions@01"
}
]
},
Expand Down Expand Up @@ -3041,7 +3046,7 @@
},
"dependencies": {
"@ibm/ibmi-eventf-parser": "^1.0.2",
"@vscode-elements/elements": "^1.9.1",
"@vscode-elements/elements": "^1.9.1",
"adm-zip": "^0.5.14",
"crc-32": "https://cdn.sheetjs.com/crc-32-latest/crc-32-latest.tgz",
"csv": "^6.2.1",
Expand Down
39 changes: 20 additions & 19 deletions src/Instance.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { EventEmitter } from "stream";
import * as vscode from "vscode";
import { ConnectionConfig, ConnectionData, IBMiEvent } from "./typings";
import { ILELibrarySettings } from "./api/CompileTools";
import IBMi, { ConnectionResult } from "./api/IBMi";
import { CodeForIStorage } from "./api/configuration/storage/CodeForIStorage";
import { handleConnectionResults, messageCallback } from "./ui/connection";
import { VsStorage } from "./config/Storage";
import { VsCodeConfig } from "./config/Configuration";
import { EventEmitter } from "stream";
import { ConnectionStorage } from "./api/configuration/storage/ConnectionStorage";
import { VscodeTools } from "./ui/Tools";
import { ILELibrarySettings } from "./api/CompileTools";
import { VsCodeConfig } from "./config/Configuration";
import { VsStorage } from "./config/Storage";
import { getEnvConfig } from "./filesystems/local/env";
import { ConnectionConfig, ConnectionData, IBMiEvent } from "./typings";
import { VscodeTools } from "./ui/Tools";
import { handleConnectionResults, messageCallback } from "./ui/connection";


type IBMiEventSubscription = {
func: Function,
Expand All @@ -19,9 +20,9 @@ type IBMiEventSubscription = {
type SubscriptionMap = Map<string, IBMiEventSubscription>

export interface ConnectionOptions {
data: ConnectionData,
reconnecting?: boolean,
reloadServerSettings?: boolean,
data: ConnectionData,
reconnecting?: boolean,
reloadServerSettings?: boolean,
onConnectedOperations?: Function[]
}

Expand Down Expand Up @@ -99,15 +100,15 @@ export default class Instance {
this.disconnect();

if (reconnect) {
await this.connect({...options, reconnecting: true});
await this.connect({ ...options, reconnecting: true });
}
}
};

return VscodeTools.withContext("code-for-ibmi:connecting", async () => {
while (true) {
let customError: string|undefined;
await vscode.window.withProgress({location: vscode.ProgressLocation.Notification, title: options.data.name, cancellable: true}, async (p, cancelToken) => {
let customError: string | undefined;
await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: options.data.name, cancellable: true }, async (p, cancelToken) => {
try {
const cancelEmitter = new EventEmitter();

Expand All @@ -116,16 +117,16 @@ export default class Instance {
});

result = await connection.connect(
options.data,
options.data,
{
timeoutCallback: timeoutHandler,
onConnectedOperations: options.onConnectedOperations || [],
uiErrorHandler: handleConnectionResults,
progress: (message) => {p.report(message)},
progress: (message) => { p.report(message) },
message: messageCallback,
cancelEmitter
},
options.reconnecting,
},
options.reconnecting,
options.reloadServerSettings,
);
} catch (e: any) {
Expand All @@ -144,7 +145,7 @@ export default class Instance {
modal: true,
detail: `Reconnection has failed. Would you like to try again?\n\n${customError || `No error provided.`}`
}, `Yes`)) {

options.reconnecting = true;
continue;

Expand All @@ -164,7 +165,7 @@ export default class Instance {

async disconnect() {
await this.setConnection();

await Promise.all([
vscode.commands.executeCommand("code-for-ibmi.refreshObjectBrowser"),
vscode.commands.executeCommand("code-for-ibmi.refreshLibraryListView"),
Expand Down
4 changes: 2 additions & 2 deletions src/api/Search.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as path from 'path';
import { GetMemberInfo } from './components/getMemberInfo';
import { IBMiMember, SearchHit, SearchResults } from './types';
import { Tools } from './Tools';
import IBMi from './IBMi';
import { Tools } from './Tools';
import { IBMiMember, SearchHit, SearchResults } from './types';

export namespace Search {
export async function searchMembers(connection: IBMi, library: string, sourceFile: string, searchTerm: string, members: string|IBMiMember[], readOnly?: boolean,): Promise<SearchResults> {
Expand Down
5 changes: 4 additions & 1 deletion src/api/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ export class Variables extends Map<string, string> {
toPaseVariables(): Record<string, string> {
const variables: Record<string, string> = {};
for (const [key, value] of this.entries()) {
variables[key.startsWith('&') ? key.substring(1) : key] = value;
//Env variables can't contain * or {}; keeping only &xxx variables
if(key.startsWith('&')){
variables[key.substring(1)] = value;
}
}
return variables;
}
Expand Down
Loading
Loading