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

Basic VSCode support for Enso language and development #4014

Merged
merged 10 commits into from
Jan 6, 2023
2 changes: 1 addition & 1 deletion .github/workflows/enso4igv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
mvn versions:set -DnewVersion=`mvn -q -DforceStdout help:evaluate -Dexpression=project.version | cut -f1 -d -`.$GITHUB_RUN_NUMBER

- name: Build with Maven
run: mvn -B package --file tools/enso4igv/pom.xml
run: mvn -B -Pvsix package --file tools/enso4igv/pom.xml
- name: Archive NBM file
uses: actions/upload-artifact@v3
with:
Expand Down
2 changes: 2 additions & 0 deletions tools/enso4igv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.vsix
nbcode
5 changes: 5 additions & 0 deletions tools/enso4igv/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
target
src
*.vsix
node_modules

24 changes: 23 additions & 1 deletion tools/enso4igv/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Enso Language Support for NetBeans & Ideal Graph Visualizer
# Enso Language Support for NetBeans, Ideal Graph Visualizer & VSCode

[![Enso Language Support for IGV](https://github.com/enso-org/enso/actions/workflows/enso4igv.yml/badge.svg)](https://github.com/enso-org/enso/actions/workflows/enso4igv.yml)

Expand Down Expand Up @@ -150,3 +150,25 @@ target/enso4igv-*-SNAPSHOT.nbm

an NBM file is generated which can be installed into IGV, NetBeans or any other
NetBeans based application.

## Building VSCode Extension

One can package the same plugin into a VSCode extension and obtain _Enso_
syntax coloring as well as support for editing `engine/runtime` sources in
**VSCode**. Just invoke:

```
enso/tools/enso4igv$ npm install
enso/tools/enso4igv$ npm run vsix
enso/tools/enso4igv$ ls *.vsix
enso4vscode-*.vsix
```

one needs to have `npm`, Java and `mvn` available to successfully build the
VSCode extension. Alternatively one can use Maven to built the VSIX extension
via `mvn clean install -Pvsix`.

![Install from VSIX...](https://user-images.githubusercontent.com/26887752/210131513-8c729f9b-5ddc-43aa-9ad5-420b7d87d81d.png)

Once the `.vsix` file is created, it can be installed into VSCode. Select
_Extension perspective_ and choose _Install from VSIX..._ menu item.
97 changes: 97 additions & 0 deletions tools/enso4igv/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
"name": "enso4vscode",
"displayName": "Enso Tools for VSCode",
"description": "Support for Enso programming and development",
"version": "0.1.0",
"preview": true,
"license": "SEE LICENSE IN dist/LICENSE",
"publisher": "enso",
"author": {
"name": "Enso.org"
},
"homepage": "https://github.com/enso-org/enso/blob/develop/tools/enso4igv/README.md",
"repository": {
"type": "git",
"url": "https://github.com/enso-org/enso.git"
},
"bugs": {
"url": "https://github.com/enso-org/enso/issues"
},
"engines": {
"vscode": "^1.49.0"
},
"categories": [
"Programming Languages",
"Other"
],
"keywords": [
"polyglot",
"graalvm",
"truffle"
],
"activationEvents": [
"onLanguage:enso"
],
"main": "./dist/extension",
"contributes": {
"configuration": {},
"commands": [],
"viewsContainers": {},
"viewsWelcome": [],
"views": {},
"menus": {},
"languages": [
{
"id": "enso",
"aliases": [
"Enso"
],
"extensions": [
".enso"
],
"configuration": "./src/main/resources/org/enso/tools/enso4igv/enso.tmLanguage.json"
}
],
"grammars": [
{
"language": "enso",
"scopeName": "source.enso",
"path": "./src/main/resources/org/enso/tools/enso4igv/enso.tmLanguage.json"
}
],
"snippets": [],
"breakpoints": [
{
"language": "enso"
}
],
"debuggers": []
},
"scripts": {
"vsix": "vsce package",
"vscode:prepublish": "webpack --mode production",
"compile": "tsc -p ./",
"webpack": "webpack --mode development",
"info": "webpack --display-modules",
"watch": "webpack --mode development --watch",
"lint": "tslint -p ./"
},
"dependencies": {
"copy-webpack-plugin": "^10.2.4",
"decompress": "4.2.1",
"maven": "^5.0.0"
},
"devDependencies": {
"@types/vscode": "=1.49.0",
"@types/xml2js": "^0.4.8",
"ts-loader": "^6.2.1",
"tslint": "^6.1.0",
"typescript": "^3.9.10",
"vsce": "^2.6.4",
"webpack": "^5.40.0",
"webpack-cli": "^4.7.2"
},
"extensionDependencies": [
"asf.apache-netbeans-java"
]
}
33 changes: 33 additions & 0 deletions tools/enso4igv/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,37 @@
<netbeans.version>RELEASE113</netbeans.version>
<netbeans.compile.on.save>none</netbeans.compile.on.save>
</properties>
<profiles>
<profile>
<id>vsix</id>
<build>
<plugins>
<plugin>
<groupId>com.seovic.maven.plugins</groupId>
<artifactId>npm-maven-plugin</artifactId>
<version>1.0.4</version>
<executions>
<execution>
<id>install</id>
<phase>pre-integration-test</phase>
<goals>
<goal>install</goal>
</goals>
</execution>
<execution>
<id>vsix</id>
<phase>post-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<script>vsix</script>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
1 change: 1 addition & 0 deletions tools/enso4igv/src/main/vscode/extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Copy link
Member

Choose a reason for hiding this comment

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

Very elegant piece of code! 👀

23 changes: 23 additions & 0 deletions tools/enso4igv/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "dist",
"lib": [
"es6"
],
"sourceMap": true,
"rootDir": "src/main/vscode",
/* Strict Type-Checking Option */
"strict": true, /* enable all strict type-checking options */
/* Additional Checks */
"noUnusedLocals": true, /* Report errors on unused locals. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
"noUnusedParameters": true /* Report errors on unused parameters. */
},
"exclude": [
"node_modules",
".vscode-test"
]
}
141 changes: 141 additions & 0 deletions tools/enso4igv/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//@ts-check

'use strict';

const path = require('path');
const maven = require('maven');
const CopyPlugin = require("copy-webpack-plugin");
const webpack = require('webpack');

const mvnBuild = {
apply: (compiler) => {
compiler.hooks.beforeCompile.tapPromise('MavenPlugin', (compilation) => {
const mvn = maven.create({ cwd: '.' });
return mvn.execute(['package'], { 'skipTests': true });
}
);
}
};

const copyCluster = new CopyPlugin({
patterns: [
{
from: "./target/nbm/clusters/extra/",
to: "../nbcode/enso4igv/"
}
]
});
const copyLicense = new CopyPlugin({
patterns: [
{
from: "../../LICENSE",
to: "."
}
]
});

const entryExtension = {
extension: './src/main/vscode/extension.ts' // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
};


/**@type {import('webpack').Configuration}*/
const config = {
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/

plugins: [
mvnBuild,
copyCluster,
copyLicense
],
entry: entryExtension,
output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
devtool: 'source-map',
externals: {
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
},
resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js'],
symlinks: false
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
include: path.resolve(__dirname, 'src'),
use: [{
loader: 'ts-loader'
}]
}]
},
}
const devConf = {
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/

plugins: [
mvnBuild,
copyCluster,
copyLicense,
new webpack.AutomaticPrefetchPlugin()
],
entry: entryExtension,
output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
devtool: 'source-map',
externals: {
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
},
resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js'],
symlinks: false,
cacheWithContext: false
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
include: path.resolve(__dirname, 'src'),
use: [{
loader: 'ts-loader',
options: {
transpileOnly: true, // https://github.com/TypeStrong/ts-loader#faster-builds
}
}]
}]
},
optimization: {
minimize: false
},
cache: {
type: 'filesystem',
buildDependencies: {
// This makes all dependencies of this file - build dependencies
config: [__filename],
// By default webpack and loaders are build dependencies
},
},
}
// https://webpack.js.org/configuration/mode/#mode-none
module.exports = (env, argv) => {
if (argv.mode === 'development') {
return devConf;
}

if (argv.mode === 'production') {
return config;
}
return config;
};