Skip to content
This repository has been archived by the owner on Nov 16, 2021. It is now read-only.

RIP 0.1 Reach TypeScript Design Style Request #39

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
32 changes: 32 additions & 0 deletions client/src/CONSTANTS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export class CONSTANTS {
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer only things that are used more than once are abstracted to constants. Otherwise, I find it easier to have the values inlined

public static fs = require('fs');
public static url = require('url');

public static REACH_IDE_S:string = 'Reach IDE';
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: drop the _S

public static PATH_SERVER_JOIN:string = 'server';
public static PATH_SERVER_OUT:string = 'out';
public static PATH_SERVER_JS_S:string = 'server.js';
public static FILE_ASSOCIATIONS:string = 'files.associations';
public static REACH_FILE_EXT:string = '*.rsh';
public static JAVASCRIPT:string = 'javascript';
public static SERVER_DEBUG_OPTIONS_NOLAZY:string = '--nolazy';
public static REACH_EXECUTABLE_PATH:string ='reachide.executableLocation';
public static SERVER_DEBUG_OPTIONS_INSPECT_6009 = '--inspect=6009';
public static CANNOT_CREATE_SETTINGS:string = `Could not create .vscode/settings.json:`;
public static REACH_PATH:string = './reach';
public static REACH_CLIENT_ID:string = 'reachide';
public static CREATE_FILESYSTEM_WATCHER_PARAM:string = '**/*.rsh';
Copy link
Contributor

Choose a reason for hiding this comment

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

public static RECURSIVE_REACH_FILE_SELECTOR : string = '**/*.rsh'

public static SCHEME:string = 'file';
public static JOIN_REACH:string = 'reach';
public static WORKSPACE_FOLDERS_DOT:string = '.';
public static REACH_COMMANDS:string = 'reach-commands';
public static REACH_HELP:string = 'reach-help';
public static REACH_DOCS:string = 'reach-docs';
public static VSCODE_DOT_EXT:string = '.vscode';
public static MKDIR_P:string = 'mkdir -p ';
public static VS_CODE_SETTING_JSON:string = '.vscode/settings.json';


}


29 changes: 29 additions & 0 deletions client/src/ENUMS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export enum CMD_HELPER {
COMPILE = <any>'compile',
Copy link
Contributor

Choose a reason for hiding this comment

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

why <any>?

RUN = <any>'run',
CLEAN = <any>'clean',
UPGRADE = <any>'upgrade',
UPDATE = <any>'update',
HASHES = <any>'hashes',
VERSION = <any>'version',
DOCKER_RESET = <any>'docker-reset',
DEVNET = <any>'devnet',
RPC_SERVER = <any>'rpc-server',
RPC_RUN = <any>'run',
RPC_REACT= <any>'react',
SCAFFOLD = <any>'scaffold',
DOWN = <any>'down',
INIT = <any>'init'
}
export enum URL_HELPER {
DOCS = <any>'docs',
DOCS_URL = <any>'https://docs.reach.sh/doc-index.html',
ISSUE = <any>'issue',
ISSUE_URL = <any>'https://github.com/reach-sh/reach-lang/issues/new',
DISCORD = <any>'discord',
DISCORD_URL = <any>'https://discord.gg/2XzY6MVpFH',
GIST = <any>'gist',
GIST_URL = <any>'https://gist.github.com/'
}


Empty file added client/src/README.md
Empty file.
15 changes: 13 additions & 2 deletions client/src/buttons.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ExtensionContext } from 'vscode';
import * as vscode from 'vscode';

const REACH_COMPILE_S:string = 'Reach Compile';
Copy link
Contributor

Choose a reason for hiding this comment

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

same comments as previous PR

const REACH_COMPILE:string = 'reach.compile';
const REACH_RUN_S:string = 'Reach Run';
const REACH_RUN:string = 'reach.run';
const POST_ISSUE_S:string = 'Post Issue';
const POST_ISSUE:string = 'reach.issue';
const CREATE_GIST_S:string = 'Create Gist';
const CREATE_GIST:string = 'reach.gist';

let shownButtons = [];

function createButtons(buttons) {
Expand All @@ -23,8 +32,10 @@ function removeAllButtons() {

function showButtons() {
createButtons([
['Reach Compile', 'reach.compile'],
['Reach Run', 'reach.run'],
[REACH_COMPILE_S, REACH_COMPILE ],
[REACH_RUN_S, REACH_RUN],
[POST_ISSUE_S, POST_ISSUE],
[CREATE_GIST_S, CREATE_GIST],
]);
}

Expand Down
99 changes: 43 additions & 56 deletions client/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import * as path from 'path';
import { workspace, ExtensionContext, commands, window, env, ViewColumn, Uri, WorkspaceFolder } from 'vscode';
import { exec } from 'child_process';
import { initButtons } from './buttons';
import {CONSTANTS} from './CONSTANTS';
import {CMD_HELPER,URL_HELPER} from './ENUMS';

import {
LanguageClient,
Expand All @@ -24,22 +26,19 @@ import {
import { CommandsTreeDataProvider, DocumentationTreeDataProvider, HelpTreeDataProvider } from './CommandsTreeDataProvider';

let client: LanguageClient;
let terminal;
let rootFolder: string;

var terminal;

const fs = require('fs');
const url = require('url');

var rootFolder: string;
const SETTINGS_ROOT:string = `${rootFolder}${path.sep}${CONSTANTS.VS_CODE_SETTING_JSON}`;

export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join('server', 'out', 'server.js')
path.join(CONSTANTS.PATH_SERVER_JOIN, CONSTANTS.PATH_SERVER_OUT, CONSTANTS.PATH_SERVER_JS_S)
);
// The debug options for the server
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
let debugOptions = { execArgv: [CONSTANTS.SERVER_DEBUG_OPTIONS_NOLAZY, CONSTANTS.SERVER_DEBUG_OPTIONS_INSPECT_6009] };

// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
Expand All @@ -52,11 +51,11 @@ export function activate(context: ExtensionContext) {
}
};

terminal = window.createTerminal({ name: 'Reach IDE' });
const reachExecutablePath = workspace.getConfiguration().get('reachide.executableLocation') as string;
const wf = workspace.workspaceFolders[0].uri.path || '.';
const reachPath = (reachExecutablePath === './reach')
? path.join(wf, 'reach')
terminal = window.createTerminal({ name: CONSTANTS.REACH_IDE_S });
const reachExecutablePath = workspace.getConfiguration().get(CONSTANTS.REACH_EXECUTABLE_PATH) as string;
const wf = workspace.workspaceFolders[0].uri.path || CONSTANTS.WORKSPACE_FOLDERS_DOT;
const reachPath = (reachExecutablePath === CONSTANTS.REACH_PATH)
? path.join(wf, CONSTANTS.JOIN_REACH)
: reachExecutablePath;
registerCommands(context, reachPath);

Expand All @@ -66,20 +65,20 @@ export function activate(context: ExtensionContext) {
// Register the server for Reach .rsh documents
documentSelector: [
{
pattern: '**/*.rsh',
scheme: 'file'
pattern: CONSTANTS.CREATE_FILESYSTEM_WATCHER_PARAM,
scheme: CONSTANTS.SCHEME
}
],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/*.rsh')
fileEvents: workspace.createFileSystemWatcher(CONSTANTS.CREATE_FILESYSTEM_WATCHER_PARAM)
}
};

// Create the language client and start the client.
client = new LanguageClient(
'reachide',
'Reach IDE',
CONSTANTS.REACH_CLIENT_ID,
CONSTANTS.REACH_IDE_S,
serverOptions,
clientOptions
);
Expand All @@ -91,89 +90,77 @@ export function activate(context: ExtensionContext) {

// Inject association for .rsh file type
if (workspace.workspaceFolders !== undefined) {
rootFolder = url.fileURLToPath( workspace.workspaceFolders[0].uri.toString() );
rootFolder = CONSTANTS.url.fileURLToPath( workspace.workspaceFolders[0].uri.toString() );
}
associateRshFiles();

window.registerTreeDataProvider('reach-commands', new CommandsTreeDataProvider());
window.registerTreeDataProvider('reach-help', new HelpTreeDataProvider());
window.registerTreeDataProvider('reach-docs', new DocumentationTreeDataProvider());
window.registerTreeDataProvider(CONSTANTS.REACH_COMMANDS, new CommandsTreeDataProvider());
window.registerTreeDataProvider(CONSTANTS.REACH_HELP, new HelpTreeDataProvider());
window.registerTreeDataProvider(CONSTANTS.REACH_DOCS, new DocumentationTreeDataProvider());
}

const commandHelper = (context, reachPath) => (label) => {
const disposable = commands.registerCommand(`reach.${label}`, () => {
const disposable = commands.registerCommand(`${CONSTANTS.JOIN_REACH}.${label}`, () => {
terminal.show();
terminal.sendText(`${reachPath} ${label}`);
terminal.sendText(`${reachPath}${label}`);
});
context.subscriptions.push(disposable);
};

const urlHelper = (context, label, url) => {
const disposable = commands.registerCommand(`reach.${label}`, () => {
const disposable = commands.registerCommand(`${CONSTANTS.JOIN_REACH}.${label}`, () => {
env.openExternal(Uri.parse(url));
});
context.subscriptions.push(disposable);
};

function registerCommands(context: ExtensionContext, reachPath: string) {
const cmdHelper = commandHelper(context, reachPath);

cmdHelper('compile');
cmdHelper('run');
cmdHelper('clean');
cmdHelper('upgrade');
cmdHelper('update');
cmdHelper('hashes');
cmdHelper('version');
cmdHelper('docker-reset');
cmdHelper('devnet');
cmdHelper('rpc-server');
cmdHelper('rpc-run');
cmdHelper('react');
cmdHelper('scaffold');
cmdHelper('down');
cmdHelper('init');

urlHelper(context, 'docs', 'https://docs.reach.sh/doc-index.html');
urlHelper(context, 'issue', 'https://github.com/reach-sh/reach-lang/issues/new');
urlHelper(context, 'discord', 'https://discord.gg/2XzY6MVpFH');
urlHelper(context, 'gist', 'https://gist.github.com/');

for (const value in CMD_HELPER) {
cmdHelper(value);
}

urlHelper(context, URL_HELPER.DOCS, URL_HELPER.DOCS_URL);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe just make this:

const helperUrls = {
  'docs': 'https://docs.reach.sh/doc-index.html',
  // ...
}

for (const [key, value] of Object.entries(helperUrls)) {
  urlHelper(context, key, value);
}

urlHelper(context, URL_HELPER.ISSUE, URL_HELPER.ISSUE_URL);
urlHelper(context, URL_HELPER.DISCORD, URL_HELPER.DISCORD_URL);
urlHelper(context, URL_HELPER.GIST, URL_HELPER.GIST_URL);

}

function associateRshFiles() {
exec(`mkdir -p ${rootFolder}${path.sep}.vscode`, (error: { message: any; }, stdout: any, stderr: any) => {
exec(`${CONSTANTS.MKDIR_P}${rootFolder}${path.sep}${CONSTANTS.VSCODE_DOT_EXT}`, (error: { message: any; }, stdout: any, stderr: any) => {
if (error) {
console.error(`Could not create .vscode directory: ${error.message}`);
console.error(`${CONSTANTS.CANNOT_CREATE_SETTINGS}${error.message}`);
return;
}
if (stderr) {
console.error(`Could not create .vscode directory: ${stderr}`);
console.error(`${CONSTANTS.CANNOT_CREATE_SETTINGS}${stderr}`);
return;
}
injectRshFileAssocation();
});
}

function injectRshFileAssocation() {
const settingsFile:string = `${rootFolder}${path.sep}.vscode/settings.json`;
const settingsFile:string = SETTINGS_ROOT;

fs.readFile(settingsFile, function (err: any, content: string) {
CONSTANTS.fs.readFile(settingsFile, function (err: any, content: string) {
let parseJson: { [x: string]: { [x: string]: string; }; };
try {
parseJson = JSON.parse(content);
} catch {
parseJson = {};
}
let fileAssoc = parseJson['files.associations'];
let fileAssoc = parseJson[CONSTANTS.FILE_ASSOCIATIONS];
if (fileAssoc === undefined) {
parseJson['files.associations'] = { '*.rsh': 'javascript' };
parseJson[CONSTANTS.FILE_ASSOCIATIONS] = { REACH_FILE_EXT: CONSTANTS.JAVASCRIPT };
} else {
parseJson['files.associations']['*.rsh'] = 'javascript';
parseJson[CONSTANTS.FILE_ASSOCIATIONS][CONSTANTS.REACH_FILE_EXT] = CONSTANTS.JAVASCRIPT;
}
fs.writeFile(settingsFile, JSON.stringify(parseJson), function (err: any) {
CONSTANTS.fs.writeFile(settingsFile, JSON.stringify(parseJson), function (err: any) {
if (err) {
console.error(`Could not create .vscode/settings.json: ${err}`);
console.error(`${CONSTANTS.CANNOT_CREATE_SETTINGS}${err}`);
return;
}
});
Expand Down