From ae90c173c8432cef6f6b05562ef66cbb5f2fba56 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 20 Sep 2017 14:13:19 +0200 Subject: [PATCH 1/8] add cmdinterpreter --- src/app.js | 14 +++++++++++++- src/app/panels/editor-panel.js | 1 + src/app/panels/terminal.js | 1 + src/lib/cmdInterpreter.js | 30 ++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 src/lib/cmdInterpreter.js diff --git a/src/app.js b/src/app.js index 02096d324c..1b51dffdc5 100644 --- a/src/app.js +++ b/src/app.js @@ -40,6 +40,7 @@ var ContextualListener = require('./app/editor/contextualListener') var ContextView = require('./app/editor/contextView') var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer') var toolTip = require('./app/ui/tooltip') +var CommandInterpreter = require('./lib/cmdInterpreter') var styleGuide = remixLib.ui.themeChooser var styles = styleGuide.chooser() @@ -204,7 +205,7 @@ function run () { var self = this if (window.location.hostname === 'yann300.github.io') { - modalDialogCustom.alert(`This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.`) + modalDialogCustom.alert('This UNSTABLE ALPHA branch of Remix has been moved to http://ethereum.github.io/remix-live-alpha.') } else if (window.location.hostname === 'ethereum.github.io' && window.location.pathname.indexOf('/remix-live-alpha') === 0) { modalDialogCustom.alert(`This instance of the Remix IDE is an UNSTABLE ALPHA branch.\n @@ -607,10 +608,21 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } var staticanalysis = new StaticAnalysis(staticAnalysisAPI, compiler.event) + // ----------------- Command Interpreter ----------------- + /* + this module basically listen on user input (from terminal && editor) + and interpret them as command + */ + var cmdInterpreter = new CommandInterpreter() + cmdInterpreter.event.register('debug', (hash) => { + startdebugging(hash) + }) + // ---------------- Righthand-panel -------------------- var rhpAPI = { config: config, + cmdInterpreter: cmdInterpreter, setEditorSize (delta) { $('#righthand-panel').css('width', delta) self._view.centerpanel.style.right = delta + 'px' diff --git a/src/app/panels/editor-panel.js b/src/app/panels/editor-panel.js index 9c7cb19ab1..ac93a5c0ab 100644 --- a/src/app/panels/editor-panel.js +++ b/src/app/panels/editor-panel.js @@ -27,6 +27,7 @@ class EditorPanel { editor: opts.api.editor, // @TODO: instantiate in eventpanel instead of passing via `opts` terminal: new Terminal({ api: { + cmdInterpreter: self._api.cmdInterpreter, getPosition (event) { var limitUp = 36 var limitDown = 20 diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 0095b96704..32865d5ced 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -71,6 +71,7 @@ class Terminal { self.registerCommand('error', self._blocksRenderer('error'), { activate: true }) self.registerCommand('script', function execute (args, scopedCommands, append) { var script = String(args[0]) + if (self._api.cmdInterpreter && self._api.cmdInterpreter.interpret(script)) return scopedCommands.log(`> ${script}`) self._shell(script, scopedCommands, function (error, output) { if (error) scopedCommands.error(error) diff --git a/src/lib/cmdInterpreter.js b/src/lib/cmdInterpreter.js new file mode 100644 index 0000000000..39a032d0c4 --- /dev/null +++ b/src/lib/cmdInterpreter.js @@ -0,0 +1,30 @@ +'use strict' +var remix = require('ethereum-remix') +var EventManager = remix.lib.EventManager + +class CmdInterpreter { + constructor () { + this.event = new EventManager() + } + interpret (cmd) { + if (!cmd) return false + for (var c in commands) { + if (commands[c].exec(cmd)) { + commands[c].action(this, cmd) + return true + } + } + return false + } +} + +var commands = [ + { + command: /^debug /, + action: (self, command) => { + self.event.trigger('debug', command.replace('debug ', '')) + } + } +] + +module.exports = CmdInterpreter From 96a751b165d1281c73d8e26fa8c71a0e13647901 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 20 Sep 2017 17:53:54 +0200 Subject: [PATCH 2/8] cmdInterpreter: debug, loadgist, loadswarm, setproviderurl --- src/app.js | 80 ++++++++++++++++++++++++++------------ src/app/panels/terminal.js | 2 +- src/lib/cmdInterpreter.js | 20 +++------- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/app.js b/src/app.js index 1b51dffdc5..1ba77de9d9 100644 --- a/src/app.js +++ b/src/app.js @@ -6,6 +6,7 @@ var yo = require('yo-yo') var async = require('async') var remixLib = require('remix-lib') var EventManager = remixLib.EventManager +var swarmgw = require('swarmgw') var UniversalDApp = require('./universal-dapp.js') var UniversalDAppUI = require('./universal-dapp-ui.js') @@ -351,6 +352,42 @@ Please make a backup of your contracts and start using http://remix.ethereum.org }) txlistener.startListening() + + // ----------------- Command Interpreter ----------------- + /* + this module basically listen on user input (from terminal && editor) + and interpret them as commands + */ + var cmdInterpreter = new CommandInterpreter() + cmdInterpreter.event.register('debug', (hash) => { + startdebugging(hash) + }) + cmdInterpreter.event.register('loadgist', (id) => { + loadFromGist({gist: id}) + }) + cmdInterpreter.event.register('loadswarm', (url) => { + swarmgw.get(url, function (err, ret) { + if (err) { + modalDialogCustom.log(`Unable to load ${url} from swarm: ${err}`) + } else { + ret = JSON.parse(ret) + for (var k in ret.sources) { + var url = ret.sources[k].urls[0] // @TODO retrieve all other content + swarmgw.get(url, (error, content) => { + if (!error) { + filesProviders['browser'].addReadOnly(k, content) + } else { + filesProviders['browser'].addReadOnly(k, `Cannot retrieve the content of ${url}: ${error}`) + } + }) + } + } + }) + }) + cmdInterpreter.event.register('setproviderurl', (url) => { + executionContext.setContext('web3', url, true) + }) + // ----------------- editor ---------------------------- this._components.editor = new Editor({}) // @TODO: put into editorpanel var editor = self._components.editor // shortcut for the editor @@ -436,6 +473,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org // ----------------- editor panel ---------------------- this._components.editorpanel = new EditorPanel({ api: { + cmdInterpreter: cmdInterpreter, editor: self._components.editor, config: self._api.config, txListener: txlistener, @@ -503,23 +541,26 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } // ------------------ gist load ---------------- - - var loadingFromGist = gistHandler.handleLoad(queryParams.get(), function (gistId) { - $.ajax({ - url: 'https://api.github.com/gists/' + gistId, - jsonp: 'callback', - dataType: 'jsonp', - success: function (response) { - if (response.data) { - if (!response.data.files) { - modalDialogCustom.alert('Gist load error: ' + response.data.message) - return + function loadFromGist (gistId) { + return gistHandler.handleLoad(gistId, function (gistId) { + $.ajax({ + url: 'https://api.github.com/gists/' + gistId, + jsonp: 'callback', + dataType: 'jsonp', + success: function (response) { + if (response.data) { + if (!response.data.files) { + modalDialogCustom.alert('Gist load error: ' + response.data.message) + return + } + loadFiles(response.data.files, 'gist') } - loadFiles(response.data.files, 'gist') } - } + }) }) - }) + } + + var loadingFromGist = loadFromGist(queryParams.get()) // insert ballot contract if there are no files available if (!loadingFromGist) { @@ -608,21 +649,10 @@ Please make a backup of your contracts and start using http://remix.ethereum.org } var staticanalysis = new StaticAnalysis(staticAnalysisAPI, compiler.event) - // ----------------- Command Interpreter ----------------- - /* - this module basically listen on user input (from terminal && editor) - and interpret them as command - */ - var cmdInterpreter = new CommandInterpreter() - cmdInterpreter.event.register('debug', (hash) => { - startdebugging(hash) - }) - // ---------------- Righthand-panel -------------------- var rhpAPI = { config: config, - cmdInterpreter: cmdInterpreter, setEditorSize (delta) { $('#righthand-panel').css('width', delta) self._view.centerpanel.style.right = delta + 'px' diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js index 32865d5ced..304dc558a8 100644 --- a/src/app/panels/terminal.js +++ b/src/app/panels/terminal.js @@ -71,8 +71,8 @@ class Terminal { self.registerCommand('error', self._blocksRenderer('error'), { activate: true }) self.registerCommand('script', function execute (args, scopedCommands, append) { var script = String(args[0]) - if (self._api.cmdInterpreter && self._api.cmdInterpreter.interpret(script)) return scopedCommands.log(`> ${script}`) + if (self._api.cmdInterpreter && self._api.cmdInterpreter.interpret(script)) return self._shell(script, scopedCommands, function (error, output) { if (error) scopedCommands.error(error) else scopedCommands.log(output) diff --git a/src/lib/cmdInterpreter.js b/src/lib/cmdInterpreter.js index 39a032d0c4..f06ac52666 100644 --- a/src/lib/cmdInterpreter.js +++ b/src/lib/cmdInterpreter.js @@ -8,23 +8,15 @@ class CmdInterpreter { } interpret (cmd) { if (!cmd) return false - for (var c in commands) { - if (commands[c].exec(cmd)) { - commands[c].action(this, cmd) - return true - } + var accept = commandsRegEx.exec(cmd) + if (accept) { + this.event.trigger(accept[1], [cmd.replace(commandsRegEx, '')]) + return accept[1] } - return false + return null } } -var commands = [ - { - command: /^debug /, - action: (self, command) => { - self.event.trigger('debug', command.replace('debug ', '')) - } - } -] +var commandsRegEx = /^remix:(debug|loadgist|setproviderurl|loadswarm)\s/ module.exports = CmdInterpreter From 3f005689d62cfce7d0c4fdff1479ab5a72e43d77 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 20 Sep 2017 18:34:57 +0200 Subject: [PATCH 3/8] update context dropdown if needed --- src/app/tabs/run-tab.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index 28f73c5c40..b9c9db240b 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -85,6 +85,9 @@ function runTab (container, appAPI, appEvents) { }, setFinalContext) }) selectExEnv.value = executionContext.getProvider() + executionContext.event.register('contextChanged', (context, silent) => { + selectExEnv.value = executionContext.getProvider() + }) fillAccountsList(appAPI, el) setInterval(() => { updateAccountBalances(container, appAPI) From 04b04e313281bc5be2337c5fd2c28843f26092c1 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 21 Sep 2017 09:07:37 +0200 Subject: [PATCH 4/8] switch to the solidity target --- src/app.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/app.js b/src/app.js index 1ba77de9d9..ec2b2bc075 100644 --- a/src/app.js +++ b/src/app.js @@ -366,18 +366,21 @@ Please make a backup of your contracts and start using http://remix.ethereum.org loadFromGist({gist: id}) }) cmdInterpreter.event.register('loadswarm', (url) => { - swarmgw.get(url, function (err, ret) { + swarmgw.get(url, function (err, content) { if (err) { modalDialogCustom.log(`Unable to load ${url} from swarm: ${err}`) } else { - ret = JSON.parse(ret) - for (var k in ret.sources) { - var url = ret.sources[k].urls[0] // @TODO retrieve all other content + content = JSON.parse(content) + for (var k in content.sources) { + var url = content.sources[k].urls[0] // @TODO retrieve all other contents ? swarmgw.get(url, (error, content) => { if (!error) { filesProviders['browser'].addReadOnly(k, content) } else { filesProviders['browser'].addReadOnly(k, `Cannot retrieve the content of ${url}: ${error}`) + if (content.settings && Object.keys(content.settings.compilationTarget)[0] === k) { + fileManager.switchFile(Object.keys(content.settings.compilationTarget)[0]) + } } }) } From 8ecf94393ad60885c27fa56511551391dcbe7b23 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 28 Feb 2018 11:59:07 +0100 Subject: [PATCH 5/8] update account list --- src/app/tabs/run-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index b9c9db240b..5fff59d730 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -86,7 +86,7 @@ function runTab (container, appAPI, appEvents) { }) selectExEnv.value = executionContext.getProvider() executionContext.event.register('contextChanged', (context, silent) => { - selectExEnv.value = executionContext.getProvider() + setFinalContext() }) fillAccountsList(appAPI, el) setInterval(() => { From 75bd6a3d3615e99c414a018d069ea65ecc7466e3 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 28 Feb 2018 11:59:29 +0100 Subject: [PATCH 6/8] add batch command --- src/lib/cmdInterpreter.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib/cmdInterpreter.js b/src/lib/cmdInterpreter.js index f06ac52666..c20baf07ac 100644 --- a/src/lib/cmdInterpreter.js +++ b/src/lib/cmdInterpreter.js @@ -1,6 +1,6 @@ 'use strict' -var remix = require('ethereum-remix') -var EventManager = remix.lib.EventManager +var remixLib = require('remix-lib') +var EventManager = remixLib.EventManager class CmdInterpreter { constructor () { @@ -10,13 +10,15 @@ class CmdInterpreter { if (!cmd) return false var accept = commandsRegEx.exec(cmd) if (accept) { - this.event.trigger(accept[1], [cmd.replace(commandsRegEx, '')]) + var param = accept[2] + if (param) param = param.trim() + this.event.trigger(accept[1], [param]) return accept[1] } return null } } -var commandsRegEx = /^remix:(debug|loadgist|setproviderurl|loadswarm)\s/ +var commandsRegEx = /^remix:(debug|loadgist|setproviderurl|loadurl|batch)(.*)/ module.exports = CmdInterpreter From a93da3deb196a431602b9fb3b275ff0f486baf02 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 28 Feb 2018 12:00:11 +0100 Subject: [PATCH 7/8] fix setproviderurl,swarm command & add batch command --- src/app.js | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/app.js b/src/app.js index ec2b2bc075..e9f68cbc77 100644 --- a/src/app.js +++ b/src/app.js @@ -6,7 +6,6 @@ var yo = require('yo-yo') var async = require('async') var remixLib = require('remix-lib') var EventManager = remixLib.EventManager -var swarmgw = require('swarmgw') var UniversalDApp = require('./universal-dapp.js') var UniversalDAppUI = require('./universal-dapp-ui.js') @@ -365,30 +364,43 @@ Please make a backup of your contracts and start using http://remix.ethereum.org cmdInterpreter.event.register('loadgist', (id) => { loadFromGist({gist: id}) }) - cmdInterpreter.event.register('loadswarm', (url) => { - swarmgw.get(url, function (err, content) { + cmdInterpreter.event.register('loadurl', (url) => { + importExternal(url, (err, content) => { if (err) { - modalDialogCustom.log(`Unable to load ${url} from swarm: ${err}`) + toolTip(`Unable to load ${url} from swarm: ${err}`) } else { - content = JSON.parse(content) - for (var k in content.sources) { - var url = content.sources[k].urls[0] // @TODO retrieve all other contents ? - swarmgw.get(url, (error, content) => { - if (!error) { - filesProviders['browser'].addReadOnly(k, content) - } else { - filesProviders['browser'].addReadOnly(k, `Cannot retrieve the content of ${url}: ${error}`) - if (content.settings && Object.keys(content.settings.compilationTarget)[0] === k) { - fileManager.switchFile(Object.keys(content.settings.compilationTarget)[0]) + try { + content = JSON.parse(content) + for (var k in content.sources) { + var url = content.sources[k].urls[0] // @TODO retrieve all other contents ? + importExternal(url, (error, content) => { + if (error) { + toolTip(`Cannot retrieve the content of ${url}: ${error}`) } - } - }) + }) + } + } catch (e) { + filesProviders['swarm'].addReadOnly(url, content) } } }) }) cmdInterpreter.event.register('setproviderurl', (url) => { - executionContext.setContext('web3', url, true) + executionContext.setProviderFromEndpoint(url, 'web3', (error) => { + if (error) toolTip(error) + }) + }) + cmdInterpreter.event.register('batch', (url) => { + var content = editor.get(editor.current()) + if (!content) { + toolTip('no content to execute') + } + var split = content.split('\n') + async.eachSeries(split, (value, cb) => { + cmdInterpreter.interpret(value) ? cb() : cb(`Cannot run ${value}. stopping`) + }, (error) => { + if (error) toolTip(error) + }) }) // ----------------- editor ---------------------------- From c2700c22817a069d2ff85393bc0d7f2c6fdfc62e Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 28 Feb 2018 12:50:36 +0100 Subject: [PATCH 8/8] execute batch in serie --- src/app.js | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/app.js b/src/app.js index e9f68cbc77..9b20c3ab83 100644 --- a/src/app.js +++ b/src/app.js @@ -358,48 +358,61 @@ Please make a backup of your contracts and start using http://remix.ethereum.org and interpret them as commands */ var cmdInterpreter = new CommandInterpreter() - cmdInterpreter.event.register('debug', (hash) => { + cmdInterpreter.event.register('debug', (hash, cb) => { startdebugging(hash) + if (cb) cb() }) - cmdInterpreter.event.register('loadgist', (id) => { + cmdInterpreter.event.register('loadgist', (id, cb) => { loadFromGist({gist: id}) + if (cb) cb() }) - cmdInterpreter.event.register('loadurl', (url) => { + cmdInterpreter.event.register('loadurl', (url, cb) => { importExternal(url, (err, content) => { if (err) { toolTip(`Unable to load ${url} from swarm: ${err}`) + if (cb) cb(err) } else { try { content = JSON.parse(content) - for (var k in content.sources) { - var url = content.sources[k].urls[0] // @TODO retrieve all other contents ? + async.eachOfSeries(content.sources, (value, file, callbackSource) => { + var url = value.urls[0] // @TODO retrieve all other contents ? importExternal(url, (error, content) => { if (error) { toolTip(`Cannot retrieve the content of ${url}: ${error}`) } + callbackSource() }) - } - } catch (e) { - filesProviders['swarm'].addReadOnly(url, content) - } + }, (error) => { + if (cb) cb(error) + }) + } catch (e) {} + if (cb) cb() } }) }) - cmdInterpreter.event.register('setproviderurl', (url) => { + cmdInterpreter.event.register('setproviderurl', (url, cb) => { executionContext.setProviderFromEndpoint(url, 'web3', (error) => { if (error) toolTip(error) + if (cb) cb() }) }) - cmdInterpreter.event.register('batch', (url) => { + cmdInterpreter.event.register('batch', (url, cb) => { var content = editor.get(editor.current()) if (!content) { toolTip('no content to execute') + if (cb) cb() + return } var split = content.split('\n') async.eachSeries(split, (value, cb) => { - cmdInterpreter.interpret(value) ? cb() : cb(`Cannot run ${value}. stopping`) + if (!cmdInterpreter.interpret(value, (error) => { + error ? cb(`Cannot run ${value}. stopping`) : cb() + })) { + cb(`Cannot interpret ${value}. stopping`) + } }, (error) => { if (error) toolTip(error) + if (cb) cb() }) })