Skip to content
This repository has been archived by the owner on Aug 31, 2021. It is now read-only.

[[ Bugs 19951, 8228 ]] Line continuation formatting #1726

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -477,12 +477,18 @@ private function textFormatGetLineIndent pLine
return tResult
end textFormatGetLineIndent

-- all chars after a continuation are treated as a comment
-- this will work fine until someone uses format with multiple
-- \"\" but there's not much getting around that
private function lineIsContinued pLine
if word -1 of pLine is "\" then
return true
else
return false
end if
put lineStripComments(pLine) into pLine
split pLine by quote
repeat with tIndex = 1 to the number of elements of pLine step 2
if pLine[tIndex] contains "\" then
return true
end if
end repeat
return false
end lineIsContinued

private function textFormatGetContinuationIndent pLastLineNumber
Expand All @@ -493,15 +499,15 @@ end textFormatGetContinuationIndent

private function combineContinuedLine pLastLineNumber, @pTextLines
local tContinuation
put pTextLines[pLastLineNumber] into tContinuation
put lineStripComments(pTextLines[pLastLineNumber]) into tContinuation

local tIndex
repeat with tIndex = (pLastLineNumber - 1) down to 1
if not lineIsContinued( pTextLines[tIndex]) then
exit repeat
end if

put pTextLines[tIndex] before tContinuation
put lineStripComments(pTextLines[tIndex]) before tContinuation
end repeat
replace "\" with empty in tContinuation
return tContinuation
Expand Down Expand Up @@ -537,10 +543,12 @@ private function textFormatLine pLine, pTextLines, @xPreviousLine
end if

local tPreviousLine
local tPreviousLineWasCombined = false
if xPreviousLine > 0 then
# This is the case where we have reached the end of a continued line. Here, we treat the continued line
# as a single entity in order to calculate its indentation properties correctly for the line after it.
if lineIsContinued(pTextLines[xPreviousLine - 1]) then
put true into tPreviousLineWasCombined
put combineContinuedLine(xPreviousLine, pTextLines) into tPreviousLine
else
put pTextLines[xPreviousLine] into tPreviousLine
Expand Down Expand Up @@ -571,15 +579,15 @@ private function textFormatLine pLine, pTextLines, @xPreviousLine
# we always add the continuation indent because we combined the continued lines
put kContinuationIndent into tIndentPreviousLineAdds
else
put textFormatIndentLineAdds(pTextLines[xPreviousLine]) into tIndentPreviousLineAdds
put textFormatIndentLineAdds(tPreviousLine) into tIndentPreviousLineAdds
end if

local tCurrentIndent
repeat (the number of chars of tPreviousLineIndent + tIndentCurrentLineRemoves + tIndentPreviousLineAdds)
put space after tCurrentIndent
end repeat

put ((the number of chars of tPreviousLineIndent + tIndentCurrentLineRemoves + tIndentPreviousLineAdds) - the number of chars of tCurrentLineIndent) & comma into tResult
put ((the number of chars of tPreviousLineIndent + tIndentCurrentLineRemoves + tIndentPreviousLineAdds) - the number of chars of tCurrentLineIndent) into tResult

-- Finally, calculate the expected next indent.
local tNewIndent
Expand All @@ -596,6 +604,13 @@ private function textFormatLine pLine, pTextLines, @xPreviousLine
put textFormatIndentLineAdds(pTextLines[pLine]) into tIndentCurrentLineAdds
end if

if tPreviousLineWasContinued then
local tCombinedLine
put tPreviousLine && pTextLines[pLine] into tCombinedLine
replace "\" with empty in tCombinedLine
add textFormatIndentLineAdds(tCombinedLine) to tIndentCurrentLineAdds
end if

if tIndentCurrentLineAdds < 0 then
repeat -tIndentCurrentLineAdds times
delete char 1 of tNewIndent
Expand All @@ -606,7 +621,7 @@ private function textFormatLine pLine, pTextLines, @xPreviousLine
end repeat
end if

put tNewIndent after tResult
put comma & tNewIndent after tResult

if token 1 of pTextLines[pLine] is not empty then
put pLine into xPreviousLine
Expand Down Expand Up @@ -2505,22 +2520,34 @@ end dragEnd
# Description
## Returns a line stripped of comments at the end of the line
private function lineStripComments pLine
local tOffset,tCommentChar
put offset("#", pLine) into tOffset
if tOffset = 0 then
put offset("--", pLine) into tOffset
put "--" into tCommentChar
else
put "#" into tCommentChar
end if
local tLine
split pLine by quote

repeat with tIndex = 1 to the number of elements of pLine step 2
local tDecommented
put __StripComment(pLine[tIndex]) into tDecommented
put tDecommented after tLine
if pLine[tIndex] is tDecommented and \
tIndex is not the number of elements of pLine then
put quote & pLine[tIndex+1] & quote after tLine
end if
end repeat

if tCommentChar is empty then
return pLine
else
return char 1 to tOffset of pLine
end if
return tLine
end lineStripComments

private function __StripComment pLine
local tOffset
repeat for each word tComment in "# -- // /*"
put offset(tComment, pLine) into tOffset
if tOffset is not 0 then
delete char tOffset to -1 of pLine
end if
end repeat

return pLine
end __StripComment

################################################################################

command actionCopy
Expand Down
1 change: 1 addition & 0 deletions notes/bugfix-19951.md
@@ -0,0 +1 @@
# Fix a range of edge case indentation issues related to line continuation
1 change: 1 addition & 0 deletions notes/bugfix-8228.md
@@ -0,0 +1 @@
# Indent scripts correctly when a comment is after the line continuation character
33 changes: 33 additions & 0 deletions tests/scripteditor/_indentation_tests/bug-19951.livecodescript
@@ -0,0 +1,33 @@
repeat \
forever
-- code
end repeat

switch \
tVar
case "foo"
-- code
break
case \
"foo"
-- code
break
default
-- code
break
end switch

try
-- code
catch \
tError
-- code
end try

if something \
then
-- code
end if

put "foo" &\
"bar"
8 changes: 8 additions & 0 deletions tests/scripteditor/_indentation_tests/bug-8228.livecodescript
@@ -0,0 +1,8 @@
if (gDatf[tPost,i] <> "") and \
(((gPoly[tPost] = "") and (gSurf[tPost] = gSurg[tPost,i])) or ((gPoly[tPost] <> "") and (gPoly[tPost] = gPolz[tPost,i]))) and \
(gFra1[tPost,i] <> "") and (gFra2[tPost,i] <> "") and \
((gPos2[tPost,i] <> "") or (quote is in gPos2[tPost,i])) and ((gPos3[tPost,i] <> "") or (quote is in gPos3[tPost,i])) and ((gPos4[tPost,i] <> "") or (quote is in gPos4[tPost,i])) and ((gPos5[tPost,i] <> "") or (quote is in gPos5[tPost,i])) and \
(abs(gDist[tPost]) - abs(gDisu[tPost,i]) <= 0) and \ -- (abs(abs(gDist[tPost]) - abs(gDisu[tPost,i])) <= 440)
(gBea5[tPost,i] <= 2.0) then
put tab & gDatf[tPost,i] & tab & gPos2[tPost,i] & gPos3[tPost,i] & gPos4[tPost,i] & gPos5[tPost,i] & tab & gSco1[tPost,i] & tab & gSco2[tPost,i] & tab & gSco3[tPost,i] & tab & gOdds[tPost] & return after fld "Indey"
end if
39 changes: 39 additions & 0 deletions tests/scripteditor/_indentation_tests/handlers.livecodescript
@@ -0,0 +1,39 @@
on Foo pParam
-- code
end Foo

command Foo pParam
-- code
end Foo

private command Foo pParam
-- code
end Foo

private on Foo pParam
-- code
end Foo

before Foo pParam
-- code
end Foo

after Foo pParam
-- code
end Foo

function Foo pParam
-- code
end Foo

private function Foo pParam
-- code
end Foo

setProp Foo pParam
-- code
end Foo

getProp Foo pParam
-- code
end Foo
27 changes: 27 additions & 0 deletions tests/scripteditor/_indentation_tests/if.livecodescript
@@ -0,0 +1,27 @@
if foo() then
-- code
else if bar() then
-- code
else
-- code
end if

if foo()
then -- code
else if bar() then
-- code
else
-- code
end if

if foo()
then code
else if bar() then
-- code
else code

if foo()
then code
else code

if foo() then code else code
47 changes: 47 additions & 0 deletions tests/scripteditor/_indentation_tests/repeat.livecodescript
@@ -0,0 +1,47 @@
repeat forever
-- code
end repeat

repeat while foo()
-- code
end repeat

repeat until foo()
-- code
end repeat

repeat 3
-- code
end repeat

repeat for 3
-- code
end repeat

repeat for 3 times
-- code
end repeat

repeat 3 times
-- code
end repeat

repeat with X = 1 to 5
-- code
end repeat

repeat with X = 1 to 5 step 2
-- code
end repeat

repeat with X = 5 down to 1
-- code
end repeat

repeat with X = 5 down to 1 step 2
-- code
end repeat

repeat for each line tLine in tFoo
-- code
end repeat
17 changes: 17 additions & 0 deletions tests/scripteditor/_indentation_tests/switch.livecodescript
@@ -0,0 +1,17 @@
switch tFoo
case "foo"
-- code
break
default
-- code
break
end switch

switch
case tFoo begins with "foo"
-- code
break
default
-- code
break
end switch
7 changes: 7 additions & 0 deletions tests/scripteditor/_indentation_tests/try.livecodescript
@@ -0,0 +1,7 @@
try
-- code
catch tError
-- code
finally
-- code
end try