diff --git a/client/src/CONSTANTS.ts b/client/src/CONSTANTS.ts new file mode 100644 index 0000000..e4ea177 --- /dev/null +++ b/client/src/CONSTANTS.ts @@ -0,0 +1,32 @@ +export class CONSTANTS { +public static fs = require('fs'); +public static url = require('url'); + +public static REACH_IDE_S:string = 'Reach IDE'; +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'; +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'; + + +} + + diff --git a/client/src/ENUMS.ts b/client/src/ENUMS.ts new file mode 100644 index 0000000..ca72319 --- /dev/null +++ b/client/src/ENUMS.ts @@ -0,0 +1,29 @@ +export enum CMD_HELPER { + COMPILE = 'compile', + RUN = 'run', + CLEAN = 'clean', + UPGRADE = 'upgrade', + UPDATE = 'update', + HASHES = 'hashes', + VERSION = 'version', + DOCKER_RESET = 'docker-reset', + DEVNET = 'devnet', + RPC_SERVER = 'rpc-server', + RPC_RUN = 'run', + RPC_REACT= 'react', + SCAFFOLD = 'scaffold', + DOWN = 'down', + INIT = 'init' + } +export enum URL_HELPER { + DOCS = 'docs', + DOCS_URL = 'https://docs.reach.sh/doc-index.html', + ISSUE = 'issue', + ISSUE_URL = 'https://github.com/reach-sh/reach-lang/issues/new', + DISCORD = 'discord', + DISCORD_URL = 'https://discord.gg/2XzY6MVpFH', + GIST = 'gist', + GIST_URL = 'https://gist.github.com/' + } + + diff --git a/client/src/README.md b/client/src/README.md new file mode 100644 index 0000000..e69de29 diff --git a/client/src/buttons.ts b/client/src/buttons.ts index 6ad5b8d..4953e30 100644 --- a/client/src/buttons.ts +++ b/client/src/buttons.ts @@ -1,6 +1,15 @@ import { ExtensionContext } from 'vscode'; import * as vscode from 'vscode'; +const REACH_COMPILE_S:string = 'Reach Compile'; +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) { @@ -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], ]); } diff --git a/client/src/extension.ts b/client/src/extension.ts index 18bcab5..5a6c39f 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -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, @@ -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 @@ -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); @@ -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 ); @@ -91,25 +90,25 @@ 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); @@ -117,38 +116,26 @@ const urlHelper = (context, label, url) => { 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); + 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(); @@ -156,24 +143,24 @@ function associateRshFiles() { } 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; } });