40 lines
1.1 KiB
Swift
40 lines
1.1 KiB
Swift
import Foundation
|
|
|
|
public typealias PasteboardItem = [String: Data]
|
|
|
|
public protocol PasteboardProviding {
|
|
func readItems() -> [PasteboardItem]
|
|
func writeString(_ text: String)
|
|
func writeItems(_ items: [PasteboardItem])
|
|
}
|
|
|
|
public protocol KeystrokePosting {
|
|
func postPaste() throws
|
|
}
|
|
|
|
public struct TextInserter: TextInserting {
|
|
private let pasteboard: PasteboardProviding
|
|
private let paster: KeystrokePosting
|
|
private let restoreDelay: Duration
|
|
|
|
public init(
|
|
pasteboard: PasteboardProviding,
|
|
paster: KeystrokePosting,
|
|
restoreDelay: Duration = .milliseconds(150)
|
|
) {
|
|
self.pasteboard = pasteboard
|
|
self.paster = paster
|
|
self.restoreDelay = restoreDelay
|
|
}
|
|
|
|
public func insert(_ text: String) async throws {
|
|
let saved = pasteboard.readItems()
|
|
pasteboard.writeString(text)
|
|
// On failure the text deliberately stays on the clipboard.
|
|
try paster.postPaste()
|
|
// Give the target app time to read the clipboard before restoring it.
|
|
try await Task.sleep(for: restoreDelay)
|
|
pasteboard.writeItems(saved)
|
|
}
|
|
}
|