Browse Source

again and again, little dwraf do the same

Benjamin Van Ryseghem 12 years ago
parent
commit
ed6e9fd08d

+ 6 - 6
js/Helios-Browser.deploy.js

@@ -1767,14 +1767,14 @@ messageSends: ["announce:", "error:", "new", "yourself", "announcer"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
-"_moveMethodToClass_",
+"_moveMethodToClass_ifAbsent_",
 smalltalk.method({
-selector: "moveMethodToClass:",
-fn: function (aClassName){
+selector: "moveMethodToClass:ifAbsent:",
+fn: function (aClassName,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(_st("moveMethodToClass ").__comma(aClassName));
-return self}, function($ctx1) {$ctx1.fill(self,"moveMethodToClass:",{aClassName:aClassName},smalltalk.HLBrowserModel)})},
-messageSends: ["log:", ","]}),
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._moveMethod_toClass_ifAbsent_(_st(self)._selectedMethod(),aClassName,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethodToClass:ifAbsent:",{aClassName:aClassName,aBlock:aBlock},smalltalk.HLBrowserModel)})},
+messageSends: ["moveMethod:toClass:ifAbsent:", "selectedMethod", "environment"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(

+ 8 - 8
js/Helios-Browser.js

@@ -2307,17 +2307,17 @@ referencedClasses: ["HLUnknownVariableErrorRaised"]
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
-"_moveMethodToClass_",
+"_moveMethodToClass_ifAbsent_",
 smalltalk.method({
-selector: "moveMethodToClass:",
+selector: "moveMethodToClass:ifAbsent:",
 category: 'commands actions',
-fn: function (aClassName){
+fn: function (aClassName,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(_st("moveMethodToClass ").__comma(aClassName));
-return self}, function($ctx1) {$ctx1.fill(self,"moveMethodToClass:",{aClassName:aClassName},smalltalk.HLBrowserModel)})},
-args: ["aClassName"],
-source: "moveMethodToClass: aClassName\x0a\x09console log: 'moveMethodToClass ', aClassName",
-messageSends: ["log:", ","],
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._moveMethod_toClass_ifAbsent_(_st(self)._selectedMethod(),aClassName,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethodToClass:ifAbsent:",{aClassName:aClassName,aBlock:aBlock},smalltalk.HLBrowserModel)})},
+args: ["aClassName", "aBlock"],
+source: "moveMethodToClass: aClassName ifAbsent: aBlock\x0a\x09self environment \x0a\x09\x09moveMethod: self selectedMethod \x0a\x09\x09toClass: aClassName \x0a\x09\x09ifAbsent: aBlock",
+messageSends: ["moveMethod:toClass:ifAbsent:", "selectedMethod", "environment"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserModel);

+ 3 - 12
js/Helios-Commands-Browser.deploy.js

@@ -295,18 +295,9 @@ smalltalk.method({
 selector: "execute",
 fn: function (){
 var self=this;
-var class_;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-class_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(self)._input());
-$1=class_;
-if(($receiver = $1) == nil || $receiver == undefined){
-_st(self)._commandError_(_st("No class named: ").__comma(_st(self)._input()));
-} else {
-$1;
-};
-_st(_st(self)._model())._moveMethodToClass_(class_);
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{class_:class_},smalltalk.HLMoveMethodToClassCommand)})},
-messageSends: ["at:", "input", "current", "ifNil:", "commandError:", ",", "moveMethodToClass:", "model"]}),
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._moveMethodToClass_ifAbsent_(_st(self)._input(),_st(self)._errorBlock());
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLMoveMethodToClassCommand)})},
+messageSends: ["moveMethodToClass:ifAbsent:", "input", "errorBlock", "model"]}),
 smalltalk.HLMoveMethodToClassCommand);
 
 smalltalk.addMethod(

+ 6 - 15
js/Helios-Commands-Browser.js

@@ -411,21 +411,12 @@ selector: "execute",
 category: 'executing',
 fn: function (){
 var self=this;
-var class_;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-class_=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(self)._input());
-$1=class_;
-if(($receiver = $1) == nil || $receiver == undefined){
-_st(self)._commandError_(_st("No class named: ").__comma(_st(self)._input()));
-} else {
-$1;
-};
-_st(_st(self)._model())._moveMethodToClass_(class_);
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{class_:class_},smalltalk.HLMoveMethodToClassCommand)})},
-args: [],
-source: "execute\x0a\x09| class |\x0a\x09class := Smalltalk current at: self input.\x0a\x09class ifNil: [ self commandError: 'No class named: ', self input ].\x0a\x09\x0a\x09self model moveMethodToClass: class",
-messageSends: ["at:", "input", "current", "ifNil:", "commandError:", ",", "moveMethodToClass:", "model"],
-referencedClasses: ["Smalltalk"]
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._moveMethodToClass_ifAbsent_(_st(self)._input(),_st(self)._errorBlock());
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLMoveMethodToClassCommand)})},
+args: [],
+source: "execute\x0a\x09self model moveMethodToClass: self input ifAbsent: self errorBlock",
+messageSends: ["moveMethodToClass:ifAbsent:", "input", "errorBlock", "model"],
+referencedClasses: []
 }),
 smalltalk.HLMoveMethodToClassCommand);
 

+ 25 - 1
js/Helios-Commands-Core.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-Commands-Core');
-smalltalk.addClass('HLCommand', smalltalk.Object, ['input'], 'Helios-Commands-Core');
+smalltalk.addClass('HLCommand', smalltalk.Object, ['input', 'errorBlock'], 'Helios-Commands-Core');
 smalltalk.addMethod(
 "_asActionBinding",
 smalltalk.method({
@@ -71,6 +71,30 @@ return $1;
 messageSends: ["documentation", "class"]}),
 smalltalk.HLCommand);
 
+smalltalk.addMethod(
+"_errorBlock",
+smalltalk.method({
+selector: "errorBlock",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@errorBlock"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"errorBlock",{},smalltalk.HLCommand)})},
+messageSends: []}),
+smalltalk.HLCommand);
+
+smalltalk.addMethod(
+"_errorBlock_",
+smalltalk.method({
+selector: "errorBlock:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@errorBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"errorBlock:",{aBlock:aBlock},smalltalk.HLCommand)})},
+messageSends: []}),
+smalltalk.HLCommand);
+
 smalltalk.addMethod(
 "_execute",
 smalltalk.method({

+ 35 - 1
js/Helios-Commands-Core.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-Commands-Core');
-smalltalk.addClass('HLCommand', smalltalk.Object, ['input'], 'Helios-Commands-Core');
+smalltalk.addClass('HLCommand', smalltalk.Object, ['input', 'errorBlock'], 'Helios-Commands-Core');
 smalltalk.addMethod(
 "_asActionBinding",
 smalltalk.method({
@@ -96,6 +96,40 @@ referencedClasses: []
 }),
 smalltalk.HLCommand);
 
+smalltalk.addMethod(
+"_errorBlock",
+smalltalk.method({
+selector: "errorBlock",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@errorBlock"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"errorBlock",{},smalltalk.HLCommand)})},
+args: [],
+source: "errorBlock\x0a\x09^ errorBlock",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLCommand);
+
+smalltalk.addMethod(
+"_errorBlock_",
+smalltalk.method({
+selector: "errorBlock:",
+category: 'accessing',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@errorBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"errorBlock:",{aBlock:aBlock},smalltalk.HLCommand)})},
+args: ["aBlock"],
+source: "errorBlock: aBlock\x0a\x09errorBlock := aBlock",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLCommand);
+
 smalltalk.addMethod(
 "_execute",
 smalltalk.method({

+ 58 - 0
js/Helios-Environments.deploy.js

@@ -74,6 +74,17 @@ return $1;
 messageSends: ["subclassResponsibility"]}),
 smalltalk.HLEnvironment);
 
+smalltalk.addMethod(
+"_moveMethod_toClass_ifAbsent_",
+smalltalk.method({
+selector: "moveMethod:toClass:ifAbsent:",
+fn: function (aMethod,aClassName,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethod:toClass:ifAbsent:",{aMethod:aMethod,aClassName:aClassName,aBlock:aBlock},smalltalk.HLEnvironment)})},
+messageSends: ["subclassResponsibility"]}),
+smalltalk.HLEnvironment);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -128,6 +139,28 @@ catch(e) {if(e===$early)return e[0]; throw e}
 messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:on:"]}),
 smalltalk.HLLocalEnvironment);
 
+smalltalk.addMethod(
+"_moveMethod_toClass_ifAbsent_",
+smalltalk.method({
+selector: "moveMethod:toClass:ifAbsent:",
+fn: function (aMethod,aClassName,aBlock){
+var self=this;
+var destinationClass;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+destinationClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(aClassName)._asSymbol());
+$1=destinationClass;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(aBlock)._value();
+return $2;
+} else {
+$1;
+};
+_st(destinationClass)._adoptMethod_(aMethod);
+_st(_st(aMethod)._methodClass())._forsakeMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethod:toClass:ifAbsent:",{aMethod:aMethod,aClassName:aClassName,aBlock:aBlock,destinationClass:destinationClass},smalltalk.HLLocalEnvironment)})},
+messageSends: ["at:", "asSymbol", "current", "ifNil:", "value", "adoptMethod:", "forsakeMethod:", "methodClass"]}),
+smalltalk.HLLocalEnvironment);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -201,3 +234,28 @@ smalltalk.HLRemoteObject);
 
 
 
+smalltalk.addMethod(
+"_adoptMethod_",
+smalltalk.method({
+selector: "adoptMethod:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self;
+_st($1)._compile_(_st(aMethod)._source());
+$2=_st($1)._category_(_st(aMethod)._protocol());
+return self}, function($ctx1) {$ctx1.fill(self,"adoptMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
+messageSends: ["compile:", "source", "category:", "protocol"]}),
+smalltalk.Behavior);
+
+smalltalk.addMethod(
+"_forsakeMethod_",
+smalltalk.method({
+selector: "forsakeMethod:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._removeCompiledMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"forsakeMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
+messageSends: ["removeCompiledMethod:"]}),
+smalltalk.Behavior);
+

+ 78 - 0
js/Helios-Environments.js

@@ -105,6 +105,22 @@ referencedClasses: []
 }),
 smalltalk.HLEnvironment);
 
+smalltalk.addMethod(
+"_moveMethod_toClass_ifAbsent_",
+smalltalk.method({
+selector: "moveMethod:toClass:ifAbsent:",
+category: 'actions',
+fn: function (aMethod,aClassName,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethod:toClass:ifAbsent:",{aMethod:aMethod,aClassName:aClassName,aBlock:aBlock},smalltalk.HLEnvironment)})},
+args: ["aMethod", "aClassName", "aBlock"],
+source: "moveMethod: aMethod toClass: aClassName ifAbsent: aBlock\x0a\x09self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
+referencedClasses: []
+}),
+smalltalk.HLEnvironment);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -174,6 +190,33 @@ referencedClasses: ["Compiler", "Error"]
 }),
 smalltalk.HLLocalEnvironment);
 
+smalltalk.addMethod(
+"_moveMethod_toClass_ifAbsent_",
+smalltalk.method({
+selector: "moveMethod:toClass:ifAbsent:",
+category: 'actions',
+fn: function (aMethod,aClassName,aBlock){
+var self=this;
+var destinationClass;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+destinationClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(_st(aClassName)._asSymbol());
+$1=destinationClass;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(aBlock)._value();
+return $2;
+} else {
+$1;
+};
+_st(destinationClass)._adoptMethod_(aMethod);
+_st(_st(aMethod)._methodClass())._forsakeMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"moveMethod:toClass:ifAbsent:",{aMethod:aMethod,aClassName:aClassName,aBlock:aBlock,destinationClass:destinationClass},smalltalk.HLLocalEnvironment)})},
+args: ["aMethod", "aClassName", "aBlock"],
+source: "moveMethod: aMethod toClass: aClassName ifAbsent: aBlock\x0a\x09| destinationClass |\x0a\x09\x0a\x09destinationClass := Smalltalk current at: aClassName asSymbol.\x0a\x09destinationClass ifNil: [ ^ aBlock value ].\x0a\x09\x0a\x09destinationClass adoptMethod: aMethod.\x0a\x09aMethod methodClass forsakeMethod: aMethod.\x0a\x09",
+messageSends: ["at:", "asSymbol", "current", "ifNil:", "value", "adoptMethod:", "forsakeMethod:", "methodClass"],
+referencedClasses: ["Smalltalk"]
+}),
+smalltalk.HLLocalEnvironment);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -278,3 +321,38 @@ smalltalk.HLRemoteObject);
 
 
 
+smalltalk.addMethod(
+"_adoptMethod_",
+smalltalk.method({
+selector: "adoptMethod:",
+category: '*Helios-Environments',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self;
+_st($1)._compile_(_st(aMethod)._source());
+$2=_st($1)._category_(_st(aMethod)._protocol());
+return self}, function($ctx1) {$ctx1.fill(self,"adoptMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
+args: ["aMethod"],
+source: "adoptMethod: aMethod\x0a\x09self \x0a\x09\x09compile: aMethod source;\x0a\x09\x09category: aMethod protocol.",
+messageSends: ["compile:", "source", "category:", "protocol"],
+referencedClasses: []
+}),
+smalltalk.Behavior);
+
+smalltalk.addMethod(
+"_forsakeMethod_",
+smalltalk.method({
+selector: "forsakeMethod:",
+category: '*Helios-Environments',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._removeCompiledMethod_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"forsakeMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
+args: ["aMethod"],
+source: "forsakeMethod: aMethod\x0a\x09self removeCompiledMethod: aMethod",
+messageSends: ["removeCompiledMethod:"],
+referencedClasses: []
+}),
+smalltalk.Behavior);
+

+ 184 - 29
js/Helios-KeyBindings.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-KeyBindings');
-smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label', 'each'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -116,6 +116,16 @@ return self}, function($ctx1) {$ctx1.fill(self,"label:",{aString:aString}, small
 messageSends: []}),
 smalltalk.HLBinding);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBinding)})},
+messageSends: []}),
+smalltalk.HLBinding);
+
 smalltalk.addMethod(
 "_renderActionFor_html_",
 smalltalk.method({
@@ -235,17 +245,18 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$5,$1;
 $2=_st((smalltalk.HLBindingInput || HLBindingInput))._new();
 _st($2)._label_(_st(_st(self)._command())._inputLabel());
-_st($2)._callback_((function(val){
+_st($2)._callback_((function(val,errorBlock){
 return smalltalk.withContext(function($ctx2) {
$3=_st(self)._command();
 _st($3)._input_(val);
+_st($3)._errorBlock_(errorBlock);
 $4=_st($3)._execute();
 return $4;
-}, function($ctx2) {$ctx2.fillBlock({val:val},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({val:val,errorBlock:errorBlock},$ctx1)})}));
 $5=_st($2)._yourself();
 $1=$5;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"inputBinding",{},smalltalk.HLBindingAction)})},
-messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "execute", "yourself"]}),
+messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "errorBlock:", "execute", "yourself"]}),
 smalltalk.HLBindingAction);
 
 smalltalk.addMethod(
@@ -431,6 +442,19 @@ return $1;
 messageSends: ["notEmpty", "activeBindings"]}),
 smalltalk.HLBindingGroup);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._bindings())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._release();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingGroup)})},
+messageSends: ["do:", "release", "bindings"]}),
+smalltalk.HLBindingGroup);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -448,16 +472,24 @@ smalltalk.HLBindingGroup);
 
 
 
-smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback', 'status', 'inputText', 'wrapper', 'binder'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
 selector: "applyOn:",
 fn: function (aKeyBinder){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._evaluate_(_st(self)._input());
-return self}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
-messageSends: ["evaluate:", "input"]}),
+return smalltalk.withContext(function($ctx1) { 
var $early={};
+try {
+_st(self)._evaluate_onError_(_st(self)._input(),(function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._errorStatus();
+_st(self)._refresh();
+throw $early=[false];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
+messageSends: ["evaluate:onError:", "input", "errorStatus", "refresh"]}),
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
@@ -492,14 +524,25 @@ messageSends: []}),
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
-"_evaluate_",
+"_errorStatus",
 smalltalk.method({
-selector: "evaluate:",
-fn: function (aString){
+selector: "errorStatus",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._status_("error");
+return self}, function($ctx1) {$ctx1.fill(self,"errorStatus",{},smalltalk.HLBindingInput)})},
+messageSends: ["status:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_evaluate_onError_",
+smalltalk.method({
+selector: "evaluate:onError:",
+fn: function (aString,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"evaluate:",{aString:aString},smalltalk.HLBindingInput)})},
-messageSends: ["value:", "callback"]}),
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_value_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"evaluate:onError:",{aString:aString,aBlock:aBlock},smalltalk.HLBindingInput)})},
+messageSends: ["value:value:", "callback"]}),
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
@@ -509,10 +552,40 @@ selector: "input",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st(self["@input"])._asJQuery())._val();
+$1=self["@input"];
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"input",{},smalltalk.HLBindingInput)})},
-messageSends: ["val", "asJQuery"]}),
+messageSends: []}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText",
+smalltalk.method({
+selector: "inputText",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@inputText"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inputText"]="";
+$1=self["@inputText"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inputText",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText_",
+smalltalk.method({
+selector: "inputText:",
+fn: function (aText){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@inputText"]=aText;
+return self}, function($ctx1) {$ctx1.fill(self,"inputText:",{aText:aText},smalltalk.HLBindingInput)})},
+messageSends: []}),
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
@@ -526,31 +599,106 @@ return smalltalk.withContext(function($ctx1) { 
return true;
 messageSends: []}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self["@wrapper"])._asJQuery())._empty();
+_st((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._renderActionFor_html_(self["@binder"],html);
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_(_st(self["@wrapper"])._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:", "empty", "asJQuery", "appendToJQuery:", "renderActionFor:html:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=nil;
+self["@wrapper"]=nil;
+self["@binder"]=nil;
+self["@inputText"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingInput)})},
+messageSends: []}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_renderActionFor_html_",
 smalltalk.method({
 selector: "renderActionFor:html:",
 fn: function (aBinder,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2,$5;
-$1=_st(html)._span();
-_st($1)._class_("command");
-$2=_st($1)._with_((function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(html)._input();
-_st($3)._class_("search-query");
-$4=_st($3)._placeholder_(_st(self)._displayLabel());
-self["@input"]=$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$3,$6;
+self["@binder"]=aBinder;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@wrapper"]=_st(html)._span();
+self["@wrapper"];
+} else {
+$1;
+};
+$2=self["@wrapper"];
+_st($2)._class_(_st("control-group ").__comma(_st(self)._status()));
+$3=_st($2)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
$4=_st(html)._input();
+_st($4)._class_("input");
+_st($4)._placeholder_(_st(self)._displayLabel());
+$5=_st($4)._with_(_st(self)._inputText());
+self["@input"]=$5;
 return self["@input"];
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(self["@input"])._onKeyPress_((function(event){
-return smalltalk.withContext(function($ctx2) {
$5=_st(_st(event)._keyCode()).__eq((13));
-if(smalltalk.assert($5)){
+return smalltalk.withContext(function($ctx2) {
$6=_st(_st(event)._keyCode()).__eq((13));
+if(smalltalk.assert($6)){
 return _st(self)._applyOn_(aBinder);
 };
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
 _st(_st(self["@input"])._asJQuery())._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"renderActionFor:html:",{aBinder:aBinder,html:html},smalltalk.HLBindingInput)})},
-messageSends: ["class:", "span", "with:", "input", "placeholder:", "displayLabel", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"]}),
+messageSends: ["ifNil:", "span", "class:", ",", "status", "with:", "input", "placeholder:", "displayLabel", "inputText", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status",
+smalltalk.method({
+selector: "status",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=status;
+if(($receiver = $2) == nil || $receiver == undefined){
+status="info";
+$1=status;
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"status",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status_",
+smalltalk.method({
+selector: "status:",
+fn: function (aStatus){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=aStatus;
+return self}, function($ctx1) {$ctx1.fill(self,"status:",{aStatus:aStatus},smalltalk.HLBindingInput)})},
+messageSends: []}),
 smalltalk.HLBindingInput);
 
 
@@ -636,10 +784,17 @@ smalltalk.method({
 selector: "deactivate",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selectedBinding"]=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selectedBinding"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@selectedBinding"])._release();
+};
+self["@selectedBinding"]=nil;
 _st(_st(self)._helper())._hide();
 return self}, function($ctx1) {$ctx1.fill(self,"deactivate",{},smalltalk.HLKeyBinder)})},
-messageSends: ["hide", "helper"]}),
+messageSends: ["ifNotNil:", "release", "hide", "helper"]}),
 smalltalk.HLKeyBinder);
 
 smalltalk.addMethod(

+ 237 - 37
js/Helios-KeyBindings.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-KeyBindings');
-smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label', 'each'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -166,6 +166,21 @@ referencedClasses: []
 }),
 smalltalk.HLBinding);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBinding)})},
+args: [],
+source: "release",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBinding);
+
 smalltalk.addMethod(
 "_renderActionFor_html_",
 smalltalk.method({
@@ -321,19 +336,20 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$5,$1;
 $2=_st((smalltalk.HLBindingInput || HLBindingInput))._new();
 _st($2)._label_(_st(_st(self)._command())._inputLabel());
-_st($2)._callback_((function(val){
+_st($2)._callback_((function(val,errorBlock){
 return smalltalk.withContext(function($ctx2) {
$3=_st(self)._command();
 _st($3)._input_(val);
+_st($3)._errorBlock_(errorBlock);
 $4=_st($3)._execute();
 return $4;
-}, function($ctx2) {$ctx2.fillBlock({val:val},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({val:val,errorBlock:errorBlock},$ctx1)})}));
 $5=_st($2)._yourself();
 $1=$5;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"inputBinding",{},smalltalk.HLBindingAction)})},
 args: [],
-source: "inputBinding\x0a\x09^ HLBindingInput new\x0a\x09\x09label: self command inputLabel;\x0a\x09\x09callback: [ :val | \x0a\x09\x09\x09self command \x0a\x09\x09\x09\x09input: val;\x0a\x09\x09\x09\x09execute ];\x0a\x09\x09yourself",
-messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "execute", "yourself"],
+source: "inputBinding\x0a\x09^ HLBindingInput new\x0a\x09\x09label: self command inputLabel;\x0a\x09\x09callback: [ :val :errorBlock | \x0a\x09\x09\x09self command \x0a\x09\x09\x09\x09input: val;\x0a\x09\x09\x09\x09errorBlock: errorBlock;\x0a\x09\x09\x09\x09execute ];\x0a\x09\x09yourself",
+messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "errorBlock:", "execute", "yourself"],
 referencedClasses: ["HLBindingInput"]
 }),
 smalltalk.HLBindingAction);
@@ -581,6 +597,24 @@ referencedClasses: []
 }),
 smalltalk.HLBindingGroup);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._bindings())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._release();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingGroup)})},
+args: [],
+source: "release\x0a\x09self bindings do: [ :each | each release ]",
+messageSends: ["do:", "release", "bindings"],
+referencedClasses: []
+}),
+smalltalk.HLBindingGroup);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -603,7 +637,7 @@ smalltalk.HLBindingGroup);
 
 
 
-smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback', 'status', 'inputText', 'wrapper', 'binder'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -611,11 +645,19 @@ selector: "applyOn:",
 category: 'actions',
 fn: function (aKeyBinder){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._evaluate_(_st(self)._input());
-return self}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
+return smalltalk.withContext(function($ctx1) { 
var $early={};
+try {
+_st(self)._evaluate_onError_(_st(self)._input(),(function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._errorStatus();
+_st(self)._refresh();
+throw $early=[false];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
 args: ["aKeyBinder"],
-source: "applyOn: aKeyBinder\x0a\x09self evaluate: self input",
-messageSends: ["evaluate:", "input"],
+source: "applyOn: aKeyBinder\x0a\x09self \x0a\x09\x09evaluate: self input \x0a\x09\x09onError: [ \x0a\x09\x09\x09self errorStatus.\x0a\x09\x09\x09self refresh.\x0a\x09\x09\x09^ false ]",
+messageSends: ["evaluate:onError:", "input", "errorStatus", "refresh"],
 referencedClasses: []
 }),
 smalltalk.HLBindingInput);
@@ -662,17 +704,33 @@ referencedClasses: []
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
-"_evaluate_",
+"_errorStatus",
 smalltalk.method({
-selector: "evaluate:",
+selector: "errorStatus",
 category: 'actions',
-fn: function (aString){
+fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"evaluate:",{aString:aString},smalltalk.HLBindingInput)})},
-args: ["aString"],
-source: "evaluate: aString\x0a\x09self callback value: aString",
-messageSends: ["value:", "callback"],
+return smalltalk.withContext(function($ctx1) { 
_st(self)._status_("error");
+return self}, function($ctx1) {$ctx1.fill(self,"errorStatus",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "errorStatus\x0a\x09self status: 'error'",
+messageSends: ["status:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_evaluate_onError_",
+smalltalk.method({
+selector: "evaluate:onError:",
+category: 'actions',
+fn: function (aString,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_value_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"evaluate:onError:",{aString:aString,aBlock:aBlock},smalltalk.HLBindingInput)})},
+args: ["aString", "aBlock"],
+source: "evaluate: aString onError: aBlock\x0a\x09self callback value: aString value: aBlock",
+messageSends: ["value:value:", "callback"],
 referencedClasses: []
 }),
 smalltalk.HLBindingInput);
@@ -685,12 +743,52 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st(self["@input"])._asJQuery())._val();
+$1=self["@input"];
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"input",{},smalltalk.HLBindingInput)})},
 args: [],
-source: "input\x0a\x09^ input asJQuery val",
-messageSends: ["val", "asJQuery"],
+source: "input\x0a\x09^ input",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText",
+smalltalk.method({
+selector: "inputText",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@inputText"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inputText"]="";
+$1=self["@inputText"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inputText",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "inputText\x0a\x09^ inputText ifNil: [ inputText := '' ].",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText_",
+smalltalk.method({
+selector: "inputText:",
+category: 'accessing',
+fn: function (aText){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@inputText"]=aText;
+return self}, function($ctx1) {$ctx1.fill(self,"inputText:",{aText:aText},smalltalk.HLBindingInput)})},
+args: ["aText"],
+source: "inputText: aText\x0a\x09inputText := aText",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.HLBindingInput);
@@ -711,34 +809,129 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+category: 'rendering',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self["@wrapper"])._asJQuery())._empty();
+_st((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._renderActionFor_html_(self["@binder"],html);
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_(_st(self["@wrapper"])._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "refresh\x0a\x09wrapper ifNil: [ ^ self ].\x0a    \x0a\x09wrapper asJQuery empty.\x0a    [ :html | self renderActionFor: binder html: html ] appendToJQuery: wrapper asJQuery",
+messageSends: ["ifNil:", "empty", "asJQuery", "appendToJQuery:", "renderActionFor:html:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=nil;
+self["@wrapper"]=nil;
+self["@binder"]=nil;
+self["@inputText"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "release\x0a\x09status := nil.\x0a\x09wrapper := nil.\x0a\x09binder := nil.\x0a\x09inputText := nil",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_renderActionFor_html_",
 smalltalk.method({
 selector: "renderActionFor:html:",
-category: 'accessing',
+category: 'rendering',
 fn: function (aBinder,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2,$5;
-$1=_st(html)._span();
-_st($1)._class_("command");
-$2=_st($1)._with_((function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(html)._input();
-_st($3)._class_("search-query");
-$4=_st($3)._placeholder_(_st(self)._displayLabel());
-self["@input"]=$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$3,$6;
+self["@binder"]=aBinder;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@wrapper"]=_st(html)._span();
+self["@wrapper"];
+} else {
+$1;
+};
+$2=self["@wrapper"];
+_st($2)._class_(_st("control-group ").__comma(_st(self)._status()));
+$3=_st($2)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
$4=_st(html)._input();
+_st($4)._class_("input");
+_st($4)._placeholder_(_st(self)._displayLabel());
+$5=_st($4)._with_(_st(self)._inputText());
+self["@input"]=$5;
 return self["@input"];
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(self["@input"])._onKeyPress_((function(event){
-return smalltalk.withContext(function($ctx2) {
$5=_st(_st(event)._keyCode()).__eq((13));
-if(smalltalk.assert($5)){
+return smalltalk.withContext(function($ctx2) {
$6=_st(_st(event)._keyCode()).__eq((13));
+if(smalltalk.assert($6)){
 return _st(self)._applyOn_(aBinder);
 };
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
 _st(_st(self["@input"])._asJQuery())._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"renderActionFor:html:",{aBinder:aBinder,html:html},smalltalk.HLBindingInput)})},
 args: ["aBinder", "html"],
-source: "renderActionFor: aBinder html: html\x0a\x09html span \x0a\x09\x09class: 'command'; \x0a\x09\x09with: [\x0a\x09\x09\x09input := html input\x0a\x09\x09\x09\x09class: 'search-query';\x0a\x09\x09\x09\x09placeholder: self displayLabel ].\x0a\x09\x09\x09\x09\x0a\x09input onKeyPress: [:event |\x0a\x09\x09event keyCode = 13 ifTrue: [\x0a\x09\x09\x09self applyOn: aBinder ] ].\x0a\x09\x09\x09\x09\x0a\x09input asJQuery focus",
-messageSends: ["class:", "span", "with:", "input", "placeholder:", "displayLabel", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"],
+source: "renderActionFor: aBinder html: html\x0a\x09binder := aBinder.\x0a\x09wrapper ifNil: [ wrapper := html span ].\x0a\x09\x0a\x09wrapper\x0a\x09\x09class: 'control-group ', self status; \x0a\x09\x09with: [\x0a\x09\x09\x09input := html input\x0a\x09\x09\x09\x09class: 'input';\x0a\x09\x09\x09\x09placeholder: self displayLabel;\x0a\x09\x09\x09\x09with: self inputText ].\x0a\x09\x09\x09\x09\x0a\x09input onKeyPress: [ :event |\x0a\x09\x09event keyCode = 13 \x0a\x09\x09\x09ifTrue: [ self applyOn: aBinder ] ].\x0a\x09\x09\x09\x09\x0a\x09input asJQuery focus",
+messageSends: ["ifNil:", "span", "class:", ",", "status", "with:", "input", "placeholder:", "displayLabel", "inputText", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status",
+smalltalk.method({
+selector: "status",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=status;
+if(($receiver = $2) == nil || $receiver == undefined){
+status="info";
+$1=status;
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"status",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "status\x0a\x09^ status ifNil: [ status := 'info' ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status_",
+smalltalk.method({
+selector: "status:",
+category: 'accessing',
+fn: function (aStatus){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=aStatus;
+return self}, function($ctx1) {$ctx1.fill(self,"status:",{aStatus:aStatus},smalltalk.HLBindingInput)})},
+args: ["aStatus"],
+source: "status: aStatus\x0a\x09status := aStatus",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.HLBindingInput);
@@ -852,12 +1045,19 @@ selector: "deactivate",
 category: 'actions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selectedBinding"]=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selectedBinding"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@selectedBinding"])._release();
+};
+self["@selectedBinding"]=nil;
 _st(_st(self)._helper())._hide();
 return self}, function($ctx1) {$ctx1.fill(self,"deactivate",{},smalltalk.HLKeyBinder)})},
 args: [],
-source: "deactivate\x0a    selectedBinding := nil.\x0a\x09self helper hide",
-messageSends: ["hide", "helper"],
+source: "deactivate\x0a\x09selectedBinding ifNotNil: [ selectedBinding release ].\x0a    selectedBinding := nil.\x0a\x09self helper hide",
+messageSends: ["ifNotNil:", "release", "hide", "helper"],
 referencedClasses: []
 }),
 smalltalk.HLKeyBinder);

+ 5 - 2
st/Helios-Browser.st

@@ -846,8 +846,11 @@ saveSourceCode
 
 !HLBrowserModel methodsFor: 'commands actions'!
 
-moveMethodToClass: aClassName
-	console log: 'moveMethodToClass ', aClassName
+moveMethodToClass: aClassName ifAbsent: aBlock
+	self environment 
+		moveMethod: self selectedMethod 
+		toClass: aClassName 
+		ifAbsent: aBlock
 ! !
 
 !HLBrowserModel methodsFor: 'compiling'!

+ 1 - 5
st/Helios-Commands-Browser.st

@@ -182,11 +182,7 @@ inputLabel
 !HLMoveMethodToClassCommand methodsFor: 'executing'!
 
 execute
-	| class |
-	class := Smalltalk current at: self input.
-	class ifNil: [ self commandError: 'No class named: ', self input ].
-	
-	self model moveMethodToClass: class
+	self model moveMethodToClass: self input ifAbsent: self errorBlock
 ! !
 
 !HLMoveMethodToClassCommand methodsFor: 'testing'!

+ 9 - 1
st/Helios-Commands-Core.st

@@ -1,6 +1,6 @@
 Smalltalk current createPackage: 'Helios-Commands-Core'!
 Object subclass: #HLCommand
- instanceVariableNames: 'input'
+ instanceVariableNames: 'input errorBlock'
  package: 'Helios-Commands-Core'!
 
 !HLCommand methodsFor: 'accessing'!
@@ -9,6 +9,14 @@ documentation
 	^ self class documentation
 !
 
+errorBlock
+	^ errorBlock
+!
+
+errorBlock: aBlock
+	errorBlock := aBlock
+!
+
 input
 	^ input
 !

+ 34 - 8
st/Helios-Environments.st

@@ -1,7 +1,7 @@
 Smalltalk current createPackage: 'Helios-Environments'!
 Object subclass: #HLEnvironment
-	instanceVariableNames: ''
-	package: 'Helios-Environments'!
+ instanceVariableNames: ''
+ package: 'Helios-Environments'!
 !HLEnvironment commentStamp!
 Abstract class defining common behavior for local and remote environments!
 
@@ -20,6 +20,10 @@ packages
 eval: someCode on: aReceiver
 
 	^ self subclassResponsibility
+!
+
+moveMethod: aMethod toClass: aClassName ifAbsent: aBlock
+	self subclassResponsibility
 ! !
 
 !HLEnvironment methodsFor: 'compiling'!
@@ -47,8 +51,8 @@ compileMethod: sourceCode for: class protocol: protocol
 ! !
 
 HLEnvironment subclass: #HLLocalEnvironment
-	instanceVariableNames: ''
-	package: 'Helios-Environments'!
+ instanceVariableNames: ''
+ package: 'Helios-Environments'!
 
 !HLLocalEnvironment methodsFor: 'accessing'!
 
@@ -68,11 +72,21 @@ eval: aString on: aReceiver
 	[ compiler parseExpression: aString ] on: Error do: [ :ex |
 		^ window alert: ex messageText ].
 	^ compiler evaluateExpression: aString on: aReceiver
+!
+
+moveMethod: aMethod toClass: aClassName ifAbsent: aBlock
+	| destinationClass |
+	
+	destinationClass := Smalltalk current at: aClassName asSymbol.
+	destinationClass ifNil: [ ^ aBlock value ].
+	
+	destinationClass adoptMethod: aMethod.
+	aMethod methodClass forsakeMethod: aMethod.
 ! !
 
 HLEnvironment subclass: #HLRemoteEnvironment
-	instanceVariableNames: ''
-	package: 'Helios-Environments'!
+ instanceVariableNames: ''
+ package: 'Helios-Environments'!
 
 !HLRemoteEnvironment methodsFor: 'accessing'!
 
@@ -98,8 +112,8 @@ eval: someCode on: aReceiver
 ! !
 
 Object subclass: #HLRemoteObject
-	instanceVariableNames: ''
-	package: 'Helios-Environments'!
+ instanceVariableNames: ''
+ package: 'Helios-Environments'!
 !HLRemoteObject commentStamp!
 This is a local proxy to a remote object.
 Tipically useful for evaluating and inspecting and interacting with instances of a remote VM.!
@@ -126,3 +140,15 @@ printString
 	^ 'this is a remote object'
 ! !
 
+!Behavior methodsFor: '*Helios-Environments'!
+
+adoptMethod: aMethod
+	self 
+		compile: aMethod source;
+		category: aMethod protocol.
+!
+
+forsakeMethod: aMethod
+	self removeCompiledMethod: aMethod
+! !
+

+ 76 - 20
st/Helios-KeyBindings.st

@@ -1,6 +1,6 @@
 Smalltalk current createPackage: 'Helios-KeyBindings'!
 Object subclass: #HLBinding
- instanceVariableNames: 'key label each'
+ instanceVariableNames: 'key label'
  package: 'Helios-KeyBindings'!
 
 !HLBinding methodsFor: 'accessing'!
@@ -39,6 +39,9 @@ applyOn: aKeyBinder
 !
 
 applyOn: aKeyBinder then: aBlock
+!
+
+release
 ! !
 
 !HLBinding methodsFor: 'rendering'!
@@ -95,9 +98,10 @@ command: aCommand
 inputBinding
 	^ HLBindingInput new
 		label: self command inputLabel;
-		callback: [ :val | 
+		callback: [ :val :errorBlock | 
 			self command 
 				input: val;
+				errorBlock: errorBlock;
 				execute ];
 		yourself
 ! !
@@ -173,6 +177,12 @@ displayLabel
 	^ super displayLabel, '...'
 ! !
 
+!HLBindingGroup methodsFor: 'actions'!
+
+release
+	self bindings do: [ :each | each release ]
+! !
+
 !HLBindingGroup methodsFor: 'rendering'!
 
 renderOn: aBindingHelper html: html
@@ -187,7 +197,7 @@ isActive
 ! !
 
 HLBinding subclass: #HLBindingInput
- instanceVariableNames: 'input callback'
+ instanceVariableNames: 'input callback status inputText wrapper binder'
  package: 'Helios-KeyBindings'!
 
 !HLBindingInput methodsFor: 'accessing'!
@@ -201,32 +211,77 @@ callback: aBlock
 !
 
 input
-	^ input asJQuery val
+	^ input
 !
 
-renderActionFor: aBinder html: html
-	html span 
-		class: 'command'; 
-		with: [
-			input := html input
-				class: 'search-query';
-				placeholder: self displayLabel ].
-				
-	input onKeyPress: [:event |
-		event keyCode = 13 ifTrue: [
-			self applyOn: aBinder ] ].
-				
-	input asJQuery focus
+inputText
+	^ inputText ifNil: [ inputText := '' ].
+!
+
+inputText: aText
+	inputText := aText
+!
+
+status
+	^ status ifNil: [ status := 'info' ]
+!
+
+status: aStatus
+	status := aStatus
 ! !
 
 !HLBindingInput methodsFor: 'actions'!
 
 applyOn: aKeyBinder
-	self evaluate: self input
+	self 
+		evaluate: self input 
+		onError: [ 
+			self errorStatus.
+			self refresh.
+			^ false ]
 !
 
-evaluate: aString
-	self callback value: aString
+errorStatus
+	self status: 'error'
+!
+
+evaluate: aString onError: aBlock
+	self callback value: aString value: aBlock
+!
+
+release
+	status := nil.
+	wrapper := nil.
+	binder := nil.
+	inputText := nil
+! !
+
+!HLBindingInput methodsFor: 'rendering'!
+
+refresh
+	wrapper ifNil: [ ^ self ].
+    
+	wrapper asJQuery empty.
+    [ :html | self renderActionFor: binder html: html ] appendToJQuery: wrapper asJQuery
+!
+
+renderActionFor: aBinder html: html
+	binder := aBinder.
+	wrapper ifNil: [ wrapper := html span ].
+	
+	wrapper
+		class: 'control-group ', self status; 
+		with: [
+			input := html input
+				class: 'input';
+				placeholder: self displayLabel;
+				with: self inputText ].
+				
+	input onKeyPress: [ :event |
+		event keyCode = 13 
+			ifTrue: [ self applyOn: aBinder ] ].
+				
+	input asJQuery focus
 ! !
 
 !HLBindingInput methodsFor: 'testing'!
@@ -283,6 +338,7 @@ applyBinding: aBinding
 !
 
 deactivate
+	selectedBinding ifNotNil: [ selectedBinding release ].
     selectedBinding := nil.
 	self helper hide
 !