import Foundation import SuggestionBasic public struct PostProcessingSuggestionServiceMiddleware: SuggestionServiceMiddleware { public init() {} public func getSuggestion( _ request: SuggestionRequest, configuration: SuggestionServiceConfiguration, next: Next ) async throws -> [CodeSuggestion] { let suggestions = try await next(request) return suggestions.compactMap { var suggestion = $0 if suggestion.text.allSatisfy({ $0.isWhitespace || $0.isNewline }) { return nil } Self.removeTrailingWhitespacesAndNewlines(&suggestion) if !Self.checkIfSuggestionHasNoEffect(suggestion, request: request) { return nil } return suggestion } } public func getNESSuggestion( _ request: SuggestionRequest, configuration: SuggestionServiceConfiguration, next: Next ) async throws -> [CodeSuggestion] { let suggestions = try await next(request) return suggestions.compactMap { var suggestion = $0 if suggestion.text.allSatisfy({ $0.isWhitespace || $0.isNewline }) { return nil } Self.removeTrailingWhitespacesAndNewlines(&suggestion) // TODO: If need to check? // if !Self.checkIfSuggestionHasNoEffect(suggestion, request: request) { return nil } return suggestion } } static func removeTrailingWhitespacesAndNewlines(_ suggestion: inout CodeSuggestion) { var text = suggestion.text[...] while let last = text.last, last.isNewline || last.isWhitespace { text = text.dropLast(1) } suggestion.text = String(text) } static func checkIfSuggestionHasNoEffect( _ suggestion: CodeSuggestion, request: SuggestionRequest ) -> Bool { // We only check suggestions that are on a single line. if suggestion.range.isOneLine { let line = suggestion.range.start.line if line >= 0, line < request.lines.count { let replacingText = request.lines[line] let start = suggestion.range.start.character let end = suggestion.range.end.character if let endIndex = replacingText.utf16.index( replacingText.startIndex, offsetBy: end, limitedBy: replacingText.endIndex ), let startIndex = replacingText.utf16.index( replacingText.startIndex, offsetBy: start, limitedBy: endIndex ), startIndex < endIndex { let replacingRange = startIndex..