<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
Hi Christoph,<div><br></div><div>why is this a bug? A quick experiment in Sublime Text suggested that this might be the expected behavior. At least for actually empty lines, having not a single white-space character.</div><div><br></div><div>Best,</div><div>Marcle</div><div class="mb_sig"></div><blockquote class='history_container' type='cite' style='border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;'>
<p style='color: #AAAAAA; margin-top: 10px;'>Am 07.03.2021 20:43:09 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style='font-family:Arial,Helvetica,sans-serif'>Christoph Thiede uploaded a new version of Morphic to project The Inbox:<br>http://source.squeak.org/inbox/Morphic-ct.1733.mcz<br><br>==================== Summary ====================<br><br>Name: Morphic-ct.1733<br>Author: ct<br>Time: 7 March 2021, 8:42:45.180906 pm<br>UUID: b8246d49-b132-40af-8ad4-7428c544390c<br>Ancestors: Morphic-mt.1731<br><br>Fixes an eternity-old bug in TextEditor which skipped empty lines when indenting/outdenting the selection.<br><br>=============== Diff against Morphic-mt.1731 ===============<br><br>Item was changed:<br> ----- Method: TextEditor>>inOutdent:delta: (in category 'editing keys') -----<br> inOutdent: aKeyboardEvent delta: delta<br> "Add/remove a tab at the front of every line occupied by the selection. Flushes typeahead. Derived from work by Larry Tesler back in December 1985. Now triggered by Cmd-L and Cmd-R. 2/29/96 sw"<br> <br> | realStart realStop lines startLine stopLine start stop adjustStart "indentation" numLines oldText newText newSize |<br>- <br> "Operate on entire lines, but remember the real selection for re-highlighting later"<br> realStart := self startIndex.<br> realStop := self stopIndex - 1.<br> <br> "Special case a caret on a line of its own, including weird case at end of paragraph"<br> (realStart > realStop and:<br> [realStart < 2 or: [(paragraph string at: realStart - 1) == Character cr or: [(paragraph string at: realStart - 1) == Character lf]]])<br> ifTrue:<br> [delta < 0<br> ifTrue:<br> [morph flash]<br> ifFalse:<br> [self replaceSelectionWith: Character tab asText.<br> self selectAt: realStart + 1].<br> ^true].<br> <br> lines := paragraph lines.<br> startLine := paragraph lineIndexOfCharacterIndex: realStart.<br> "start on a real line, not a wrapped line"<br> [startLine = 1 or: [CharacterSet crlf includes: (paragraph string at: (lines at: startLine-1) last)]] whileFalse: [startLine := startLine - 1].<br> stopLine := paragraph lineIndexOfCharacterIndex: (realStart max: realStop).<br> start := (lines at: startLine) first.<br> stop := (lines at: stopLine) last.<br> <br> "Pin the start of highlighting unless the selection starts a line"<br> adjustStart := realStart > start.<br> <br> "Find the indentation of the least-indented non-blank line; never outdent more"<br> "indentation := (startLine to: stopLine) inject: 1000 into:<br> [:m :l |<br> m min: (paragraph indentationOfLineIndex: l ifBlank: [:tabs | 1000])].<br> indentation + delta <= 0 ifTrue: [^false]."<br> <br> numLines := stopLine + 1 - startLine.<br> oldText := paragraph text copyFrom: start to: stop.<br> newText := oldText species new: oldText size + ((numLines * delta) max: 0).<br> <br> "Do the actual work"<br> newSize := 0.<br> delta > 0<br> ifTrue: [| tabs |<br> tabs := oldText species new: delta withAll: Character tab.<br> oldText string lineIndicesDo: [:startL :endWithoutDelimiters :endL |<br>+ newText replaceFrom: 1 + newSize to: (newSize := newSize + delta) with: tabs startingAt: 1.<br>- startL < endWithoutDelimiters ifTrue: [newText replaceFrom: 1 + newSize to: (newSize := newSize + delta) with: tabs startingAt: 1].<br> newText replaceFrom: 1 + newSize to: (newSize := 1 + newSize + endL - startL) with: oldText startingAt: startL]]<br> ifFalse: [| tab |<br> tab := Character tab.<br> oldText string lineIndicesDo: [:startL :endWithoutDelimiters :endL |<br> | i |<br> i := 0.<br> [i + delta < 0 and: [ i + startL <= endWithoutDelimiters and: [(oldText at: i + startL) == tab]]] whileTrue: [i := i + 1].<br> newText replaceFrom: 1 + newSize to: (newSize := 1 + newSize + endL - (i + startL)) with: oldText startingAt: i + startL]].<br> newSize < newText size ifTrue: [newText := newText copyFrom: 1 to: newSize].<br> <br> "Adjust the range that will be highlighted later"<br> adjustStart ifTrue: [realStart := (realStart + delta) max: start].<br> realStop := realStop + newSize - oldText size.<br> <br> "Replace selection"<br> self selectInvisiblyFrom: start to: stop.<br> self replaceSelectionWith: newText.<br> self selectFrom: realStart to: realStop. "highlight only the original range"<br> ^ true!<br><br><br></div></blockquote>
</div></body>