-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
2,893 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import Cocoa | ||
|
||
var urlStrings = [ | ||
"string", | ||
"www.example.com/host", | ||
"www.example.com/pathwith?[];/test?query=s" | ||
] | ||
|
||
var urls = urlStrings | ||
.map { | ||
URL(string: $0) | ||
} | ||
|
||
print(urls) | ||
|
||
let cs = URLComponents(string: urlStrings[2]) | ||
|
||
print(cs) | ||
|
||
extension CharacterSet { | ||
var characters: Set<String> { | ||
(self as NSCharacterSet).characters | ||
} | ||
} | ||
|
||
|
||
extension NSCharacterSet { | ||
|
||
var characters: Set<String> { | ||
/// An array to hold all the found characters | ||
var characters: Set<String> = [] | ||
|
||
/// Iterate over the 17 Unicode planes (0..16) | ||
for plane:UInt8 in 0..<17 { | ||
/// Iterating over all potential code points of each plane could be expensive as | ||
/// there can be as many as 2^16 code points per plane. Therefore, only search | ||
/// through a plane that has a character within the set. | ||
if self.hasMemberInPlane(plane) { | ||
|
||
/// Define the lower end of the plane (i.e. U+FFFF for beginning of Plane 0) | ||
let planeStart = UInt32(plane) << 16 | ||
/// Define the lower end of the next plane (i.e. U+1FFFF for beginning of | ||
/// Plane 1) | ||
let nextPlaneStart = (UInt32(plane) + 1) << 16 | ||
|
||
/// Iterate over all possible UTF32 characters from the beginning of the | ||
/// current plane until the next plane. | ||
for char: UTF32Char in planeStart..<nextPlaneStart { | ||
|
||
/// Test if the character being iterated over is part of this | ||
/// `NSCharacterSet` | ||
if self.longCharacterIsMember(char) { | ||
|
||
/// Convert `UTF32Char` (a typealiased `UInt32`) into a | ||
/// `UnicodeScalar`. Otherwise, converting `UTF32Char` directly | ||
/// to `String` would turn it into a decimal representation of | ||
/// the code point, not the character. | ||
if let unicodeCharacter = UnicodeScalar(char) { | ||
characters.insert(String(unicodeCharacter)) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
return characters | ||
} | ||
} | ||
|
||
let urlHostAllowed = CharacterSet.urlHostAllowed.characters | ||
let urlPathAllowed = CharacterSet.urlPathAllowed.characters | ||
let urlQueryAllowed = CharacterSet.urlQueryAllowed.characters | ||
let urlFragmentAllowed = CharacterSet.urlFragmentAllowed.characters | ||
|
||
let allowedInAll = [urlPathAllowed, urlQueryAllowed, urlFragmentAllowed].reduce(urlHostAllowed) { $0.intersection($1) } | ||
let allowedInOne = [urlPathAllowed, urlQueryAllowed, urlFragmentAllowed].reduce(urlHostAllowed) { $0.union($1) } | ||
|
||
print("Allowed in all") | ||
print(allowedInAll.sorted().joined(separator: ", ")) | ||
|
||
print("Allowed in host") | ||
print(urlHostAllowed.subtracting(allowedInAll).sorted()) | ||
|
||
print("Allowed in path") | ||
print(urlPathAllowed.subtracting(allowedInAll).sorted()) | ||
|
||
print("Allowed in query") | ||
print(urlQueryAllowed.subtracting(allowedInAll).sorted()) | ||
|
||
print("Allowed in host") | ||
print(urlFragmentAllowed.subtracting(allowedInAll).sorted()) | ||
|
||
print("Not allowed in host") | ||
print(allowedInOne.subtracting(urlHostAllowed).sorted()) | ||
|
||
print("Not allowed in path") | ||
print(allowedInOne.subtracting(urlPathAllowed).sorted()) | ||
|
||
print("Not allowed in query") | ||
print(allowedInOne.subtracting(urlQueryAllowed).sorted()) | ||
|
||
print("Not allowed in host") | ||
print(allowedInOne.subtracting(urlFragmentAllowed).sorted()) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='macos' buildActiveScheme='true'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// Collection+FoundationalHelpers.swift | ||
// XcodeUniversalSearch | ||
// | ||
// Created by Sam Miller on 11/3/20. | ||
// | ||
|
||
import Foundation | ||
|
||
extension Collection { | ||
subscript (safe index: Index) -> Element? { | ||
indices.contains(index) ? self[index] : nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// | ||
// Configuration.swift | ||
// XcodeUniversalSearch | ||
// | ||
// Created by Sam Miller on 11/3/20. | ||
// | ||
|
||
import Foundation | ||
|
||
struct Configuration: Codable { | ||
|
||
struct Command: Codable { | ||
struct Options: Codable { | ||
let shouldEscapeForRegex: Bool | ||
let shouldEscapeDoubleQuotes: Bool | ||
|
||
static var `default`: Self { | ||
.init(shouldEscapeForRegex: false, shouldEscapeDoubleQuotes: false) | ||
} | ||
} | ||
|
||
let name: String | ||
let urlTemplate: String | ||
let options: Options | ||
} | ||
|
||
let commands: [Command] | ||
} | ||
|
||
final class ConfigurationManager { | ||
|
||
enum Result { | ||
case success(_ configuration: Configuration?) | ||
case error(_ error: Error) | ||
|
||
var data: Configuration? { | ||
switch self { | ||
case .success(let configuration): return configuration | ||
case .error(_): return nil | ||
} | ||
} | ||
} | ||
|
||
init?() { | ||
guard let userDefaults = UserDefaults(suiteName: "M952V223C9.group.com.pandaprograms.XcodeUniversalSearch") else { | ||
return nil | ||
} | ||
self.userDefaults = userDefaults | ||
} | ||
|
||
func load() -> Result { | ||
let storedData = userDefaults.data(forKey: StorageKey.configuration.rawValue) | ||
guard let data = storedData else { | ||
return .success(nil) | ||
} | ||
|
||
do { | ||
return .success(try Self.decoder.decode(Configuration.self, from: data)) | ||
} catch { | ||
return .error(error) | ||
} | ||
} | ||
|
||
func save(_ configuration: Configuration) -> Bool { | ||
guard let data = try? Self.encoder.encode(configuration) else { | ||
return false | ||
} | ||
|
||
userDefaults.set(data, forKey: StorageKey.configuration.rawValue) | ||
return true | ||
} | ||
|
||
func clearStorage() { | ||
userDefaults.removeObject(forKey: StorageKey.configuration.rawValue) | ||
} | ||
|
||
// MARK: - Private | ||
|
||
private enum StorageKey: String { | ||
case configuration | ||
} | ||
|
||
private let userDefaults: UserDefaults | ||
|
||
private static let decoder = JSONDecoder() | ||
private static let encoder = JSONEncoder() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// String+FoundationalHelpers.swift | ||
// XcodeUniversalSearch | ||
// | ||
// Created by Sam Miller on 11/3/20. | ||
// | ||
|
||
import Foundation | ||
|
||
extension String { | ||
subscript (_ range: Range<Int>) -> Substring { | ||
let start = index(startIndex, offsetBy: range.startIndex) | ||
let end = index(startIndex, offsetBy: range.startIndex + range.count) | ||
return self[start..<end] | ||
} | ||
} |
Oops, something went wrong.