├── .gitignore ├── LICENSE ├── README.md ├── Regxr.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── WorkspaceSettings.xcsettings ├── Regxr ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon-1024.png │ │ ├── icon-128.png │ │ ├── icon-16.png │ │ ├── icon-256.png │ │ ├── icon-32.png │ │ ├── icon-512.png │ │ └── icon-64.png │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist ├── PreferencesViewController.swift ├── PreferencesWindowController.swift ├── RegexHighlighter.swift ├── RegexViewController.swift ├── SidebarViewController.swift └── WindowController.swift └── reference.html /.gitignore: -------------------------------------------------------------------------------- 1 | Regxr.xcodeproj/xcuserdata 2 | Regxr.xcodeproj/project.xcworkspace/xcuserdata -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Regxr 2 | 3 | Regxr is a minimal, lightweight and beautiful MacOS desktop application that allows for easy checking of regular expression pattern matching. 4 | 5 | ### Features 6 | - Syntax highlighting 7 | - Dark and light modes 8 | - Minimal and simple to use 9 | - Live preview of multiple pattern matches 10 | - Full screeen support 11 | - Reference manual 12 | 13 | ### Download 14 | 15 | Visit [lukakerr.github.io](https://lukakerr.github.io/projects/regxr.html) to download 16 | 17 | I have also developed a [menubar application](https://github.com/lukakerr/regxr-menubar) that does the same thing, but lives in the menubar. 18 | 19 |

20 | regxr1 21 |

22 | 23 |

24 | regxr2 25 |

26 | 27 |

28 | regxr3 29 |

30 | 31 |

32 | regxr4 33 |

34 | -------------------------------------------------------------------------------- /Regxr.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A110F90D1F78ADC700675ED7 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A110F90B1F78ADC700675ED7 /* PreferencesViewController.swift */; }; 11 | A110F90E1F78ADC700675ED7 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A110F90C1F78ADC700675ED7 /* PreferencesWindowController.swift */; }; 12 | A11AC46B1F77C8A800094AE6 /* SidebarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A11AC46A1F77C8A800094AE6 /* SidebarViewController.swift */; }; 13 | A13944021F77D30D0022A176 /* reference.html in Resources */ = {isa = PBXBuildFile; fileRef = A13944011F77D30D0022A176 /* reference.html */; }; 14 | A19C347D1F76182E00BA7FC3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19C347C1F76182E00BA7FC3 /* AppDelegate.swift */; }; 15 | A19C347F1F76182E00BA7FC3 /* RegexViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19C347E1F76182E00BA7FC3 /* RegexViewController.swift */; }; 16 | A19C34841F76182E00BA7FC3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A19C34821F76182E00BA7FC3 /* Main.storyboard */; }; 17 | A1A133AD1F830FBD0072CB58 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1A133AC1F830FBD0072CB58 /* Assets.xcassets */; }; 18 | A1B787301F77AA2700F6C5DF /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B7872F1F77AA2700F6C5DF /* WindowController.swift */; }; 19 | A1FDFEEA1F78CEA300B2DABD /* RegexHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FDFEE91F78CEA300B2DABD /* RegexHighlighter.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | A110F90B1F78ADC700675ED7 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = ""; }; 24 | A110F90C1F78ADC700675ED7 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; 25 | A11AC46A1F77C8A800094AE6 /* SidebarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewController.swift; sourceTree = ""; }; 26 | A13944011F77D30D0022A176 /* reference.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = reference.html; sourceTree = ""; }; 27 | A19C34791F76182E00BA7FC3 /* Regxr.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Regxr.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | A19C347C1F76182E00BA7FC3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 29 | A19C347E1F76182E00BA7FC3 /* RegexViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexViewController.swift; sourceTree = ""; }; 30 | A19C34831F76182E00BA7FC3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 31 | A19C34851F76182E00BA7FC3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | A1A133AC1F830FBD0072CB58 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 33 | A1B7872F1F77AA2700F6C5DF /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; 34 | A1FDFEE91F78CEA300B2DABD /* RegexHighlighter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegexHighlighter.swift; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | A19C34761F76182E00BA7FC3 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | A19C34701F76182E00BA7FC3 = { 49 | isa = PBXGroup; 50 | children = ( 51 | A13944011F77D30D0022A176 /* reference.html */, 52 | A19C347B1F76182E00BA7FC3 /* Regxr */, 53 | A19C347A1F76182E00BA7FC3 /* Products */, 54 | ); 55 | sourceTree = ""; 56 | }; 57 | A19C347A1F76182E00BA7FC3 /* Products */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | A19C34791F76182E00BA7FC3 /* Regxr.app */, 61 | ); 62 | name = Products; 63 | sourceTree = ""; 64 | }; 65 | A19C347B1F76182E00BA7FC3 /* Regxr */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | A1B7872F1F77AA2700F6C5DF /* WindowController.swift */, 69 | A19C347C1F76182E00BA7FC3 /* AppDelegate.swift */, 70 | A19C347E1F76182E00BA7FC3 /* RegexViewController.swift */, 71 | A1FDFEE91F78CEA300B2DABD /* RegexHighlighter.swift */, 72 | A19C34821F76182E00BA7FC3 /* Main.storyboard */, 73 | A19C34851F76182E00BA7FC3 /* Info.plist */, 74 | A110F90B1F78ADC700675ED7 /* PreferencesViewController.swift */, 75 | A110F90C1F78ADC700675ED7 /* PreferencesWindowController.swift */, 76 | A11AC46A1F77C8A800094AE6 /* SidebarViewController.swift */, 77 | A1A133AC1F830FBD0072CB58 /* Assets.xcassets */, 78 | ); 79 | path = Regxr; 80 | sourceTree = ""; 81 | }; 82 | /* End PBXGroup section */ 83 | 84 | /* Begin PBXNativeTarget section */ 85 | A19C34781F76182E00BA7FC3 /* Regxr */ = { 86 | isa = PBXNativeTarget; 87 | buildConfigurationList = A19C34891F76182E00BA7FC3 /* Build configuration list for PBXNativeTarget "Regxr" */; 88 | buildPhases = ( 89 | A19C34751F76182E00BA7FC3 /* Sources */, 90 | A19C34761F76182E00BA7FC3 /* Frameworks */, 91 | A19C34771F76182E00BA7FC3 /* Resources */, 92 | ); 93 | buildRules = ( 94 | ); 95 | dependencies = ( 96 | ); 97 | name = Regxr; 98 | productName = Minimal; 99 | productReference = A19C34791F76182E00BA7FC3 /* Regxr.app */; 100 | productType = "com.apple.product-type.application"; 101 | }; 102 | /* End PBXNativeTarget section */ 103 | 104 | /* Begin PBXProject section */ 105 | A19C34711F76182E00BA7FC3 /* Project object */ = { 106 | isa = PBXProject; 107 | attributes = { 108 | LastSwiftUpdateCheck = 0900; 109 | LastUpgradeCheck = 0900; 110 | ORGANIZATIONNAME = "Luka Kerr"; 111 | TargetAttributes = { 112 | A19C34781F76182E00BA7FC3 = { 113 | CreatedOnToolsVersion = 9.0; 114 | ProvisioningStyle = Manual; 115 | }; 116 | }; 117 | }; 118 | buildConfigurationList = A19C34741F76182E00BA7FC3 /* Build configuration list for PBXProject "Regxr" */; 119 | compatibilityVersion = "Xcode 8.0"; 120 | developmentRegion = en; 121 | hasScannedForEncodings = 0; 122 | knownRegions = ( 123 | en, 124 | Base, 125 | ); 126 | mainGroup = A19C34701F76182E00BA7FC3; 127 | productRefGroup = A19C347A1F76182E00BA7FC3 /* Products */; 128 | projectDirPath = ""; 129 | projectRoot = ""; 130 | targets = ( 131 | A19C34781F76182E00BA7FC3 /* Regxr */, 132 | ); 133 | }; 134 | /* End PBXProject section */ 135 | 136 | /* Begin PBXResourcesBuildPhase section */ 137 | A19C34771F76182E00BA7FC3 /* Resources */ = { 138 | isa = PBXResourcesBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | A13944021F77D30D0022A176 /* reference.html in Resources */, 142 | A1A133AD1F830FBD0072CB58 /* Assets.xcassets in Resources */, 143 | A19C34841F76182E00BA7FC3 /* Main.storyboard in Resources */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXResourcesBuildPhase section */ 148 | 149 | /* Begin PBXSourcesBuildPhase section */ 150 | A19C34751F76182E00BA7FC3 /* Sources */ = { 151 | isa = PBXSourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | A110F90E1F78ADC700675ED7 /* PreferencesWindowController.swift in Sources */, 155 | A110F90D1F78ADC700675ED7 /* PreferencesViewController.swift in Sources */, 156 | A1FDFEEA1F78CEA300B2DABD /* RegexHighlighter.swift in Sources */, 157 | A19C347F1F76182E00BA7FC3 /* RegexViewController.swift in Sources */, 158 | A1B787301F77AA2700F6C5DF /* WindowController.swift in Sources */, 159 | A19C347D1F76182E00BA7FC3 /* AppDelegate.swift in Sources */, 160 | A11AC46B1F77C8A800094AE6 /* SidebarViewController.swift in Sources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXSourcesBuildPhase section */ 165 | 166 | /* Begin PBXVariantGroup section */ 167 | A19C34821F76182E00BA7FC3 /* Main.storyboard */ = { 168 | isa = PBXVariantGroup; 169 | children = ( 170 | A19C34831F76182E00BA7FC3 /* Base */, 171 | ); 172 | name = Main.storyboard; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXVariantGroup section */ 176 | 177 | /* Begin XCBuildConfiguration section */ 178 | A19C34871F76182E00BA7FC3 /* Debug */ = { 179 | isa = XCBuildConfiguration; 180 | buildSettings = { 181 | ALWAYS_SEARCH_USER_PATHS = NO; 182 | CLANG_ANALYZER_NONNULL = YES; 183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 185 | CLANG_CXX_LIBRARY = "libc++"; 186 | CLANG_ENABLE_MODULES = YES; 187 | CLANG_ENABLE_OBJC_ARC = YES; 188 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_COMMA = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 193 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 194 | CLANG_WARN_EMPTY_BODY = YES; 195 | CLANG_WARN_ENUM_CONVERSION = YES; 196 | CLANG_WARN_INFINITE_RECURSION = YES; 197 | CLANG_WARN_INT_CONVERSION = YES; 198 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 199 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 200 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 201 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 202 | CLANG_WARN_STRICT_PROTOTYPES = YES; 203 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 204 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 205 | CLANG_WARN_UNREACHABLE_CODE = YES; 206 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 207 | CODE_SIGN_IDENTITY = "Mac Developer"; 208 | COPY_PHASE_STRIP = NO; 209 | DEBUG_INFORMATION_FORMAT = dwarf; 210 | ENABLE_STRICT_OBJC_MSGSEND = YES; 211 | ENABLE_TESTABILITY = YES; 212 | GCC_C_LANGUAGE_STANDARD = gnu11; 213 | GCC_DYNAMIC_NO_PIC = NO; 214 | GCC_NO_COMMON_BLOCKS = YES; 215 | GCC_OPTIMIZATION_LEVEL = 0; 216 | GCC_PREPROCESSOR_DEFINITIONS = ( 217 | "DEBUG=1", 218 | "$(inherited)", 219 | ); 220 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 221 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 222 | GCC_WARN_UNDECLARED_SELECTOR = YES; 223 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 224 | GCC_WARN_UNUSED_FUNCTION = YES; 225 | GCC_WARN_UNUSED_VARIABLE = YES; 226 | MACOSX_DEPLOYMENT_TARGET = 10.12; 227 | MTL_ENABLE_DEBUG_INFO = YES; 228 | ONLY_ACTIVE_ARCH = YES; 229 | SDKROOT = macosx; 230 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 231 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 232 | }; 233 | name = Debug; 234 | }; 235 | A19C34881F76182E00BA7FC3 /* Release */ = { 236 | isa = XCBuildConfiguration; 237 | buildSettings = { 238 | ALWAYS_SEARCH_USER_PATHS = NO; 239 | CLANG_ANALYZER_NONNULL = YES; 240 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 242 | CLANG_CXX_LIBRARY = "libc++"; 243 | CLANG_ENABLE_MODULES = YES; 244 | CLANG_ENABLE_OBJC_ARC = YES; 245 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 246 | CLANG_WARN_BOOL_CONVERSION = YES; 247 | CLANG_WARN_COMMA = YES; 248 | CLANG_WARN_CONSTANT_CONVERSION = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INFINITE_RECURSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 259 | CLANG_WARN_STRICT_PROTOTYPES = YES; 260 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "Mac Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu11; 270 | GCC_NO_COMMON_BLOCKS = YES; 271 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 272 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 273 | GCC_WARN_UNDECLARED_SELECTOR = YES; 274 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 275 | GCC_WARN_UNUSED_FUNCTION = YES; 276 | GCC_WARN_UNUSED_VARIABLE = YES; 277 | MACOSX_DEPLOYMENT_TARGET = 10.12; 278 | MTL_ENABLE_DEBUG_INFO = NO; 279 | SDKROOT = macosx; 280 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 281 | }; 282 | name = Release; 283 | }; 284 | A19C348A1F76182E00BA7FC3 /* Debug */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 288 | CODE_SIGN_IDENTITY = ""; 289 | CODE_SIGN_STYLE = Manual; 290 | COMBINE_HIDPI_IMAGES = YES; 291 | DEVELOPMENT_TEAM = QY544RDL2W; 292 | INFOPLIST_FILE = Regxr/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 294 | MACOSX_DEPLOYMENT_TARGET = 10.11; 295 | PRODUCT_BUNDLE_IDENTIFIER = com.lukakerr.regxr; 296 | PRODUCT_NAME = "$(TARGET_NAME)"; 297 | PROVISIONING_PROFILE_SPECIFIER = ""; 298 | SWIFT_VERSION = 4.0; 299 | }; 300 | name = Debug; 301 | }; 302 | A19C348B1F76182E00BA7FC3 /* Release */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 306 | CODE_SIGN_IDENTITY = ""; 307 | CODE_SIGN_STYLE = Manual; 308 | COMBINE_HIDPI_IMAGES = YES; 309 | DEVELOPMENT_TEAM = QY544RDL2W; 310 | INFOPLIST_FILE = Regxr/Info.plist; 311 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 312 | MACOSX_DEPLOYMENT_TARGET = 10.11; 313 | PRODUCT_BUNDLE_IDENTIFIER = com.lukakerr.regxr; 314 | PRODUCT_NAME = "$(TARGET_NAME)"; 315 | PROVISIONING_PROFILE_SPECIFIER = ""; 316 | SWIFT_VERSION = 4.0; 317 | }; 318 | name = Release; 319 | }; 320 | /* End XCBuildConfiguration section */ 321 | 322 | /* Begin XCConfigurationList section */ 323 | A19C34741F76182E00BA7FC3 /* Build configuration list for PBXProject "Regxr" */ = { 324 | isa = XCConfigurationList; 325 | buildConfigurations = ( 326 | A19C34871F76182E00BA7FC3 /* Debug */, 327 | A19C34881F76182E00BA7FC3 /* Release */, 328 | ); 329 | defaultConfigurationIsVisible = 0; 330 | defaultConfigurationName = Release; 331 | }; 332 | A19C34891F76182E00BA7FC3 /* Build configuration list for PBXNativeTarget "Regxr" */ = { 333 | isa = XCConfigurationList; 334 | buildConfigurations = ( 335 | A19C348A1F76182E00BA7FC3 /* Debug */, 336 | A19C348B1F76182E00BA7FC3 /* Release */, 337 | ); 338 | defaultConfigurationIsVisible = 0; 339 | defaultConfigurationName = Release; 340 | }; 341 | /* End XCConfigurationList section */ 342 | }; 343 | rootObject = A19C34711F76182E00BA7FC3 /* Project object */; 344 | } 345 | -------------------------------------------------------------------------------- /Regxr.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Regxr.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Latest 7 | 8 | 9 | -------------------------------------------------------------------------------- /Regxr/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 23/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { 13 | 14 | let defaults = UserDefaults.standard 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Main window 18 | let window = NSApplication.shared.windows.first! 19 | 20 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 21 | 22 | if (theme == "Light") { 23 | window.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight) 24 | } else { 25 | window.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark) 26 | } 27 | 28 | // Title bar properties 29 | window.titleVisibility = NSWindow.TitleVisibility.hidden; 30 | window.titlebarAppearsTransparent = true; 31 | window.styleMask.insert(.fullSizeContentView) 32 | window.isOpaque = false 33 | window.invalidateShadow() 34 | } 35 | 36 | func applicationWillTerminate(_ aNotification: Notification) { 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon-32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon-64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon-256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon-512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon-512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon-1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-128.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-16.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-256.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-32.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-512.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/AppIcon.appiconset/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikishorek/regxr/d4ff8fe2edf5629c5916c943cc2d259267f0a1b1/Regxr/Assets.xcassets/AppIcon.appiconset/icon-64.png -------------------------------------------------------------------------------- /Regxr/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Regxr/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 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 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | -------------------------------------------------------------------------------- /Regxr/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleVersion 20 | 1 21 | LSApplicationCategoryType 22 | public.app-category.developer-tools 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Luka Kerr. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Regxr/PreferencesViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesViewController.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 25/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class PreferencesViewController: NSViewController { 12 | 13 | @IBOutlet weak var themeButton: NSSegmentedControl! 14 | @IBOutlet weak var referencesManualCheckbox: NSButton! 15 | 16 | let defaults = UserDefaults.standard 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 22 | 23 | switch theme { 24 | case "Light": 25 | themeButton.selectedSegment = 0 26 | default: 27 | themeButton.selectedSegment = 1 28 | } 29 | 30 | let showReferenceOnStartup = defaults.bool(forKey: "showReference") 31 | referencesManualCheckbox.state = showReferenceOnStartup ? .on : .off 32 | } 33 | 34 | var wc = WindowController() 35 | 36 | @IBAction func themeChanged(_ sender: NSSegmentedControl) { 37 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 38 | var chosenTheme = theme 39 | 40 | if (sender.selectedSegment == 0) { 41 | // Light theme chosen 42 | chosenTheme = "Light" 43 | self.view.window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight) 44 | } else { 45 | chosenTheme = "Dark" 46 | self.view.window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark) 47 | } 48 | wc.setWindowColor(theme: chosenTheme) 49 | 50 | NotificationCenter.default.post( 51 | name: NSNotification.Name(rawValue: "changeThemeNotification"), 52 | object: chosenTheme 53 | ) 54 | 55 | defaults.setValue(chosenTheme, forKey: "theme") 56 | } 57 | 58 | @IBAction func referenceManualChecked(_ sender: NSButton) { 59 | var show : Bool 60 | if (sender.state.rawValue == 0) { 61 | show = false 62 | } else { 63 | show = true 64 | } 65 | defaults.setValue(show, forKey: "showReference") 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Regxr/PreferencesWindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PreferencesWindowController.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 25/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class PreferencesWindowController: NSWindowController, NSWindowDelegate { 12 | 13 | let defaults = UserDefaults.standard 14 | 15 | override func windowDidLoad() { 16 | super.windowDidLoad() 17 | 18 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 19 | 20 | if let window = window { 21 | if (theme == "Light") { 22 | window.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight) 23 | } else { 24 | window.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark) 25 | } 26 | window.titleVisibility = NSWindow.TitleVisibility.hidden; 27 | window.titlebarAppearsTransparent = true; 28 | window.styleMask.insert(.fullSizeContentView) 29 | window.isOpaque = false 30 | window.invalidateShadow() 31 | window.center() 32 | window.makeKeyAndOrderFront(nil) 33 | } 34 | 35 | NSApp.activate(ignoringOtherApps: true) 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Regxr/RegexHighlighter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RegexHighlighter.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 25/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class RegexHighlighter { 12 | func highlight(string: String, theme: String) -> NSMutableAttributedString { 13 | let purpleFoundMatches = matches( 14 | for: "\\(|\\)|\\?|\\+|\\*|\\^|\\{|\\}|\\||\\.|\\^|\\$|\\\\", 15 | in: string 16 | ) 17 | let blueFoundMatches = matches( 18 | for: "\\\\w|\\\\t|\\\\n|\\\\d|\\\\s|\\[|\\]|\\\\D|\\\\S|\\\\W", 19 | in: string 20 | ) 21 | 22 | let attribute = NSMutableAttributedString(string: string) 23 | let attributeLength = attribute.string.characters.count 24 | 25 | switch theme { 26 | case "Light": 27 | attribute.addAttribute( 28 | NSAttributedStringKey.foregroundColor, 29 | value: NSColor.black, 30 | range: NSRange(location: 0, length: attribute.length) 31 | ) 32 | default: 33 | attribute.addAttribute( 34 | NSAttributedStringKey.foregroundColor, 35 | value: NSColor.white, 36 | range: NSRange(location: 0, length: attribute.length) 37 | ) 38 | } 39 | 40 | for match in purpleFoundMatches { 41 | var range = match.range(at: 0) 42 | var index = string.index(string.startIndex, offsetBy: range.location + range.length) 43 | var outputStr = String(string[.. [NSTextCheckingResult] { 80 | do { 81 | let regex = try NSRegularExpression(pattern: regex, options: []) 82 | return regex.matches( 83 | in: text, 84 | options: [], 85 | range: NSRange(location: 0, length: text.characters.count) 86 | ) 87 | } catch _ { 88 | return [] 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Regxr/RegexViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 23/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | let DEFAULT_THEME = "Light" 12 | let DEFAULT_SHOW_REFERENCE = true 13 | 14 | class RegexViewController: NSViewController, NSWindowDelegate { 15 | 16 | @IBOutlet var regexInput: NSTextView! 17 | @IBOutlet var textOutput: NSTextView! 18 | @IBOutlet weak var invalidLabel: NSTextField! 19 | @IBOutlet weak var topHalf: NSVisualEffectView! 20 | @IBOutlet weak var bottomHalf: NSVisualEffectView! 21 | @IBOutlet weak var referenceButton: NSButton! 22 | 23 | let defaults = UserDefaults.standard 24 | let highlighter = RegexHighlighter() 25 | 26 | @objc dynamic var regexTextInput: String = "" { 27 | didSet { 28 | setRegexInputColor(notification: nil) 29 | } 30 | } 31 | 32 | @objc private var attributedRegexTextInput: NSAttributedString { 33 | get { 34 | return NSAttributedString(string: self.regexTextInput) 35 | } 36 | set { 37 | self.regexTextInput = newValue.string 38 | } 39 | } 40 | 41 | @objc dynamic var textInput: String = "" { 42 | didSet { 43 | let attr = setRegexHighlight( 44 | regex: regexInput.textStorage?.string, 45 | text: self.textInput, 46 | event: nil 47 | ) 48 | setOutputHighlight(attr: attr) 49 | setRegexInputColor(notification: nil) 50 | } 51 | } 52 | 53 | @objc private var attributedTextInput: NSAttributedString { 54 | get { 55 | return NSAttributedString(string: self.textInput) 56 | } 57 | set { 58 | self.textInput = newValue.string 59 | } 60 | } 61 | 62 | // Needed because NSTextView only has an "Attributed String" binding 63 | @objc private static let keyPathsForValuesAffectingAttributedTextInput: Set = [ 64 | #keyPath(textInput), 65 | #keyPath(regexTextInput) 66 | ] 67 | 68 | override func viewWillAppear() { 69 | super.viewWillAppear() 70 | 71 | defaults.register(defaults: ["showReference": true]) 72 | 73 | if let splitViewController = self.parent as? NSSplitViewController { 74 | let showReferenceOnStartup = defaults.bool(forKey: "showReference") 75 | let splitViewItem = splitViewController.splitViewItems 76 | 77 | if (showReferenceOnStartup) { 78 | splitViewItem.last!.isCollapsed = false 79 | } else { 80 | splitViewItem.last!.isCollapsed = true 81 | } 82 | } 83 | 84 | NotificationCenter.default.addObserver( 85 | self, 86 | selector: #selector(self.setThemeColor), 87 | name: NSNotification.Name(rawValue: "changeThemeNotification"), 88 | object: nil 89 | ) 90 | 91 | NotificationCenter.default.addObserver( 92 | self, 93 | selector: #selector(self.setRegexInputColor), 94 | name: NSNotification.Name(rawValue: "changeThemeNotification"), 95 | object: nil 96 | ) 97 | } 98 | 99 | override func viewDidLoad() { 100 | super.viewDidLoad() 101 | NSEvent.addLocalMonitorForEvents(matching: .keyDown) { (event) -> NSEvent? in 102 | self.keyDown(with: event) 103 | return event 104 | } 105 | 106 | setThemeColor(notification: nil) 107 | } 108 | 109 | // Set color for regex input when regex is syntax highlighted 110 | @objc func setRegexInputColor(notification: Notification?) { 111 | var theme = notification?.object as? String ?? defaults.string(forKey: "theme") 112 | if theme == nil { 113 | theme = DEFAULT_THEME 114 | } 115 | if let theme = theme { 116 | let highlightedText = highlighter.highlight(string: self.regexTextInput, theme: theme) 117 | regexInput.textStorage?.mutableString.setString("") 118 | regexInput.textStorage?.append(highlightedText) 119 | } 120 | } 121 | 122 | @objc func setThemeColor(notification: Notification?) { 123 | var theme = notification?.object as? String ?? defaults.string(forKey: "theme") 124 | if theme == nil { 125 | theme = DEFAULT_THEME 126 | } 127 | if let theme = theme { 128 | if (theme == "Light") { 129 | self.view.window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight) 130 | topHalf.material = .light 131 | bottomHalf.material = .mediumLight 132 | regexInput.textColor = NSColor.black 133 | textOutput.textColor = NSColor.black 134 | } else { 135 | self.view.window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark) 136 | topHalf.material = .dark 137 | bottomHalf.material = .ultraDark 138 | regexInput.textColor = NSColor.white 139 | textOutput.textColor = NSColor.white 140 | } 141 | } 142 | regexInput.font = NSFont(name: "Monaco", size: 15) 143 | textOutput.font = NSFont(name: "Monaco", size: 15) 144 | } 145 | 146 | func matches(for regex: String, in text: String) -> [NSTextCheckingResult] { 147 | do { 148 | invalidLabel.stringValue = "" 149 | let regex = try NSRegularExpression(pattern: regex, options: []) 150 | let results = regex.matches( 151 | in: text, 152 | options: [], 153 | range: NSRange(location: 0, length: text.characters.count) 154 | ) 155 | return results 156 | } catch _ { 157 | if (regex.count > 0) { 158 | invalidLabel.stringValue = "Expression is invalid" 159 | } 160 | return [] 161 | } 162 | } 163 | 164 | func setOutputHighlight(attr: NSMutableAttributedString) { 165 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 166 | 167 | if (theme == "Light") { 168 | regexInput.textColor = NSColor.black 169 | textOutput.textColor = NSColor.black 170 | attr.addAttribute( 171 | NSAttributedStringKey.foregroundColor, 172 | value: NSColor.black, 173 | range: NSRange(location: 0, length: attr.length) 174 | ) 175 | } else { 176 | regexInput.textColor = NSColor.white 177 | textOutput.textColor = NSColor.white 178 | attr.addAttribute( 179 | NSAttributedStringKey.foregroundColor, 180 | value: NSColor.white, 181 | range: NSRange(location: 0, length: attr.length) 182 | ) 183 | } 184 | 185 | textOutput.textStorage?.mutableString.setString("") 186 | textOutput.textStorage?.append(attr) 187 | textOutput.font = NSFont(name: "Monaco", size: 15) 188 | } 189 | 190 | func setRegexHighlight(regex regexInput: String?, text textInput: String?, event: NSEvent?) -> NSMutableAttributedString { 191 | let topBox = regexInput 192 | let bottomBox = textInput 193 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 194 | 195 | if let topBox = topBox, let bottomBox = bottomBox { 196 | var foundMatches : [NSTextCheckingResult] = [] 197 | 198 | // If backspace, drop backspace character from regex 199 | // Otherwise get topBox regex and current key character 200 | if let event = event { 201 | if event.charactersIgnoringModifiers == String(Character(UnicodeScalar(NSDeleteCharacter)!)) { 202 | foundMatches = matches(for: String(topBox.characters.dropLast()), in: bottomBox) 203 | } else { 204 | foundMatches = matches(for: topBox + String(describing: event.characters!), in: bottomBox) 205 | } 206 | } else { 207 | foundMatches = matches(for: topBox, in: bottomBox) 208 | } 209 | 210 | let attribute = NSMutableAttributedString(string: bottomBox) 211 | let attributeLength = attribute.string.characters.count 212 | 213 | var newColor = false 214 | 215 | for match in foundMatches { 216 | var range = match.range(at: 0) 217 | var index = bottomBox.index(bottomBox.startIndex, offsetBy: range.location + range.length) 218 | var outputStr = String(bottomBox[.. 64 | body{color:#444;} 65 | span.content{color:#444} 66 | div.item:nth-child(odd) {background: rgba(0, 0, 0, 0.05);} 67 | div.item:nth-child(even) {background: rgba(0, 0, 0, 0.025);} 68 | 69 | 70 | 71 | """ 72 | default: 73 | contentToAppend = """ 74 | 80 | 81 | 82 | """ 83 | } 84 | 85 | // Check if file exists 86 | if let fileHandle = FileHandle(forWritingAtPath: filePath) { 87 | fileHandle.seekToEndOfFile() 88 | fileHandle.write(contentToAppend.data(using: String.Encoding.utf8)!) 89 | } 90 | 91 | referenceView.mainFrameURL = filePath 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Regxr/WindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.swift 3 | // Regxr 4 | // 5 | // Created by Luka Kerr on 24/9/17. 6 | // Copyright © 2017 Luka Kerr. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class WindowController: NSWindowController { 12 | 13 | let defaults = UserDefaults.standard 14 | 15 | override func windowDidLoad() { 16 | super.windowDidLoad() 17 | 18 | let theme = defaults.string(forKey: "theme") ?? DEFAULT_THEME 19 | 20 | if let window = window { 21 | setWindowColor(theme: theme) 22 | 23 | window.titleVisibility = NSWindow.TitleVisibility.hidden; 24 | window.titlebarAppearsTransparent = true; 25 | window.styleMask.insert(.fullSizeContentView) 26 | window.isOpaque = false 27 | window.invalidateShadow() 28 | } 29 | 30 | } 31 | 32 | func setWindowColor(theme: String) { 33 | if (theme == "Light") { 34 | window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantLight) 35 | } else { 36 | window?.appearance = NSAppearance(named: NSAppearance.Name.vibrantDark) 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /reference.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 55 | 56 | 57 |

Basics

58 |
59 |
.
60 |
Any character except a newline
61 |
62 |
63 |
64 | a 65 |
66 |
The letter a
67 |
68 |
69 |
70 | a|b 71 |
72 |
Either a or b
73 |
74 |
75 |
76 | a* 77 |
78 |
0 or more a's
79 |
80 |
81 |
82 | \ 83 |
84 |
Escapes a special character
85 |
86 | 87 |

Characters

88 |
89 |
\d
90 |
One digit from 0-9
91 |
92 |
93 |
94 | \w 95 |
96 |
A word
97 |
98 |
99 |
100 | \s 101 |
102 |
Whitespace character
103 |
104 |
105 |
106 | \D 107 |
108 |
One non-digit
109 |
110 |
111 |
112 | \S 113 |
114 |
One non-whitespace
115 |
116 |
117 |
118 | \W 119 |
120 |
One non-word
121 |
122 |
123 |
124 | [\b] 125 |
126 |
Backspace
127 |
128 |
129 |
130 | [a-z] 131 |
132 |
Any letter from a-z
133 |
134 |
135 |
136 | [A-Z] 137 |
138 |
Any letter from A-Z
139 |
140 | 141 |

Special Characters

142 |
143 |
144 | \n 145 |
146 |
Newline
147 |
148 |
149 |
150 | \r 151 |
152 |
Carriage return
153 |
154 |
155 |
156 | \t 157 |
158 |
Tab
159 |
160 |
161 |
162 | \0 163 |
164 |
Null character
165 |
166 | 167 |

Assertions

168 |
169 |
170 | ^ 171 |
172 |
Start of string
173 |
174 |
175 |
176 | $ 177 |
178 |
End of string
179 |
180 |
181 |
182 | \b 183 |
184 |
Word boundary
185 |
186 |
187 |
188 | \B 189 |
190 |
Non-word boundary
191 |
192 | 193 |

Quantifiers

194 |
195 |
196 | * 197 |
198 |
0 or more
199 |
200 |
201 |
202 | + 203 |
204 |
1 or more
205 |
206 |
207 |
208 | ? 209 |
210 |
0 or 1
211 |
212 |
213 |
214 | {2} 215 |
216 |
Exactly 2
217 |
218 |
219 |
220 | {2, 5} 221 |
222 |
Between 2 and 5
223 |
224 |
225 |
226 | {2,} 227 |
228 |
2 or more
229 |
230 | --------------------------------------------------------------------------------