#FEATURE by cg
class: ReadEvalPrintLoop
class definition
changed:
#cmd_edit:
#directive:
--- a/ReadEvalPrintLoop.st Tue Nov 08 19:25:24 2016 +0100
+++ b/ReadEvalPrintLoop.st Tue Nov 08 20:12:13 2016 +0100
@@ -16,7 +16,7 @@
Object subclass:#ReadEvalPrintLoop
instanceVariableNames:'inputStream outputStream errorStream compiler prompt
doChunkFormat traceFlag timingFlag profilingFlag printFlag
- exitAction currentDirectory lastEditedClass'
+ exitAction currentDirectory lastEditedClass lastEditedSelector'
classVariableNames:''
poolDictionaries:''
category:'System-Support'
@@ -219,36 +219,44 @@
isNewClass := editFullClass := false.
lineStream skipSeparators.
- lineStream atEnd ifTrue:[^ self].
+ lineStream atEnd ifTrue:[
+ cls := lastEditedClass.
+ methodName := lastEditedSelector.
+ ] ifFalse:[
- classOrMethodName := lineStream
- upToElementForWhich:[:ch |
- ch isLetterOrDigit not and:[ch ~~ $_]
- ].
- "/
- (classOrMethodName isUppercaseFirst) ifTrue:[
- (cls := Smalltalk classNamed:classOrMethodName) isNil ifTrue:[
- errStream show:'edit: no such class: ',classOrMethodName,' ; create (y/n)? '.
- (self inputStream nextLine withoutSeparators startsWith:'y') ifFalse:[^ self].
- isNewClass := true.
- code :=
-'Object
+ classOrMethodName := lineStream
+ upToElementForWhich:[:ch |
+ ch isLetterOrDigit not and:[ch ~~ $_]
+ ].
+ "/
+ (classOrMethodName isUppercaseFirst) ifTrue:[
+ (cls := Smalltalk classNamed:classOrMethodName) isNil ifTrue:[
+ errStream show:'edit: no such class: ',classOrMethodName,' ; create (y/n)? '.
+ (self inputStream nextLine withoutSeparators startsWith:'y') ifFalse:[^ self].
+ isNewClass := true.
+ code :=
+'"/ change the code as required, then save and exit the editor.
+"/ To cancel this edit, leave the editor WITHOUT saving.
+"/
+
+Object
subclass:#%1
instanceVariableNames:''''
classVariableNames:''''
poolDictionaries:''''
category:''user classes''
' bindWith:classOrMethodName.
- ] ifFalse:[
- lineStream skipSeparators.
- lineStream atEnd ifFalse:[
- methodName := lineStream upToSeparator.
+ ] ifFalse:[
+ lineStream skipSeparators.
+ lineStream atEnd ifFalse:[
+ methodName := lineStream upToSeparator.
+ ].
].
+ ] ifFalse:[
+ methodName := classOrMethodName
].
- ] ifFalse:[
- methodName := classOrMethodName
].
-
+
isNewClass ifFalse:[
cls := cls ? lastEditedClass.
cls isNil ifTrue:[
@@ -256,9 +264,12 @@
errStream showCR:' #edit className selector'.
errStream showCR:' #edit className '.
errStream showCR:' #edit selector (class as in previous edit)'.
+ errStream showCR:' #edit (class/method as in previous edit)'.
^ self.
].
lastEditedClass := cls.
+ lastEditedSelector := methodName.
+
methodName isNil ifTrue:[
editFullClass := true.
code := cls source asString
@@ -267,13 +278,16 @@
or:[ (cls implements:selector) not]) ifTrue:[
errStream show:('"',methodName,'" is a new method; create (y/n)? ').
(self inputStream nextLine withoutSeparators startsWith:'y') ifFalse:[^ self].
- code := '
+ code :=
+'"/ change the code as required, then save and exit the editor.
+"/ To cancel this edit, leave the editor WITHOUT saving.
+
%1
"this is a new method"
self halt
' bindWith:methodName.
] ifFalse:[
- code := cls compiledMethodAt:selector.
+ code := (cls compiledMethodAt:selector) source.
].
].
].
@@ -285,9 +299,9 @@
OperatingSystem
executeCommand:('%1 "%2" < /dev/tty' bindWith:editor with:tmpFile pathName)
- inputFrom:('/dev/tty' asFilename readStream) "/ self inputStream
- outputTo:('/dev/tty' asFilename writeStream) "/ self outputStream
- errorTo:('/dev/tty' asFilename writeStream). "/ self errorStream.
+ inputFrom:Stdin
+ outputTo:Stdout
+ errorTo:Stderr.
tmpFile modificationTime ~= modifiedTime ifTrue:[
isNewClass ifTrue:[
@@ -568,15 +582,21 @@
self errorStream showCR:('Directive aborted: ', ex description)
] do:[
Error handle:[:ex |
- self errorStream showCR:('Ignored in directive: ', ex description).
+ self errorStream showCR:('Caught in directive: ', ex description).
+ ex suspendedContext fullPrintAll.
] do:[
- self
- perform:('cmd_',cmd) asMutator with:s
- ifNotUnderstood:[
- self errorStream
- show:'?? invalid command: '; show:cmd;
- showCR:'. Type "#help" for help.'
- ].
+ ControlInterrupt handle:[:ex |
+ self errorStream showCR:('Ignored in directive: ', ex description).
+ ex proceed.
+ ] do:[
+ self
+ perform:('cmd_',cmd) asMutator with:s
+ ifNotUnderstood:[
+ self errorStream
+ show:'?? invalid command: '; show:cmd;
+ showCR:'. Type "#help" for help.'
+ ].
+ ].
].
].
].