Skip to content

Commit 1a708ec

Browse files
authored
Merge pull request #1870 from ahoppen/no-escape-open-brace
Don’t escape `{` inside placeholder snippets
2 parents 5183889 + ee1f4b1 commit 1a708ec

File tree

3 files changed

+22
-22
lines changed

3 files changed

+22
-22
lines changed

Sources/SourceKitLSP/Swift/RewriteSourceKitPlaceholders.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ public func rewriteSourceKitPlaceholders(in input: String, clientSupportsSnippet
3737
placeholders.latest.contents += text
3838
}
3939

40-
case let .curlyBrace(brace):
40+
case .escapeInsidePlaceholder(let character):
4141
if placeholders.isEmpty {
42-
result.append(brace)
42+
result.append(character)
4343
} else {
44-
// Braces are only escaped _inside_ a placeholder; otherwise the client
45-
// would include the backslashes literally.
46-
placeholders.latest.contents.append(contentsOf: ["\\", brace])
44+
// A closing brace is only escaped _inside_ a placeholder; otherwise the client would include the backslashes
45+
// literally.
46+
placeholders.latest.contents += [#"\"#, character]
4747
}
4848

4949
case .placeholderOpen:
@@ -115,10 +115,10 @@ private func tokenize(_ input: String) -> [SnippetToken] {
115115
text.append(char)
116116
}
117117

118-
case "{", "}":
118+
case "$", "}", "\\":
119119
tokens.append(.text(text))
120120
text.removeAll()
121-
tokens.append(.curlyBrace(char))
121+
tokens.append(.escapeInsidePlaceholder(char))
122122

123123
case let c:
124124
text.append(c)
@@ -134,8 +134,8 @@ private func tokenize(_ input: String) -> [SnippetToken] {
134134
private enum SnippetToken {
135135
/// A placeholder delimiter.
136136
case placeholderOpen, placeholderClose
137-
/// One of '{' or '}', which may need to be escaped in the output.
138-
case curlyBrace(Character)
137+
/// '$', '}' or '\', which need to be escaped when used inside a placeholder.
138+
case escapeInsidePlaceholder(Character)
139139
/// Any other consecutive run of characters from the input, which needs no
140140
/// special treatment.
141141
case text(String)

Tests/SourceKitLSPTests/RewriteSourceKitPlaceholdersTests.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,20 @@ final class RewriteSourceKitPlaceholdersTests: XCTestCase {
4747
let input = "foo(bar: <#{ <#T##Int##Int#> }#>)"
4848
let rewritten = rewriteSourceKitPlaceholders(in: input, clientSupportsSnippets: true)
4949

50-
XCTAssertEqual(rewritten, #"foo(bar: ${1:\{ ${2:Int} \}})"#)
50+
XCTAssertEqual(rewritten, #"foo(bar: ${1:{ ${2:Int} \}})"#)
5151
}
5252

5353
func testClosurePlaceholderArgumentType() {
5454
let input = "foo(bar: <#{ <#T##Int##Int#> in <#T##Void##Void#> }#>)"
5555
let rewritten = rewriteSourceKitPlaceholders(in: input, clientSupportsSnippets: true)
5656

57-
XCTAssertEqual(rewritten, #"foo(bar: ${1:\{ ${2:Int} in ${3:Void} \}})"#)
57+
XCTAssertEqual(rewritten, #"foo(bar: ${1:{ ${2:Int} in ${3:Void} \}})"#)
5858
}
5959

6060
func testMultipleClosurePlaceholders() {
6161
let input = "foo(<#{ <#T##Int##Int#> }#>, baz: <#{ <#Int#> in <#T##Bool##Bool#> }#>)"
6262
let rewritten = rewriteSourceKitPlaceholders(in: input, clientSupportsSnippets: true)
6363

64-
XCTAssertEqual(rewritten, #"foo(${1:\{ ${2:Int} \}}, baz: ${3:\{ ${4:Int} in ${5:Bool} \}})"#)
64+
XCTAssertEqual(rewritten, #"foo(${1:{ ${2:Int} \}}, baz: ${3:{ ${4:Int} in ${5:Bool} \}})"#)
6565
}
6666
}

Tests/SourceKitLSPTests/SwiftCompletionTests.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -864,14 +864,14 @@ final class SwiftCompletionTests: XCTestCase {
864864
sortText: nil,
865865
filterText: "myMap(:)",
866866
insertText: #"""
867-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
867+
myMap(${1:{ ${2:Int} in ${3:Bool} \}})
868868
"""#,
869869
insertTextFormat: .snippet,
870870
textEdit: .textEdit(
871871
TextEdit(
872872
range: Range(positions["1️⃣"]),
873873
newText: #"""
874-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
874+
myMap(${1:{ ${2:Int} in ${3:Bool} \}})
875875
"""#
876876
)
877877
)
@@ -908,14 +908,14 @@ final class SwiftCompletionTests: XCTestCase {
908908
sortText: nil,
909909
filterText: ".myMap(:)",
910910
insertText: #"""
911-
?.myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
911+
?.myMap(${1:{ ${2:Int} in ${3:Bool} \}})
912912
"""#,
913913
insertTextFormat: .snippet,
914914
textEdit: .textEdit(
915915
TextEdit(
916916
range: positions["1️⃣"]..<positions["2️⃣"],
917917
newText: #"""
918-
?.myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
918+
?.myMap(${1:{ ${2:Int} in ${3:Bool} \}})
919919
"""#
920920
)
921921
)
@@ -952,14 +952,14 @@ final class SwiftCompletionTests: XCTestCase {
952952
sortText: nil,
953953
filterText: "myMap(::)",
954954
insertText: #"""
955-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}}, ${4:\{ ${5:Int} in ${6:String} \}})
955+
myMap(${1:{ ${2:Int} in ${3:Bool} \}}, ${4:{ ${5:Int} in ${6:String} \}})
956956
"""#,
957957
insertTextFormat: .snippet,
958958
textEdit: .textEdit(
959959
TextEdit(
960960
range: Range(positions["1️⃣"]),
961961
newText: #"""
962-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}}, ${4:\{ ${5:Int} in ${6:String} \}})
962+
myMap(${1:{ ${2:Int} in ${3:Bool} \}}, ${4:{ ${5:Int} in ${6:String} \}})
963963
"""#
964964
)
965965
)
@@ -996,14 +996,14 @@ final class SwiftCompletionTests: XCTestCase {
996996
sortText: nil,
997997
filterText: "myMap(:second:)",
998998
insertText: #"""
999-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}}, second: ${4:\{ ${5:Int} in ${6:String} \}})
999+
myMap(${1:{ ${2:Int} in ${3:Bool} \}}, second: ${4:{ ${5:Int} in ${6:String} \}})
10001000
"""#,
10011001
insertTextFormat: .snippet,
10021002
textEdit: .textEdit(
10031003
TextEdit(
10041004
range: Range(positions["1️⃣"]),
10051005
newText: #"""
1006-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}}, second: ${4:\{ ${5:Int} in ${6:String} \}})
1006+
myMap(${1:{ ${2:Int} in ${3:Bool} \}}, second: ${4:{ ${5:Int} in ${6:String} \}})
10071007
"""#
10081008
)
10091009
)
@@ -1042,14 +1042,14 @@ final class SwiftCompletionTests: XCTestCase {
10421042
sortText: nil,
10431043
filterText: "myMap(:)",
10441044
insertText: #"""
1045-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
1045+
myMap(${1:{ ${2:Int} in ${3:Bool} \}})
10461046
"""#,
10471047
insertTextFormat: .snippet,
10481048
textEdit: .textEdit(
10491049
TextEdit(
10501050
range: Range(positions["1️⃣"]),
10511051
newText: #"""
1052-
myMap(${1:\{ ${2:Int} in ${3:Bool} \}})
1052+
myMap(${1:{ ${2:Int} in ${3:Bool} \}})
10531053
"""#
10541054
)
10551055
)

0 commit comments

Comments
 (0)