<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<meta content="text/html; charset=UTF-8">
<style type="text/css" style="">
<!--
p
        {margin-top:0;
        margin-bottom:0}
-->
</style>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Helvetica,sans-serif">
<p>Hi Jaromir,</p>
<p><br>
</p>
<p>thank you for <span>Morphic-jar.1815, it looks really nice.</span></p>
<p><span><br>
</span></p>
<p><span>> </span><span style="font-size:12pt">I'm not sure what you mean... Like if you select a whole line beginning and ending with matching brackets you'd like to strip the brackets even if they are inside the selection? That would change the semantics
 of enclosing (or de-enclosing) *a selection* :) If that's what you meant...?</span><span></p>
<div><br>
</div>
<div>You are right, it would change the semantics. But it could also be more convenient. :-) If the selection is not enclosed by inclusive brackets, check the exclusive adjacent characters for brackets instead. Do you think we should give this a try or would
 you consider this a too disrupting change?</div>
<div><br>
</div>
<div>By the way, we could also discuss whether pressing a closing bracket on a bracket-free selection should really add new brackets. It feels a bit inconsistent as opposed to the behavior with at least one bracket. Alternatively, you could also return false
 in this case.</div>
<div><br>
</div>
<div>One last note: In my image, I have changed the condition like this:</div>
<div><br>
</div>
<div>
<div>  ((startIndex > 1 and: [stopIndex <= t size])</div>
<div><span style="white-space:pre"></span>and: [ (t at: startIndex-1) = left and: [(t at: stopIndex) = right]]</div>
<div>- <span style="white-space:pre"> </span>and: [closingBracket])</div>
<div>+ <span style="white-space:pre"> </span>and: [closingBracket or: [left = right]])</div>
<br>
</div>
<div>so that you can also un-enclose quoted strings again. :)</div>
<div><br>
</div>
<div>Best,</div>
<div>Christoph</div>
</span>
<p></p>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> mail@jaromir.net <mail@jaromir.net><br>
<b>Gesendet:</b> Mittwoch, 1. Dezember 2021 22:52:31<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org; Thiede, Christoph<br>
<b>Betreff:</b> Re: Merge Request: autoEncloseBeforeSpace.cs</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Hi Christoph,<br>
<br>
I cleaned the condition - see the enclosed changeset.<br>
<br>
> [...] when I select a full line like this<br>
> <br>
> <br>
> (1+2+3)<br>
> <br>
> <br>
> I cannot type $) to remove the outer brackets. Could we change that, too?<br>
<br>
I'm not sure what you mean... Like if you select a whole line beginning and ending with matching brackets you'd like to strip the brackets even if they are inside the selection? That would change the semantics of enclosing (or de-enclosing) *a selection* :)
 If that's what you meant...?<br>
<br>
(Selecting 1+2+3 inside (1+2+3) and pressing ) strips the outer parentheses.)<br>
<br>
Thanks,<br>
<br>
~~~<br>
^[^    Jaromir<br>
<br>
Sent from Squeak Inbox Talk<br>
<br>
On 2021-12-01T21:28:00+00:00, christoph.thiede@student.hpi.uni-potsdam.de wrote:<br>
<br>
> Hi Jaromir,<br>
> <br>
> <br>
> thanks for the patch! The only thing that has attracted my attention is that when I select a full line like this<br>
> <br>
> <br>
> (1+2+3)<br>
> <br>
> <br>
> I cannot type $) to remove the outer brackets. Could we change that, too?<br>
> <br>
> <br>
> Regarding code polishing, as both ifFalse blocks are identical, it should be possible to insert "closing not and: [" to the outer condition instead. Very minor. :-)<br>
> <br>
> <br>
> Best,<br>
> <br>
> Christoph<br>
> <br>
> ________________________________<br>
> Von: mail at jaromir.net <mail at jaromir.net><br>
> Gesendet: Mittwoch, 1. Dezember 2021 21:03:22<br>
> An: squeak-dev at lists.squeakfoundation.org; Thiede, Christoph<br>
> Betreff: Re: Merge Request: autoEncloseBeforeSpace.cs<br>
> <br>
> > > A quick idea: an opener bracket on a selection adds a level and a closer bracket removes a level?<br>
> ><br>
> > Genious! Would you like to implement this by yourself? :-)<br>
> ><br>
> Thanks for your confidence :D Please check the logic in the enclosed fileout. Both opening and closing brackets on a selection enclose the selection with the first lever brackets; on higher levels opening brackets add and closing brackets remove one level...<br>
> <br>
> The code needs polishing if agreed.<br>
> <br>
> Best,<br>
> <br>
> ~~~<br>
> ^[^    Jaromir<br>
> <br>
> Sent from Squeak Inbox Talk<br>
> <br>
> On 2021-12-01T19:57:16+00:00, christoph.thiede at student.hpi.uni-potsdam.de wrote:<br>
> <br>
> > > A quick idea: an opener bracket on a selection adds a level and a closer bracket removes a level?<br>
> ><br>
> > Genious! Would you like to implement this by yourself? :-)<br>
> ><br>
> > Best,<br>
> > Christoph<br>
> ><br>
> > ________________________________<br>
> > Von: mail at jaromir.net <mail at jaromir.net><br>
> > Gesendet: Mittwoch, 1. Dezember 2021 20:24:44<br>
> > An: squeak-dev at lists.squeakfoundation.org; Thiede, Christoph<br>
> > Betreff: Re: Merge Request: autoEncloseBeforeSpace.cs<br>
> ><br>
> > Hi Christoph,<br>
> ><br>
> > > > About "enclose selection": if you select text between two brackets and enter the opener bracket, both enclosing brackets will be removed... that's intentional, right? Without a hint in the preference comment I never noticed.<br>
> > ><br>
> > ><br>
> > > I think this is intentional. Take it as a more or less convenient "toggle brackets" option.<br>
> ><br>
> > Toggling is good! Hmm, pressing CTRL and a bracket (or CTRL SHIFT and a bracket or ALT and a bracket) also toggles brackets around a selection but the logic is a bit chaotic (e.g. CTRL-[ encloses with {}... weird).<br>
> ><br>
> > > Unfortunately, it can be hard to use when you actually want to insert a second level of brackets ...<br>
> ><br>
> > A quick idea: an opener bracket on a selection adds a level and a closer bracket removes a level?<br>
> ><br>
> > Thanks<br>
> ><br>
> > ~~~<br>
> > ^[^    Jaromir<br>
> ><br>
> > Sent from Squeak Inbox Talk<br>
> ><br>
> > On 2021-12-01T19:08:57+00:00, christoph.thiede at student.hpi.uni-potsdam.de wrote:<br>
> ><br>
> > > Hi Marcel, hi Jaromir,<br>
> > ><br>
> > ><br>
> > > works like a charm for me! :-) Unless anyone misses the classical mode, I would love to see this in the Trunk.<br>
> > ><br>
> > ><br>
> > > > About "enclose selection": if you select text between two brackets and enter the opener bracket, both enclosing brackets will be removed... that's intentional, right? Without a hint in the preference comment I never noticed.<br>
> > ><br>
> > ><br>
> > > I think this is intentional. Take it as a more or less convenient "toggle brackets" option. Unfortunately, it can be hard to use when you actually want to insert a second level of brackets ... In this case, my current heuristic is to advance/shrink the
 selection by one character so that typing the bracket again will actually enclose the selection into new brackets. But this is a bit tricky, do you have any idea to make it more convenient? :-)<br>
> > ><br>
> > ><br>
> > > Best,<br>
> > ><br>
> > > Christoph<br>
> > ><br>
> > > ________________________________<br>
> > > Von: Squeak-dev <squeak-dev-bounces at lists.squeakfoundation.org> im Auftrag von mail at jaromir.net <mail at jaromir.net><br>
> > > Gesendet: Mittwoch, 1. Dezember 2021 19:25:24<br>
> > > An: squeak-dev at lists.squeakfoundation.org; Taeumel, Marcel<br>
> > > Betreff: Re: [squeak-dev] Merge Request: autoEncloseBeforeSpace.cs<br>
> > ><br>
> > > Hi Marcel,<br>
> > ><br>
> > > > Please find attached another take on this idea. No extra preference.<br>
> > ><br>
> > > ... more than happy :)<br>
> > ><br>
> > > > Just tweaking the current autoEnclose-feature. In this form, I would consider using it. :-D Together with "Enclose selection".<br>
> > ><br>
> > > About "enclose selection": if you select text between two brackets and enter the opener bracket, both enclosing brackets will be removed... that's intentional, right? Without a hint in the preference comment I never noticed.<br>
> > ><br>
> > > Thanks,<br>
> > ><br>
> > ><br>
> > > ~~~<br>
> > > ^[^<br>
> > >   --    Jaromir<br>
> > ><br>
> > > Sent from Squeak Inbox Talk<br>
> > ><br>
> > > On 2021-12-01T14:46:45+01:00, marcel.taeumel at hpi.de wrote:<br>
> > ><br>
> > > > Hi Chris, hi Christoph, hi Jaromir, hi all!<br>
> > > ><br>
> > > > Please find attached another take on this idea. No extra preference. Just tweaking the current autoEnclose-feature. In this form, I would consider using it. :-D Together with "Enclose selection".<br>
> > > ><br>
> > > > Best,<br>
> > > > Marcel<br>
> > > > Am 06.11.2021 23:34:06 schrieb christoph.thiede at student.hpi.uni-potsdam.de <christoph.thiede at student.hpi.uni-potsdam.de>:<br>
> > > > Hi Chris,<br>
> > > ><br>
> > > > > Hopefully also when the cursor is at the end of the text, too (I didn't test it).<br>
> > > ><br>
> > > > Yes, it does. :-)<br>
> > > ><br>
> > > > > It seems like this feature should not disrupt expression-editing at all,<br>
> > > > > which is what I made autoEnclose for.<br>
> > > ><br>
> > > > Sure, but without knowing everyone's personal preferences, anyone might be used the existing workflow. Shall we keep the old preference for this eventuality or would it be okay to remove until anyone shouts? :-)<br>
> > > ><br>
> > > > Below the complete diff of the changeset for convenience, just because my new diff generators is so funny.<br>
> > > ><br>
> > > > Best,<br>
> > > > Christoph<br>
> > > ><br>
> > > ><br>
> > > > =============== Postscript ===============<br>
> > > ><br>
> > > > "Postscript:<br>
> > > > Leave the line above, and replace the rest of this comment by a useful one.<br>
> > > > Executable statements should follow this comment, and should<br>
> > > > be separated by periods, with no exclamation points (!).<br>
> > > > Be sure to put any further comments in double-quotes, like this one."<br>
> > > ><br>
> > > > TextEditor autoEnclose: TextEditor autoEnclose.<br>
> > > ><br>
> > > > =============== Diff ===============<br>
> > > ><br>
> > > > PreferenceWizardMorph>>initializePage03Interaction {initialization - pages} B7 ct 11/1/2021 20:19 (changed)<br>
> > > > initializePage03Interaction<br>
> > > ><br>
> > > >     | currentPage pane |<br>
> > > >     currentPage := pages add: self createPage.<br>
> > > >     pane := self createScrollPane.<br>
> > > ><br>
> > > >     currentPage addMorphBack: (self createLabel: 'Choose interaction settings' color: Color white).<br>
> > > >     currentPage addMorphBack: pane.<br>
> > > ><br>
> > > >     pane scroller firstSubmorph addAllMorphsBack: {<br>
> > > >         self createCheckbox: 'Swap mouse buttons' translated for: #SwapMouseButtons help: #(swap mouse).<br>
> > > >         self createCheckbox: 'Focus follows mouse' translated for: #FocusFollowsMouse help: #(mouse over keyboard).<br>
> > > >         self createCheckbox: 'Mouse wheel to focus' translated for: #SendMouseWheelToKeyboardFocus help: #(wheel keyboard).<br>
> > > >         self createVerticalSpace.<br>
> > > > -         self createCheckbox: 'Auto enclose brackets' translated for: #AutoEnclose help: #(auto enclose).<br>
> > > > +         self createCheckbox: 'Auto enclose all brackets' translated for: #AutoEncloseAlways help: #(auto enclose).<br>
> > > > +         self createCheckbox: 'Auto enclose brackets before spaces only' translated for: #AutoEncloseBeforeSpaces help: #(auto enclose).<br>
> > > >         self createCheckbox: 'Auto indent lines' translated for: #AutoIndent help: #(auto indent).<br>
> > > >         self createCheckbox: 'Enclose text selections' translated for: #EncloseSelection help: #(enclose selection).<br>
> > > >         self createVerticalSpace.<br>
> > > >         self createCheckbox: 'Arrows in scrollbar' translated for: #ScrollBarsWithoutArrowButtons help: 'Whether to show arrows for scrolling or not.' translated.<br>
> > > >         self createCheckbox: 'Menu in scrollbar' translated for: #ScrollBarsWithoutMenuButton help: 'Whether to show a menu button or not.' translated.<br>
> > > >         self createCheckbox: 'Scrollbars on the right' translated for: #ScrollBarsOnRight help: #(right scroll).<br>
> > > >         self createCheckbox: 'Retractable scrollbars' translated for: #UseRetractableScrollBars help: #(retractable).<br>
> > > >         self createCheckbox: 'Narrow scrollbars' translated for: #ScrollBarsNarrow help: #(narrow scroll).<br>
> > > ><br>
> > > >         }.<br>
> > > ><br>
> > > > PreferenceWizardMorph>>stateAutoEncloseAlways {actions - buttons} B7 ct 11/1/2021 20:19<br>
> > > > + stateAutoEncloseAlways<br>
> > > > +<br>
> > > > +     ^ TextEditor autoEncloseAlways<br>
> > > ><br>
> > > > PreferenceWizardMorph>>stateAutoEncloseBeforeSpaces {actions - buttons} B7 ct 11/1/2021 20:19<br>
> > > > + stateAutoEncloseBeforeSpaces<br>
> > > > +<br>
> > > > +     ^ TextEditor autoEncloseBeforeSpaces<br>
> > > ><br>
> > > > PreferenceWizardMorph>>toggleAutoEncloseAlways {actions - buttons} B7 ct 11/1/2021 20:20<br>
> > > > + toggleAutoEncloseAlways<br>
> > > > +<br>
> > > > +     TextEditor autoEncloseAlways: TextEditor autoEncloseAlways not.<br>
> > > > +     self<br>
> > > > +         changed: #stateAutoEncloseAlways;<br>
> > > > +         changed: #stateAutoEncloseBeforeSpaces.<br>
> > > ><br>
> > > > PreferenceWizardMorph>>toggleAutoEncloseBeforeSpaces {actions - buttons} B7 ct 11/1/2021 20:20<br>
> > > > + toggleAutoEncloseBeforeSpaces<br>
> > > > +<br>
> > > > +     TextEditor autoEncloseBeforeSpaces: TextEditor autoEncloseBeforeSpaces not.<br>
> > > > +     self<br>
> > > > +         changed: #stateAutoEncloseAlways;<br>
> > > > +         changed: #stateAutoEncloseBeforeSpaces.<br>
> > > ><br>
> > > > ReleaseBuilder class>>setPreferences {scripts} B7 ct 11/1/2021 20:18 (changed)<br>
> > > > setPreferences<br>
> > > >     "Preferences class defaultValueTableForCurrentRelease"<br>
> > > > -     "    Preferences outOfTheBox."<br>
> > > > -     "<-- uncomment after #defaultValueTableForCurrentRelease is fixed up."<br>
> > > > -     "General User interaction"<br>
> > > ><br>
> > > > + "    Preferences outOfTheBox." "<-- uncomment after #defaultValueTableForCurrentRelease is fixed up."<br>
> > > > +<br>
> > > > +     "General User interaction"<br>
> > > >     Preferences<br>
> > > > -         enable: #generalizedYellowButtonMenu;<br>
> > > > +         enable: #generalizedYellowButtonMenu ;<br>
> > > >         enable: #swapMouseButtons;<br>
> > > >         disable: #mouseOverForKeyboardFocus.<br>
> > > >     Morph indicateKeyboardFocus: true.<br>
> > > >     Project uiManager openToolsAttachedToMouseCursor: false.<br>
> > > >     SearchBar useScratchPad: false.<br>
> > > ><br>
> > > >     HandMorph sendMouseWheelToKeyboardFocus: false.<br>
> > > >     HandMorph synthesizeMouseWheelEvents: true.<br>
> > > ><br>
> > > >     "Text input."<br>
> > > >     TextEditor<br>
> > > > -         autoEnclose: true;<br>
> > > > -         autoIndent: true;<br>
> > > > -         encloseSelection: false;<br>
> > > > -         destructiveBackWord: false;<br>
> > > > -         blinkingCursor: true;<br>
> > > > -         dumbbellCursor: false.<br>
> > > > +          autoEnclose: #beforeSpaces ;<br>
> > > > +          autoIndent: true ;<br>
> > > > +          encloseSelection: false ;<br>
> > > > +          destructiveBackWord: false ;<br>
> > > > +          blinkingCursor: true ;<br>
> > > > +          dumbbellCursor: false.<br>
> > > >     PluggableTextMorph simpleFrameAdornments: false.<br>
> > > >     TextMorphForEditView draggableTextSelection: true.<br>
> > > > -     "Windows"<br>
> > > ><br>
> > > > +     "Windows"<br>
> > > >     SystemWindow reuseWindows: false.<br>
> > > >     SystemWindow windowsRaiseOnClick: true.<br>
> > > >     SystemWindow windowTitleActiveOnFirstClick: true.<br>
> > > > -     Model windowActiveOnFirstClick: false.<br>
> > > > -     "Not good for little screen real estate."<br>
> > > > -     Model useColorfulWindows: false.<br>
> > > > -<br>
> > > > -     Preferences disable: #fastDragWindowForMorphic.<br>
> > > > +     Model windowActiveOnFirstClick: false. "Not good for little screen real estate."<br>
> > > > +     Model useColorfulWindows: false.<br>
> > > > +<br>
> > > > +     Preferences<br>
> > > > +         disable: #fastDragWindowForMorphic.<br>
> > > >     AbstractResizerMorph<br>
> > > >         gripThickness: 4;<br>
> > > >         handleLength: 25.<br>
> > > >     CornerGripMorph<br>
> > > >         drawCornerResizeHandles: false;<br>
> > > >         drawEdgeResizeHandles: false.<br>
> > > >     ProportionalSplitterMorph<br>
> > > >         showSplitterHandles: false;<br>
> > > >         smartHorizontalSplitters: false;<br>
> > > >         smartVerticalSplitters: false.<br>
> > > > -<br>
> > > > +<br>
> > > >     "Scroll bars."<br>
> > > >     Preferences<br>
> > > >         enable: #scrollBarsNarrow;<br>
> > > >         enable: #scrollBarsOnRight;<br>
> > > >         enable: #alwaysHideHScrollbar;<br>
> > > >         disable: #alwaysShowHScrollbar;<br>
> > > >         disable: #alwaysShowVScrollbar.<br>
> > > >     ScrollBar<br>
> > > >         scrollBarsWithoutArrowButtons: true;<br>
> > > >         scrollBarsWithoutMenuButton: true.<br>
> > > > -     ScrollPane useRetractableScrollBars: false.<br>
> > > > -<br>
> > > > +     ScrollPane<br>
> > > > +         useRetractableScrollBars: false.<br>
> > > > +<br>
> > > >     "Rounded corners."<br>
> > > >     Morph preferredCornerRadius: 8.<br>
> > > >     SystemWindow roundedWindowCorners: false.<br>
> > > >     DialogWindow roundedDialogCorners: false.<br>
> > > >     MenuMorph roundedMenuCorners: false.<br>
> > > >     PluggableButtonMorph roundedButtonCorners: false.<br>
> > > >     ScrollBar roundedScrollBarLook: false.<br>
> > > ><br>
> > > >     "Gradients."<br>
> > > >     SystemWindow gradientWindow: false.<br>
> > > >     DialogWindow gradientDialog: false.<br>
> > > >     MenuMorph gradientMenu: false.<br>
> > > >     PluggableButtonMorph gradientButton: false.<br>
> > > >     ScrollBar gradientScrollBar: false.<br>
> > > > -<br>
> > > > +<br>
> > > >     "Shadows"<br>
> > > >     Preferences enable: #menuAppearance3d.<br>
> > > >     Morph useSoftDropShadow: true.<br>
> > > ><br>
> > > >     "Lists and Trees"<br>
> > > >     PluggableListMorph<br>
> > > >         filterableLists: true;<br>
> > > >         clearFilterAutomatically: false;<br>
> > > >         clearFilterDelay: 500;<br>
> > > >         highlightHoveredRow: true;<br>
> > > >         highlightPreSelection: false;<br>
> > > >         menuRequestUpdatesSelection: true.<br>
> > > >     PluggableTreeMorph<br>
> > > >         filterByLabelsOnly: false;<br>
> > > >         maximumSearchDepth: 1.<br>
> > > ><br>
> > > >     "Standard Tools"<br>
> > > >     TheWorldMainDockingBar<br>
> > > >         showWorldMainDockingBar: true;<br>
> > > >         showSecondsInClock: true;<br>
> > > >         twentyFourHourClock: true.<br>
> > > >     SearchBar useSmartSearch: true.<br>
> > > >     Workspace shouldStyle: false.<br>
> > > >     TranscriptStream<br>
> > > >         forceUpdate: true;<br>
> > > >         redirectToStdOut: false;<br>
> > > >         characterLimit: 20000.<br>
> > > >     Browser<br>
> > > >         listClassesHierarchically: true;<br>
> > > >         showClassIcons: true;<br>
> > > >         showMessageIcons: true;<br>
> > > >         sortMessageCategoriesAlphabetically: true.<br>
> > > >     SystemBrowser browseWithDragNDrop: true.<br>
> > > >     MessageSet useUnifiedMessageLabels: true.<br>
> > > >     Preferences<br>
> > > >         enable: #annotationPanes;<br>
> > > > -         defaultAnnotationRequests: #(#timeStamp #author #messageCategory #implementorsCount #allChangeSets);<br>
> > > > +         defaultAnnotationRequests: #(timeStamp author messageCategory implementorsCount allChangeSets);<br>
> > > >         enable: #optionalButtons;<br>
> > > >         disable: #diffsWithPrettyPrint;<br>
> > > >         enable: #traceMessages;<br>
> > > >         enable: #alternativeBrowseIt;<br>
> > > >         enable: #menuWithIcons;<br>
> > > >         enable: #visualExplorer.<br>
> > > >     Preferences disable: #debugLogTimestamp.<br>
> > > > +<br>
> > > >     "Halo"<br>
> > > > -<br>
> > > >     Preferences<br>
> > > > -         enable: #showBoundsInHalo;<br>
> > > > +         enable: #showBoundsInHalo ;<br>
> > > >         disable: #alternateHandlesLook;<br>
> > > >         disable: #showDirectionHandles.<br>
> > > >     Morph<br>
> > > >         haloForAll: true;<br>
> > > >         metaMenuForAll: true.<br>
> > > > -<br>
> > > > +<br>
> > > >     "System"<br>
> > > > -     NetNameResolver enableIPv6: true.<br>
> > > > +     NetNameResolver enableIPv6: false.<br>
> > > >     Scanner<br>
> > > >         allowUnderscoreAsAssignment: true;<br>
> > > >         prefAllowUnderscoreSelectors: true.<br>
> > > > -<br>
> > > > +<br>
> > > >     Deprecation showDeprecationWarnings: true<br>
> > > > +<br>
> > > >     "that's all, folks"<br>
> > > ><br>
> > > > TextEditor class>>autoEnclose {preferences} B7 ct 11/1/2021 20:26 (changed)<br>
> > > > autoEnclose<br>
> > > > -     <preference: 'Auto enclose brackets () {} []'<br>
> > > > -         categoryList: #('Morphic' 'editing')<br>
> > > > -         description: 'When true, typing an opening parenthesis, bracket or square-bracket will also add its corresponding closing character after the cursor so you can type within the bracket.'<br>
> > > > -         type: #Boolean><br>
> > > > -<br>
> > > > -     ^ AutoEnclose ifNil: [ false ]<br>
> > > > +<br>
> > > > +     ^ AutoEnclose ifNil: [#never]<br>
> > > ><br>
> > > > TextEditor class>>autoEnclose: {preferences} B7 ct 11/1/2021 20:30 (changed)<br>
> > > > - autoEnclose: aBoolean<br>
> > > > -     AutoEnclose := aBoolean<br>
> > > > + autoEnclose: aSymbol<br>
> > > > +<br>
> > > > +     aSymbol == true ifTrue: [<br>
> > > > +         "backward compatibility."<br>
> > > > +         ^ self autoEnclose: #always].<br>
> > > > +<br>
> > > > +     self assert: [#(always beforeSpaces never) includes: aSymbol].<br>
> > > > +<br>
> > > > +     AutoEnclose := aSymbol.<br>
> > > ><br>
> > > > TextEditor class>>autoEncloseAlways {preferences} B7 ct 11/1/2021 21:48<br>
> > > > + autoEncloseAlways<br>
> > > > +     <preference: 'Auto enclose all brackets () {} [] '''' "" || <>'<br>
> > > > +         categoryList: #('Morphic' 'editing')<br>
> > > > +         description: 'When true, typing an opening character will ALWAYS add its corresponding closing character after the cursor so you can type within the bracket.'<br>
> > > > +         type: #Boolean><br>
> > > > +<br>
> > > > +     ^ self autoEnclose = #always<br>
> > > ><br>
> > > > TextEditor class>>autoEncloseAlways: {preferences} B7 ct 11/1/2021 20:32<br>
> > > > + autoEncloseAlways: aBoolean<br>
> > > > +<br>
> > > > +     self autoEnclose: (aBoolean<br>
> > > > +         ifTrue: [#always]<br>
> > > > +         ifFalse: [#never]).<br>
> > > ><br>
> > > > TextEditor class>>autoEncloseBeforeSpaces {preferences} B7 ct 11/1/2021 21:49<br>
> > > > + autoEncloseBeforeSpaces<br>
> > > > +     <preference: 'Auto enclose brackets before spaces only () {} [] '''' "" || <>'<br>
> > > > +         categoryList: #('Morphic' 'editing')<br>
> > > > +         description: 'When true, typing an opening character BEFORE some space will add its corresponding closing character after the cursor so you can type within the bracket.'<br>
> > > > +         type: #Boolean><br>
> > > > +<br>
> > > > +     ^ self autoEnclose = #beforeSpaces<br>
> > > ><br>
> > > > TextEditor class>>autoEncloseBeforeSpaces: {preferences} B7 ct 11/1/2021 20:32<br>
> > > > + autoEncloseBeforeSpaces: aBoolean<br>
> > > > +<br>
> > > > +     self autoEnclose: (aBoolean<br>
> > > > +         ifTrue: [#beforeSpaces]<br>
> > > > +         ifFalse: [#never]).<br>
> > > ><br>
> > > > TextEditor>>autoEncloseFor: {typing support} B7 ct 11/1/2021 20:28 (changed)<br>
> > > > autoEncloseFor: typedChar<br>
> > > >     "Answer whether typeChar was handled by auto-enclosure. Caller should call normalCharacter if not."<br>
> > > >     | openers closers |<br>
> > > > +     self class autoEnclose = #never<br>
> > > > +         ifTrue: [ ^ false ].<br>
> > > > +     (self class autoEnclose = #beforeSpaces<br>
> > > > +         ==> [ self string at: self startIndex ifPresent: [:c | c isSeparator] ifAbsent: [true] ])<br>
> > > > +             ifFalse: [ ^ false ].<br>
> > > > +<br>
> > > >     openers := '([{'.<br>
> > > >     closers := ')]}'.<br>
> > > >     (closers includes: typedChar) ifTrue:<br>
> > > >         [ | pos |<br>
> > > >         self blinkPrevParen: typedChar.<br>
> > > >         ((pos := self indexOfNextNonwhitespaceCharacter) notNil and: [ (paragraph string at: pos) = typedChar ])<br>
> > > >             ifTrue:<br>
> > > >                 [ self<br>
> > > >                     moveCursor: [ : position | position + pos - pointBlock stringIndex + 1 ]<br>
> > > >                     forward: true<br>
> > > >                     select: false.<br>
> > > >                 ^ true ]<br>
> > > >             ifFalse: [ ^ false ] ].<br>
> > > >     (openers includes: typedChar) ifTrue:<br>
> > > >         [ self<br>
> > > >             openTypeIn;<br>
> > > >             addString: typedChar asString;<br>
> > > >             addString: (closers at: (openers indexOf: typedChar)) asString;<br>
> > > >             insertAndCloseTypeIn;<br>
> > > ><br>
> > > >             moveCursor: [ : position | position - 1 ]<br>
> > > >             forward: false<br>
> > > >             select: false.<br>
> > > >         ^ true ].<br>
> > > >     ^ false<br>
> > > ><br>
> > > > TextEditor>>dispatchOnKeyboardEvent: {typing support} B7 ct 11/1/2021 20:28 (changed)<br>
> > > > dispatchOnKeyboardEvent: aKeyboardEvent<br>
> > > >     "Carry out the action associated with this character, if any. Type-ahead is passed so some routines can flush or use it."<br>
> > > ><br>
> > > >     | honorCommandKeys typedChar |<br>
> > > >     typedChar := aKeyboardEvent keyCharacter.<br>
> > > ><br>
> > > >     "Handle one-line input fields."<br>
> > > >     (typedChar == Character cr and: [morph acceptOnCR])<br>
> > > >         ifTrue: [^ true].<br>
> > > ><br>
> > > >     "Clear highlight for last opened parenthesis."<br>
> > > >     self clearParens.<br>
> > > ><br>
> > > >     "Handle line breaks and auto indent."<br>
> > > >     typedChar == Character cr ifTrue: [<br>
> > > >         aKeyboardEvent controlKeyPressed<br>
> > > >             ifTrue: [^ self normalCharacter: aKeyboardEvent].<br>
> > > >         aKeyboardEvent shiftPressed<br>
> > > >             ifTrue: [^ self lf: aKeyboardEvent].<br>
> > > >         aKeyboardEvent commandKeyPressed<br>
> > > >             ifTrue: [^ self crlf: aKeyboardEvent].<br>
> > > >         ^ self crWithIndent: aKeyboardEvent].<br>
> > > ><br>
> > > >     "Handle indent/outdent with selected text block."<br>
> > > >     typedChar == Character tab ifTrue: [<br>
> > > >         aKeyboardEvent shiftPressed<br>
> > > >             ifTrue: [self outdent: aKeyboardEvent. ^ true]<br>
> > > >             ifFalse: [self hasMultipleLinesSelected<br>
> > > >                 ifTrue: [self indent: aKeyboardEvent. ^ true]]].<br>
> > > ><br>
> > > >     honorCommandKeys := Preferences cmdKeysInText.<br>
> > > ><br>
> > > >     (honorCommandKeys and: [typedChar == Character enter])<br>
> > > >         ifTrue: [^ self dispatchOnEnterWith: aKeyboardEvent].<br>
> > > ><br>
> > > >     "Special keys overwrite crtl+key combinations - at least on Windows. To resolve this<br>
> > > >     conflict, assume that keys other than cursor keys aren't used together with Crtl."<br>
> > > >     ((self class specialShiftCmdKeys includes: aKeyboardEvent keyValue)<br>
> > > >         and: [aKeyboardEvent keyValue < 27])<br>
> > > >             ifTrue: [^ aKeyboardEvent controlKeyPressed<br>
> > > >                 ifTrue: [self<br>
> > > >                             perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1)<br>
> > > >                             with: aKeyboardEvent]<br>
> > > >                 ifFalse: [self<br>
> > > >                             perform: (self class cmdActions at: aKeyboardEvent keyValue + 1)<br>
> > > >                             with: aKeyboardEvent]].<br>
> > > ><br>
> > > >     "backspace, and escape keys (ascii 8 and 27) are command keys"<br>
> > > >     ((honorCommandKeys and: [aKeyboardEvent commandKeyPressed])<br>
> > > >         or: [self class specialShiftCmdKeys includes: aKeyboardEvent keyValue])<br>
> > > >             ifTrue: [ ^ aKeyboardEvent shiftPressed<br>
> > > >                 ifTrue: [self<br>
> > > >                             perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1)<br>
> > > >                             with: aKeyboardEvent]<br>
> > > >                 ifFalse: [self<br>
> > > >                             perform: (self class cmdActions at: aKeyboardEvent keyValue + 1)<br>
> > > >                             with: aKeyboardEvent]].<br>
> > > ><br>
> > > >     "the control key can be used to invoke shift-cmd shortcuts"<br>
> > > >     (honorCommandKeys and: [ aKeyboardEvent controlKeyPressed ])<br>
> > > >         ifTrue: [^ self<br>
> > > >                     perform: (self class shiftCmdActions at: aKeyboardEvent keyValue + 1)<br>
> > > >                     with: aKeyboardEvent].<br>
> > > ><br>
> > > >     "Enclose selection with brackets etc."<br>
> > > >     ((self class encloseSelection and: [self hasSelection]) and: [self enclose: aKeyboardEvent])<br>
> > > >         ifTrue: [^ true].<br>
> > > ><br>
> > > >     "Automatically enclose paired characters such as brackets."<br>
> > > > -     (self class autoEnclose and: [self autoEncloseFor: typedChar])<br>
> > > > +     (self autoEncloseFor: typedChar)<br>
> > > >         ifTrue: [^ true].<br>
> > > ><br>
> > > >     "Even if no enclosing feature was used, highlight the matching bracket when closing one."<br>
> > > >     (')]}' includes: typedChar)<br>
> > > >         ifTrue: [self blinkPrevParen: typedChar].<br>
> > > ><br>
> > > >     self normalCharacter: aKeyboardEvent.<br>
> > > >     ^ false<br>
> > > ><br>
> > > > ---<br>
> > > > Sent from Squeak Inbox Talk [<a href="https://github.com/hpi-swa-lab/squeak-inbox-talk">https://github.com/hpi-swa-lab/squeak-inbox-talk</a>]<br>
> > > ><br>
> > > > On 2021-11-05T19:46:16-05:00, asqueaker at gmail.com wrote:<br>
> > > ><br>
> > > > > Hi Christoph,<br>
> > > > ><br>
> > > > > This changeset refines the existing autoEnclose mechanism. Instead of<br>
> > > > > > having inserted enclosing brackets always, you can now activate a new<br>
> > > > > > preference to only insert these characters if there is any space after the<br>
> > > > > > cursor.<br>
> > > > ><br>
> > > > ><br>
> > > > > Hopefully also when the cursor is at the end of the text, too (I didn't<br>
> > > > > test it).<br>
> > > > ><br>
> > > > > > I am not sure whether a single preference would fit everyone's needs.<br>
> > > > ><br>
> > > > > It seems like this feature should not disrupt expression-editing at all,<br>
> > > > > which is what I made autoEnclose for.<br>
> > > > ><br>
> > > > > Thanks,<br>
> > > > > Chris<br>
> > > > > -------------- next part --------------<br>
> > > > > An HTML attachment was scrubbed...<br>
> > > > > URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211105/7d2cc226/attachment.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211105/7d2cc226/attachment.html</a>><br>
> > > > ><br>
> > > > ><br>
> > > > -------------- next part --------------<br>
> > > > An HTML attachment was scrubbed...<br>
> > > > URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/9eecd3ee/attachment.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/9eecd3ee/attachment.html</a>><br>
> > > > -------------- next part --------------<br>
> > > > A non-text attachment was scrubbed...<br>
> > > > Name: TextEditor-autoEncloseFor.st<br>
> > > > Type: application/octet-stream<br>
> > > > Size: 1261 bytes<br>
> > > > Desc: not available<br>
> > > > URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/9eecd3ee/attachment.obj">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/9eecd3ee/attachment.obj</a>><br>
> > > ><br>
> > > ><br>
> > ><br>
> > > -------------- next part --------------<br>
> > > An HTML attachment was scrubbed...<br>
> > > URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/3c0fafb7/attachment.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/3c0fafb7/attachment.html</a>><br>
> > ><br>
> > ><br>
> > -------------- next part --------------<br>
> > An HTML attachment was scrubbed...<br>
> > URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/36d5c675/attachment-0001.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/36d5c675/attachment-0001.html</a>><br>
> ><br>
> ><br>
> -------------- next part --------------<br>
> An HTML attachment was scrubbed...<br>
> URL: <<a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/52f47a4f/attachment-0001.html">http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211201/52f47a4f/attachment-0001.html</a>><br>
> <br>
> </div>
</span></font>
</body>
</html>