Adding jar to vscode debug extension - visual-studio-code

We are having a runnable jar for the DAP(Debugger Adapater Protocol) of ABL language and we are planning to add a vscode extension for that ABL DAP.
Could you provide us some documentation or give us an idea about how to do it?

There are basically two approaches for making VS Code run your *.jar:
Declarative:
In the package.json of your extension, you can register your executable as part of the debuggers extension point. Here is the doc: https://code.visualstudio.com/api/extension-guides/debugger-extension#anatomy-of-the-package.json-of-a-debugger-extension.
And here is an example from the node.js debugger.
Basically the following attributes are available:
"runtime": "node",
"runtimeArgs": [ "--arguments_passed_to_runtime" ],
"program": "./dist/dap.js",
"args": [ "--arguments_passed_to_program" ],
The resulting command that VS Code will call is this:
node --arguments_passed_to_runtime ./dist/dap.js --arguments_passed_to_program
You do not have to make a distinction between runtime and program. You can use either "runtime" or "program" and leave out the other.
Non-declarative:
Alternatively you can use extension code to "calculate" the command that VS Code should execute when launching your Debug Adapter. See this API: https://github.com/microsoft/vscode/blob/4c3769071459718f89bd48fa3b6e806c83cf3336/src/vs/vscode.d.ts#L8797-L8816
Based on this API the following snippet shows how you could create a DebugAdapterDescriptor for your abl debugger:
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: ExtensionContext) {
vscode.debug.registerDebugAdapterDescriptorFactory('abl', {
createDebugAdapterDescriptor(session: DebugSession, executable: DebugAdapterExecutable | undefined): ProviderResult<DebugAdapterDescriptor> {
return new vscode.DebugAdapterExecutable(
"/usr/bin/java",
[
join(context.extensionPath, "bin", "abl.jar")
],
{
"cwd": "some current working directory path",
"env": {
"key": "value"
}
}
);
}
});
}

Related

VSCode extension for quick semantic info

I am used to point the mouse and get information about certain references in Visual studio code.
Here one example, using Javascript, I point the mouse to a function reference and I get information about the function signature.
I would like to have something similar to other files.
e.g.
Take the following example, in a less popular language
module top #(
parameter NB=4
);
logic [NB /*I would like info here */ -1:0] b;
endmodule
How can I write an extension that when I point the mouse to the parameter it shows me the the declaration in a box, preferably with the same syntax highlight as it is shown in the editor.
Now there is a pull request with a sample to vscode-extension-samples.
Basically you have to write something like this
import * as vscode from 'vscode';
class SimpleHoverProvider implements vscode.HoverProvider {
public provideHover(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
): vscode.Hover | null {
return new vscode.Hover(`${location.line}: ${location.character}`);
// return null; if there is no information to show
}
}
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, hover-provider-sample extension is active!');
const hoverProvider = new SimpleHoverProvider();
vscode.languages.registerHoverProvider('text', hoverProvider);
}
And define languages and activation events on package.json
{
"activationEvents": [
"onLanguage:text",
"onLanguage:report"
],
"contributes": {
"languages": [
{
"id": "text",
"extensions": [
".txt"
]
},
{
"id": "report",
"extensions": [
".rpt"
]
}
]
},
}

VS-Code command inputs using an (example) extension

In the VSCode documentation for variable substitution, it says there is now a way of using an extension to generate a list of options. Specifically, it gives an example and then says "It is assumed that some extension provides an extension.mochaSupport.testPicker command...".
I accept there is help provided in how to get started with extensions of various kinds, but I was wondering if anyone had indeed already written something equivalent to extension.mochaSupport.testPicker?
I appreciate it's probably trivial for someone not starting from scratch, but the graphic simulation on the first page implies someone has indeed already written such an extension (to generate the graphic), so my question is "does anyone know of an extension that is documented anywhere that complements this example to select an input from a list?"
I was faced with the same issue, so I wrote a small example extension. You can find the sample code on https://github.com/GianUlli/vscode-custom-command-input-example.
The basic idea is to register a command that returns a string. Following the official VS Code guide, you start by registering the command when the extension is activated in extension.ts in the activate function:
let disposable = vscode.commands.registerCommand(
'vscode-custom-command-input-example.pickTestCase',
async () => {
return pickTestCase().catch(console.error);
}
);
context.subscriptions.push(disposable);
pickTestCase is the custom function that extracts all test cases from the workspace using a glob search.
export async function pickTestCase() {
let workingFolder = getWorkspaceFolder();
return new Promise<string[]>((resolve, reject) => {
glob('*.json', { cwd: workingFolder }, (err, files) => {
if (err) {
return reject(err);
}
resolve(files);
});
})
.then((files) => {
if (files.length > 0) {
return window.showQuickPick(files);
} else {
window.showErrorMessage('Could not find any test cases.');
return undefined;
}
})
.then((testCase) => {
return testCase;
});
}
Do not forget to register the command in package.json:
"contributes": {
"commands": [
{
"command": "vscode-custom-command-input-example.pickTestCase",
"title": "Pick a test case"
}
]
}
With those pieces, the user is now able to put ${command:vscode-custom-command-input-example.pickTestCase} in his task definitions (.vscode/tasks.json) and launch configurations (.vscode/launch.json), for example in a build task:
{
"label": "Echo example",
"command": "echo",
"type": "shell",
"args": ["${command:vscode-custom-command-input-example.pickTestCase}"],
"presentation": {
"reveal": "always"
},
"group": "build"
}

Extension API - Task Provider - Build Task example

I've built an extension for a programming language that I use and I've created hotkey shortcuts for calling the compiler executable with the currently open document's URI. I want to convert that to a build task in my extension. I have made a tasks.json file with a build task that works and catches errors and such, but it only works if I put it in the current workspace.
There are absolutely no examples of adding a build task anywhere and the API documentation for task providers is specifically for Ruby Rakefiles or something. I'm just wanting to make a shell executable build task with a problem matcher. Can anyone give me an example of that?
Here's a minimal TaskProvider implementation that simply runs echo "Hello World" in the shell:
'use strict';
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
var type = "exampleProvider";
vscode.tasks.registerTaskProvider(type, {
provideTasks(token?: vscode.CancellationToken) {
var execution = new vscode.ShellExecution("echo \"Hello World\"");
var problemMatchers = ["$myProblemMatcher"];
return [
new vscode.Task({type: type}, vscode.TaskScope.Workspace,
"Build", "myExtension", execution, problemMatchers)
];
},
resolveTask(task: vscode.Task, token?: vscode.CancellationToken) {
return task;
}
});
}
The task definition (first argument for new Task()) needs to be contributed via package.json and can have additional properties if needed:
"contributes": {
"taskDefinitions": [
{
"type": "exampleProvider"
}
]
}
Extensions with a task provider should activate when the Tasks: Run Task command is executed:
"activationEvents": [
"onCommand:workbench.action.tasks.runTask"
]
And finally, the problem matcher(s) you want to reference need to be contributed in the package.json's contributes.problemMatchers section.

How can I run tests against all browsers in karma.conf.js, without making all browsers the default, or having to list them all on the command line?

I have a karma.conf.js that has defines browsers and a lot of custom launchers for testing on Browser Stack:
browsers: ["Chrome", "Firefox"],
customLaunchers: {
IE11: {
base: "BrowserStack",
browser: "IE",
browser_version: "11",
os: "Windows",
os_version: "10",
},
IE10: {
base: "BrowserStack",
browser: "IE",
browser_version: "10",
os: "Windows",
os_version: "8",
},
// ...
}
Most of the time I want to run only against Chrome and Firefox, but once in a while I want to have the tests run against all browsers known to the configuration.
I know I could put all keys of customLaunchers in browsers but that's not a great option because it would mean that most of the time I'd have to pass --browsers to limit the run to Chrome and Firefox.
I know I could list all the browsers on the command line but that's cumbersome because the list has 11 items in it and would grow even longer over time.
So is there a way to tell Karma "run against all the launchers known to you from karma.conf.js"? I've checked the documentation, searched issues and SO and found nothing.
There is no built-in option that I know of. However, the karma.conf.js file can be modified to accept a fake browser name like all that can be used as a signal that custom code in karma.conf.js should set the configuration to use all browsers known to the configuration file:
module.exports = function configure(config) {
"use strict";
var options = {
basePath: "",
// ...
browsers: ["Chrome", "Firefox"],
customLaunchers: {
IE11: // ...
IE10: // ...,
// ...
}
};
// If the user passed `--browsers all`, then we grab the list
// from the `options` object and modify `config.browsers`.
var browsers = config.browsers;
if (browsers.length === 1 && browsers[0] === "all") {
var newList = options.browsers.concat(Object.keys(options.customLaunchers));
browsers.splice.apply(browsers, [0, browsers.length].concat(newList));
}
config.set(options);
}
The options object contains the configuration for your project. When the user passes --browsers all on the command line, the value of config.browsers is modified in place to list all browsers. Note that it has to be modified in place. Replacing the value with a new array won't work, probably because Karma stores a reference before karma.conf.js is run and uses that reference from then on. Also, modifying the value of options.browsers has no effect, because config.browsers has priority. (Otherwise, --browsers [...] would not override what is in the configuration passed through karma.conf.js.)

How do I use jest with coffeescript and ES6/ES2015 (e.g. via Babel)?

My team has been using both coffeescript and ES6/ES2015 (via Babel) in our project. Since the files are ultimately compatible due to Babel, it's been working great. But I can't figure out how we can write a jest test that allows both.
I've found examples of how to use jest with coffee, or ES6 features, but not both:
Example with coffeescript
Another example with coffeescript
Example with Babel
Somewhere someone suggested to set the preprocessor as babel-jest, which works fine for me if I only use it with ES6.
These all work. But again, I can't figure out how to combine them
What I've tried
I tried my own solution:
In package.json I have:
"jest": {
"scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/node_modules/fbjs"
],
"testFileExtensions": ["coffee", "cjsx", "js", "jsx"],
"moduleFileExtensions": ["coffee", "cjsx", "js", "jsx"]
}
In jest-script-preprocessor.js, I have:
var coffee = require('coffee-react');
var transform = require('coffee-react-transform');
var babelJest = require("babel-jest");
module.exports = {
process: function(src, path) {
if (coffee.helpers.isCoffee(path)) {
console.log(path);
return coffee.compile(transform(src), {
'bare': true
});
} else {
console.log(path);
return babelJest.process(src, {
filename: path,
stage: 0
});
}
}
};
If I run a test like npm test __tests__/sometest.jsx, it loads the ES6 test file fine. That test file will import the module under test, which is also ES6, and THAT'S where it blows up. It simply says Unexpected reserved word as soon as it hits an ES6-only syntax, like import, export, etc. There is no additional line information, but I know it's ES6 that causes the problem because if I change the module under test to be ONLY export default 'mystring', it blows up, and if I change it to non-ES6 syntax like var q = 5 + 5; module.exports = q;, it imports the module fine. (Of course, that's not really a testable module, but it doesn't need to be for this proof-of-concept.)
Note the console.log() lines in there. I never see them. So one reason this has been so tricky to track down is I can't put any of my own debug logic in. I'm sure these lines run, because if I throw in some random syntax on those lines, it'll choke. But no console output.
I've tried jest-webpack-alias, which is officially recommended by jest, and it sounds great in theory: you use jest with webpack, which then allows you to use whatever preprocessors you've already set up. It gives me the same error of Unexpected reserved word. I wrote up an issue on their github repo.
Notes
I found jestpack, but I don't want to use it as it requires Node >= 5, and I want to use Node 4.2.3. It also doesn't work with Jest >= 0.8, and I want to use Jest 0.8, as it's currently the latest and I assume has the best chance of being in sync with the live docs and react version (0.14.6).
Here's what I'm doing that's working for me.
npm install --save-dev babel-jest
npm install --save-dev coffee-react
In package.json:
"jest": {
"scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/."
],
"testFileExtensions": ["coffee", "cjsx", "js", "jsx"],
"moduleFileExtensions": ["coffee", "cjsx", "js", "jsx"]
}
Take note of the unmockedModulePathPatterns. I set it to match everything in node_modules. You might not want that, but if you start getting errors like Error: Failed to get mock metadata:..., consider it, as recommended here.
In jest-script-preprocessor.js:
var babelJest = require('babel-jest');
var coffee = require('coffee-react');
module.exports = {
process: function(src, filename) {
if (filename.indexOf('node_modules') === -1) {
if (filename.match(/\.coffee|\.cjsx/)) {
src = coffee.compile(src, {bare: true});
} else {
src = babelJest.process(src, filename);
}
}
return src;
}
};