Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
63af3b4
Merge tag '0.27.0' into develop
intitni Nov 9, 2023
651b639
Support retrieval in context aware prompt to code
intitni Nov 16, 2023
ba79efd
Update
intitni Nov 16, 2023
221a034
Merge tag '0.27.1' into develop
intitni Nov 18, 2023
6e0895c
Rename FocusCodeFinder to FocusCodeFinderType
intitni Nov 16, 2023
9c47de5
Simplify interface of focused code finder
intitni Nov 16, 2023
1d89fcc
Remove tree sitter for Swift
intitni Nov 25, 2023
6b040e3
Update syntax tree dump
intitni Nov 25, 2023
71bc6e7
Fix code finder tests
intitni Nov 26, 2023
2b027e9
Update focused code finder
intitni Nov 26, 2023
3516f57
Fix imports
intitni Nov 26, 2023
f9c5301
Add ObjectiveCFocusedCodeFinder
intitni Nov 26, 2023
3e807b0
Update
intitni Nov 26, 2023
975a1df
Fix SwiftFocusedCodeFinderTests
intitni Nov 26, 2023
72035e7
Fix parseSignatureBeforeBody
intitni Nov 26, 2023
7dcd116
Simplify contextContainingNode
intitni Nov 26, 2023
3a0b5e5
Fix super class and protocol conformance parsing
intitni Nov 27, 2023
b17d282
Add parseDeclarationInterfaceNode to parse all declaration contexts
intitni Nov 27, 2023
2749e2e
Fix parsing includes and imports
intitni Nov 27, 2023
f4ea0f6
Fix focused code
intitni Nov 27, 2023
e8c3ba4
Update
intitni Nov 27, 2023
ecfdfc0
Merge branch 'feature/objective-c-code-finder' into develop
intitni Nov 27, 2023
6d22d48
Add AutoresizingCustomTextEditor
intitni Nov 28, 2023
1305c72
Rename SuggestionProvider to CodeSuggestionProvider
intitni Nov 28, 2023
02900cb
Update
intitni Nov 28, 2023
e5967e0
Merge branch 'feature/informative-suggestion-wip' into develop
intitni Nov 30, 2023
03882d7
Update the context system prompt to use role user
intitni Nov 30, 2023
bc39122
Adjust the prompt in chat
intitni Nov 30, 2023
a1c1043
Rename ChatMessage in chat panel to DisplayedChatMessage
intitni Nov 30, 2023
9b22c29
Add references to chat message
intitni Nov 30, 2023
94aaade
Change the definition of a memory
intitni Nov 30, 2023
68ea73b
Update RetrievedContent in ChatContext
intitni Nov 30, 2023
ba592c2
Support displaying references in chat panel
intitni Dec 1, 2023
aac293e
Break ChatPanel.swift into multiple files
intitni Dec 1, 2023
be2376a
Update to stream references to message
intitni Dec 1, 2023
1925397
Support opening references in Xcode
intitni Dec 1, 2023
774216b
Support jump to specific line of reference file
intitni Dec 1, 2023
5d57f90
Fix the UI of reference list
intitni Dec 1, 2023
01bcaad
Fix opening reference
intitni Dec 1, 2023
353c686
Fix cancellation
intitni Dec 2, 2023
9c3840d
Update
intitni Dec 2, 2023
46da74c
Support providing history compose logic from other types
intitni Dec 2, 2023
67221f4
Update
intitni Dec 2, 2023
2b317fd
Update prompt of prompt to code
intitni Dec 2, 2023
b3ae4ec
Fix that context retriever was incorrect when the context is too long
intitni Dec 2, 2023
6c129d7
Fix that multiple function result was added to history
intitni Dec 2, 2023
d117fb1
Fix unit tests
intitni Dec 2, 2023
f4130c9
Merge branch 'feature/prompt-improvements-28' into develop
intitni Dec 2, 2023
966f654
Add SubSection
intitni Dec 2, 2023
ed339b6
Replace wrappers with SubSection
intitni Dec 2, 2023
3aba060
Update style
intitni Dec 2, 2023
b11f49e
Add scope settings to prompt to code
intitni Dec 2, 2023
bc0eb57
Update
intitni Dec 2, 2023
5b3051d
Merge branch 'feature/improve-scope-settings' into develop
intitni Dec 2, 2023
4f1a60b
Add instructions to chat model settings
intitni Dec 2, 2023
c0e8aa0
Handle errors from azure openai
intitni Dec 2, 2023
9f528c6
Update
intitni Dec 2, 2023
81051ab
Add git ignore checker
intitni Dec 3, 2023
a916e14
Update to not generate suggestion if a file is git ignored
intitni Dec 3, 2023
6c4fc82
Update ActiveDocumentChatContextCollector to only include selected co…
intitni Dec 3, 2023
f6ee5b7
Update
intitni Dec 3, 2023
e9dfeb1
Update
intitni Dec 3, 2023
5ca3bf0
Merge branch 'feature/keyword-base-retrieval' into develop
intitni Dec 3, 2023
a00c478
Fix gitignore check
intitni Dec 3, 2023
e43902a
Limit to 15 references
intitni Dec 3, 2023
28ac89c
Limit references token usage
intitni Dec 3, 2023
de6fa08
Update
intitni Dec 4, 2023
c1404c4
Bump version to 0.28.0
intitni Dec 4, 2023
0c55c5d
Merge branch 'main' into release/0.28.0
intitni Dec 4, 2023
0b54d7c
Update README.md
intitni Dec 4, 2023
66a3494
Use fallback solution when it can't find xcode
intitni Dec 4, 2023
ed2a203
Remove a fatalError
intitni Dec 4, 2023
c452fae
Update
intitni Dec 4, 2023
2312248
Adjust UI
intitni Dec 4, 2023
8ccb85f
Update appcast.xml
intitni Dec 4, 2023
28cf55b
Merge tag '0.28.0' into develop
intitni Dec 4, 2023
bd0f17d
Merge branch 'release/0.28.0'
intitni Dec 4, 2023
143c966
Update
intitni Dec 4, 2023
ea61843
Disable git ignore check by default
intitni Dec 4, 2023
c5dd90e
Bump version to 0.28.1
intitni Dec 4, 2023
de2b382
Update appcast.xml
intitni Dec 4, 2023
d426013
Merge tag '0.28.1' into develop
intitni Dec 4, 2023
b3a73bc
Merge branch 'hotfix/0.28.1'
intitni Dec 4, 2023
b5b6019
Fix git ignore check
intitni Dec 4, 2023
95ba0c3
Bump version 0.28.2
intitni Dec 4, 2023
d0e41d2
Update appcast.xml
intitni Dec 4, 2023
8613f35
Merge branch 'release/0.28.2'
intitni Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update
  • Loading branch information
intitni committed Nov 28, 2023
commit 02900cbfbb2179f7cd06f423c6cc54b63eb55870
289 changes: 289 additions & 0 deletions Tool/Sources/SharedUIComponents/Experiment/NewCodeBlock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
import STTextView
import SwiftUI

private let insetBottom = 12 as Double
private let insetTop = 12 as Double

/// This SwiftUI view can be used to view and edit rich text.
struct _CodeBlock: View {
@Binding private var selection: NSRange?
@State private var contentHeight: Double = 500
let fontSize: Double
let commonPrecedingSpaceCount: Int
let highlightedCode: AttributedString
let colorScheme: ColorScheme

/// Create a text edit view with a certain text that uses a certain options.
/// - Parameters:
/// - text: The attributed string content
/// - options: Editor options
/// - plugins: Editor plugins
public init(
code: String,
language: String,
firstLinePrecedingSpaceCount: Int,
colorScheme: ColorScheme,
fontSize: Double,
selection: Binding<NSRange?> = .constant(nil)
) {
_selection = selection
self.fontSize = fontSize
self.colorScheme = colorScheme

let padding = firstLinePrecedingSpaceCount > 0
? String(repeating: " ", count: firstLinePrecedingSpaceCount)
: ""
let result = Self.highlight(
code: padding + code,
language: language,
colorScheme: colorScheme,
fontSize: fontSize
)
commonPrecedingSpaceCount = result.commonLeadingSpaceCount
highlightedCode = result.code
}

public var body: some View {
_CodeBlockRepresentable(
text: highlightedCode,
selection: $selection,
fontSize: fontSize,
onHeightChange: { height in
print("Q", height)
contentHeight = height
}
)
.frame(height: contentHeight, alignment: .topLeading)
.background(.background)
.colorScheme(colorScheme)
.onAppear {
print("")
}
}

static func highlight(
code: String,
language: String,
colorScheme: ColorScheme,
fontSize: Double
) -> (code: AttributedString, commonLeadingSpaceCount: Int) {
let (lines, commonLeadingSpaceCount) = highlighted(
code: code,
language: language,
brightMode: colorScheme != .dark,
droppingLeadingSpaces: UserDefaults.shared
.value(for: \.hideCommonPrecedingSpacesInSuggestion),
fontSize: fontSize,
replaceSpacesWithMiddleDots: false
)

let string = NSMutableAttributedString()
for (index, line) in lines.enumerated() {
string.append(line)
if index < lines.count - 1 {
string.append(NSAttributedString(string: "\n"))
}
}

return (code: .init(string), commonLeadingSpaceCount: commonLeadingSpaceCount)
}
}

private struct _CodeBlockRepresentable: NSViewRepresentable {
@Environment(\.isEnabled) private var isEnabled
@Environment(\.lineSpacing) private var lineSpacing

@Binding private var selection: NSRange?
let text: AttributedString
let fontSize: Double
let onHeightChange: (Double) -> Void

init(
text: AttributedString,
selection: Binding<NSRange?>,
fontSize: Double,
onHeightChange: @escaping (Double) -> Void
) {
self.text = text
_selection = selection
self.fontSize = fontSize
self.onHeightChange = onHeightChange
}

func makeNSView(context: Context) -> NSScrollView {
let scrollView = STTextViewFrameObservable.scrollableTextView()
scrollView.contentInsets = .init(top: 0, left: 0, bottom: insetBottom, right: 0)
scrollView.automaticallyAdjustsContentInsets = false
let textView = scrollView.documentView as! STTextView
textView.delegate = context.coordinator
textView.highlightSelectedLine = false
textView.widthTracksTextView = true
textView.heightTracksTextView = true
textView.isEditable = true

textView.setSelectedRange(NSRange())
let lineNumberRuler = STLineNumberRulerView(textView: textView)
lineNumberRuler.backgroundColor = .clear
lineNumberRuler.separatorColor = .clear
lineNumberRuler.rulerInsets = .init(leading: 10, trailing: 10)
scrollView.verticalRulerView = lineNumberRuler
let columnNumberRuler = ColumnRuler(textView: textView)
scrollView.horizontalRulerView = columnNumberRuler
scrollView.rulersVisible = true

context.coordinator.isUpdating = true
textView.setAttributedString(NSAttributedString(text))
context.coordinator.isUpdating = false

return scrollView
}

func updateNSView(_ scrollView: NSScrollView, context: Context) {
context.coordinator.parent = self

let textView = scrollView.documentView as! STTextViewFrameObservable

textView.onHeightChange = onHeightChange
textView.showsInvisibleCharacters = true
textView.textContainer.lineBreakMode = .byCharWrapping

if let columnNumberRuler = scrollView.horizontalRulerView as? ColumnRuler {
columnNumberRuler.columnNumber = 5
}

do {
context.coordinator.isUpdating = true
if context.coordinator.isDidChangeText == false {
textView.setAttributedString(.init(text))
}
context.coordinator.isUpdating = false
context.coordinator.isDidChangeText = false
}

if textView.selectedRange() != selection, let selection {
textView.setSelectedRange(selection)
}

if textView.isSelectable != isEnabled {
textView.isSelectable = isEnabled
}

textView.isEditable = false

if !textView.widthTracksTextView {
textView.widthTracksTextView = false
}

if !textView.heightTracksTextView {
textView.heightTracksTextView = true
}

let font = NSFont.monospacedSystemFont(ofSize: fontSize, weight: .regular)
if textView.font != font {
textView.font = font
}
}

func makeCoordinator() -> TextCoordinator {
TextCoordinator(parent: self)
}

private func styledAttributedString(_ typingAttributes: [NSAttributedString.Key: Any])
-> AttributedString
{
let paragraph = (typingAttributes[.paragraphStyle] as! NSParagraphStyle)
.mutableCopy() as! NSMutableParagraphStyle
if paragraph.lineSpacing != lineSpacing {
paragraph.lineSpacing = lineSpacing
var typingAttributes = typingAttributes
typingAttributes[.paragraphStyle] = paragraph

let attributeContainer = AttributeContainer(typingAttributes)
var styledText = text
styledText.mergeAttributes(attributeContainer, mergePolicy: .keepNew)
return styledText
}

return text
}

class TextCoordinator: STTextViewDelegate {
var parent: _CodeBlockRepresentable
var isUpdating: Bool = false
var isDidChangeText: Bool = false
var enqueuedValue: AttributedString?

init(parent: _CodeBlockRepresentable) {
self.parent = parent
}

func textViewDidChangeText(_ notification: Notification) {
guard let textView = notification.object as? STTextView else {
return
}

(textView as! STTextViewFrameObservable).recalculateSize()
}

func textViewDidChangeSelection(_ notification: Notification) {
guard let textView = notification.object as? STTextView else {
return
}

Task { @MainActor in
self.parent.selection = textView.selectedRange()
}
}
}
}

private class STTextViewFrameObservable: STTextView {
var onHeightChange: ((Double) -> Void)?
func recalculateSize() {
var maxY = 0 as Double
textLayoutManager.enumerateTextLayoutFragments(in: textLayoutManager.documentRange, options: [.ensuresLayout]) { fragment in
print(fragment.layoutFragmentFrame)
maxY = max(maxY, fragment.layoutFragmentFrame.maxY)
return true
}
onHeightChange?(maxY)
}
}

private final class ColumnRuler: NSRulerView {
var columnNumber: Int = 0

private var textView: STTextView? {
clientView as? STTextView
}

public required init(textView: STTextView, scrollView: NSScrollView? = nil) {
super.init(
scrollView: scrollView ?? textView.enclosingScrollView,
orientation: .verticalRuler
)
clientView = textView
ruleThickness = insetBottom
}

@available(*, unavailable)
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func draw(_: NSRect) {
guard let context: CGContext = NSGraphicsContext.current?.cgContext else { return }
NSColor.windowBackgroundColor.withAlphaComponent(0.6).setFill()
context.fill(bounds)

let insetLeft = scrollView?.verticalRulerView?.bounds.width ?? 0
var drawingBounds = bounds
drawingBounds.origin.x += insetLeft + 4
let fontSize = 10 as Double
drawingBounds.origin.y = (insetTop - fontSize) / 2
NSString(string: "\(columnNumber)").draw(in: drawingBounds, withAttributes: [
.font: NSFont.monospacedSystemFont(ofSize: fontSize, weight: .regular),
.foregroundColor: NSColor.tertiaryLabelColor,
])
}
}
45 changes: 25 additions & 20 deletions Tool/Sources/SharedUIComponents/SyntaxHighlighting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public func highlighted(
language: String,
brightMode: Bool,
droppingLeadingSpaces: Bool,
fontSize: Double
fontSize: Double,
replaceSpacesWithMiddleDots: Bool = true
) -> (code: [NSAttributedString], commonLeadingSpaceCount: Int) {
let formatted = highlightedCodeBlock(
code: code,
Expand All @@ -56,14 +57,16 @@ public func highlighted(
return convertToCodeLines(
formatted,
middleDotColor: middleDotColor,
droppingLeadingSpaces: droppingLeadingSpaces
droppingLeadingSpaces: droppingLeadingSpaces,
replaceSpacesWithMiddleDots: replaceSpacesWithMiddleDots
)
}

func convertToCodeLines(
_ formattedCode: NSAttributedString,
middleDotColor: NSColor,
droppingLeadingSpaces: Bool
droppingLeadingSpaces: Bool,
replaceSpacesWithMiddleDots: Bool = true
) -> (code: [NSAttributedString], commonLeadingSpaceCount: Int) {
let input = formattedCode.string
func isEmptyLine(_ line: String) -> Bool {
Expand Down Expand Up @@ -115,24 +118,26 @@ func convertToCodeLines(
}
}

// use regex to replace all spaces to a middle dot
do {
let regex = try NSRegularExpression(pattern: "[ ]*", options: [])
let result = regex.matches(
in: mutable.string,
range: NSRange(location: 0, length: mutable.mutableString.length)
)
for r in result {
let range = r.range
mutable.replaceCharacters(
in: range,
with: String(repeating: "·", count: range.length)
if replaceSpacesWithMiddleDots {
// use regex to replace all spaces to a middle dot
do {
let regex = try NSRegularExpression(pattern: "[ ]*", options: [])
let result = regex.matches(
in: mutable.string,
range: NSRange(location: 0, length: mutable.mutableString.length)
)
mutable.addAttributes([
.foregroundColor: middleDotColor,
], range: range)
}
} catch {}
for r in result {
let range = r.range
mutable.replaceCharacters(
in: range,
with: String(repeating: "·", count: range.length)
)
mutable.addAttributes([
.foregroundColor: middleDotColor,
], range: range)
}
} catch {}
}
output.append(mutable)
start += range.length + 1
}
Expand Down