WIP: add code snippet cards

This commit is contained in:
Akshay Kolli
2026-07-01 15:12:49 -07:00
parent c5bafa3a83
commit ca3bdfbc70
16 changed files with 417 additions and 31 deletions

View File

@@ -108,6 +108,37 @@ final class ClipboardMonitorServiceTests: XCTestCase {
XCTAssertEqual(store.items.filter { $0.payload == text }.count, 1)
}
func testPollNowCapturesCodeSnippetAsCode() {
let settings = SettingsModel(defaults: makeTestDefaults())
settings.pruneDuplicates = false
let (store, cacheService) = makeStoreAndCache(settings: settings)
let monitor = ClipboardMonitorService(
store: store,
cacheService: cacheService,
settings: settings
)
let snippet = "func greet(name: String) -> String {\n return \"Hi \\(name)\"\n}"
let captured = expectation(description: "code snippet captured")
store.observeItems { items in
if items.contains(where: { $0.kind == .code && $0.payload == snippet }) {
captured.fulfill()
}
}
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
XCTAssertTrue(pasteboard.setString(snippet, forType: .string))
monitor.pollNowAndWait()
wait(for: [captured], timeout: 1.0)
let item = store.items.first
XCTAssertEqual(item?.kind, .code)
XCTAssertEqual(item?.displayText, "Swift Snippet")
XCTAssertEqual(item?.payload, snippet)
}
func testPollNowIgnoresClipBoredPasteboardWrites() {
let settings = SettingsModel(defaults: makeTestDefaults())
let (store, cacheService) = makeStoreAndCache(settings: settings)
@@ -639,6 +670,24 @@ final class ClipboardMonitorServiceTests: XCTestCase {
XCTAssertEqual(settings.captureStatusMessage, "Skipped: Color items are ignored in capture settings.")
}
func testIgnoredCodeKindDoesNotCaptureSnippet() throws {
let settings = SettingsModel(defaults: makeTestDefaults())
settings.ignoredItemKindsRaw = [ClipboardItemKind.code.rawValue]
let (store, cacheService, _) = makeStoreCacheAndBaseURL(settings: settings)
let monitor = ClipboardMonitorService(store: store, cacheService: cacheService, settings: settings)
let snippet = "const title = \"ClipBored\";\nreturn title.toUpperCase();"
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
XCTAssertTrue(pasteboard.setString(snippet, forType: .string))
monitor.pollNowAndWait()
RunLoop.main.run(until: Date().addingTimeInterval(0.05))
XCTAssertTrue(store.items.isEmpty)
XCTAssertEqual(settings.captureStatusMessage, "Skipped: Code items are ignored in capture settings.")
}
func testIgnoredPDFKindDoesNotWriteAttachmentFiles() throws {
let settings = SettingsModel(defaults: makeTestDefaults())
settings.ignoredItemKindsRaw = [ClipboardItemKind.pdf.rawValue]

View File

@@ -157,6 +157,7 @@ final class ClipboardPanelControllerTests: XCTestCase {
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 26, modifiers: [.command, .option]), .pinned)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 28, modifiers: [.command, .option]), .audio)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 25, modifiers: [.command, .option]), .colors)
XCTAssertEqual(ClipboardPanelController.collectionShortcutMode(forKeyCode: 29, modifiers: [.command, .option]), .code)
}
func testCollectionShortcutsRequireCommandOptionSoQuickPasteKeepsCommandNumbers() {

View File

@@ -84,6 +84,51 @@ final class ClipboardPanelViewModelTests: XCTestCase {
)
}
func testComputeVisibleItemsFiltersCodeSnippetsAndKeepsThemInTextView() {
let settings = makeSettings()
let store = makeStore(settings: settings)
let viewModel = ClipboardPanelViewModel(store: store, settings: settings, cacheService: ClipboardCacheService())
let code = ClipboardItem(
id: UUID(),
kind: .code,
displayText: "Swift Snippet",
payload: "func greet(name: String) -> String {\n return \"Hi \\(name)\"\n}",
payloadHash: hash("swift-snippet"),
createdAt: Date(timeIntervalSince1970: 200),
lastUsedAt: Date(timeIntervalSince1970: 200),
useCount: 0,
sourceApp: "Xcode",
imagePath: nil,
thumbnailPath: nil
)
let text = ClipboardItem(
id: UUID(),
kind: .text,
displayText: "Meeting note",
payload: "Meeting note",
payloadHash: hash("Meeting note"),
createdAt: Date(timeIntervalSince1970: 100),
lastUsedAt: Date(timeIntervalSince1970: 100),
useCount: 0,
sourceApp: "Notes",
imagePath: nil,
thumbnailPath: nil
)
XCTAssertEqual(
viewModel.computeVisibleItems(from: [code, text], query: "", sortMode: .code).map(\.kind),
[.code]
)
XCTAssertEqual(
viewModel.computeVisibleItems(from: [code, text], query: "", sortMode: .text).map(\.kind),
[.code, .text]
)
XCTAssertEqual(
viewModel.computeVisibleItems(from: [code, text], query: "type:snippet greet", sortMode: .mostRecent).map(\.kind),
[.code]
)
}
func testSearchMatchesIndependentTokensCaseInsensitively() {
let settings = makeSettings()
let store = makeStore(settings: settings)

View File

@@ -246,11 +246,11 @@ final class ClipboardPanelViewTests: XCTestCase {
XCTAssertEqual(
fixture.view.debugCollectionTitles,
["Clipboard", "Frequent", "Text", "Links", "Images", "Colors", "Audio", "Files", "Pinned"]
["Clipboard", "Frequent", "Text", "Links", "Images", "Colors", "Audio", "Files", "Pinned", "Code"]
)
XCTAssertEqual(
fixture.view.debugCollectionLeadingSymbols,
["doc.on.clipboard", "chart.bar.fill", "text.alignleft", "link", "photo", "paintpalette", "music.note", "doc.fill", "pin.fill"]
["doc.on.clipboard", "chart.bar.fill", "text.alignleft", "link", "photo", "paintpalette", "music.note", "doc.fill", "pin.fill", "chevron.left.forwardslash.chevron.right"]
)
XCTAssertEqual(fixture.view.debugSelectedCollectionTitle, "Clipboard")
@@ -681,15 +681,21 @@ final class ClipboardPanelViewTests: XCTestCase {
let color = makeItem(kind: .color, displayText: "#0A84FF", payload: "#0A84FF", store: fixture.store)
let audio = makeItem(kind: .audio, text: "audio payload", store: fixture.store)
let file = makeItem(kind: .file, text: "/tmp/report.pdf", store: fixture.store)
let code = makeItem(
kind: .code,
displayText: "Swift Snippet",
payload: "func greet(name: String) -> String {\n return \"Hi \\(name)\"\n}",
store: fixture.store
)
[pinned, rich, link, image, color, audio, file].forEach {
[pinned, rich, link, image, color, audio, file, code].forEach {
fixture.store.upsert($0)
drainMainQueue()
}
XCTAssertEqual(fixture.viewModel.visibleItems.count, 7)
XCTAssertEqual(ClipboardSortMode.allCases.map { fixture.viewModel.collectionCount(for: $0) }, [7, 7, 2, 1, 1, 1, 1, 1, 1])
XCTAssertEqual(fixture.view.debugCollectionCounts, [7, 7, 2, 1, 1, 1, 1, 1, 1])
XCTAssertEqual(fixture.viewModel.visibleItems.count, 8)
XCTAssertEqual(ClipboardSortMode.allCases.map { fixture.viewModel.collectionCount(for: $0) }, [8, 8, 3, 1, 1, 1, 1, 1, 1, 1])
XCTAssertEqual(fixture.view.debugCollectionCounts, [8, 8, 3, 1, 1, 1, 1, 1, 1, 1])
XCTAssertEqual(fixture.view.debugCollectionCountLabelHiddenStates, Array(repeating: false, count: ClipboardSortMode.allCases.count))
}
@@ -1334,6 +1340,29 @@ final class ClipboardPanelViewTests: XCTestCase {
XCTAssertEqual(fixture.view.debugCardPreviewStyles, ["color-preview"])
}
func testCodeCardsUseMonospaceSnippetPreview() {
let fixture = makePanelFixture()
let item = makeItem(
kind: .code,
displayText: "Swift Snippet",
payload: "func greet(name: String) -> String {\n return \"Hi \\(name)\"\n}",
store: fixture.store
)
fixture.store.upsert(item)
fixture.viewModel.sortMode = .code
drainMainQueue()
fixture.window.contentView?.layoutSubtreeIfNeeded()
XCTAssertEqual(fixture.view.debugCardAccessibilityLabels, ["Code: Swift Snippet"])
XCTAssertEqual(
fixture.view.debugCardPreviewSummaries,
["Swift Snippet|func greet(name: String) -> String { return \"Hi \\(name)\" }|Swift"]
)
XCTAssertEqual(fixture.view.debugCardPreviewStyles, ["code-preview"])
XCTAssertEqual(fixture.view.debugFirstCardVisibleActionLabels, ["Paste", "Copy", "Pin", "Collect", "Edit", "Preview", "Delete"])
}
private func makePanelWithPanelView() -> (NSWindow, ClipboardPanelView) {
let fixture = makePanelFixture()
return (fixture.window, fixture.view)

View File

@@ -32,6 +32,27 @@ final class PasteActionServiceTests: XCTestCase {
XCTAssertEqual(NSPasteboard.general.string(forType: .string), "Hello")
}
func testCopyWritesCodeSnippetAsPlainString() {
let service = PasteActionService()
let snippet = "func greet(name: String) -> String {\n return \"Hi \\(name)\"\n}"
let item = ClipboardItem(
id: UUID(),
kind: .code,
displayText: "Swift Snippet",
payload: snippet,
payloadHash: "hash",
createdAt: Date(),
lastUsedAt: Date(),
useCount: 0,
sourceApp: "Xcode",
imagePath: nil,
thumbnailPath: nil
)
XCTAssertEqual(service.copy(item), .copied)
XCTAssertEqual(NSPasteboard.general.string(forType: .string), snippet)
}
func testPasteboardWritersExposeTextForDragOut() {
let service = PasteActionService()
let item = ClipboardItem(