@@ -137,6 +137,55 @@ struct CheckString {
137137 }
138138 }
139139 }
140+
141+ var NumLinesForward = 0
142+ var BestLine : Int ? = nil
143+ var BestQuality = 0.0
144+
145+ for i in 0 ..< min ( buffer. count, 4096 ) {
146+ let exampleString : String
147+ if pattern. fixedString. isEmpty {
148+ exampleString = pattern. regExPattern
149+ } else {
150+ exampleString = pattern. fixedString
151+ }
152+
153+ if exampleString. isEmpty {
154+ break
155+ }
156+
157+ let char = buffer [ buffer. index ( buffer. startIndex, offsetBy: i) ]
158+ if char == " \n " {
159+ NumLinesForward += 1
160+ }
161+
162+ // Patterns have leading whitespace stripped, so skip whitespace when
163+ // looking for something which looks like a pattern.
164+ if char == " " || char == " \t " {
165+ continue ;
166+ }
167+
168+ // Compute the "quality" of this match as an arbitrary combination of
169+ // the match distance and the number of lines skipped to get to this
170+ // match.
171+ let distance = editDistance ( from: Array ( buffer. characters) , to: Array ( exampleString. characters) )
172+ let quality = Double ( distance) + ( Double ( NumLinesForward) / 100.0 )
173+ if quality < BestQuality || BestLine == nil {
174+ BestLine = i
175+ BestQuality = quality
176+ }
177+ }
178+
179+ if let Best = BestLine, BestQuality < 50 {
180+ buffer. utf8CString. withUnsafeBufferPointer { buf in
181+ let otherPatternLoc = CheckLoc . inBuffer (
182+ buf. baseAddress!. advanced ( by: Best) ,
183+ UnsafeBufferPointer ( rebasing: buf. suffix ( from: Best) )
184+ )
185+ diagnose ( . note, at: otherPatternLoc, with: " possible intended match here " , options: options)
186+ }
187+ }
188+
140189 return nil
141190 }
142191 let ( matchPos, matchLen) = ( range. location, range. length)
0 commit comments