Skip to content

Commit

Permalink
Merge pull request #36 from chrispahm/main-gms-statusbar
Browse files Browse the repository at this point in the history
✨ add menubar item and commands for main gms file
  • Loading branch information
chrispahm authored Oct 14, 2023
2 parents 9178393 + 89d7b13 commit be7fbc3
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 17 deletions.
104 changes: 102 additions & 2 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ const getGamsIdeDataViewContainerContent = require("./src/utils/getGamsIdeDataVi
const debouncedListenToLstFiles = require("./src/parseLstFiles");
const provideGAMSCompletionItems = require("./src/provideGAMSCompletionItems");
const provideGAMSSignatureHelp = require("./src/provideGAMSSignatureHelp");
const updateStatusBar = require("./src/utils/updateStatusBar");
const checkIfExcluded = require("./src/utils/checkIfExcluded");
const State = require("./src/State.js");

let terminal;
let gamsView;
let gamsDataView;

let gamsStatusBarItem;

async function activate(context) {
// first, we try to delete all contents of the scratch directory (scrdir) to avoid
Expand Down Expand Up @@ -110,11 +112,102 @@ async function activate(context) {
}, "(", ",")
);

// register status bar item showing the current main file
gamsStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
context.subscriptions.push(gamsStatusBarItem);

// register some listener that make sure the status bar
// item id always up-to-date
context.subscriptions.push(
vscode.window.onDidChangeActiveTextEditor(() => updateStatusBar(gamsStatusBarItem))
);

updateStatusBar(gamsStatusBarItem);

// register a command to execute a GAMS file
context.subscriptions.push(
vscode.commands.registerCommand("gams.run", () => runGams(terminal))
);

// gams stop -> sigterm
context.subscriptions.push(
vscode.commands.registerCommand("gams.stop", () => terminal.sendText(String.fromCharCode(3)))
);

// gams kill -> sigkill
context.subscriptions.push(
vscode.commands.registerCommand("gams.kill", () => terminal.sendText(String.fromCharCode(24)))
);

// add "Set as main GAMS file" command
context.subscriptions.push(
vscode.commands.registerCommand("gams.setAsMainGmsFile", () => {
const file = vscode.window.activeTextEditor?.document.fileName;
vscode.workspace.getConfiguration().update("gamsIde.mainGmsFile", file, vscode.ConfigurationTarget.Workspace);
})
);

// add "Clear main GAMS file" command
context.subscriptions.push(
vscode.commands.registerCommand("gams.clearMainGmsFile", () => {
vscode.workspace.getConfiguration().update("gamsIde.mainGmsFile", "", vscode.ConfigurationTarget.Workspace);
})
);

// add "Add to exclude from main GAMS file" command
context.subscriptions.push(
vscode.commands.registerCommand("gams.addToExcludeFromMainGmsFile", () => {
const file = vscode.window.activeTextEditor?.document.fileName;
const excludeFromMainGmsFile = vscode.workspace.getConfiguration().get("gamsIde.excludeFromMainGmsFile");
// check if the file is already excluded
if (checkIfExcluded(file, excludeFromMainGmsFile)) {
vscode.window.showInformationMessage("File is already excluded.");
return;
} else {
excludeFromMainGmsFile.push(file);
vscode.workspace.getConfiguration().update("gamsIde.excludeFromMainGmsFile", excludeFromMainGmsFile, vscode.ConfigurationTarget.Workspace);
}
})
);

// add "Remove from exclude from main GAMS file" command
context.subscriptions.push(
vscode.commands.registerCommand("gams.removeFromExcludeFromMainGmsFile", () => {
const file = vscode.window.activeTextEditor?.document.fileName;
const excludeFromMainGmsFile = vscode.workspace.getConfiguration().get("gamsIde.excludeFromMainGmsFile");
const matchedExcludePath = checkIfExcluded(file, excludeFromMainGmsFile, true);
// check if the file is already excluded
if (!matchedExcludePath) {
vscode.window.showInformationMessage("File is not excluded.");
return;
} else {
const index = excludeFromMainGmsFile.indexOf(matchedExcludePath);
excludeFromMainGmsFile.splice(index, 1);
vscode.workspace.getConfiguration().update("gamsIde.excludeFromMainGmsFile", excludeFromMainGmsFile, vscode.ConfigurationTarget.Workspace);
}
})
);

// add "Select main GAMS file" command
context.subscriptions.push(
vscode.commands.registerCommand("gams.selectMainGmsFile", async () => {
// show a quick pick to select the main GAMS file
// only show gams files from the current workspace
const gmsFiles = await vscode.workspace.findFiles("**/*.gms");
const quickPick = vscode.window.createQuickPick();
quickPick.items = gmsFiles.map((file) => ({ label: file.fsPath }));
quickPick.title = "Select main GAMS file";
quickPick.onDidChangeSelection((selection) => {
if (selection[0]) {
vscode.workspace.getConfiguration().update("gamsIde.mainGmsFile", selection[0].label, vscode.ConfigurationTarget.Workspace);
quickPick.hide();
}
});
quickPick.onDidHide(() => quickPick.dispose());
quickPick.show();
})
);

context.subscriptions.push(
vscode.commands.registerCommand("gams.runThisFile", () => runGams(terminal, false, true))
);
Expand Down Expand Up @@ -301,7 +394,7 @@ async function activate(context) {

webviewView.webview.onDidReceiveMessage(async message => {
switch (message.command) {
case 'enableSymbolParsing':
case 'enableDataParsing':
vscode.workspace.getConfiguration("gamsIde").update("parseGamsData", true);
break;
}
Expand Down Expand Up @@ -352,6 +445,13 @@ async function activate(context) {
updateDiagnostics({ document: editor.document, collection, gamsDataView, state, terminal });
}
}
} else if (e.affectsConfiguration("gamsIde.mainGmsFile") || e.affectsConfiguration("gamsIde.excludeFromMainGmsFile")) {
updateStatusBar(gamsStatusBarItem);
// re-run diagnostics
const editor = vscode.window.activeTextEditor;
if (editor && editor.document.languageId === "gams") {
updateDiagnostics({ document: editor.document, collection, gamsDataView, state, terminal });
}
}
});
}
Expand Down
30 changes: 29 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,34 @@
{
"command": "gams.openSymbolPanel",
"title": "GAMS: Open Symbol Panel"
},
{
"command": "gams.stop",
"title": "GAMS: Stop"
},
{
"command": "gams.kill",
"title": "GAMS: Kill"
},
{
"command": "gams.setAsMainGmsFile",
"title": "GAMS: Set as main GAMS file"
},
{
"command": "gams.clearMainGmsFile",
"title": "GAMS: Clear main GAMS file"
},
{
"command": "gams.addToExcludeFromMainGmsFile",
"title": "GAMS: Add to exclude from main GAMS file list"
},
{
"command": "gams.removeFromExcludeFromMainGmsFile",
"title": "GAMS: Remove from exclude from main GAMS file list"
},
{
"command": "gams.selectMainGmsFile",
"title": "GAMS: Select main GAMS file"
}
],
"configuration": {
Expand Down Expand Up @@ -151,7 +179,7 @@
"panel": [
{
"id": "gamsIdeSymbolContainer",
"title": "GAMS Symbols",
"title": "GAMS Data",
"icon": "media/logo.svg"
}
]
Expand Down
2 changes: 1 addition & 1 deletion src/diagnostics.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ module.exports = async function updateDiagnostics(args) {
// show error in VS Code output
// and add button to open the dmp file
if (!state.get("ignoreDataValueParsingError")) {
vscode.window.showWarningMessage("GAMS Symbols: " + err + ".\nClick 'Hide error' to hide for this session.", "Hide error", "Disable data parsing", "Open DMP .lst").then((value) => {
vscode.window.showWarningMessage("GAMS Data Parsing: " + err + ".\nClick 'Hide error' to hide for this session.", "Hide error", "Disable data parsing", "Open DMP .lst").then((value) => {
if (value === "Open DMP .lst") {
vscode.workspace.openTextDocument(format({ ...parse(compileCommand.dumpPath), base: '', ext: '.lst' })).then((doc) => {
vscode.window.showTextDocument(doc);
Expand Down
14 changes: 5 additions & 9 deletions src/utils/checkIfExcluded.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const path = require('path');

module.exports = function checkIfExcluded(filePath, pathsToExclude) {
module.exports = function checkIfExcluded(filePath = "", pathsToExclude = [], returnMatchedPath = false) {
// filePath is an absolute file path (e.g. "/home/user/subdir/file.gms")
// pathsToExclude is an array of strings, where each entry can be:
// - a relative path to a file or folder (e.g. "subdir/file.gms", "subdir")
Expand All @@ -12,24 +12,20 @@ module.exports = function checkIfExcluded(filePath, pathsToExclude) {
if (path.isAbsolute(pathToExclude)) {
// check if the file is excluded
if (filePath.startsWith(pathToExclude)) {
console.log("Excluded file: ", filePath, pathToExclude);
return true;
return returnMatchedPath ? pathToExclude : true;
}
} else {
// check if the a single file is referenced
if (pathToExclude.toLowerCase().endsWith(".gms") && filePath.endsWith(pathToExclude)) {
console.log("Excluded file: ", filePath, pathToExclude);
return true;
return returnMatchedPath ? pathToExclude : true;
} else if (path.parse(filePath).dir.endsWith(pathToExclude)) {
console.log("Excluded file: ", filePath, pathToExclude);
return true;
return returnMatchedPath ? pathToExclude : true;
}
// for folders, we have to check if any of the parent directories has the same name
const directoriesInFilePath = filePath.split(path.sep);
directoriesInFilePath.some((directory) => {
if (directory === pathToExclude) {
console.log("Excluded file: ", filePath, pathToExclude);
return true;
return returnMatchedPath ? pathToExclude : true;
}
});
}
Expand Down
8 changes: 4 additions & 4 deletions src/utils/getGamsIdeDataViewContainerContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = function getGamsIdeDataViewContainerContent(options) {
</vscode-dropdown>
</div>
<pre id="gams-symbols-content" style="padding: 40px 0px;">
${ !isDataParsingEnabled ? "Symbol parsing is disabled. <a class='link' onclick='enableSymbolParsing()'>Click here to enable it.</a>" : "No data to show. Click on a symbol to get started!" }
${ !isDataParsingEnabled ? "GAMS Data parsing is disabled. <a class='link' onclick='enableDataParsing()'>Click here to enable it.</a>" : "No data to show. Click on a symbol to get started!" }
</pre>
</body>
<script type="module">
Expand Down Expand Up @@ -83,9 +83,9 @@ module.exports = function getGamsIdeDataViewContainerContent(options) {
const dropdown = document.getElementById('gams-symbols-dropdown');
const content = document.getElementById('gams-symbols-content');
window.enableSymbolParsing = function() {
window.enableDataParsing = function() {
vscode.postMessage({
command: 'enableSymbolParsing'
command: 'enableDataParsing'
});
}
// Handle messages sent from the extension to the webview
Expand All @@ -96,7 +96,7 @@ module.exports = function getGamsIdeDataViewContainerContent(options) {
if (message.data.isDataParsingEnabled) {
content.innerHTML = "No data to show. Click on a symbol to get started!";
} else {
content.innerHTML = "Symbol parsing is disabled. <a class='link' onclick='enableSymbolParsing()'>Click here to enable it.</a>";
content.innerHTML = "Symbol parsing is disabled. <a class='link' onclick='enableDataParsing()'>Click here to enable it.</a>";
}
break;
case 'updateSymbolError':
Expand Down
26 changes: 26 additions & 0 deletions src/utils/updateStatusBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const checkIfExcluded = require('./checkIfExcluded');
const path = require('path');
const vscode = require('vscode');

module.exports = function updateStatusBar(gamsStatusBarItem) {
const file = vscode.window.activeTextEditor?.document.fileName;
const mainGmsFile = vscode.workspace.getConfiguration('gamsIde').get('mainGmsFile');
const excludedFiles = vscode.workspace.getConfiguration('gamsIde').get('excludeFromMainGmsFile');
const fileIsExcluded = checkIfExcluded(file, excludedFiles);
const languageId = vscode.window.activeTextEditor?.document.languageId;
if (languageId !== 'gams') {
gamsStatusBarItem.hide();
} else if (fileIsExcluded && mainGmsFile) {
gamsStatusBarItem.text = `Main GMS: File is excluded`;
// open workspace settings.json -> excludeFromMainGmsFile
gamsStatusBarItem.command = 'workbench.action.openWorkspaceSettingsFile';
gamsStatusBarItem.show();
} else if (mainGmsFile) {
gamsStatusBarItem.text = `Main GMS: ${path.basename(mainGmsFile)}`;
// open settings for mainGmsFile
gamsStatusBarItem.command = 'gams.selectMainGmsFile';
gamsStatusBarItem.show();
} else {
gamsStatusBarItem.hide();
}
};

0 comments on commit be7fbc3

Please sign in to comment.