Skip to content

Commit 3a74dc9

Browse files
committed
Support syntax highlighting and copy code in chat panel
1 parent a7af744 commit 3a74dc9

File tree

4 files changed

+51
-17
lines changed

4 files changed

+51
-17
lines changed

Copilot for Xcode.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Core/Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ let package = Package(
3737
.package(url: "https://github.com/raspu/Highlightr", from: "2.1.0"),
3838
.package(url: "https://github.com/JohnSundell/Splash", from: "0.1.0"),
3939
.package(url: "https://github.com/nmdias/FeedKit", from: "9.1.2"),
40-
.package(url: "https://github.com/gonzalezreal/swift-markdown-ui", from: "2.0.0"),
41-
.package(url: "https://github.com/sparkle-project/Sparkle", from: "2.0.0"),
40+
.package(url: "https://github.com/intitni/swift-markdown-ui", branch: "main"),
41+
.package(url: "https://github.com/sparkle-project/Sparkle", from: "2.0.0"),
4242
],
4343
targets: [
4444
.target(name: "CGEventObserver"),

Core/Sources/SuggestionWidget/SuggestionPanelContent/ChatPanel.swift

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import MarkdownUI
22
import SwiftUI
33

44
struct ChatPanel: View {
5-
var viewModel: SuggestionPanelViewModel
5+
@ObservedObject var viewModel: SuggestionPanelViewModel
66
@ObservedObject var chat: ChatRoom
77
@Namespace var inputAreaNamespace
88
@State var typedMessage = ""
99

1010
var body: some View {
1111
ZStack(alignment: .topTrailing) {
1212
VStack {
13-
ChatPanelMessages(chat: chat, inputAreaNamespace: inputAreaNamespace)
14-
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
13+
ChatPanelMessages(
14+
chat: chat,
15+
inputAreaNamespace: inputAreaNamespace,
16+
colorScheme: viewModel.colorScheme
17+
)
18+
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
1519

1620
if !chat.isReceivingMessage {
1721
ChatPanelInputArea(
@@ -41,6 +45,7 @@ struct ChatPanel: View {
4145
struct ChatPanelMessages: View {
4246
@ObservedObject var chat: ChatRoom
4347
var inputAreaNamespace: Namespace.ID
48+
var colorScheme: ColorScheme
4449
@AppStorage(\.disableLazyVStack) var disableLazyVStack
4550

4651
@ViewBuilder
@@ -101,6 +106,9 @@ struct ChatPanelMessages: View {
101106
.markdownTheme(.gitHub.text {
102107
BackgroundColor(Color.clear)
103108
})
109+
.markdownCodeSyntaxHighlighter(
110+
ChatCodeSyntaxHighlighter(brightMode: colorScheme != .dark)
111+
)
104112
.frame(maxWidth: .infinity, alignment: .leading)
105113
.padding()
106114
.background(
@@ -219,6 +227,9 @@ struct ChatPanel_Preview: PreviewProvider {
219227
```swift
220228
func foo() {}
221229
```
230+
```objectivec
231+
- (void)bar {}
232+
```
222233
"""#
223234
),
224235
]
@@ -237,6 +248,23 @@ struct ChatPanel_Preview: PreviewProvider {
237248
}
238249
}
239250

251+
struct ChatCodeSyntaxHighlighter: CodeSyntaxHighlighter {
252+
let brightMode: Bool
253+
254+
init(brightMode: Bool) {
255+
self.brightMode = brightMode
256+
}
257+
258+
func highlightCode(_ content: String, language: String?) -> Text {
259+
let content = highlightedCodeBlock(
260+
code: content,
261+
language: language ?? "",
262+
brightMode: brightMode
263+
)
264+
return Text(AttributedString(content))
265+
}
266+
}
267+
240268
struct ChatPanel_InputText_Preview: PreviewProvider {
241269
static var previews: some View {
242270
ChatPanel(viewModel: .init(

Core/Sources/SuggestionWidget/SyntaxHighlighting.swift

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@ import Foundation
33
import Highlightr
44
import Splash
55
import XPCShared
6+
import SwiftUI
67

7-
func highlighted(code: String, language: String, brightMode: Bool) -> [NSAttributedString] {
8-
let middleDotColor = brightMode
9-
? NSColor.black.withAlphaComponent(0.1)
10-
: NSColor.white.withAlphaComponent(0.1)
8+
func highlightedCodeBlock(code: String, language: String, brightMode: Bool) -> NSAttributedString {
119
switch language {
1210
case "swift":
1311
let plainTextColor = brightMode
@@ -47,17 +45,17 @@ func highlighted(code: String, language: String, brightMode: Bool) -> [NSAttribu
4745
[.font: NSFont.monospacedSystemFont(ofSize: 13, weight: .regular)],
4846
range: NSRange(location: 0, length: formatted.length)
4947
)
50-
return convertToCodeLines(formatted, middleDotColor: middleDotColor)
48+
return formatted
5149
default:
5250
var language = language
5351
if language == "objective-c" {
5452
language = "objectivec"
5553
}
56-
func unhighlightedCode() -> [NSAttributedString] {
57-
return convertToCodeLines(NSAttributedString(
54+
func unhighlightedCode() -> NSAttributedString {
55+
return NSAttributedString(
5856
string: code,
5957
attributes: [.foregroundColor: NSColor.white]
60-
), middleDotColor: middleDotColor)
58+
)
6159
}
6260
guard let highlighter = Highlightr() else {
6361
return unhighlightedCode()
@@ -70,10 +68,18 @@ func highlighted(code: String, language: String, brightMode: Bool) -> [NSAttribu
7068
if formatted.string == "undefined" {
7169
return unhighlightedCode()
7270
}
73-
return convertToCodeLines(formatted, middleDotColor: middleDotColor)
71+
return formatted
7472
}
7573
}
7674

75+
func highlighted(code: String, language: String, brightMode: Bool) -> [NSAttributedString] {
76+
let formatted = highlightedCodeBlock(code: code, language: language, brightMode: brightMode)
77+
let middleDotColor = brightMode
78+
? NSColor.black.withAlphaComponent(0.1)
79+
: NSColor.white.withAlphaComponent(0.1)
80+
return convertToCodeLines(formatted, middleDotColor: middleDotColor)
81+
}
82+
7783
private func convertToCodeLines(
7884
_ formattedCode: NSAttributedString,
7985
middleDotColor: NSColor

0 commit comments

Comments
 (0)