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

feat(Go to file): Autotype suggestions typing path #1680

Merged
178 changes: 167 additions & 11 deletions src/instantiate.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Tools } from './api/Tools';

import path, { dirname } from 'path';
import * as vscode from "vscode";
Expand Down Expand Up @@ -171,12 +172,19 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {
vscode.commands.registerCommand(`code-for-ibmi.goToFileReadOnly`, async () => vscode.commands.executeCommand(`code-for-ibmi.goToFile`, true)),
vscode.commands.registerCommand(`code-for-ibmi.goToFile`, async (readonly?: boolean) => {
const storage = instance.getStorage();
if (!storage) return;
const content = instance.getContent();
const config = instance.getConfig();

const sources = storage.getSourceList();
const dirs = Object.keys(sources);
if (!storage && !content) return;
let list: string[] = [];

const sources = storage!.getSourceList();
const dirs = Object.keys(sources);

let listSchema: vscode.QuickPickItem[] = [],
listFile: vscode.QuickPickItem[] = [],
listMember: vscode.QuickPickItem[] = [];

dirs.forEach(dir => {
sources[dir].forEach(source => {
list.push(`${dir}${dir.endsWith(`/`) ? `` : `/`}${source}`);
Expand All @@ -185,26 +193,174 @@ export async function loadAllofExtension(context: vscode.ExtensionContext) {

list.push(`Clear list`);

const quickPick = vscode.window.createQuickPick();
quickPick.items = list.map(item => ({ label: item }));
quickPick.placeholder = `Enter file path (Format: LIB/SPF/NAME.ext or /home/xx/file.txt)`;
const listItems: vscode.QuickPickItem[] = list.map(item => ({ label: item }));

quickPick.onDidChangeValue(() => {
const quickPick = vscode.window.createQuickPick();
quickPick.items = listItems;
quickPick.placeholder = `Enter file path (format: LIB/SPF/NAME.ext (wildcard: '*') or /home/xx/file.txt)`;

// Create a cache for Schema if autosuggest enabled
if (listSchema.length === 0 && config && config.enableSQL) {
const resultSetLibrary = await content!.runSQL(`SELECT cast(SYSTEM_SCHEMA_NAME as char(10) for bit data) SYSTEM_SCHEMA_NAME,
ifnull(cast(SCHEMA_TEXT as char(50) for bit data), '') SCHEMA_TEXT
FROM QSYS2.SYSSCHEMAS
ORDER BY 1 `);

if (listSchema.length === 0 && resultSetLibrary.length > 0) {
resultSetLibrary.forEach(row => {
listSchema.push({
label: String(row.SYSTEM_SCHEMA_NAME),
detail: String(row.SCHEMA_TEXT)
})
})
}
}

quickPick.onDidChangeValue(async () => {
// INJECT user values into proposed values
if (!list.includes(quickPick.value.toUpperCase())) quickPick.items = [quickPick.value.toUpperCase(), ...list].map(label => ({ label }));

// autosuggest
if (config && config.enableSQL && (!quickPick.value.startsWith(`/`)) && quickPick.value.endsWith(`*`)) {
let filterText = '';

const selectionSplit = quickPick.value.toUpperCase().split('/');
let resultSet: Tools.DB2Row[] = [];
let listDisplay: vscode.QuickPickItem[] = [];

switch (selectionSplit.length) {
case 1:
// Clear cache when bib change
listFile = [];
listMember = [];

filterText = selectionSplit[0].substring(0, selectionSplit[0].indexOf(`*`));
listDisplay = listSchema.filter(schema => schema.label.startsWith(filterText));

quickPick.items = [
{
label: 'Libraries',
kind: vscode.QuickPickItemKind.Separator
},
...listDisplay,
{
label: 'Files',
kind: vscode.QuickPickItemKind.Separator
},
...listItems
]

break;

case 2:
// Create cache
listMember = [];
if (listFile.length === 0) {

filterText = selectionSplit[1].substring(0, selectionSplit[1].indexOf(`*`));

resultSet = await content!.runSQL(`SELECT
ifnull(cast(system_table_name as char(10) for bit data), '') AS SYSTEM_TABLE_NAME,
ifnull(TABLE_TEXT, '') TABLE_TEXT
FROM QSYS2.SYSTABLES
WHERE TABLE_SCHEMA = '${selectionSplit[0]}'
AND FILE_TYPE = 'S'
AND SYSTEM_TABLE_NAME like '${filterText}%'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here about filterText being blank.

ORDER BY 1`);

if (listFile.length === 0 && resultSet.length > 0) {
resultSet.forEach(row => {
listFile.push({
label: selectionSplit[0] + '/' + String(row.SYSTEM_TABLE_NAME),
detail: String(row.TABLE_TEXT)
})
})
}
}

listDisplay = listFile.filter(file => file.label.startsWith(selectionSplit[0] + '/' + filterText));

quickPick.items = [
{
label: 'Source files',
kind: vscode.QuickPickItemKind.Separator
},
...listDisplay,
{
label: 'Files',
kind: vscode.QuickPickItemKind.Separator
},
...listItems
]

break;

case 3:
// Create cache
if (listMember.length === 0) {

filterText = selectionSplit[2].substring(0, selectionSplit[2].indexOf(`*`));

resultSet = await content!.runSQL(`SELECT cast(TABLE_PARTITION as char(10) for bit data) TABLE_PARTITION,
ifnull(PARTITION_TEXT, '') PARTITION_TEXT,
lower(ifnull(SOURCE_TYPE, '')) SOURCE_TYPE
FROM qsys2.SYSPARTITIONSTAT
WHERE TABLE_SCHEMA = '${selectionSplit[0]}'
AND table_name = '${selectionSplit[1]}'
AND TABLE_PARTITION like '${filterText}%'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider not adding this condition against TABLE_PARTITION when filterText is blank. It's evaluating to: TABLE_PARITION like '%'.

QSYSINC/H/*

ORDER BY 1
LIMIT 30`);

if (listMember.length === 0 && resultSet.length > 0) {
resultSet.forEach(row => {
listMember.push({
label: selectionSplit[0] + '/' + selectionSplit[1] + '/' + String(row.TABLE_PARTITION) + '.' + String(row.SOURCE_TYPE),
detail: String(row.PARTITION_TEXT)
})
})
}
}

listDisplay = listMember.filter(member => member.label.startsWith(selectionSplit[0] + '/' + selectionSplit[1] + '/' + filterText));

quickPick.items = [
{
label: 'Members',
kind: vscode.QuickPickItemKind.Separator
},
...listDisplay,
{
label: 'Files',
kind: vscode.QuickPickItemKind.Separator
},
...listItems
]

break;

default:
break;
}
}
})

quickPick.onDidAccept(() => {
quickPick.onDidAccept(() => {
const selection = quickPick.selectedItems[0].label;
if (selection) {
if (selection === `Clear list`) {
storage.setSourceList({});
storage!.setSourceList({});
vscode.window.showInformationMessage(`Cleared list.`);
quickPick.hide()
} else {
vscode.commands.executeCommand(`code-for-ibmi.openEditable`, selection, 0, { readonly });
const selectionSplit = selection.split('/')
if (selectionSplit.length === 3 || selection.startsWith(`/`)) {
vscode.commands.executeCommand(`code-for-ibmi.openEditable`, selection, 0, { readonly });
quickPick.hide()
} else {
quickPick.value = selection.toUpperCase() + '/'
}
}
}
quickPick.hide()
})
quickPick.onDidHide(() => quickPick.dispose());
quickPick.show();
Expand Down