-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspellcheck
executable file
·97 lines (71 loc) · 2.67 KB
/
spellcheck
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env swift
//
// All Contributions by Match Group
//
// Copyright © 2025 Tinder (Match Group, LLC)
//
// Licensed under the Match Group Modified 3-Clause BSD License.
// See https://github.com/Tinder/spellcheck-cli/blob/main/LICENSE for license information.
//
import AppKit
let arguments: [String] = CommandLine.arguments
let spellChecker: NSSpellChecker = .shared
if arguments.contains("-h") || arguments.contains("--help") {
print("Available Languages:")
print(spellChecker.availableLanguages.joined(separator: "\n"))
exit(EXIT_SUCCESS)
}
let json: Bool = arguments.contains("--json")
let language: String?
if let index: Int = arguments.firstIndex(of: "--language"), index < arguments.count - 1 {
language = arguments[index + 1]
} else {
language = ProcessInfo.processInfo.environment["SPELLCHECK_CLI_LANGUAGE"]
}
struct MisspelledWord: Codable {
let word: String
let guesses: [String]
}
func readStandardInput() -> String {
var input: String = ""
while let line: String = readLine(strippingNewline: false) {
input.append(line)
}
return input
}
func misspelledWords(in text: String) -> [MisspelledWord] {
_ = language.flatMap(spellChecker.setLanguage)
var misspelledWords: [MisspelledWord] = []
var location: Int = 0
while location < NSMaxRange(NSRange(text.startIndex..., in: text)) {
let range: NSRange = spellChecker.checkSpelling(of: text, startingAt: location)
guard range.location != NSNotFound,
range.location >= location
else { break }
let guesses: [String] = spellChecker.guesses(forWordRange: range,
in: text,
language: nil,
inSpellDocumentWithTag: 0) ?? []
if let range: Range = .init(range, in: text) {
let misspelledWord: MisspelledWord = .init(word: String(text[range]),
guesses: guesses)
misspelledWords.append(misspelledWord)
}
location = NSMaxRange(range)
}
return misspelledWords
}
let misspelledWords: [MisspelledWord] = misspelledWords(in: readStandardInput())
if json {
let data: Data = try JSONEncoder().encode(misspelledWords)
print(String(decoding: data, as: UTF8.self))
exit(EXIT_SUCCESS)
}
for misspelledWord in misspelledWords {
misspelledWord.guesses.isEmpty
? print(misspelledWord.word)
: print(misspelledWord.word, "->", misspelledWord.guesses.joined(separator: " "))
}
misspelledWords.isEmpty
? exit(EXIT_SUCCESS)
: exit(EXIT_FAILURE)