<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p>Hi Marcel,</p>
<p><br>
</p>
<p>most editors support both ways through configuration.</p>
<p><br>
</p>
<p>I fear that's stuff for a principal debate, just like "tabs vs spaces" ... So let the games begin! :D</p>
<p><br>
</p>
<p>Most methods in Squeak are formatted with empty lines indented just like their surrounding lines, and this also matches my own preference. This has a number of advantages:</p>
<p><span style="font-size: 12pt;"><br>
</span></p>
<p>1. It's just more consistent that every line that is part of a logic unit (e.g. block, expression, or array) is indented in the same way, without defining any special treatments for empty lines.</p>
<p><span style="font-size: 12pt;">2. If you fill an empty line with some statement, the indentation is already there and you do not need to correct (i.e. add) it.</span></p>
<p><span style="font-size: 12pt;">3. If you remove a statement from an empty line, you do not need to "correct" (i.e. remove) the indentation.</span></p>
<p><span style="font-size: 12pt;">4. It's easier to navigate through all lines with the caret because it does not jump back to the unintended beginning of a line.</span></p>
<p><span style="font-size: 12pt;">5.</span><span style="font-size: 12pt;"> Auto-generation is easier because we don't have an edge case for empty lines.</span></p>
<p><span style="font-size: 12pt;"><br>
</span></p>
<p><span style="font-size: 12pt;">But I know that the party of the "no-empty-indenters" also has at least one counterargument because they call these indentations trailing whitespace.</span></p>
<p><span style="font-size: 12pt;"><br>
</span></p>
<p><span style="font-size: 12pt;">> </span><span style="font-size: 12pt;">Note that "actually empty" would translate to "single indent/tab" in Squeak because of the way method source code is presented.</span><span style="font-size: 12pt;"></p>
<div><br>
</div>
<div>And here's where the special treatments (cf. arg 1 above) would begin. If every line in a method (except the signature) has a minimum indentation of one, why should empty lines deserve a negative indentation of 1 compared to the default? If you have a
 method like this where the default indentation is effectively 2, why should empty lines only be intended with 1 tab?</div>
<div><br>
</div>
<div>treat: something</div>
<div>    something ifNotNil: [</div>
<div>        something foo.</div>
<div>        something bar.</div>
<div>        </div>
<div>        something baz].</div>
<div><br>
</div>
<div>For these reasons, I think indenting every line consistently would just be more consistent. :-)</div>
<div><br>
</div>
<div>Best,</div>
<div>Christoph</div>
</span>
<p></p>
<div id="Signature">
<div id="divtagdefaultwrapper" dir="ltr" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;">
<div name="divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Taeumel, Marcel<br>
<b>Gesendet:</b> Montag, 8. März 2021 10:55:19<br>
<b>An:</b> squeak-dev<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: Morphic-ct.1733.mcz</font>
<div> </div>
</div>
<div>
<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
Note that "actually empty" would translate to "single indent/tab" in Squeak because of the way method source code is presented.
<div><br>
</div>
<div>Best,</div>
<div>Marcel</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 08.03.2021 10:52:54 schrieb Marcel Taeumel <marcel.taeumel@hpi.de>:</p>
<div style="font-family:Arial,Helvetica,sans-serif">
<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>
</div>
</blockquote>
</div>
</div>
</body>
</html>