Nicolas Cellier uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ct.1640.mcz
==================== Summary ====================
Name: Morphic-ct.1640
Author: ct
Time: 22 March 2020, 12:09:37.99656 am
UUID: bf7487fc-35a0-9641-9e60-1d3056d35384
Ancestors: Morphic-eem.1638
Reverts Morphic-ct.1606, which attempted to solve an issue around interactive parser selections on the wrong way and introduced a new regression.
To reproduce this new regression, in an interactive environment (no automatic variable declarations! u could use an empty browser, for example), try to printIt:
x:=6*7
Answer the UnknownVariable dialog with "declare method temp".
Expected output:
| x |
x:=6*7 42
Actual output:
| x |
42x:=6*7
Let me explain:
In Morphic-ct.1606, we reverted any selection change that occured during the interactive compilation. While this is fine for warnings that can be accepted only, by that change we neglected the fact that certain parser notifications actually modify the source and thus need to permanently adjust the selection. This is what we depend on for a correct functionality of #declareTemp:at: and others. See also #correct:from:to:.
Instead, the actual bug occurs in the parser, where #queryUndefined forgets to reset the selection after the UndefinedVariable warning has been skipped. Other error correction tools know how to do this correctly, for example #correctVariable:interval:. This bug will be fixed in straightly the next commit. Sorry for the trouble! Load together with Compiler-ct.423 only.
=============== Diff against Morphic-eem.1638 ===============
Item was changed:
----- Method: TextEditor>>evaluateSelectionAndDo: (in category 'do-its') -----
evaluateSelectionAndDo: aBlock
"Treat the current selection as an expression; evaluate it and invoke aBlock with the result."
+ | result rcvr ctxt |
-
- | result rcvr ctxt selectionInterval |
self lineSelectAndEmptyCheck: [^ nil].
(model respondsTo: #evaluateExpression:) ifTrue: [
^ aBlock value: (model perform: #evaluateExpression: with: self selection)].
(model respondsTo: #doItReceiver)
ifTrue: [ rcvr := model doItReceiver.
ctxt := model doItContext]
ifFalse: [rcvr := ctxt := nil].
-
- selectionInterval := self selectionInterval.
result := [
rcvr class evaluatorClass new
evaluate: self selectionAsStream
in: ctxt
to: rcvr
environment: (model environment ifNil: [Smalltalk globals])
notifying: self
ifFail: [morph flash. ^ nil]
logged: true.
]
on: OutOfScopeNotification
do: [ :ex | ex resume: true].
+
- "The parser might change the current selection for interactive error correction."
- self selectInterval: selectionInterval.
-
(model respondsTo: #expressionEvaluated:result:) ifTrue: [
model perform: #expressionEvaluated:result: with: self selection with: result].
^aBlock value: result!
Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.427.mcz
==================== Summary ====================
Name: Compiler-nice.427
Author: nice
Time: 8 May 2020, 6:59:54.689381 pm
UUID: e2c7d4b2-b79d-4d02-a576-872003ec88ed
Ancestors: Compiler-ct.426
Avoid sending select/deselect to the editor in case of interactive correction.
These are st80 specific, forcing Morphic to have stubs, and are considered too intrusive: we should better let such responsibility to the editor, that's its own business.
The send of #select was un-necessary anyway, because selectFrom:to: will send #selectAndScroll, which will send #select.
However, deselect was still required for st80, so replace the sequence deselect; selectInvisiblyFrom:to: with a single message #selectIntervalInvisibly: which is provided by ST80-nice.254 and Morphic-nice.1657.
Why is this needed? As explained in the st80 commit, we want to restore the (eventually slightly modified) user selection once the corrections are performed.
We must do that at each correction, so as to correctly track addition or delection of characters (the selection interval might need to grow or shrink accordingly).
But we do not want to make the user selection visible instantly, otherwise the selection will go back to user selection and forth to next zone of interactive correction repeatedly creating an annoying flashing effect.
Care to let future reader know about it with a comment, there's nothing that obvious which could make the comment superfluous!
=============== Diff against Compiler-ct.426 ===============
Item was changed:
----- Method: Parser>>ambiguousSelector:inRange: (in category 'error correction') -----
ambiguousSelector: aString inRange: anInterval
+ | correctedSelector userSelection intervalWithOffset |
- | correctedSelector userSelection offset intervalWithOffset |
self interactive ifFalse: [
"In non interactive mode, compile with backward comapatibility: $- is part of literal argument"
Transcript cr; store: encoder classEncoding; nextPutAll:#'>>';store: encoder selector; show: ' would send ' , token , '-'.
^super ambiguousSelector: aString inRange: anInterval].
"handle the text selection"
userSelection := cue requestor selectionInterval.
intervalWithOffset := anInterval first + requestorOffset to: anInterval last + requestorOffset.
cue requestor selectFrom: intervalWithOffset first to: intervalWithOffset last.
- cue requestor select.
"Build the menu with alternatives"
correctedSelector := AmbiguousSelector
signalName: aString
inRange: intervalWithOffset.
correctedSelector ifNil: [^self fail].
+ "Restore the user selection state, but do not display selection yet
+ This will avoid flashing effect when chaining multiple corrections."
+ cue requestor selectIntervalInvisibly: userSelection.
+
"Execute the selected action"
+ self substituteWord: correctedSelector wordInterval: intervalWithOffset offset: 0.
- offset := self substituteWord: correctedSelector wordInterval: intervalWithOffset offset: 0.
- cue requestor deselect.
- cue requestor selectInvisiblyFrom: userSelection first to: userSelection last + offset.
token := (correctedSelector readStream upTo: Character space) asSymbol!
Item was changed:
----- Method: Parser>>correctSelector:wordIntervals:exprInterval:ifAbort: (in category 'error correction') -----
correctSelector: proposedKeyword wordIntervals: spots exprInterval: expInt ifAbort: abortAction
"Correct the proposedKeyword to some selector symbol, correcting the original text if such action is indicated. abortAction is invoked if the proposedKeyword couldn't be converted into a valid selector. Spots is an ordered collection of intervals within the test stream of the for each of the keyword parts."
| correctSelector userSelection |
"If we can't ask the user, assume that the keyword will be defined later"
self interactive ifFalse: [^proposedKeyword asSymbol].
userSelection := cue requestor selectionInterval.
cue requestor selectFrom: spots first first to: spots last last.
- cue requestor select.
correctSelector := UnknownSelector name: proposedKeyword.
correctSelector ifNil: [^abortAction value].
+ "Restore the user selection state, but do not display selection yet
+ This will avoid flashing effect when chaining multiple corrections."
+ cue requestor selectIntervalInvisibly: userSelection.
- cue requestor deselect.
- cue requestor selectInvisiblyFrom: userSelection first to: userSelection last.
self substituteSelector: correctSelector keywords wordIntervals: spots.
^(proposedKeyword last ~~ $:
and: [correctSelector last == $:])
ifTrue: [abortAction value]
ifFalse: [correctSelector]!
Item was changed:
----- Method: Parser>>correctVariable:interval: (in category 'error correction') -----
correctVariable: proposedVariable interval: spot
"Correct the proposedVariable to a known variable, or declare it as a new
variable if such action is requested. We support declaring lowercase
variables as temps or inst-vars, and uppercase variables as Globals or
ClassVars, depending on whether the context is nil (class=UndefinedObject).
Spot is the interval within the test stream of the variable.
rr 3/4/2004 10:26 : adds the option to define a new class. "
"Check if this is an i-var, that has been corrected already (ugly)"
"Display the pop-up menu"
| binding userSelection action |
(encoder classEncoding instVarNames includes: proposedVariable) ifTrue:
[^InstanceVariableNode new
name: proposedVariable
index: (encoder classEncoding allInstVarNames indexOf: proposedVariable)].
"First check to see if the requestor knows anything about the variable"
(binding := cue requestor ifNotNil: [:object | object bindingOf: proposedVariable])
ifNotNil: [^encoder global: binding name: proposedVariable].
"If we can't ask the user for correction, make it undeclared"
self interactive ifFalse: [^encoder undeclared: proposedVariable].
userSelection := cue requestor selectionInterval.
cue requestor selectFrom: spot first to: spot last.
- cue requestor select.
"Build the menu with alternatives"
action := UndeclaredVariable
signalFor: self
name: proposedVariable
inRange: spot.
action ifNil: [^self fail].
+ "Restore the user selection state, but do not display selection yet
+ This will avoid flashing effect when chaining multiple corrections."
+ cue requestor selectIntervalInvisibly: userSelection.
+
"Execute the selected action"
- cue requestor deselect.
- cue requestor selectInvisiblyFrom: userSelection first to: userSelection last.
^action value!
Item was changed:
----- Method: Parser>>queryUndefined (in category 'error correction') -----
queryUndefined
| varStart varName |
varName := parseNode key.
varStart := self endOfLastToken + requestorOffset - varName size + 1.
+ cue requestor selectFrom: varStart to: varStart + varName size - 1.
- cue requestor selectFrom: varStart to: varStart + varName size - 1; select.
(UndefinedVariable name: varName) ifFalse: [^ self fail]!
Item was changed:
----- Method: Parser>>substituteSelector:wordIntervals: (in category 'error correction') -----
substituteSelector: selectorParts wordIntervals: spots
+ "Substitute the correctSelector into the (presumed interactive) receiver."
- "Substitute the correctSelector into the (presuamed interactive) receiver."
| offset |
offset := 0.
selectorParts with: spots do:
[ :word :interval |
offset := self substituteWord: word wordInterval: interval offset: offset ]
!
Nicolas Cellier uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-nice.1657.mcz
==================== Summary ====================
Name: Morphic-nice.1657
Author: nice
Time: 8 May 2020, 6:45:14.165388 pm
UUID: 3ad63913-040d-4558-a021-19cb1240eb37
Ancestors: Morphic-nice.1656
Provide #selectIntervalInvisibly: for the interactive correction from the Parser.
See ST80-nice.254.
This replace the sends to select and deselect which should now (or in a very near future) be gone. Nuke'em all!
TextEditor: also avoid sending deselect to ourself now that we know that it will do nothing.
=============== Diff against Morphic-nice.1656 ===============
Item was removed:
- ----- Method: Editor>>deselect (in category 'current selection') -----
- deselect
- "Compatibility stub with st80"
- !
Item was added:
+ ----- Method: Editor>>selectIntervalInvisibly: (in category 'new selection') -----
+ selectIntervalInvisibly: anInterval
+ "Deselect, then select the specified characters inclusive.
+ Do not yet make the new selection visible."
+
+ self selectInvisiblyFrom: anInterval first to: anInterval last!
Item was removed:
- ----- Method: PluggableTextMorph>>deselect (in category 'interactive error protocol') -----
- deselect
- ^ textMorph editor deselect!
Item was removed:
- ----- Method: PluggableTextMorph>>select (in category 'interactive error protocol') -----
- select
- ^ textMorph editor select!
Item was added:
+ ----- Method: PluggableTextMorph>>selectIntervalInvisibly: (in category 'interactive error protocol') -----
+ selectIntervalInvisibly: aSelectionInterval
+ ^ textMorph editor selectIntervalInvisibly: aSelectionInterval!
Item was removed:
- ----- Method: SmalltalkEditor>>select (in category 'compatibility') -----
- select
- "Sent by the parser when correcting variables etc. Ignored here."!
Item was changed:
----- Method: TextEditor>>keyStroke: (in category 'events') -----
keyStroke: anEvent
+ self resetTypeAhead.
- self resetTypeAhead; deselect.
(self dispatchOnKeyboardEvent: anEvent)
ifTrue: [
self closeTypeIn.
self storeSelectionInParagraph.
^self].
self openTypeIn.
self
zapSelectionWith: self typeAhead contents;
resetTypeAhead;
unselect;
storeSelectionInParagraph.!
Item was changed:
----- Method: TextEditor>>prettyPrint: (in category 'menu messages') -----
prettyPrint: decorated
"Reformat the contents of the receiver's view (a Browser or Workspace)."
model selectedClassOrMetaClass
ifNil: [ "arbitrary text selection in a workspace, not directly associated with a class"
(Compiler new formatNoPattern: self selection environment: model environment)
ifNotNilDo: [:newText | self replaceSelectionWith: newText]]
ifNotNil: [:selectedClass | "source for a method in the selected class"
(selectedClass newCompiler
format: self text
in: selectedClass
notifying: self
decorated: decorated)
ifNotNilDo: [ :newText |
+ self selectInvisiblyFrom: 1 to: paragraph text size.
- self deselect; selectInvisiblyFrom: 1 to: paragraph text size.
self replaceSelectionWith: (selectedClass ifNil: [newText] ifNotNil: [newText asText makeSelectorBoldIn: selectedClass]).
self selectAt: self text size + 1 ]].
!
Item was changed:
----- Method: TextEditor>>zapSelectionWith: (in category 'mvc compatibility') -----
zapSelectionWith: replacement
| start stop rep |
morph readOnly ifTrue: [^ self].
- self deselect.
start := self startIndex.
stop := self stopIndex.
(replacement isEmpty and: [stop > start]) ifTrue: [
"If deleting, then set emphasisHere from 1st character of the deletion"
emphasisHere := (self text attributesAt: start) select: [:att | att mayBeExtended]].
(start = stop and: [ replacement isEmpty ]) ifFalse: [
replacement isText
ifTrue: [ rep := replacement]
ifFalse: [ rep := Text string: replacement attributes: emphasisHere ].
self text replaceFrom: start to: stop - 1 with: rep.
paragraph
recomposeFrom: start
to: start + rep size - 1
delta: rep size - (stop-start).
self markIndex: start pointIndex: start + rep size.
otherInterval := self selectionInterval].
self userHasEdited " -- note text now dirty"!
Nicolas Cellier uploaded a new version of ST80 to project The Trunk:
http://source.squeak.org/trunk/ST80-nice.254.mcz
==================== Summary ====================
Name: ST80-nice.254
Author: nice
Time: 8 May 2020, 6:37:59.968801 pm
UUID: b793958a-326b-463e-b3d0-db17fd8aab42
Ancestors: ST80-mt.253
Add a new #selectIntervalInvisibly: method used for interactive correction in Parser.
The Parser wants to interact with the editor so as to perform correction.
But it also want to restore the (eventually slightly modified) user selection once the corrections are performed.
When chaining several corrections, this might create an annoying flashing effect, going from user selection to correction zone back and forth.
In order to avoid such flashing effect, the Parser did request to #select the error zone, #deselect, then #selectInvisiblyFrom:to: the previous user selection.
But only st80 ParagraphEditor needs to select and deselect.
Those are implementation details not required in Morphic Editor, so it's better to provide a new message dedicated to this task and let the responsibility of select/deselect to the editor.
=============== Diff against ST80-mt.253 ===============
Item was added:
+ ----- Method: ParagraphEditor>>selectIntervalInvisibly: (in category 'new selection') -----
+ selectIntervalInvisibly: anInterval
+ "Deselect, then select the specified characters inclusive.
+ Do not yet make the new selection visible."
+
+ self deselect.
+ self selectInvisiblyFrom: anInterval first to: anInterval last!
Nicolas Cellier uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-nice.1656.mcz
==================== Summary ====================
Name: Morphic-nice.1656
Author: nice
Time: 8 May 2020, 5:03:44.586886 pm
UUID: 4550059e-1a22-4ef8-9476-af4aadbcee48
Ancestors: Morphic-mt.1655
Nuke selectionShowing, it's never true.
Thus nuke reverseSelection, it's never sent.
If selectionShowing were true, then we would send #reverseFrom:to: to NewParagraph, and NewParagraph would bark because such message is not understood, it's food for st-80 Paragraph, not for Morphic.
Keep deselect (as we kept select two levels down in SmalltalkEditor) because it's still used by the Parser for st80 compatibility. IMO, the Parser should better mind its own business, and let the Editor handle that responsibility (ParagraphEditor, if you hear me...).
In one of my image, the selection stopped showing in Debugger, and that is ultra upsetting. While tracking the cause, obsolete unused stuff like this is hurdles put on your way just for pleasure to see how well you jump. Not so well if you wanna know...
=============== Diff against Morphic-mt.1655 ===============
Item was changed:
Object subclass: #Editor
+ instanceVariableNames: 'morph'
- instanceVariableNames: 'morph selectionShowing'
classVariableNames: 'BlinkingCursor DestructiveBackWord DumbbellCursor KeystrokeActions SelectionsMayShrink'
poolDictionaries: ''
category: 'Morphic-Text Support'!
!Editor commentStamp: 'hjh 9/28/2017 11:37' prior: 0!
New text editors.
TextEditor provides most of the functionality that used to be in TextMorphEditor.
SmalltalkEditor is has Smalltalk code specific features.
!
Item was changed:
----- Method: Editor>>deselect (in category 'current selection') -----
deselect
+ "Compatibility stub with st80"
+ !
- "If the text selection is visible on the screen, reverse its highlight."
-
- selectionShowing ifTrue: [self reverseSelection]!
Item was changed:
----- Method: TextEditor>>correctFrom:to:with: (in category 'new selection') -----
correctFrom: start to: stop with: aString
"Make a correction in the model that the user has authorised from somewhere else in the system (such as from the compilier). The user's selection is not changed, only corrected."
+ | userSelection delta loc |
- | userSelection delta loc wasShowing |
aString = '#insert period' ifTrue: [
loc := start.
[(loc := loc-1)>0 and: [(paragraph string at: loc) isSeparator]]
whileTrue: [loc := loc-1].
^ self correctFrom: loc+1 to: loc with: '.'].
- (wasShowing := selectionShowing) ifTrue: [ self reverseSelection ].
userSelection := self selectionInterval.
self selectInvisiblyFrom: start to: stop.
self replaceSelectionWith: aString.
delta := aString size - (stop - start + 1).
self
selectInvisiblyFrom: userSelection first + (userSelection first > start ifFalse: [ 0 ] ifTrue: [ delta ])
+ to: userSelection last + (userSelection last > start ifFalse: [ 0 ] ifTrue: [ delta ]).!
- to: userSelection last + (userSelection last > start ifFalse: [ 0 ] ifTrue: [ delta ]).
- wasShowing ifTrue: [ self reverseSelection ].
- !
Item was changed:
----- Method: TextEditor>>resetState (in category 'initialize-release') -----
resetState
"Establish the initial conditions for editing the paragraph: place caret
before first character, set the emphasis to that of the first character,
and save the paragraph for purposes of canceling."
pointBlock := markBlock := paragraph defaultCharacterBlock.
beginTypeInIndex := nil.
otherInterval := 1 to: 0.
+ self setEmphasisHere.!
- self setEmphasisHere.
- selectionShowing := false!
Item was removed:
- ----- Method: TextEditor>>reverseSelection (in category 'current selection') -----
- reverseSelection
- "Reverse the valence of the current selection highlighting."
- selectionShowing := selectionShowing not.
- paragraph reverseFrom: pointBlock to: markBlock!
Marcel Taeumel uploaded a new version of WebClient-Core to project The Trunk:
http://source.squeak.org/trunk/WebClient-Core-tobe.120.mcz
==================== Summary ====================
Name: WebClient-Core-tobe.120
Author: tobe
Time: 7 May 2020, 8:03:26.842149 pm
UUID: e511b96d-6164-458e-bebd-4bb4f42cfb72
Ancestors: WebClient-Core-nice.119
If we get a 304, do not try to parse content
In particular, since content-length is typically not set for a 304 response (https://tools.ietf.org/html/rfc7230#section-3.3.2) and we somehow failed to notice the connection being closed, we ended up with a timeout instead. This caused some Metacello tests to time out.
=============== Diff against WebClient-Core-nice.119 ===============
Item was changed:
----- Method: WebResponse>>getContent (in category 'private') -----
getContent
"Do not read any content if this was a HEAD request or code is 204 (no content)"
+ (request method = 'HEAD' or: [code = 204 or: [code = 304]]) ifTrue:[^''].
- (request method = 'HEAD' or: [code = 204]) ifTrue:[^''].
^super getContent!
Marcel Taeumel uploaded a new version of WebClient-Core to project The Trunk:
http://source.squeak.org/trunk/WebClient-Core-tobe.121.mcz
==================== Summary ====================
Name: WebClient-Core-tobe.121
Author: tobe
Time: 7 May 2020, 9:23:39.84201 pm
UUID: c6e964fd-dbe1-41dc-8724-e9b825130b7e
Ancestors: WebClient-Core-tobe.120
ignore content as stated in rfc7230, if:
- we have a HEAD request
- code is 1xx
- code is 204 No Content
- code is 304 Not Modified
=============== Diff against WebClient-Core-nice.119 ===============
Item was changed:
----- Method: WebResponse>>getContent (in category 'private') -----
getContent
+ " Any response to a HEAD request and any response with a 1xx
+ (Informational), 204 (No Content), or 304 (Not Modified) status
+ code is always terminated by the first empty line after the
+ header fields, regardless of the header fields present in the
+ message, and thus cannot contain a message body.
+ - https://tools.ietf.org/html/rfc7230#section-3.3.3 "
+
+ (request method = 'HEAD' or: [(code between: 100 and: 199) or: [code = 204 or: [code = 304]]]) ifTrue:[^''].
- "Do not read any content if this was a HEAD request or code is 204 (no content)"
- (request method = 'HEAD' or: [code = 204]) ifTrue:[^''].
^super getContent!