1import Cocoa
2
3// Compilation: swiftc spellcheck.swift -o spellcheck
4// Usage: ./spellcheck "Your text with typos here"
5
6struct Misspelling: Codable {
7 let word: String
8 let suggestions: [String]
9 let range: [Int] // [location, length]
10}
11
12func checkSpelling(text: String) {
13 let spellChecker = NSSpellChecker.shared
14 let range = NSRange(location: 0, length: text.utf16.count)
15 var misspellings: [Misspelling] = []
16
17 var offset = 0
18 while offset < range.length {
19 let currentRange = NSRange(location: offset, length: range.length - offset)
20 let misspelledRange = spellChecker.checkSpelling(of: text, startingAt: currentRange.location)
21
22 if misspelledRange.location == NSNotFound || misspelledRange.length == 0 {
23 break
24 }
25
26 let word = (text as NSString).substring(with: misspelledRange)
27 let suggestions = spellChecker.guesses(forWordRange: misspelledRange, in: text, language: nil, inSpellDocumentWithTag: 0) ?? []
28
29 misspellings.append(Misspelling(
30 word: word,
31 suggestions: Array(suggestions.prefix(3)), // Top 3 suggestions
32 range: [misspelledRange.location, misspelledRange.length]
33 ))
34
35 offset = misspelledRange.location + misspelledRange.length
36 }
37
38 let encoder = JSONEncoder()
39 if let data = try? encoder.encode(misspellings),
40 let jsonString = String(data: data, encoding: .utf8) {
41 print(jsonString)
42 }
43}
44
45let args = ProcessInfo.processInfo.arguments
46if args.count > 1 {
47 checkSpelling(text: args[1])
48} else {
49 // Read from stdin if no arg provided
50 let input = FileHandle.standardInput.readDataToEndOfFile()
51 if let text = String(data: input, encoding: .utf8) {
52 checkSpelling(text: text)
53 }
54}